authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-08-28 04:09:09-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-08-28 04:09:09-04:00
logd7a539906d2dd49872abb161f3d3364c9641ccd2
tree0d9c04fdc537326431a34ca2e7797c976fa4b91b
parent2a49c876be76dc98996a3251310728ad32b22363
parent1525e2c0561bb598b1e94ad9cdced5dd22e7d66d

Merge branch 'embed-lld'

Zig now depends on LLVM 5.0.0. For the latest version that supports LLVM 4.0.1, use 2a49c876be76dc98996a3251310728ad32b22363. Unfortunately we had to embed LLD into Zig due to some MACH-O related LLD bugs. One of them is already upstream and another is awaiting feedback on the llvm-dev mailing list. You can use cmake option -DZIG_FORCE_EXTERNAL_LLD=ON to still use external LLD if you want to live with the MACH-O bugs or if your system LLD is patched. Closes #273

1823 files changed, 128198 insertions(+), 857 deletions(-)

.travis.yml+10-17
......@@ -1,23 +1,16 @@
1os:
2 - linux
3 - osx
14dist: trusty
5osx_image: xcode8.3
26sudo: required
37language: cpp
48before_install:
5 - sudo sh -c 'echo "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-4.0 main" >> /etc/apt/sources.list'
6 - wget -O - http://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add -
7 - sudo apt-get update -q
9 - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ci/travis_linux_before_install; fi
10 - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ci/travis_osx_before_install; fi
811install:
9 - sudo apt-get remove -y llvm-*
10 - sudo rm -rf /usr/local/*
11 - sudo apt-get install -y clang-4.0 libclang-4.0 libclang-4.0-dev llvm-4.0 llvm-4.0-dev liblld-4.0 liblld-4.0-dev cmake
12 - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ci/travis_linux_install; fi
13 - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ci/travis_osx_install; fi
1214script:
13 - export CC=clang-4.0
14 - export CXX=clang++-4.0
15 - which $CC
16 - which $CXX
17 - echo $PATH
18 - mkdir build
19 - cd build
20 - cmake .. -DCMAKE_INSTALL_PREFIX=$(pwd) -DZIG_LIBC_LIB_DIR=$(dirname $($CC -print-file-name=crt1.o)) -DZIG_LIBC_INCLUDE_DIR=$(echo -n | $CC -E -x c - -v 2>&1 | grep -B1 "End of search list." | head -n1 | cut -c 2- | sed "s/ .*//") -DZIG_LIBC_STATIC_LIB_DIR=$(dirname $($CC -print-file-name=crtbegin.o))
21 - make VERBOSE=1
22 - make install
23 - ./zig build --build-file ../build.zig test
15 - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ci/travis_linux_script; fi
16 - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ci/travis_osx_script; fi
CMakeLists.txt+136-24
......@@ -22,6 +22,9 @@ set(ZIG_EACH_LIB_RPATH off CACHE BOOL "Add each dynamic library to rpath for nat
2222
2323option(ZIG_TEST_COVERAGE "Build Zig with test coverage instrumentation" OFF)
2424
25# To see what patches have been applied to LLD in this repository:
26# git log -p -- deps/lld
27option(ZIG_FORCE_EXTERNAL_LLD "If your system has the LLD patches use it instead of the embedded LLD" OFF)
2528
2629
2730find_package(llvm)
......@@ -31,8 +34,137 @@ link_directories(${LLVM_LIBDIRS})
3134find_package(clang)
3235include_directories(${CLANG_INCLUDE_DIRS})
3336
34find_package(lld)
35include_directories(${LLD_INCLUDE_DIRS})
37if(ZIG_FORCE_EXTERNAL_LLD)
38 find_package(lld)
39 include_directories(${LLD_INCLUDE_DIRS})
40else()
41 set(EMBEDDED_LLD_LIB_SOURCES
42 "${CMAKE_SOURCE_DIR}/deps/lld/lib/Driver/DarwinLdDriver.cpp"
43 "${CMAKE_SOURCE_DIR}/deps/lld/lib/Config/Version.cpp"
44 "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp"
45 "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/LayoutPass.cpp"
46 "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/ArchHandler.cpp"
47 "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp"
48 "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/ObjCPass.cpp"
49 "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp"
50 "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp"
51 "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp"
52 "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/TLVPass.cpp"
53 "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp"
54 "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/GOTPass.cpp"
55 "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp"
56 "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp"
57 "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp"
58 "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp"
59 "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/ShimPass.cpp"
60 "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/WriterMachO.cpp"
61 "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/StubsPass.cpp"
62 "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp"
63 "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp"
64 "${CMAKE_SOURCE_DIR}/deps/lld/lib/ReaderWriter/FileArchive.cpp"
65 "${CMAKE_SOURCE_DIR}/deps/lld/lib/Core/TargetOptionsCommandFlags.cpp"
66 "${CMAKE_SOURCE_DIR}/deps/lld/lib/Core/File.cpp"
67 "${CMAKE_SOURCE_DIR}/deps/lld/lib/Core/Error.cpp"
68 "${CMAKE_SOURCE_DIR}/deps/lld/lib/Core/SymbolTable.cpp"
69 "${CMAKE_SOURCE_DIR}/deps/lld/lib/Core/Reader.cpp"
70 "${CMAKE_SOURCE_DIR}/deps/lld/lib/Core/Reproduce.cpp"
71 "${CMAKE_SOURCE_DIR}/deps/lld/lib/Core/Writer.cpp"
72 "${CMAKE_SOURCE_DIR}/deps/lld/lib/Core/LinkingContext.cpp"
73 "${CMAKE_SOURCE_DIR}/deps/lld/lib/Core/Resolver.cpp"
74 "${CMAKE_SOURCE_DIR}/deps/lld/lib/Core/DefinedAtom.cpp"
75 )
76 set(EMBEDDED_LLD_ELF_SOURCES
77 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/ScriptLexer.cpp"
78 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/AMDGPU.cpp"
79 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/PPC.cpp"
80 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/ARM.cpp"
81 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/AVR.cpp"
82 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/SPARCV9.cpp"
83 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/Mips.cpp"
84 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/AArch64.cpp"
85 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/X86_64.cpp"
86 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/PPC64.cpp"
87 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/MipsArchTree.cpp"
88 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Arch/X86.cpp"
89 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/GdbIndex.cpp"
90 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Driver.cpp"
91 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Relocations.cpp"
92 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Error.cpp"
93 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/LTO.cpp"
94 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Strings.cpp"
95 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/ScriptParser.cpp"
96 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/MarkLive.cpp"
97 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/SyntheticSections.cpp"
98 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/SymbolTable.cpp"
99 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/LinkerScript.cpp"
100 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/EhFrame.cpp"
101 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Target.cpp"
102 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Filesystem.cpp"
103 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/OutputSections.cpp"
104 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Symbols.cpp"
105 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/ICF.cpp"
106 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/InputFiles.cpp"
107 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Thunks.cpp"
108 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/DriverUtils.cpp"
109 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/Writer.cpp"
110 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/InputSection.cpp"
111 "${CMAKE_SOURCE_DIR}/deps/lld/ELF/MapFile.cpp"
112 )
113 set(EMBEDDED_LLD_COFF_SOURCES
114 "${CMAKE_SOURCE_DIR}/deps/lld/COFF/DLL.cpp"
115 "${CMAKE_SOURCE_DIR}/deps/lld/COFF/Driver.cpp"
116 "${CMAKE_SOURCE_DIR}/deps/lld/COFF/Chunks.cpp"
117 "${CMAKE_SOURCE_DIR}/deps/lld/COFF/PDB.cpp"
118 "${CMAKE_SOURCE_DIR}/deps/lld/COFF/Error.cpp"
119 "${CMAKE_SOURCE_DIR}/deps/lld/COFF/LTO.cpp"
120 "${CMAKE_SOURCE_DIR}/deps/lld/COFF/Strings.cpp"
121 "${CMAKE_SOURCE_DIR}/deps/lld/COFF/MarkLive.cpp"
122 "${CMAKE_SOURCE_DIR}/deps/lld/COFF/SymbolTable.cpp"
123 "${CMAKE_SOURCE_DIR}/deps/lld/COFF/Symbols.cpp"
124 "${CMAKE_SOURCE_DIR}/deps/lld/COFF/ICF.cpp"
125 "${CMAKE_SOURCE_DIR}/deps/lld/COFF/InputFiles.cpp"
126 "${CMAKE_SOURCE_DIR}/deps/lld/COFF/DriverUtils.cpp"
127 "${CMAKE_SOURCE_DIR}/deps/lld/COFF/Writer.cpp"
128 "${CMAKE_SOURCE_DIR}/deps/lld/COFF/MapFile.cpp"
129 )
130 add_library(embedded_lld_lib ${EMBEDDED_LLD_LIB_SOURCES})
131 add_library(embedded_lld_elf ${EMBEDDED_LLD_ELF_SOURCES})
132 add_library(embedded_lld_coff ${EMBEDDED_LLD_COFF_SOURCES})
133 set_target_properties(embedded_lld_lib PROPERTIES
134 COMPILE_FLAGS "-std=c++11 -fno-exceptions -fno-rtti -Wno-comment"
135 LINK_FLAGS " "
136 )
137 set_target_properties(embedded_lld_elf PROPERTIES
138 COMPILE_FLAGS "-std=c++11 -fno-exceptions -fno-rtti -Wno-comment"
139 LINK_FLAGS " "
140 )
141 set_target_properties(embedded_lld_coff PROPERTIES
142 COMPILE_FLAGS "-std=c++11 -fno-exceptions -fno-rtti -Wno-comment"
143 LINK_FLAGS " "
144 )
145 target_include_directories(embedded_lld_lib PUBLIC
146 "${CMAKE_SOURCE_DIR}/deps/lld/include"
147 "${CMAKE_SOURCE_DIR}/deps/lld-prebuilt"
148 )
149 target_include_directories(embedded_lld_elf PUBLIC
150 "${CMAKE_SOURCE_DIR}/deps/lld/ELF"
151 "${CMAKE_SOURCE_DIR}/deps/lld/include"
152 "${CMAKE_SOURCE_DIR}/deps/lld-prebuilt/ELF"
153 "${CMAKE_SOURCE_DIR}/deps/lld-prebuilt"
154 )
155 target_include_directories(embedded_lld_coff PUBLIC
156 "${CMAKE_SOURCE_DIR}/deps/lld/COFF"
157 "${CMAKE_SOURCE_DIR}/deps/lld/include"
158 "${CMAKE_SOURCE_DIR}/deps/lld-prebuilt/COFF"
159 "${CMAKE_SOURCE_DIR}/deps/lld-prebuilt"
160 )
161 set(LLD_INCLUDE_DIRS "")
162 set(LLD_LIBRARIES
163 embedded_lld_elf
164 embedded_lld_coff
165 embedded_lld_lib
166 )
167endif()
36168
37169find_package(Threads)
38170
......@@ -65,26 +197,6 @@ set(ZIG_SOURCES
65197 "${CMAKE_SOURCE_DIR}/src/zig_llvm.cpp"
66198)
67199
68set(ZIG_HOST_LINK_VERSION)
69if (APPLE)
70 set(LD_V_OUTPUT)
71 execute_process(
72 COMMAND sh -c "${CMAKE_LINKER} -v 2>&1 | head -1"
73 RESULT_VARIABLE HAD_ERROR
74 OUTPUT_VARIABLE LD_V_OUTPUT
75 )
76 if (NOT HAD_ERROR)
77 if ("${LD_V_OUTPUT}" MATCHES ".*ld64-([0-9.]+).*")
78 string(REGEX REPLACE ".*ld64-([0-9.]+).*" "\\1" ZIG_HOST_LINK_VERSION ${LD_V_OUTPUT})
79 elseif ("${LD_V_OUTPUT}" MATCHES "[^0-9]*([0-9.]+).*")
80 string(REGEX REPLACE "[^0-9]*([0-9.]+).*" "\\1" ZIG_HOST_LINK_VERSION ${LD_V_OUTPUT})
81 endif()
82 else()
83 message(FATAL_ERROR "${CMAKE_LINKER} failed with status ${HAD_ERROR}")
84 endif()
85endif()
86
87
88200set(C_HEADERS_DEST "lib/zig/include")
89201set(ZIG_STD_DEST "lib/zig/std")
90202set(CONFIGURE_OUT_FILE "${CMAKE_BINARY_DIR}/config.h")
......@@ -297,10 +409,10 @@ install(FILES "${CMAKE_SOURCE_DIR}/std/mem.zig" DESTINATION "${ZIG_STD_DEST}")
297409install(FILES "${CMAKE_SOURCE_DIR}/std/net.zig" DESTINATION "${ZIG_STD_DEST}")
298410install(FILES "${CMAKE_SOURCE_DIR}/std/os/child_process.zig" DESTINATION "${ZIG_STD_DEST}/os")
299411install(FILES "${CMAKE_SOURCE_DIR}/std/os/darwin.zig" DESTINATION "${ZIG_STD_DEST}/os")
300install(FILES "${CMAKE_SOURCE_DIR}/std/os/darwin_x86_64.zig" DESTINATION "${ZIG_STD_DEST}/os")
301install(FILES "${CMAKE_SOURCE_DIR}/std/os/errno.zig" DESTINATION "${ZIG_STD_DEST}/os")
412install(FILES "${CMAKE_SOURCE_DIR}/std/os/darwin_errno.zig" DESTINATION "${ZIG_STD_DEST}/os")
302413install(FILES "${CMAKE_SOURCE_DIR}/std/os/index.zig" DESTINATION "${ZIG_STD_DEST}/os")
303414install(FILES "${CMAKE_SOURCE_DIR}/std/os/linux.zig" DESTINATION "${ZIG_STD_DEST}/os")
415install(FILES "${CMAKE_SOURCE_DIR}/std/os/linux_errno.zig" DESTINATION "${ZIG_STD_DEST}/os")
304416install(FILES "${CMAKE_SOURCE_DIR}/std/os/linux_i386.zig" DESTINATION "${ZIG_STD_DEST}/os")
305417install(FILES "${CMAKE_SOURCE_DIR}/std/os/linux_x86_64.zig" DESTINATION "${ZIG_STD_DEST}/os")
306418install(FILES "${CMAKE_SOURCE_DIR}/std/os/path.zig" DESTINATION "${ZIG_STD_DEST}/os")
README.md+1-1
......@@ -76,7 +76,7 @@ the Zig compiler itself:
7676These libraries must be installed on your system, with the development files
7777available. The Zig compiler links against them.
7878
79 * LLVM, Clang, and LLD libraries == 4.x
79 * LLVM, Clang, and LLD libraries == 5.x
8080
8181### Debug / Development Build
8282
ci/travis_linux_before_install created+8
......@@ -0,0 +1,8 @@
1#!/bin/sh
2
3set -x
4
5sudo sh -c 'echo "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-5.0 main" >> /etc/apt/sources.list'
6wget -O - http://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add -
7sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
8sudo apt-get update -q
ci/travis_linux_install created+7
......@@ -0,0 +1,7 @@
1#!/bin/sh
2
3set -x
4
5sudo apt-get remove -y llvm-*
6sudo rm -rf /usr/local/*
7sudo apt-get install -y clang-5.0 libclang-5.0 libclang-5.0-dev llvm-5.0 llvm-5.0-dev liblld-5.0 liblld-5.0-dev cmake
ci/travis_linux_script created+15
......@@ -0,0 +1,15 @@
1#!/bin/sh
2
3set -x
4
5export CC=clang-5.0
6export CXX=clang++-5.0
7which $CC
8which $CXX
9echo $PATH
10mkdir build
11cd build
12cmake .. -DCMAKE_INSTALL_PREFIX=$(pwd) -DZIG_LIBC_LIB_DIR=$(dirname $($CC -print-file-name=crt1.o)) -DZIG_LIBC_INCLUDE_DIR=$(echo -n | $CC -E -x c - -v 2>&1 | grep -B1 "End of search list." | head -n1 | cut -c 2- | sed "s/ .*//") -DZIG_LIBC_STATIC_LIB_DIR=$(dirname $($CC -print-file-name=crtbegin.o)) -DZIG_FORCE_EXTERNAL_LLD=ON
13make VERBOSE=1
14make install
15./zig build --build-file ../build.zig test
ci/travis_osx_before_install created+5
......@@ -0,0 +1,5 @@
1#!/bin/sh
2
3set -x
4
5brew update
ci/travis_osx_install created+19
......@@ -0,0 +1,19 @@
1#!/bin/sh
2
3set -x
4
5brew install gcc@7
6brew outdated gcc@7 || brew upgrade gcc@7
7brew link --overwrite gcc@7
8
9SRC_DIR=$(pwd)
10PREFIX_DIR=$HOME/local/llvm5
11export CC=/usr/local/opt/gcc/bin/gcc-7
12export CXX=/usr/local/opt/gcc/bin/g++-7
13
14mkdir -p $HOME/local
15cd $HOME/local
16wget http://s3.amazonaws.com/superjoe/temp/llvm5.tar.xz
17tar xfp llvm5.tar.xz
18
19cd $SRC_DIR
ci/travis_osx_script created+15
......@@ -0,0 +1,15 @@
1#!/bin/sh
2
3set -x
4
5PREFIX_DIR=$HOME/local/llvm5
6export CC=/usr/local/opt/gcc/bin/gcc-7
7export CXX=/usr/local/opt/gcc/bin/g++-7
8
9echo $PATH
10mkdir build
11cd build
12cmake .. -DCMAKE_PREFIX_PATH=$PREFIX_DIR -DCMAKE_INSTALL_PREFIX=$(pwd) -DZIG_LIBC_LIB_DIR=$(dirname $($CC -print-file-name=crt1.o)) -DZIG_LIBC_INCLUDE_DIR=$(echo -n | $CC -E -x c - -v 2>&1 | grep -B1 "End of search list." | head -n1 | cut -c 2- | sed "s/ .*//") -DZIG_LIBC_STATIC_LIB_DIR=$(dirname $($CC -print-file-name=crtbegin.o)) -DZIG_FORCE_EXTERNAL_LLD=ON
13make VERBOSE=1
14make install
15./zig build --build-file ../build.zig test
cmake/Findclang.cmake+2-2
......@@ -8,14 +8,14 @@
88
99find_path(CLANG_INCLUDE_DIRS NAMES clang/Frontend/ASTUnit.h
1010 PATHS
11 /usr/lib/llvm-4.0/include
11 /usr/lib/llvm-5.0/include
1212 /mingw64/include)
1313
1414 macro(FIND_AND_ADD_CLANG_LIB _libname_)
1515 string(TOUPPER ${_libname_} _prettylibname_)
1616 find_library(CLANG_${_prettylibname_}_LIB NAMES ${_libname_}
1717 PATHS
18 /usr/lib/llvm-4.0/lib
18 /usr/lib/llvm-5.0/lib
1919 /mingw64/lib
2020 /c/msys64/mingw64/lib
2121 c:\\msys64\\mingw64\\lib)
cmake/Findlld.cmake+3-3
......@@ -8,10 +8,10 @@
88
99find_path(LLD_INCLUDE_DIRS NAMES lld/Driver/Driver.h
1010 PATHS
11 /usr/lib/llvm-4.0/include
11 /usr/lib/llvm-5.0/include
1212 /mingw64/include)
1313
14find_library(LLD_LIBRARY NAMES lld-4.0 lld PATHS /usr/lib/llvm-4.0/lib)
14find_library(LLD_LIBRARY NAMES lld-5.0 lld PATHS /usr/lib/llvm-5.0/lib)
1515if(EXISTS ${LLD_LIBRARY})
1616 set(LLD_LIBRARIES ${LLD_LIBRARY})
1717else()
......@@ -19,7 +19,7 @@ else()
1919 string(TOUPPER ${_libname_} _prettylibname_)
2020 find_library(LLD_${_prettylibname_}_LIB NAMES ${_libname_}
2121 PATHS
22 /usr/lib/llvm-4.0/lib
22 /usr/lib/llvm-5.0/lib
2323 /mingw64/lib
2424 /c/msys64/mingw64/lib
2525 c:/msys64/mingw64/lib)
cmake/Findllvm.cmake+2-2
......@@ -8,12 +8,12 @@
88# LLVM_LIBDIRS
99
1010find_program(LLVM_CONFIG_EXE
11 NAMES llvm-config llvm-config-4.0
11 NAMES llvm-config llvm-config-5.0
1212 PATHS
1313 "/mingw64/bin"
1414 "/c/msys64/mingw64/bin"
1515 "c:/msys64/mingw64/bin"
16 "C:/Libraries/llvm-4.0.0/bin")
16 "C:/Libraries/llvm-5.0.0/bin")
1717
1818execute_process(
1919 COMMAND ${LLVM_CONFIG_EXE} --libs
deps/lld-prebuilt/COFF/Options.inc created+174
......@@ -0,0 +1,174 @@
1/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
2|* *|
3|* Option Parsing Definitions *|
4|* *|
5|* Automatically generated file, do not edit! *|
6|* *|
7\*===----------------------------------------------------------------------===*/
8
9/////////
10// Prefixes
11
12#ifdef PREFIX
13#define COMMA ,
14PREFIX(prefix_0, {nullptr})
15PREFIX(prefix_2, {"/" COMMA "-" COMMA nullptr})
16PREFIX(prefix_1, {"/" COMMA "-" COMMA "-?" COMMA nullptr})
17PREFIX(prefix_3, {"/?" COMMA "-?" COMMA nullptr})
18#undef COMMA
19#endif // PREFIX
20
21/////////
22// Groups
23
24#ifdef OPTION
25
26//////////
27// Options
28
29OPTION(prefix_0, "<input>", INPUT, Input, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
30OPTION(prefix_0, "<unknown>", UNKNOWN, Unknown, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
31OPTION(prefix_1, "align:", align, Joined, INVALID, INVALID, nullptr, 0, 0,
32 "Section alignment", nullptr, nullptr)
33OPTION(prefix_1, "allowbind:no", allowbind_no, Flag, INVALID, INVALID, nullptr, 0, 0,
34 "Disable DLL binding", nullptr, nullptr)
35OPTION(prefix_1, "allowbind", allowbind, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
36OPTION(prefix_1, "allowisolation:no", allowisolation_no, Flag, INVALID, INVALID, nullptr, 0, 0,
37 "Set NO_ISOLATION bit", nullptr, nullptr)
38OPTION(prefix_1, "allowisolation", allowisolation, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
39OPTION(prefix_1, "alternatename:", alternatename, Joined, INVALID, INVALID, nullptr, 0, 0,
40 "Define weak alias", nullptr, nullptr)
41OPTION(prefix_1, "appcontainer:no", appcontainer_no, Flag, INVALID, INVALID, nullptr, 0, 0,
42 "Image can only be run in an app container", nullptr, nullptr)
43OPTION(prefix_1, "appcontainer", appcontainer, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
44OPTION(prefix_1, "base:", base, Joined, INVALID, INVALID, nullptr, 0, 0,
45 "Base address of the program", nullptr, nullptr)
46OPTION(prefix_1, "debugtype:", debugtype, Joined, INVALID, INVALID, nullptr, 0, 0,
47 "Debug Info Options", nullptr, nullptr)
48OPTION(prefix_1, "debug", debug, Flag, INVALID, INVALID, nullptr, 0, 0,
49 "Embed a symbol table in the image", nullptr, nullptr)
50OPTION(prefix_2, "def:", deffile, Joined, INVALID, INVALID, nullptr, 0, 0,
51 "Use module-definition file", nullptr, nullptr)
52OPTION(prefix_1, "defaultlib:", defaultlib, Joined, INVALID, INVALID, nullptr, 0, 0,
53 "Add the library to the list of input files", nullptr, nullptr)
54OPTION(prefix_1, "delay:", delay, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
55OPTION(prefix_1, "delayload:", delayload, Joined, INVALID, INVALID, nullptr, 0, 0,
56 "Delay loaded DLL name", nullptr, nullptr)
57OPTION(prefix_1, "disallowlib:", disallowlib, Joined, INVALID, nodefaultlib, nullptr, 0, 0, nullptr, nullptr, nullptr)
58OPTION(prefix_1, "dll", dll, Flag, INVALID, INVALID, nullptr, 0, 0,
59 "Create a DLL", nullptr, nullptr)
60OPTION(prefix_1, "driver:", driver, Joined, INVALID, INVALID, nullptr, 0, 0,
61 "Generate a Windows NT Kernel Mode Driver", nullptr, nullptr)
62OPTION(prefix_1, "dynamicbase:no", dynamicbase_no, Flag, INVALID, INVALID, nullptr, 0, 0,
63 "Disable address space layout randomization", nullptr, nullptr)
64OPTION(prefix_1, "dynamicbase", dynamicbase, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
65OPTION(prefix_1, "editandcontinue", editandcontinue, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
66OPTION(prefix_1, "entry:", entry, Joined, INVALID, INVALID, nullptr, 0, 0,
67 "Name of entry point symbol", nullptr, nullptr)
68OPTION(prefix_1, "errorlimit:", errorlimit, Joined, INVALID, INVALID, nullptr, 0, 0,
69 "Maximum number of errors to emit before stopping (0 = no limit)", nullptr, nullptr)
70OPTION(prefix_1, "errorreport:", errorreport, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
71OPTION(prefix_1, "export:", export, Joined, INVALID, INVALID, nullptr, 0, 0,
72 "Export a function", nullptr, nullptr)
73OPTION(prefix_1, "failifmismatch:", failifmismatch, Joined, INVALID, INVALID, nullptr, 0, 0,
74 "", nullptr, nullptr)
75OPTION(prefix_1, "fastfail", fastfail, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
76OPTION(prefix_1, "fixed:no", fixed_no, Flag, INVALID, INVALID, nullptr, 0, 0,
77 "Enable base relocations", nullptr, nullptr)
78OPTION(prefix_1, "fixed", fixed, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
79OPTION(prefix_1, "force:unresolved", force_unresolved, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
80OPTION(prefix_1, "force", force, Flag, INVALID, INVALID, nullptr, 0, 0,
81 "Allow undefined symbols when creating executables", nullptr, nullptr)
82OPTION(prefix_1, "functionpadmin", functionpadmin, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
83OPTION(prefix_1, "guardsym:", guardsym, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
84OPTION(prefix_1, "heap:", heap, Joined, INVALID, INVALID, nullptr, 0, 0,
85 "Size of the heap", nullptr, nullptr)
86OPTION(prefix_1, "help", help, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
87OPTION(prefix_1, "highentropyva:no", highentropyva_no, Flag, INVALID, INVALID, nullptr, 0, 0,
88 "Set HIGH_ENTROPY_VA bit", nullptr, nullptr)
89OPTION(prefix_1, "highentropyva", highentropyva, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
90OPTION(prefix_1, "idlout:", idlout, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
91OPTION(prefix_1, "ignore:", ignore, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
92OPTION(prefix_1, "ignoreidl", ignoreidl, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
93OPTION(prefix_1, "implib:", implib, Joined, INVALID, INVALID, nullptr, 0, 0,
94 "Import library name", nullptr, nullptr)
95OPTION(prefix_2, "include:", incl, Joined, INVALID, INVALID, nullptr, 0, 0,
96 "Force symbol to be added to symbol table as undefined one", nullptr, nullptr)
97OPTION(prefix_1, "incremental:no", no_incremental, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
98OPTION(prefix_1, "incremental", incremental, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
99OPTION(prefix_1, "largeaddressaware:no", largeaddressaware_no, Flag, INVALID, INVALID, nullptr, 0, 0,
100 "Disable large addresses", nullptr, nullptr)
101OPTION(prefix_1, "largeaddressaware", largeaddressaware, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
102OPTION(prefix_1, "libpath:", libpath, Joined, INVALID, INVALID, nullptr, 0, 0,
103 "Additional library search path", nullptr, nullptr)
104OPTION(prefix_1, "linkrepro:", linkrepro, Joined, INVALID, INVALID, nullptr, 0, 0,
105 "Dump linker invocation and input files for debugging", nullptr, nullptr)
106OPTION(prefix_2, "lldmap:", lldmap_file, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
107OPTION(prefix_1, "lldmap", lldmap, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
108OPTION(prefix_1, "lldsavetemps", lldsavetemps, Flag, INVALID, INVALID, nullptr, 0, 0,
109 "Save temporary files instead of deleting them", nullptr, nullptr)
110OPTION(prefix_1, "machine:", machine, Joined, INVALID, INVALID, nullptr, 0, 0,
111 "Specify target platform", nullptr, nullptr)
112OPTION(prefix_1, "manifest:", manifest_colon, Joined, INVALID, INVALID, nullptr, 0, 0,
113 "Create manifest file", nullptr, nullptr)
114OPTION(prefix_1, "manifestdependency:", manifestdependency, Joined, INVALID, INVALID, nullptr, 0, 0,
115 "Attributes for <dependency> in manifest file", nullptr, nullptr)
116OPTION(prefix_1, "manifestfile:", manifestfile, Joined, INVALID, INVALID, nullptr, 0, 0,
117 "Manifest file path", nullptr, nullptr)
118OPTION(prefix_1, "manifestinput:", manifestinput, Joined, INVALID, INVALID, nullptr, 0, 0,
119 "Specify manifest file", nullptr, nullptr)
120OPTION(prefix_1, "manifestuac:", manifestuac, Joined, INVALID, INVALID, nullptr, 0, 0,
121 "User access control", nullptr, nullptr)
122OPTION(prefix_1, "manifest", manifest, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
123OPTION(prefix_1, "maxilksize:", maxilksize, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
124OPTION(prefix_1, "merge:", merge, Joined, INVALID, INVALID, nullptr, 0, 0,
125 "Combine sections", nullptr, nullptr)
126OPTION(prefix_1, "mllvm:", mllvm, Joined, INVALID, INVALID, nullptr, 0, 0,
127 "Options to pass to LLVM", nullptr, nullptr)
128OPTION(prefix_1, "msvclto", msvclto, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
129OPTION(prefix_1, "nodefaultlib:", nodefaultlib, Joined, INVALID, INVALID, nullptr, 0, 0,
130 "Remove a default library", nullptr, nullptr)
131OPTION(prefix_1, "nodefaultlib", nodefaultlib_all, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
132OPTION(prefix_1, "noentry", noentry, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
133OPTION(prefix_1, "nologo", nologo, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
134OPTION(prefix_1, "nopdb", nopdb, Flag, INVALID, INVALID, nullptr, 0, 0,
135 "Disable PDB generation for DWARF users", nullptr, nullptr)
136OPTION(prefix_1, "nosymtab", nosymtab, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
137OPTION(prefix_1, "nxcompat:no", nxcompat_no, Flag, INVALID, INVALID, nullptr, 0, 0,
138 "Disable data execution provention", nullptr, nullptr)
139OPTION(prefix_1, "nxcompat", nxcompat, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
140OPTION(prefix_1, "opt:", opt, Joined, INVALID, INVALID, nullptr, 0, 0,
141 "Control optimizations", nullptr, nullptr)
142OPTION(prefix_1, "out:", out, Joined, INVALID, INVALID, nullptr, 0, 0,
143 "Path to file to write output", nullptr, nullptr)
144OPTION(prefix_1, "pdb:", pdb, Joined, INVALID, INVALID, nullptr, 0, 0,
145 "PDB file path", nullptr, nullptr)
146OPTION(prefix_1, "pdbaltpath:", pdbaltpath, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
147OPTION(prefix_1, "profile", profile, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
148OPTION(prefix_1, "safeseh:no", safeseh_no, Flag, INVALID, INVALID, nullptr, 0, 0,
149 "Produce an image with Safe Exception Handler", nullptr, nullptr)
150OPTION(prefix_1, "safeseh", safeseh, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
151OPTION(prefix_1, "section:", section, Joined, INVALID, INVALID, nullptr, 0, 0,
152 "Specify section attributes", nullptr, nullptr)
153OPTION(prefix_1, "stack:", stack, Joined, INVALID, INVALID, nullptr, 0, 0,
154 "Size of the stack", nullptr, nullptr)
155OPTION(prefix_1, "stub:", stub, Joined, INVALID, INVALID, nullptr, 0, 0,
156 "Specify DOS stub file", nullptr, nullptr)
157OPTION(prefix_1, "subsystem:", subsystem, Joined, INVALID, INVALID, nullptr, 0, 0,
158 "Specify subsystem", nullptr, nullptr)
159OPTION(prefix_1, "swaprun:cd", swaprun_cd, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
160OPTION(prefix_1, "swaprun:net", swaprun_net, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
161OPTION(prefix_1, "throwingnew", throwingnew, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
162OPTION(prefix_1, "tlbid:", tlbid, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
163OPTION(prefix_1, "tlbout:", tlbout, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
164OPTION(prefix_1, "tsaware:no", tsaware_no, Flag, INVALID, INVALID, nullptr, 0, 0,
165 "Create non-Terminal Server aware executable", nullptr, nullptr)
166OPTION(prefix_1, "tsaware", tsaware, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
167OPTION(prefix_1, "verbose:", verbose_all, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
168OPTION(prefix_1, "verbose", verbose, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
169OPTION(prefix_1, "version:", version, Joined, INVALID, INVALID, nullptr, 0, 0,
170 "Specify a version number in the PE header", nullptr, nullptr)
171OPTION(prefix_1, "wx:no", wx_no, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
172OPTION(prefix_1, "wx", wx, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
173OPTION(prefix_3, "", help_q, Flag, INVALID, help, nullptr, 0, 0, nullptr, nullptr, nullptr)
174#endif // OPTION
deps/lld-prebuilt/DarwinLdOptions.inc created+189
......@@ -0,0 +1,189 @@
1/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
2|* *|
3|* Option Parsing Definitions *|
4|* *|
5|* Automatically generated file, do not edit! *|
6|* *|
7\*===----------------------------------------------------------------------===*/
8
9/////////
10// Prefixes
11
12#ifdef PREFIX
13#define COMMA ,
14PREFIX(prefix_0, {nullptr})
15PREFIX(prefix_1, {"-" COMMA nullptr})
16#undef COMMA
17#endif // PREFIX
18
19/////////
20// Groups
21
22#ifdef OPTION
23OPTION(nullptr, "opts", grp_bundle, Group, INVALID, INVALID, nullptr, 0, 0,
24 "BUNDLE EXECUTABLE OPTIONS", nullptr, nullptr)
25OPTION(nullptr, "opts", grp_dylib, Group, INVALID, INVALID, nullptr, 0, 0,
26 "DYLIB EXECUTABLE OPTIONS", nullptr, nullptr)
27OPTION(nullptr, "outs", grp_kind, Group, INVALID, INVALID, nullptr, 0, 0,
28 "OUTPUT KIND", nullptr, nullptr)
29OPTION(nullptr, "libs", grp_libs, Group, INVALID, INVALID, nullptr, 0, 0,
30 "LIBRARY OPTIONS", nullptr, nullptr)
31OPTION(nullptr, "opts", grp_main, Group, INVALID, INVALID, nullptr, 0, 0,
32 "MAIN EXECUTABLE OPTIONS", nullptr, nullptr)
33OPTION(nullptr, "obsolete", grp_obsolete, Group, INVALID, INVALID, nullptr, 0, 0,
34 "OBSOLETE OPTIONS", nullptr, nullptr)
35OPTION(nullptr, "opts", grp_opts, Group, INVALID, INVALID, nullptr, 0, 0,
36 "OPTIMIZATIONS", nullptr, nullptr)
37
38//////////
39// Options
40
41OPTION(prefix_0, "<input>", INPUT, Input, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
42OPTION(prefix_0, "<unknown>", UNKNOWN, Unknown, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
43OPTION(prefix_1, "all_load", all_load, Flag, grp_libs, INVALID, nullptr, 0, 0,
44 "Forces all members of all static libraries to be loaded", nullptr, nullptr)
45OPTION(prefix_1, "arch", arch, Separate, INVALID, INVALID, nullptr, 0, 0,
46 "Architecture to link", "<arch-name>", nullptr)
47OPTION(prefix_1, "bundle_loader", bundle_loader, Separate, grp_bundle, INVALID, nullptr, 0, 0,
48 "The executable that will be loading this Mach-O bundle", "<path>", nullptr)
49OPTION(prefix_1, "bundle", bundle, Flag, grp_kind, INVALID, nullptr, 0, 0,
50 "Create dynamic bundle", nullptr, nullptr)
51OPTION(prefix_1, "compatibility_version", compatibility_version, Separate, grp_dylib, INVALID, nullptr, 0, 0,
52 "The dylib's compatibility version", "<version>", nullptr)
53OPTION(prefix_1, "current_version", current_version, Separate, grp_dylib, INVALID, nullptr, 0, 0,
54 "The dylib's current version", "<version>", nullptr)
55OPTION(prefix_1, "data_in_code_info", data_in_code_info, Flag, grp_opts, INVALID, nullptr, 0, 0,
56 "Force generation of a data in code load command", nullptr, nullptr)
57OPTION(prefix_1, "dead_strip", dead_strip, Flag, grp_opts, INVALID, nullptr, 0, 0,
58 "Remove unreference code and data", nullptr, nullptr)
59OPTION(prefix_1, "demangle", demangle, Flag, INVALID, INVALID, nullptr, 0, 0,
60 "Demangles symbol names in errors and warnings", nullptr, nullptr)
61OPTION(prefix_1, "dependency_info", dependency_info, Separate, INVALID, INVALID, nullptr, 0, 0,
62 "Write binary list of files used during link", "<file>", nullptr)
63OPTION(prefix_1, "dylib_compatibility_version", dylib_compatibility_version, Separate, INVALID, compatibility_version, nullptr, 0, 0, nullptr, "<version>", nullptr)
64OPTION(prefix_1, "dylib_current_version", dylib_current_version, Separate, INVALID, current_version, nullptr, 0, 0, nullptr, "<version>", nullptr)
65OPTION(prefix_1, "dylib_install_name", dylib_install_name, Separate, INVALID, install_name, nullptr, 0, 0, nullptr, nullptr, nullptr)
66OPTION(prefix_1, "dylib", dylib, Flag, grp_kind, INVALID, nullptr, 0, 0,
67 "Create dynamic library", nullptr, nullptr)
68OPTION(prefix_1, "dynamic", dynamic, Flag, grp_kind, INVALID, nullptr, 0, 0,
69 "Create dynamic executable (default)", nullptr, nullptr)
70OPTION(prefix_1, "execute", execute, Flag, grp_kind, INVALID, nullptr, 0, 0,
71 "Create main executable (default)", nullptr, nullptr)
72OPTION(prefix_1, "export_dynamic", export_dynamic, Flag, grp_main, INVALID, nullptr, 0, 0,
73 "Preserves all global symbols in main executables during LTO", nullptr, nullptr)
74OPTION(prefix_1, "exported_symbols_list", exported_symbols_list, Separate, grp_opts, INVALID, nullptr, 0, 0,
75 "Restricts which symbols will be exported", "<file-path>", nullptr)
76OPTION(prefix_1, "exported_symbol", exported_symbol, Separate, grp_opts, INVALID, nullptr, 0, 0,
77 "Restricts which symbols will be exported", "<symbol>", nullptr)
78OPTION(prefix_1, "e", entry, Separate, grp_main, INVALID, nullptr, 0, 0,
79 "entry symbol name", "<entry-name>", nullptr)
80OPTION(prefix_1, "filelist", filelist, Separate, INVALID, INVALID, nullptr, 0, 0,
81 "file containing paths to input files", "<path>", nullptr)
82OPTION(prefix_1, "flat_namespace", flat_namespace, Flag, grp_opts, INVALID, nullptr, 0, 0,
83 "Resolves symbols in any (transitively) linked dynamic libraries. Source libraries are not recorded: dyld will re-search all images at runtime and use the first definition found.", nullptr, nullptr)
84OPTION(prefix_1, "force_load", force_load, Separate, grp_libs, INVALID, nullptr, 0, 0,
85 "Forces all members of specified static libraries to be loaded", "<library-path>", nullptr)
86OPTION(prefix_1, "framework", framework, Separate, INVALID, INVALID, nullptr, 0, 0,
87 "Base name of framework searched for in -F directories", "<name>", nullptr)
88OPTION(prefix_1, "function_starts", function_starts, Flag, grp_opts, INVALID, nullptr, 0, 0,
89 "Force generation of a function starts load command", nullptr, nullptr)
90OPTION(prefix_1, "F", F, JoinedOrSeparate, grp_libs, INVALID, nullptr, 0, 0,
91 "Add directory to framework search path", "<dir>", nullptr)
92OPTION(prefix_1, "image_base", image_base, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
93OPTION(prefix_1, "install_name", install_name, Separate, grp_dylib, INVALID, nullptr, 0, 0,
94 "The dylib's install name", "<path>", nullptr)
95OPTION(prefix_1, "ios_simulator_version_min", ios_simulator_version_min, Separate, grp_opts, INVALID, nullptr, 0, 0,
96 "Minimum iOS simulator version", "<version>", nullptr)
97OPTION(prefix_1, "ios_version_min", ios_version_min, Separate, grp_opts, INVALID, nullptr, 0, 0,
98 "Minimum iOS version", "<version>", nullptr)
99OPTION(prefix_1, "iphoneos_version_min", iphoneos_version_min, Separate, INVALID, ios_version_min, nullptr, 0, 0, nullptr, nullptr, nullptr)
100OPTION(prefix_1, "keep_private_externs", keep_private_externs, Flag, grp_opts, INVALID, nullptr, 0, 0,
101 "Private extern (hidden) symbols should not be transformed into local symbols", nullptr, nullptr)
102OPTION(prefix_1, "L", L, JoinedOrSeparate, grp_libs, INVALID, nullptr, 0, 0,
103 "Add directory to library search path", "<dir>", nullptr)
104OPTION(prefix_1, "l", l, Joined, INVALID, INVALID, nullptr, 0, 0,
105 "Base name of library searched for in -L directories", "<libname>", nullptr)
106OPTION(prefix_1, "macosx_version_min", macosx_version_min, Separate, grp_opts, INVALID, nullptr, 0, 0,
107 "Minimum Mac OS X version", "<version>", nullptr)
108OPTION(prefix_1, "mark_dead_strippable_dylib", mark_dead_strippable_dylib, Flag, grp_dylib, INVALID, nullptr, 0, 0,
109 "Marks the dylib as having no side effects during initialization", nullptr, nullptr)
110OPTION(prefix_1, "mllvm", mllvm, Separate, grp_opts, INVALID, nullptr, 0, 0,
111 "Options to pass to LLVM during LTO", "<option>", nullptr)
112OPTION(prefix_1, "multi_module", multi_module, Flag, grp_obsolete, INVALID, nullptr, 0, 0,
113 "Unsupported way to build dylibs", nullptr, nullptr)
114OPTION(prefix_1, "no_data_in_code_info", no_data_in_code_info, Flag, grp_opts, INVALID, nullptr, 0, 0,
115 "Disable generation of a data in code load command", nullptr, nullptr)
116OPTION(prefix_1, "no_function_starts", no_function_starts, Flag, grp_opts, INVALID, nullptr, 0, 0,
117 "Disable generation of a function starts load command", nullptr, nullptr)
118OPTION(prefix_1, "no_objc_category_merging", no_objc_category_merging, Flag, grp_opts, INVALID, nullptr, 0, 0,
119 "Disables the optimisation which merges Objective-C categories on a class in to the class itself.", nullptr, nullptr)
120OPTION(prefix_1, "no_pie", no_pie, Flag, grp_main, INVALID, nullptr, 0, 0,
121 "Do not create Position Independent Executable", nullptr, nullptr)
122OPTION(prefix_1, "no_version_load_command", no_version_load_command, Flag, grp_opts, INVALID, nullptr, 0, 0,
123 "Disable generation of a version load command", nullptr, nullptr)
124OPTION(prefix_1, "objc_gc_compaction", objc_gc_compaction, Flag, grp_obsolete, INVALID, nullptr, 0, 0,
125 "Unsupported ObjC GC option", nullptr, nullptr)
126OPTION(prefix_1, "objc_gc_only", objc_gc_only, Flag, grp_obsolete, INVALID, nullptr, 0, 0,
127 "Unsupported ObjC GC option", nullptr, nullptr)
128OPTION(prefix_1, "objc_gc", objc_gc, Flag, grp_obsolete, INVALID, nullptr, 0, 0,
129 "Unsupported ObjC GC option", nullptr, nullptr)
130OPTION(prefix_1, "order_file", order_file, Separate, grp_opts, INVALID, nullptr, 0, 0,
131 "re-order and move specified symbols to start of their section", "<file-path>", nullptr)
132OPTION(prefix_1, "o", output, Separate, INVALID, INVALID, nullptr, 0, 0,
133 "Output file path", "<path>", nullptr)
134OPTION(prefix_1, "path_exists", path_exists, Separate, INVALID, INVALID, nullptr, 0, 0,
135 "Used with -test_file_usage to declare a path", "<path>", nullptr)
136OPTION(prefix_1, "pie", pie, Flag, grp_main, INVALID, nullptr, 0, 0,
137 "Create Position Independent Executable (for ASLR)", nullptr, nullptr)
138OPTION(prefix_1, "preload", preload, Flag, grp_kind, INVALID, nullptr, 0, 0,
139 "Create binary for use with embedded systems", nullptr, nullptr)
140OPTION(prefix_1, "print_atoms", print_atoms, Flag, INVALID, INVALID, nullptr, 0, 0,
141 "Emit output as yaml atoms", nullptr, nullptr)
142OPTION(prefix_1, "rpath", rpath, Separate, INVALID, INVALID, nullptr, 0, 0,
143 "Add path to the runpath search path list for image being created", "<path>", nullptr)
144OPTION(prefix_1, "r", relocatable, Flag, grp_kind, INVALID, nullptr, 0, 0,
145 "Create relocatable object file", nullptr, nullptr)
146OPTION(prefix_1, "sdk_version", sdk_version, Separate, grp_opts, INVALID, nullptr, 0, 0,
147 "SDK version", "<version>", nullptr)
148OPTION(prefix_1, "sectalign", sectalign, MultiArg, INVALID, INVALID, nullptr, 0, 3,
149 "Alignment for segment/section", "<segname> <sectname> <alignment>", nullptr)
150OPTION(prefix_1, "sectcreate", sectcreate, MultiArg, INVALID, INVALID, nullptr, 0, 3,
151 "Create section <segname>/<sectname> from contents of <file>", "<segname> <sectname> <file>", nullptr)
152OPTION(prefix_1, "seg1addr", seg1addr, Separate, INVALID, image_base, nullptr, 0, 0, nullptr, nullptr, nullptr)
153OPTION(prefix_1, "single_module", single_module, Flag, grp_obsolete, INVALID, nullptr, 0, 0,
154 "Default for dylibs", nullptr, nullptr)
155OPTION(prefix_1, "source_version", source_version, Separate, grp_opts, INVALID, nullptr, 0, 0,
156 "Source version", "<version>", nullptr)
157OPTION(prefix_1, "stack_size", stack_size, Separate, grp_main, INVALID, nullptr, 0, 0,
158 "Specifies the maximum stack size for the main thread in a program. Must be a page-size multiple. (default=8Mb)", nullptr, nullptr)
159OPTION(prefix_1, "static", static, Flag, grp_kind, INVALID, nullptr, 0, 0,
160 "Create static executable", nullptr, nullptr)
161OPTION(prefix_1, "syslibroot", syslibroot, Separate, grp_libs, INVALID, nullptr, 0, 0,
162 "Add path to SDK to all absolute library search paths", "<dir>", nullptr)
163OPTION(prefix_1, "S", S, Flag, INVALID, INVALID, nullptr, 0, 0,
164 "Remove debug information (STABS or DWARF) from the output file", nullptr, nullptr)
165OPTION(prefix_1, "test_file_usage", test_file_usage, Flag, INVALID, INVALID, nullptr, 0, 0,
166 "Only files specified by -file_exists are considered to exist. Print which files would be used", nullptr, nullptr)
167OPTION(prefix_1, "twolevel_namespace", twolevel_namespace, Flag, grp_opts, INVALID, nullptr, 0, 0,
168 "Resolves symbols in listed libraries only. Source libraries are recorded in the symbol table.", nullptr, nullptr)
169OPTION(prefix_1, "t", t, Flag, INVALID, INVALID, nullptr, 0, 0,
170 "Print the names of the input files as ld processes them", nullptr, nullptr)
171OPTION(prefix_1, "undefined", undefined, Separate, grp_opts, INVALID, nullptr, 0, 0,
172 "Determines how undefined symbols are handled.", "<undefined>", nullptr)
173OPTION(prefix_1, "unexported_symbols_list", unexported_symbols_list, Separate, grp_opts, INVALID, nullptr, 0, 0,
174 "Lists symbols that should not be exported", "<file-path>", nullptr)
175OPTION(prefix_1, "unexported_symbol", unexported_symbol, Separate, grp_opts, INVALID, nullptr, 0, 0,
176 "A symbol which should not be exported", "<symbol>", nullptr)
177OPTION(prefix_1, "upward-l", upward_l, Joined, INVALID, INVALID, nullptr, 0, 0,
178 "Base name of upward library searched for in -L directories", "<libname>", nullptr)
179OPTION(prefix_1, "upward_framework", upward_framework, Separate, INVALID, INVALID, nullptr, 0, 0,
180 "Base name of upward framework searched for in -F directories", "<name>", nullptr)
181OPTION(prefix_1, "upward_library", upward_library, Separate, INVALID, INVALID, nullptr, 0, 0,
182 "path to upward dylib to link with", "<path>", nullptr)
183OPTION(prefix_1, "version_load_command", version_load_command, Flag, grp_opts, INVALID, nullptr, 0, 0,
184 "Force generation of a version load command", nullptr, nullptr)
185OPTION(prefix_1, "v", v, Flag, INVALID, INVALID, nullptr, 0, 0,
186 "Print linker information", nullptr, nullptr)
187OPTION(prefix_1, "Z", Z, Flag, INVALID, INVALID, nullptr, 0, 0,
188 "Do not search standard directories for libraries or frameworks", nullptr, nullptr)
189#endif // OPTION
deps/lld-prebuilt/ELF/Options.inc created+352
......@@ -0,0 +1,352 @@
1/*===- TableGen'erated file -------------------------------------*- C++ -*-===*\
2|* *|
3|* Option Parsing Definitions *|
4|* *|
5|* Automatically generated file, do not edit! *|
6|* *|
7\*===----------------------------------------------------------------------===*/
8
9/////////
10// Prefixes
11
12#ifdef PREFIX
13#define COMMA ,
14PREFIX(prefix_0, {nullptr})
15PREFIX(prefix_1, {"-" COMMA nullptr})
16PREFIX(prefix_3, {"--" COMMA nullptr})
17PREFIX(prefix_2, {"--" COMMA "-" COMMA nullptr})
18#undef COMMA
19#endif // PREFIX
20
21/////////
22// Groups
23
24#ifdef OPTION
25
26//////////
27// Options
28
29OPTION(prefix_0, "<input>", INPUT, Input, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
30OPTION(prefix_0, "<unknown>", UNKNOWN, Unknown, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
31OPTION(prefix_1, "(", start_group_paren, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
32OPTION(prefix_1, ")", end_group_paren, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
33OPTION(prefix_2, "allow-multiple-definition", allow_multiple_definition, Flag, INVALID, INVALID, nullptr, 0, 0,
34 "Allow multiple definitions", nullptr, nullptr)
35OPTION(prefix_2, "allow-shlib-undefined", allow_shlib_undefined, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
36OPTION(prefix_2, "as-needed", as_needed, Flag, INVALID, INVALID, nullptr, 0, 0,
37 "Only set DT_NEEDED for shared libraries if used", nullptr, nullptr)
38OPTION(prefix_2, "auxiliary", auxiliary, Separate, INVALID, INVALID, nullptr, 0, 0,
39 "Set DT_AUXILIARY field to the specified name", nullptr, nullptr)
40OPTION(prefix_2, "Bdynamic", Bdynamic, Flag, INVALID, INVALID, nullptr, 0, 0,
41 "Link against shared libraries", nullptr, nullptr)
42OPTION(prefix_2, "Bshareable", alias_shared_Bshareable, Flag, INVALID, shared, nullptr, 0, 0, nullptr, nullptr, nullptr)
43OPTION(prefix_2, "Bstatic", Bstatic, Flag, INVALID, INVALID, nullptr, 0, 0,
44 "Do not link against shared libraries", nullptr, nullptr)
45OPTION(prefix_2, "Bsymbolic-functions", Bsymbolic_functions, Flag, INVALID, INVALID, nullptr, 0, 0,
46 "Bind defined function symbols locally", nullptr, nullptr)
47OPTION(prefix_2, "Bsymbolic", Bsymbolic, Flag, INVALID, INVALID, nullptr, 0, 0,
48 "Bind defined symbols locally", nullptr, nullptr)
49OPTION(prefix_2, "build-id=", build_id_eq, Joined, INVALID, INVALID, nullptr, 0, 0,
50 "Generate build ID note", nullptr, nullptr)
51OPTION(prefix_2, "build-id", build_id, Flag, INVALID, INVALID, nullptr, 0, 0,
52 "Generate build ID note", nullptr, nullptr)
53OPTION(prefix_2, "b", alias_format_b, Separate, INVALID, format, nullptr, 0, 0, nullptr, nullptr, nullptr)
54OPTION(prefix_2, "call_shared", alias_Bdynamic_call_shared, Flag, INVALID, Bdynamic, nullptr, 0, 0, nullptr, nullptr, nullptr)
55OPTION(prefix_2, "color-diagnostics=", color_diagnostics_eq, Joined, INVALID, INVALID, nullptr, 0, 0,
56 "Use colors in diagnostics", nullptr, nullptr)
57OPTION(prefix_2, "color-diagnostics", color_diagnostics, Flag, INVALID, INVALID, nullptr, 0, 0,
58 "Use colors in diagnostics", nullptr, nullptr)
59OPTION(prefix_2, "compress-debug-sections=", compress_debug_sections, Joined, INVALID, INVALID, nullptr, 0, 0,
60 "Compress DWARF debug sections", nullptr, nullptr)
61OPTION(prefix_3, "cref", cref, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
62OPTION(prefix_2, "dc", alias_define_common_dc, Flag, INVALID, define_common, nullptr, 0, 0, nullptr, nullptr, nullptr)
63OPTION(prefix_2, "define-common", define_common, Flag, INVALID, INVALID, nullptr, 0, 0,
64 "Assign space to common symbols", nullptr, nullptr)
65OPTION(prefix_2, "defsym=", defsym, Joined, INVALID, INVALID, nullptr, 0, 0,
66 "Define a symbol alias", nullptr, nullptr)
67OPTION(prefix_2, "defsym", alias_defsym, Separate, INVALID, defsym, nullptr, 0, 0, nullptr, nullptr, nullptr)
68OPTION(prefix_2, "demangle", demangle, Flag, INVALID, INVALID, nullptr, 0, 0,
69 "Demangle symbol names", nullptr, nullptr)
70OPTION(prefix_2, "detect-odr-violations", detect_odr_violations, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
71OPTION(prefix_2, "disable-new-dtags", disable_new_dtags, Flag, INVALID, INVALID, nullptr, 0, 0,
72 "Disable new dynamic tags", nullptr, nullptr)
73OPTION(prefix_2, "disable-verify", disable_verify, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
74OPTION(prefix_2, "discard-all", discard_all, Flag, INVALID, INVALID, nullptr, 0, 0,
75 "Delete all local symbols", nullptr, nullptr)
76OPTION(prefix_2, "discard-locals", discard_locals, Flag, INVALID, INVALID, nullptr, 0, 0,
77 "Delete temporary local symbols", nullptr, nullptr)
78OPTION(prefix_2, "discard-none", discard_none, Flag, INVALID, INVALID, nullptr, 0, 0,
79 "Keep all symbols in the symbol table", nullptr, nullptr)
80OPTION(prefix_2, "dn", alias_Bstatic_dn, Flag, INVALID, Bstatic, nullptr, 0, 0, nullptr, nullptr, nullptr)
81OPTION(prefix_2, "dp", alias_define_common_dp, Flag, INVALID, define_common, nullptr, 0, 0, nullptr, nullptr, nullptr)
82OPTION(prefix_2, "dynamic-linker", dynamic_linker, Separate, INVALID, INVALID, nullptr, 0, 0,
83 "Which dynamic linker to use", nullptr, nullptr)
84OPTION(prefix_2, "dynamic-list=", alias_dynamic_list, Joined, INVALID, dynamic_list, nullptr, 0, 0, nullptr, nullptr, nullptr)
85OPTION(prefix_2, "dynamic-list", dynamic_list, Separate, INVALID, INVALID, nullptr, 0, 0,
86 "Read a list of dynamic symbols", nullptr, nullptr)
87OPTION(prefix_2, "dy", alias_Bdynamic_dy, Flag, INVALID, Bdynamic, nullptr, 0, 0, nullptr, nullptr, nullptr)
88OPTION(prefix_1, "d", alias_define_common_d, Flag, INVALID, define_common, nullptr, 0, 0, nullptr, nullptr, nullptr)
89OPTION(prefix_2, "EB", EB, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
90OPTION(prefix_2, "eh-frame-hdr", eh_frame_hdr, Flag, INVALID, INVALID, nullptr, 0, 0,
91 "Request creation of .eh_frame_hdr section and PT_GNU_EH_FRAME segment header", nullptr, nullptr)
92OPTION(prefix_2, "EL", EL, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
93OPTION(prefix_2, "emit-relocs", emit_relocs, Flag, INVALID, INVALID, nullptr, 0, 0,
94 "Generate relocations in output", nullptr, nullptr)
95OPTION(prefix_2, "enable-new-dtags", enable_new_dtags, Flag, INVALID, INVALID, nullptr, 0, 0,
96 "Enable new dynamic tags", nullptr, nullptr)
97OPTION(prefix_2, "end-group", end_group, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
98OPTION(prefix_2, "end-lib", end_lib, Flag, INVALID, INVALID, nullptr, 0, 0,
99 "End a grouping of objects that should be treated as if they were together in an archive", nullptr, nullptr)
100OPTION(prefix_2, "entry=", alias_entry_entry, Joined, INVALID, entry, nullptr, 0, 0, nullptr, nullptr, nullptr)
101OPTION(prefix_2, "entry", entry, Separate, INVALID, INVALID, nullptr, 0, 0,
102 "Name of entry point symbol", "<entry>", nullptr)
103OPTION(prefix_2, "error-limit=", alias_error_limit, Joined, INVALID, error_limit, nullptr, 0, 0, nullptr, nullptr, nullptr)
104OPTION(prefix_2, "error-limit", error_limit, Separate, INVALID, INVALID, nullptr, 0, 0,
105 "Maximum number of errors to emit before stopping (0 = no limit)", nullptr, nullptr)
106OPTION(prefix_2, "error-unresolved-symbols", error_unresolved_symbols, Flag, INVALID, INVALID, nullptr, 0, 0,
107 "Report unresolved symbols as errors", nullptr, nullptr)
108OPTION(prefix_2, "exclude-libs=", alias_exclude_libs, Joined, INVALID, exclude_libs, nullptr, 0, 0, nullptr, nullptr, nullptr)
109OPTION(prefix_2, "exclude-libs", exclude_libs, Separate, INVALID, INVALID, nullptr, 0, 0,
110 "Exclude static libraries from automatic export", nullptr, nullptr)
111OPTION(prefix_2, "export-dynamic-symbol=", alias_export_dynamic_symbol, Joined, INVALID, export_dynamic_symbol, nullptr, 0, 0, nullptr, nullptr, nullptr)
112OPTION(prefix_2, "export-dynamic-symbol", export_dynamic_symbol, Separate, INVALID, INVALID, nullptr, 0, 0,
113 "Put a symbol in the dynamic symbol table", nullptr, nullptr)
114OPTION(prefix_2, "export-dynamic", export_dynamic, Flag, INVALID, INVALID, nullptr, 0, 0,
115 "Put symbols in the dynamic symbol table", nullptr, nullptr)
116OPTION(prefix_1, "E", alias_export_dynamic_E, Flag, INVALID, export_dynamic, nullptr, 0, 0, nullptr, nullptr, nullptr)
117OPTION(prefix_1, "e", alias_entry_e, JoinedOrSeparate, INVALID, entry, nullptr, 0, 0, nullptr, nullptr, nullptr)
118OPTION(prefix_2, "fatal-warnings", fatal_warnings, Flag, INVALID, INVALID, nullptr, 0, 0,
119 "Treat warnings as errors", nullptr, nullptr)
120OPTION(prefix_2, "filter=", filter, Joined, INVALID, INVALID, nullptr, 0, 0,
121 "Set DT_FILTER field to the specified name", nullptr, nullptr)
122OPTION(prefix_2, "fini=", alias_fini_fini, Joined, INVALID, fini, nullptr, 0, 0, nullptr, nullptr, nullptr)
123OPTION(prefix_2, "fini", fini, Separate, INVALID, INVALID, nullptr, 0, 0,
124 "Specify a finalizer function", "<symbol>", nullptr)
125OPTION(prefix_2, "format=", format, Joined, INVALID, INVALID, nullptr, 0, 0,
126 "Change the input format of the inputs following this option", "<input-format>", nullptr)
127OPTION(prefix_2, "full-shutdown", full_shutdown, Flag, INVALID, INVALID, nullptr, 0, 0,
128 "Perform a full shutdown instead of calling _exit", nullptr, nullptr)
129OPTION(prefix_1, "F", alias_filter, Separate, INVALID, filter, nullptr, 0, 0, nullptr, nullptr, nullptr)
130OPTION(prefix_1, "f", alias_auxiliary, Separate, INVALID, auxiliary, nullptr, 0, 0, nullptr, nullptr, nullptr)
131OPTION(prefix_2, "gc-sections", gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0,
132 "Enable garbage collection of unused sections", nullptr, nullptr)
133OPTION(prefix_2, "gdb-index", gdb_index, Flag, INVALID, INVALID, nullptr, 0, 0,
134 "Generate .gdb_index section", nullptr, nullptr)
135OPTION(prefix_1, "G", G, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
136OPTION(prefix_1, "g", g, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
137OPTION(prefix_2, "hash-style=", alias_hash_style_hash_style, Joined, INVALID, hash_style, nullptr, 0, 0, nullptr, nullptr, nullptr)
138OPTION(prefix_2, "hash-style", hash_style, Separate, INVALID, INVALID, nullptr, 0, 0,
139 "Specify hash style (sysv, gnu or both)", nullptr, nullptr)
140OPTION(prefix_2, "help", help, Flag, INVALID, INVALID, nullptr, 0, 0,
141 "Print option help", nullptr, nullptr)
142OPTION(prefix_1, "h", alias_soname_h, JoinedOrSeparate, INVALID, soname, nullptr, 0, 0, nullptr, nullptr, nullptr)
143OPTION(prefix_2, "icf=all", icf_all, Flag, INVALID, INVALID, nullptr, 0, 0,
144 "Enable identical code folding", nullptr, nullptr)
145OPTION(prefix_2, "icf=none", icf_none, Flag, INVALID, INVALID, nullptr, 0, 0,
146 "Disable identical code folding", nullptr, nullptr)
147OPTION(prefix_2, "image-base=", image_base, Joined, INVALID, INVALID, nullptr, 0, 0,
148 "Set the base address", nullptr, nullptr)
149OPTION(prefix_2, "init=", alias_init_init, Joined, INVALID, init, nullptr, 0, 0, nullptr, nullptr, nullptr)
150OPTION(prefix_2, "init", init, Separate, INVALID, INVALID, nullptr, 0, 0,
151 "Specify an initializer function", "<symbol>", nullptr)
152OPTION(prefix_2, "library-path=", alias_L__library_path, Joined, INVALID, L, nullptr, 0, 0, nullptr, nullptr, nullptr)
153OPTION(prefix_2, "library=", alias_l__library, Joined, INVALID, l, nullptr, 0, 0, nullptr, nullptr, nullptr)
154OPTION(prefix_2, "lto-aa-pipeline=", lto_aa_pipeline, Joined, INVALID, INVALID, nullptr, 0, 0,
155 "AA pipeline to run during LTO. Used in conjunction with -lto-newpm-passes", nullptr, nullptr)
156OPTION(prefix_2, "lto-newpm-passes=", lto_newpm_passes, Joined, INVALID, INVALID, nullptr, 0, 0,
157 "Passes to run during LTO", nullptr, nullptr)
158OPTION(prefix_2, "lto-O", lto_O, Joined, INVALID, INVALID, nullptr, 0, 0,
159 "Optimization level for LTO", "<opt-level>", nullptr)
160OPTION(prefix_2, "lto-partitions=", lto_partitions, Joined, INVALID, INVALID, nullptr, 0, 0,
161 "Number of LTO codegen partitions", nullptr, nullptr)
162OPTION(prefix_1, "L", L, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0,
163 "Add a directory to the library search path", "<dir>", nullptr)
164OPTION(prefix_1, "l", l, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0,
165 "Root name of library to use", "<libName>", nullptr)
166OPTION(prefix_2, "Map=", alias_Map_eq, Joined, INVALID, Map, nullptr, 0, 0, nullptr, nullptr, nullptr)
167OPTION(prefix_2, "Map", Map, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0,
168 "Print a link map to the specified file", nullptr, nullptr)
169OPTION(prefix_2, "mllvm", mllvm, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
170OPTION(prefix_1, "M", alias_print_map_M, Flag, INVALID, print_map, nullptr, 0, 0, nullptr, nullptr, nullptr)
171OPTION(prefix_1, "m", m, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0,
172 "Set target emulation", nullptr, nullptr)
173OPTION(prefix_2, "no-add-needed", no_add_needed, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
174OPTION(prefix_2, "no-allow-shlib-undefined", no_allow_shlib_undefined, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
175OPTION(prefix_2, "no-as-needed", no_as_needed, Flag, INVALID, INVALID, nullptr, 0, 0,
176 "Always DT_NEEDED for shared libraries", nullptr, nullptr)
177OPTION(prefix_2, "no-color-diagnostics", no_color_diagnostics, Flag, INVALID, INVALID, nullptr, 0, 0,
178 "Do not use colors in diagnostics", nullptr, nullptr)
179OPTION(prefix_2, "no-copy-dt-needed-entries", no_copy_dt_needed_entries, Flag, INVALID, no_add_needed, nullptr, 0, 0, nullptr, nullptr, nullptr)
180OPTION(prefix_2, "no-define-common", no_define_common, Flag, INVALID, INVALID, nullptr, 0, 0,
181 "Do not assign space to common symbols", nullptr, nullptr)
182OPTION(prefix_2, "no-demangle", no_demangle, Flag, INVALID, INVALID, nullptr, 0, 0,
183 "Do not demangle symbol names", nullptr, nullptr)
184OPTION(prefix_2, "no-dynamic-linker", no_dynamic_linker, Flag, INVALID, INVALID, nullptr, 0, 0,
185 "Inhibit output of .interp section", nullptr, nullptr)
186OPTION(prefix_2, "no-export-dynamic", no_export_dynamic, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
187OPTION(prefix_2, "no-fatal-warnings", no_fatal_warnings, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
188OPTION(prefix_2, "no-gc-sections", no_gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0,
189 "Disable garbage collection of unused sections", nullptr, nullptr)
190OPTION(prefix_2, "no-gnu-unique", no_gnu_unique, Flag, INVALID, INVALID, nullptr, 0, 0,
191 "Disable STB_GNU_UNIQUE symbol binding", nullptr, nullptr)
192OPTION(prefix_2, "no-keep-memory", no_keep_memory, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
193OPTION(prefix_2, "no-mmap-output-file", no_mmap_output_file, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
194OPTION(prefix_2, "no-rosegment", no_rosegment, Flag, INVALID, INVALID, nullptr, 0, 0,
195 "Do not put read-only non-executable sections in their own segment", nullptr, nullptr)
196OPTION(prefix_2, "no-threads", no_threads, Flag, INVALID, INVALID, nullptr, 0, 0,
197 "Do not run the linker multi-threaded", nullptr, nullptr)
198OPTION(prefix_2, "no-undefined-version", no_undefined_version, Flag, INVALID, INVALID, nullptr, 0, 0,
199 "Report version scripts that refer undefined symbols", nullptr, nullptr)
200OPTION(prefix_2, "no-undefined", no_undefined, Flag, INVALID, INVALID, nullptr, 0, 0,
201 "Report unresolved symbols even if the linker is creating a shared library", nullptr, nullptr)
202OPTION(prefix_2, "no-warn-common", no_warn_common, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
203OPTION(prefix_2, "no-warn-mismatch", no_warn_mismatch, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
204OPTION(prefix_2, "no-whole-archive", no_whole_archive, Flag, INVALID, INVALID, nullptr, 0, 0,
205 "Restores the default behavior of loading archive members", nullptr, nullptr)
206OPTION(prefix_2, "noinhibit-exec", noinhibit_exec, Flag, INVALID, INVALID, nullptr, 0, 0,
207 "Retain the executable output file whenever it is still usable", nullptr, nullptr)
208OPTION(prefix_2, "non_shared", alias_Bstatic_non_shared, Flag, INVALID, Bstatic, nullptr, 0, 0, nullptr, nullptr, nullptr)
209OPTION(prefix_2, "nopie", nopie, Flag, INVALID, INVALID, nullptr, 0, 0,
210 "Do not create a position independent executable", nullptr, nullptr)
211OPTION(prefix_2, "nostdlib", nostdlib, Flag, INVALID, INVALID, nullptr, 0, 0,
212 "Only search directories specified on the command line", nullptr, nullptr)
213OPTION(prefix_1, "N", alias_omagic, Flag, INVALID, omagic, nullptr, 0, 0, nullptr, nullptr, nullptr)
214OPTION(prefix_3, "oformat", oformat, Separate, INVALID, INVALID, nullptr, 0, 0,
215 "Specify the binary format for the output object file", "<format>", nullptr)
216OPTION(prefix_3, "omagic", omagic, Flag, INVALID, INVALID, nullptr, 0, 0,
217 "Set the text and data sections to be readable and writable", "<magic>", nullptr)
218OPTION(prefix_3, "opt-remarks-filename", opt_remarks_filename, Separate, INVALID, INVALID, nullptr, 0, 0,
219 "YAML output file for optimization remarks", nullptr, nullptr)
220OPTION(prefix_3, "opt-remarks-with-hotness", opt_remarks_with_hotness, Flag, INVALID, INVALID, nullptr, 0, 0,
221 "Include hotness informations in the optimization remarks file", nullptr, nullptr)
222OPTION(prefix_3, "output=", alias_o_output, Joined, INVALID, o, nullptr, 0, 0, nullptr, nullptr, nullptr)
223OPTION(prefix_3, "output", alias_o_output2, Separate, INVALID, o, nullptr, 0, 0, nullptr, nullptr, nullptr)
224OPTION(prefix_1, "O", O, Joined, INVALID, INVALID, nullptr, 0, 0,
225 "Optimize output file size", nullptr, nullptr)
226OPTION(prefix_1, "o", o, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0,
227 "Path to file to write output", "<path>", nullptr)
228OPTION(prefix_2, "pic-executable", alias_pie_pic_executable, Flag, INVALID, pie, nullptr, 0, 0, nullptr, nullptr, nullptr)
229OPTION(prefix_2, "pie", pie, Flag, INVALID, INVALID, nullptr, 0, 0,
230 "Create a position independent executable", nullptr, nullptr)
231OPTION(prefix_2, "plugin-opt=", plugin_opt_eq, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
232OPTION(prefix_2, "plugin-opt", plugin_opt, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
233OPTION(prefix_2, "plugin=", plugin_eq, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
234OPTION(prefix_2, "plugin", plugin, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
235OPTION(prefix_2, "print-gc-sections", print_gc_sections, Flag, INVALID, INVALID, nullptr, 0, 0,
236 "List removed unused sections", nullptr, nullptr)
237OPTION(prefix_2, "print-map", print_map, Flag, INVALID, INVALID, nullptr, 0, 0,
238 "Print a link map to the standard output", nullptr, nullptr)
239OPTION(prefix_2, "Qy", Qy, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
240OPTION(prefix_1, "q", alias_emit_relocs, Flag, INVALID, emit_relocs, nullptr, 0, 0, nullptr, nullptr, nullptr)
241OPTION(prefix_2, "relocatable", relocatable, Flag, INVALID, INVALID, nullptr, 0, 0,
242 "Create relocatable object file", nullptr, nullptr)
243OPTION(prefix_2, "reproduce=", alias_reproduce_eq, Joined, INVALID, reproduce, nullptr, 0, 0, nullptr, nullptr, nullptr)
244OPTION(prefix_2, "reproduce", reproduce, Separate, INVALID, INVALID, nullptr, 0, 0,
245 "Dump linker invocation and input files for debugging", nullptr, nullptr)
246OPTION(prefix_2, "retain-symbols-file=", retain_symbols_file, Joined, INVALID, INVALID, nullptr, 0, 0,
247 "Retain only the symbols listed in the file", "<file>", nullptr)
248OPTION(prefix_2, "retain-symbols-file", alias_retain_symbols_file, Separate, INVALID, retain_symbols_file, nullptr, 0, 0, nullptr, nullptr, nullptr)
249OPTION(prefix_2, "rpath-link=", rpath_link_eq, Joined, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
250OPTION(prefix_2, "rpath-link", rpath_link, Separate, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
251OPTION(prefix_2, "rpath=", alias_rpath_rpath, Joined, INVALID, rpath, nullptr, 0, 0, nullptr, nullptr, nullptr)
252OPTION(prefix_2, "rpath", rpath, Separate, INVALID, INVALID, nullptr, 0, 0,
253 "Add a DT_RUNPATH to the output", nullptr, nullptr)
254OPTION(prefix_2, "rsp-quoting=", rsp_quoting, Joined, INVALID, INVALID, nullptr, 0, 0,
255 "Quoting style for response files. Values supported: windows|posix", nullptr, nullptr)
256OPTION(prefix_1, "R", alias_rpath_R, JoinedOrSeparate, INVALID, rpath, nullptr, 0, 0, nullptr, nullptr, nullptr)
257OPTION(prefix_1, "r", alias_relocatable_r, Flag, INVALID, relocatable, nullptr, 0, 0, nullptr, nullptr, nullptr)
258OPTION(prefix_2, "save-temps", save_temps, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
259OPTION(prefix_2, "script=", alias_script, Joined, INVALID, script, nullptr, 0, 0, nullptr, nullptr, nullptr)
260OPTION(prefix_2, "script", script, Separate, INVALID, INVALID, nullptr, 0, 0,
261 "Read linker script", nullptr, nullptr)
262OPTION(prefix_2, "section-start", section_start, Separate, INVALID, INVALID, nullptr, 0, 0,
263 "Set address of section", "<address>", nullptr)
264OPTION(prefix_2, "shared", shared, Flag, INVALID, INVALID, nullptr, 0, 0,
265 "Build a shared object", nullptr, nullptr)
266OPTION(prefix_2, "soname=", soname, Joined, INVALID, INVALID, nullptr, 0, 0,
267 "Set DT_SONAME", nullptr, nullptr)
268OPTION(prefix_2, "soname", alias_soname_soname, Separate, INVALID, soname, nullptr, 0, 0, nullptr, nullptr, nullptr)
269OPTION(prefix_2, "sort-common", sort_common, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
270OPTION(prefix_2, "sort-section=", alias_sort_section, Joined, INVALID, sort_section, nullptr, 0, 0, nullptr, nullptr, nullptr)
271OPTION(prefix_2, "sort-section", sort_section, Separate, INVALID, INVALID, nullptr, 0, 0,
272 "Specifies sections sorting rule when linkerscript is used", nullptr, nullptr)
273OPTION(prefix_2, "start-group", start_group, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
274OPTION(prefix_2, "start-lib", start_lib, Flag, INVALID, INVALID, nullptr, 0, 0,
275 "Start a grouping of objects that should be treated as if they were together in an archive", nullptr, nullptr)
276OPTION(prefix_2, "static", alias_Bstatic_static, Flag, INVALID, Bstatic, nullptr, 0, 0, nullptr, nullptr, nullptr)
277OPTION(prefix_2, "stats", stats, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
278OPTION(prefix_2, "strip-all", strip_all, Flag, INVALID, INVALID, nullptr, 0, 0,
279 "Strip all symbols", nullptr, nullptr)
280OPTION(prefix_2, "strip-debug", strip_debug, Flag, INVALID, INVALID, nullptr, 0, 0,
281 "Strip debugging information", nullptr, nullptr)
282OPTION(prefix_2, "symbol-ordering-file", symbol_ordering_file, Separate, INVALID, INVALID, nullptr, 0, 0,
283 "Layout sections in the order specified by symbol file", nullptr, nullptr)
284OPTION(prefix_2, "sysroot=", sysroot, Joined, INVALID, INVALID, nullptr, 0, 0,
285 "Set the system root", nullptr, nullptr)
286OPTION(prefix_1, "S", alias_strip_debug_S, Flag, INVALID, strip_debug, nullptr, 0, 0, nullptr, nullptr, nullptr)
287OPTION(prefix_1, "s", alias_strip_all, Flag, INVALID, strip_all, nullptr, 0, 0, nullptr, nullptr, nullptr)
288OPTION(prefix_2, "target1-abs", target1_abs, Flag, INVALID, INVALID, nullptr, 0, 0,
289 "Interpret R_ARM_TARGET1 as R_ARM_ABS32", nullptr, nullptr)
290OPTION(prefix_2, "target1-rel", target1_rel, Flag, INVALID, INVALID, nullptr, 0, 0,
291 "Interpret R_ARM_TARGET1 as R_ARM_REL32", nullptr, nullptr)
292OPTION(prefix_2, "target2=", target2, Joined, INVALID, INVALID, nullptr, 0, 0,
293 "Interpret R_ARM_TARGET2 as <type>, where <type> is one of rel, abs, or got-rel", "<type>", nullptr)
294OPTION(prefix_2, "Tbss=", alias_Tbss, Joined, INVALID, Tbss, nullptr, 0, 0, nullptr, nullptr, nullptr)
295OPTION(prefix_2, "Tbss", Tbss, Separate, INVALID, INVALID, nullptr, 0, 0,
296 "Same as --section-start with .bss as the sectionname", nullptr, nullptr)
297OPTION(prefix_2, "Tdata=", alias_Tdata, Joined, INVALID, Tdata, nullptr, 0, 0, nullptr, nullptr, nullptr)
298OPTION(prefix_2, "Tdata", Tdata, Separate, INVALID, INVALID, nullptr, 0, 0,
299 "Same as --section-start with .data as the sectionname", nullptr, nullptr)
300OPTION(prefix_2, "thinlto-cache-dir=", thinlto_cache_dir, Joined, INVALID, INVALID, nullptr, 0, 0,
301 "Path to ThinLTO cached object file directory", nullptr, nullptr)
302OPTION(prefix_2, "thinlto-cache-policy", thinlto_cache_policy, Separate, INVALID, INVALID, nullptr, 0, 0,
303 "Pruning policy for the ThinLTO cache", nullptr, nullptr)
304OPTION(prefix_2, "thinlto-jobs=", thinlto_jobs, Joined, INVALID, INVALID, nullptr, 0, 0,
305 "Number of ThinLTO jobs", nullptr, nullptr)
306OPTION(prefix_2, "threads", threads, Flag, INVALID, INVALID, nullptr, 0, 0,
307 "Run the linker multi-threaded", nullptr, nullptr)
308OPTION(prefix_2, "trace-symbol=", trace_trace_symbol_eq, Joined, INVALID, trace_symbol, nullptr, 0, 0, nullptr, nullptr, nullptr)
309OPTION(prefix_2, "trace-symbol", trace_symbol, Separate, INVALID, INVALID, nullptr, 0, 0,
310 "Trace references to symbols", nullptr, nullptr)
311OPTION(prefix_2, "trace", trace, Flag, INVALID, INVALID, nullptr, 0, 0,
312 "Print the names of the input files", nullptr, nullptr)
313OPTION(prefix_2, "Ttext-segment=", alias_Ttext_segment_eq, Joined, INVALID, Ttext, nullptr, 0, 0, nullptr, nullptr, nullptr)
314OPTION(prefix_2, "Ttext-segment", alias_Ttext_segment, Separate, INVALID, Ttext, nullptr, 0, 0, nullptr, nullptr, nullptr)
315OPTION(prefix_2, "Ttext=", alias_Ttext, Joined, INVALID, Ttext, nullptr, 0, 0, nullptr, nullptr, nullptr)
316OPTION(prefix_2, "Ttext", Ttext, Separate, INVALID, INVALID, nullptr, 0, 0,
317 "Same as --section-start with .text as the sectionname", nullptr, nullptr)
318OPTION(prefix_1, "T", alias_script_T, JoinedOrSeparate, INVALID, script, nullptr, 0, 0, nullptr, nullptr, nullptr)
319OPTION(prefix_1, "t", alias_trace, Flag, INVALID, trace, nullptr, 0, 0, nullptr, nullptr, nullptr)
320OPTION(prefix_2, "undefined=", alias_undefined_eq, Joined, INVALID, undefined, nullptr, 0, 0, nullptr, nullptr, nullptr)
321OPTION(prefix_2, "undefined", undefined, Separate, INVALID, INVALID, nullptr, 0, 0,
322 "Force undefined symbol during linking", nullptr, nullptr)
323OPTION(prefix_2, "unresolved-symbols=", unresolved_symbols, Joined, INVALID, INVALID, nullptr, 0, 0,
324 "Determine how to handle unresolved symbols", nullptr, nullptr)
325OPTION(prefix_1, "u", alias_undefined_u, JoinedOrSeparate, INVALID, undefined, nullptr, 0, 0, nullptr, nullptr, nullptr)
326OPTION(prefix_2, "verbose", verbose, Flag, INVALID, INVALID, nullptr, 0, 0,
327 "Verbose mode", nullptr, nullptr)
328OPTION(prefix_2, "version-script=", alias_version_script_eq, Joined, INVALID, version_script, nullptr, 0, 0, nullptr, nullptr, nullptr)
329OPTION(prefix_2, "version-script", version_script, Separate, INVALID, INVALID, nullptr, 0, 0,
330 "Read a version script", nullptr, nullptr)
331OPTION(prefix_2, "version", version, Flag, INVALID, INVALID, nullptr, 0, 0,
332 "Display the version number and exit", nullptr, nullptr)
333OPTION(prefix_1, "V", alias_version_V, Flag, INVALID, version, nullptr, 0, 0, nullptr, nullptr, nullptr)
334OPTION(prefix_1, "v", v, Flag, INVALID, INVALID, nullptr, 0, 0,
335 "Display the version number", nullptr, nullptr)
336OPTION(prefix_2, "warn-common", warn_common, Flag, INVALID, INVALID, nullptr, 0, 0,
337 "Warn about duplicate common symbols", nullptr, nullptr)
338OPTION(prefix_2, "warn-execstack", warn_execstack, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
339OPTION(prefix_2, "warn-shared-textrel", warn_shared_textrel, Flag, INVALID, INVALID, nullptr, 0, 0, nullptr, nullptr, nullptr)
340OPTION(prefix_2, "warn-unresolved-symbols", warn_unresolved_symbols, Flag, INVALID, INVALID, nullptr, 0, 0,
341 "Report unresolved symbols as warnings", nullptr, nullptr)
342OPTION(prefix_2, "whole-archive", whole_archive, Flag, INVALID, INVALID, nullptr, 0, 0,
343 "Force load of all members in a static library", nullptr, nullptr)
344OPTION(prefix_2, "wrap=", alias_wrap_wrap, Joined, INVALID, wrap, nullptr, 0, 0, nullptr, nullptr, nullptr)
345OPTION(prefix_2, "wrap", wrap, Separate, INVALID, INVALID, nullptr, 0, 0,
346 "Use wrapper functions for symbol", "<symbol>", nullptr)
347OPTION(prefix_1, "X", alias_discard_locals_X, Flag, INVALID, discard_locals, nullptr, 0, 0, nullptr, nullptr, nullptr)
348OPTION(prefix_1, "x", alias_discard_all_x, Flag, INVALID, discard_all, nullptr, 0, 0, nullptr, nullptr, nullptr)
349OPTION(prefix_1, "y", alias_trace_symbol_y, JoinedOrSeparate, INVALID, trace_symbol, nullptr, 0, 0, nullptr, nullptr, nullptr)
350OPTION(prefix_1, "z", z, JoinedOrSeparate, INVALID, INVALID, nullptr, 0, 0,
351 "Linker option extensions", "<option>", nullptr)
352#endif // OPTION
deps/lld-prebuilt/lld/Config/Version.inc created+6
......@@ -0,0 +1,6 @@
1#define LLD_VERSION 5.0.0
2#define LLD_VERSION_STRING "5.0.0"
3#define LLD_VERSION_MAJOR 5
4#define LLD_VERSION_MINOR 0
5#define LLD_REVISION_STRING ""
6#define LLD_REPOSITORY_STRING ""
deps/lld/.arcconfig created+4
......@@ -0,0 +1,4 @@
1{
2 "project_id" : "lld",
3 "conduit_uri" : "https://reviews.llvm.org/"
4}
deps/lld/.clang-format created+1
......@@ -0,0 +1 @@
1BasedOnStyle: LLVM
deps/lld/.gitignore created+24
......@@ -0,0 +1,24 @@
1#==============================================================================#
2# This file specifies intentionally untracked files that git should ignore.
3# See: http://www.kernel.org/pub/software/scm/git/docs/gitignore.html
4#==============================================================================#
5
6#==============================================================================#
7# File extensions to be ignored anywhere in the tree.
8#==============================================================================#
9# Temp files created by most text editors.
10*~
11# Merge files created by git.
12*.orig
13# Byte compiled python modules.
14*.pyc
15# vim swap files
16.*.swp
17# Mac OS X Finder layout info
18.DS_Store
19
20#==============================================================================#
21# Directories to be ignored.
22#==============================================================================#
23# Sphinx build files.
24docs/_build
deps/lld/CMakeLists.txt created+224
......@@ -0,0 +1,224 @@
1# Check if lld is built as a standalone project.
2if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
3 project(lld)
4 cmake_minimum_required(VERSION 3.4.3)
5
6 set(CMAKE_INCLUDE_CURRENT_DIR ON)
7 set(LLD_BUILT_STANDALONE TRUE)
8
9 find_program(LLVM_CONFIG_PATH "llvm-config" DOC "Path to llvm-config binary")
10 if(NOT LLVM_CONFIG_PATH)
11 message(FATAL_ERROR "llvm-config not found: specify LLVM_CONFIG_PATH")
12 endif()
13
14 execute_process(COMMAND "${LLVM_CONFIG_PATH}"
15 "--obj-root"
16 "--includedir"
17 "--cmakedir"
18 "--src-root"
19 RESULT_VARIABLE HAD_ERROR
20 OUTPUT_VARIABLE LLVM_CONFIG_OUTPUT
21 OUTPUT_STRIP_TRAILING_WHITESPACE)
22 if(HAD_ERROR)
23 message(FATAL_ERROR "llvm-config failed with status ${HAD_ERROR}")
24 endif()
25
26 string(REGEX REPLACE "[ \t]*[\r\n]+[ \t]*" ";" LLVM_CONFIG_OUTPUT "${LLVM_CONFIG_OUTPUT}")
27
28 list(GET LLVM_CONFIG_OUTPUT 0 OBJ_ROOT)
29 list(GET LLVM_CONFIG_OUTPUT 1 MAIN_INCLUDE_DIR)
30 list(GET LLVM_CONFIG_OUTPUT 2 LLVM_CMAKE_PATH)
31 list(GET LLVM_CONFIG_OUTPUT 3 MAIN_SRC_DIR)
32
33 set(LLVM_OBJ_ROOT ${OBJ_ROOT} CACHE PATH "path to LLVM build tree")
34 set(LLVM_MAIN_INCLUDE_DIR ${MAIN_INCLUDE_DIR} CACHE PATH "path to llvm/include")
35 set(LLVM_MAIN_SRC_DIR ${MAIN_SRC_DIR} CACHE PATH "Path to LLVM source tree")
36
37 file(TO_CMAKE_PATH ${LLVM_OBJ_ROOT} LLVM_BINARY_DIR)
38
39 if(NOT EXISTS "${LLVM_CMAKE_PATH}/LLVMConfig.cmake")
40 message(FATAL_ERROR "LLVMConfig.cmake not found")
41 endif()
42 include("${LLVM_CMAKE_PATH}/LLVMConfig.cmake")
43
44 list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_PATH}")
45
46 set(PACKAGE_VERSION "${LLVM_PACKAGE_VERSION}")
47 include_directories("${LLVM_BINARY_DIR}/include" ${LLVM_INCLUDE_DIRS})
48 link_directories(${LLVM_LIBRARY_DIRS})
49
50 set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib${LLVM_LIBDIR_SUFFIX})
51 set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin)
52 find_program(LLVM_TABLEGEN_EXE "llvm-tblgen" ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH)
53
54 include(AddLLVM)
55 include(TableGen)
56 include(HandleLLVMOptions)
57
58 if(LLVM_INCLUDE_TESTS)
59 set(Python_ADDITIONAL_VERSIONS 2.7)
60 include(FindPythonInterp)
61 if(NOT PYTHONINTERP_FOUND)
62 message(FATAL_ERROR
63"Unable to find Python interpreter, required for testing.
64
65Please install Python or specify the PYTHON_EXECUTABLE CMake variable.")
66 endif()
67
68 if(${PYTHON_VERSION_STRING} VERSION_LESS 2.7)
69 message(FATAL_ERROR "Python 2.7 or newer is required")
70 endif()
71
72 # Check prebuilt llvm/utils.
73 if(EXISTS ${LLVM_TOOLS_BINARY_DIR}/FileCheck${CMAKE_EXECUTABLE_SUFFIX}
74 AND EXISTS ${LLVM_TOOLS_BINARY_DIR}/not${CMAKE_EXECUTABLE_SUFFIX})
75 set(LLVM_UTILS_PROVIDED ON)
76 endif()
77
78 if(EXISTS ${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py)
79 # Note: path not really used, except for checking if lit was found
80 set(LLVM_LIT ${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py)
81 if(NOT LLVM_UTILS_PROVIDED)
82 add_subdirectory(${LLVM_MAIN_SRC_DIR}/utils/FileCheck utils/FileCheck)
83 add_subdirectory(${LLVM_MAIN_SRC_DIR}/utils/not utils/not)
84 set(LLVM_UTILS_PROVIDED ON)
85 set(LLD_TEST_DEPS FileCheck not)
86 endif()
87 set(UNITTEST_DIR ${LLVM_MAIN_SRC_DIR}/utils/unittest)
88 if(EXISTS ${UNITTEST_DIR}/googletest/include/gtest/gtest.h
89 AND NOT EXISTS ${LLVM_LIBRARY_DIR}/${CMAKE_STATIC_LIBRARY_PREFIX}gtest${CMAKE_STATIC_LIBRARY_SUFFIX}
90 AND EXISTS ${UNITTEST_DIR}/CMakeLists.txt)
91 add_subdirectory(${UNITTEST_DIR} utils/unittest)
92 endif()
93 else()
94 # Seek installed Lit.
95 find_program(LLVM_LIT
96 NAMES llvm-lit lit.py lit
97 PATHS "${LLVM_MAIN_SRC_DIR}/utils/lit"
98 DOC "Path to lit.py")
99 endif()
100
101 if(LLVM_LIT)
102 # Define the default arguments to use with 'lit', and an option for the user
103 # to override.
104 set(LIT_ARGS_DEFAULT "-sv")
105 if (MSVC OR XCODE)
106 set(LIT_ARGS_DEFAULT "${LIT_ARGS_DEFAULT} --no-progress-bar")
107 endif()
108 set(LLVM_LIT_ARGS "${LIT_ARGS_DEFAULT}" CACHE STRING "Default options for lit")
109
110 # On Win32 hosts, provide an option to specify the path to the GnuWin32 tools.
111 if(WIN32 AND NOT CYGWIN)
112 set(LLVM_LIT_TOOLS_DIR "" CACHE PATH "Path to GnuWin32 tools")
113 endif()
114 else()
115 set(LLVM_INCLUDE_TESTS OFF)
116 endif()
117 endif()
118endif()
119
120set(LLD_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
121set(LLD_INCLUDE_DIR ${LLD_SOURCE_DIR}/include )
122set(LLD_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
123
124# Compute the LLD version from the LLVM version.
125string(REGEX MATCH "[0-9]+\\.[0-9]+(\\.[0-9]+)?" LLD_VERSION
126 ${PACKAGE_VERSION})
127message(STATUS "LLD version: ${LLD_VERSION}")
128
129string(REGEX REPLACE "([0-9]+)\\.[0-9]+(\\.[0-9]+)?" "\\1" LLD_VERSION_MAJOR
130 ${LLD_VERSION})
131string(REGEX REPLACE "[0-9]+\\.([0-9]+)(\\.[0-9]+)?" "\\1" LLD_VERSION_MINOR
132 ${LLD_VERSION})
133
134# Determine LLD revision and repository.
135# TODO: Figure out a way to get the revision and the repository on windows.
136if ( NOT CMAKE_SYSTEM_NAME MATCHES "Windows" )
137 execute_process(COMMAND ${CMAKE_SOURCE_DIR}/utils/GetSourceVersion ${LLD_SOURCE_DIR}
138 OUTPUT_VARIABLE LLD_REVISION)
139
140 execute_process(COMMAND ${CMAKE_SOURCE_DIR}/utils/GetRepositoryPath ${LLD_SOURCE_DIR}
141 OUTPUT_VARIABLE LLD_REPOSITORY)
142 if ( LLD_REPOSITORY )
143 # Replace newline characters with spaces
144 string(REGEX REPLACE "(\r?\n)+" " " LLD_REPOSITORY ${LLD_REPOSITORY})
145 # Remove leading spaces
146 STRING(REGEX REPLACE "^[ \t\r\n]+" "" LLD_REPOSITORY "${LLD_REPOSITORY}" )
147 # Remove trailing spaces
148 string(REGEX REPLACE "(\ )+$" "" LLD_REPOSITORY ${LLD_REPOSITORY})
149 endif()
150
151 if ( LLD_REVISION )
152 # Replace newline characters with spaces
153 string(REGEX REPLACE "(\r?\n)+" " " LLD_REVISION ${LLD_REVISION})
154 # Remove leading spaces
155 STRING(REGEX REPLACE "^[ \t\r\n]+" "" LLD_REVISION "${LLD_REVISION}" )
156 # Remove trailing spaces
157 string(REGEX REPLACE "(\ )+$" "" LLD_REVISION ${LLD_REVISION})
158 endif()
159endif ()
160
161# Configure the Version.inc file.
162configure_file(
163 ${CMAKE_CURRENT_SOURCE_DIR}/include/lld/Config/Version.inc.in
164 ${CMAKE_CURRENT_BINARY_DIR}/include/lld/Config/Version.inc)
165
166
167if (CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
168 message(FATAL_ERROR "In-source builds are not allowed. CMake would overwrite "
169"the makefiles distributed with LLVM. Please create a directory and run cmake "
170"from there, passing the path to this source directory as the last argument. "
171"This process created the file `CMakeCache.txt' and the directory "
172"`CMakeFiles'. Please delete them.")
173endif()
174
175list (APPEND CMAKE_MODULE_PATH "${LLD_SOURCE_DIR}/cmake/modules")
176
177include(AddLLD)
178
179option(LLD_USE_VTUNE
180 "Enable VTune user task tracking."
181 OFF)
182if (LLD_USE_VTUNE)
183 find_package(VTune)
184 if (VTUNE_FOUND)
185 include_directories(${VTune_INCLUDE_DIRS})
186 list(APPEND LLVM_COMMON_LIBS ${VTune_LIBRARIES})
187 add_definitions(-DLLD_HAS_VTUNE)
188 endif()
189endif()
190
191option(LLD_BUILD_TOOLS
192 "Build the lld tools. If OFF, just generate build targets." ON)
193
194if (MSVC)
195 add_definitions(-wd4530) # Suppress 'warning C4530: C++ exception handler used, but unwind semantics are not enabled.'
196 add_definitions(-wd4062) # Suppress 'warning C4062: enumerator X in switch of enum Y is not handled' from system header.
197endif()
198
199include_directories(BEFORE
200 ${CMAKE_CURRENT_BINARY_DIR}/include
201 ${CMAKE_CURRENT_SOURCE_DIR}/include
202 )
203
204if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
205 install(DIRECTORY include/
206 DESTINATION include
207 FILES_MATCHING
208 PATTERN "*.h"
209 PATTERN ".svn" EXCLUDE
210 )
211endif()
212
213add_subdirectory(lib)
214add_subdirectory(tools/lld)
215
216if (LLVM_INCLUDE_TESTS)
217 add_subdirectory(test)
218 add_subdirectory(unittests)
219endif()
220
221add_subdirectory(docs)
222add_subdirectory(COFF)
223add_subdirectory(ELF)
224
deps/lld/CODE_OWNERS.TXT created+19
......@@ -0,0 +1,19 @@
1This file is a list of the people responsible for ensuring that patches for a
2particular part of LLD are reviewed, either by themself or by someone else.
3They are also the gatekeepers for their part of LLD, with the final word on
4what goes in or not.
5
6The list is sorted by surname and formatted to allow easy grepping and
7beautification by scripts. The fields are: name (N), email (E), web-address
8(W), PGP key ID and fingerprint (P), description (D), and snail-mail address
9(S). Each entry should contain at least the (N), (E) and (D) fields.
10
11
12N: Rui Ueyama
13E: ruiu@google.com
14D: COFF, ELF backends (COFF/* ELF/*)
15
16N: Lang Hames, Nick Kledzik
17E: lhames@gmail.com, kledzik@apple.com
18D: Mach-O backend
19
deps/lld/COFF/CMakeLists.txt created+50
......@@ -0,0 +1,50 @@
1set(LLVM_TARGET_DEFINITIONS Options.td)
2tablegen(LLVM Options.inc -gen-opt-parser-defs)
3add_public_tablegen_target(COFFOptionsTableGen)
4
5if(NOT LLD_BUILT_STANDALONE)
6 set(tablegen_deps intrinsics_gen)
7endif()
8
9add_lld_library(lldCOFF
10 Chunks.cpp
11 DLL.cpp
12 Driver.cpp
13 DriverUtils.cpp
14 Error.cpp
15 ICF.cpp
16 InputFiles.cpp
17 LTO.cpp
18 MapFile.cpp
19 MarkLive.cpp
20 PDB.cpp
21 Strings.cpp
22 SymbolTable.cpp
23 Symbols.cpp
24 Writer.cpp
25
26 LINK_COMPONENTS
27 ${LLVM_TARGETS_TO_BUILD}
28 BinaryFormat
29 BitReader
30 Core
31 DebugInfoCodeView
32 DebugInfoMSF
33 DebugInfoPDB
34 LTO
35 LibDriver
36 Object
37 MC
38 MCDisassembler
39 Target
40 Option
41 Support
42
43 LINK_LIBS
44 lldCore
45 ${LLVM_PTHREAD_LIB}
46
47 DEPENDS
48 COFFOptionsTableGen
49 ${tablegen_deps}
50 )
deps/lld/COFF/Chunks.cpp created+500
......@@ -0,0 +1,500 @@
1//===- Chunks.cpp ---------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "Chunks.h"
11#include "Error.h"
12#include "InputFiles.h"
13#include "Symbols.h"
14#include "Writer.h"
15#include "llvm/ADT/Twine.h"
16#include "llvm/BinaryFormat/COFF.h"
17#include "llvm/Object/COFF.h"
18#include "llvm/Support/Debug.h"
19#include "llvm/Support/Endian.h"
20#include "llvm/Support/raw_ostream.h"
21#include <algorithm>
22
23using namespace llvm;
24using namespace llvm::object;
25using namespace llvm::support::endian;
26using namespace llvm::COFF;
27using llvm::support::ulittle32_t;
28
29namespace lld {
30namespace coff {
31
32SectionChunk::SectionChunk(ObjectFile *F, const coff_section *H)
33 : Chunk(SectionKind), Repl(this), Header(H), File(F),
34 Relocs(File->getCOFFObj()->getRelocations(Header)),
35 NumRelocs(std::distance(Relocs.begin(), Relocs.end())) {
36 // Initialize SectionName.
37 File->getCOFFObj()->getSectionName(Header, SectionName);
38
39 Align = Header->getAlignment();
40
41 // Chunks may be discarded during comdat merging.
42 Discarded = false;
43
44 // If linker GC is disabled, every chunk starts out alive. If linker GC is
45 // enabled, treat non-comdat sections as roots. Generally optimized object
46 // files will be built with -ffunction-sections or /Gy, so most things worth
47 // stripping will be in a comdat.
48 Live = !Config->DoGC || !isCOMDAT();
49}
50
51static void add16(uint8_t *P, int16_t V) { write16le(P, read16le(P) + V); }
52static void add32(uint8_t *P, int32_t V) { write32le(P, read32le(P) + V); }
53static void add64(uint8_t *P, int64_t V) { write64le(P, read64le(P) + V); }
54static void or16(uint8_t *P, uint16_t V) { write16le(P, read16le(P) | V); }
55static void or32(uint8_t *P, uint32_t V) { write32le(P, read32le(P) | V); }
56
57static void applySecRel(const SectionChunk *Sec, uint8_t *Off,
58 OutputSection *OS, uint64_t S) {
59 if (!OS) {
60 if (Sec->isCodeView())
61 return;
62 fatal("SECREL relocation cannot be applied to absolute symbols");
63 }
64 uint64_t SecRel = S - OS->getRVA();
65 assert(SecRel < INT32_MAX && "overflow in SECREL relocation");
66 add32(Off, SecRel);
67}
68
69static void applySecIdx(uint8_t *Off, OutputSection *OS) {
70 // If we have no output section, this must be an absolute symbol. Use the
71 // sentinel absolute symbol section index.
72 uint16_t SecIdx = OS ? OS->SectionIndex : DefinedAbsolute::OutputSectionIndex;
73 add16(Off, SecIdx);
74}
75
76void SectionChunk::applyRelX64(uint8_t *Off, uint16_t Type, OutputSection *OS,
77 uint64_t S, uint64_t P) const {
78 switch (Type) {
79 case IMAGE_REL_AMD64_ADDR32: add32(Off, S + Config->ImageBase); break;
80 case IMAGE_REL_AMD64_ADDR64: add64(Off, S + Config->ImageBase); break;
81 case IMAGE_REL_AMD64_ADDR32NB: add32(Off, S); break;
82 case IMAGE_REL_AMD64_REL32: add32(Off, S - P - 4); break;
83 case IMAGE_REL_AMD64_REL32_1: add32(Off, S - P - 5); break;
84 case IMAGE_REL_AMD64_REL32_2: add32(Off, S - P - 6); break;
85 case IMAGE_REL_AMD64_REL32_3: add32(Off, S - P - 7); break;
86 case IMAGE_REL_AMD64_REL32_4: add32(Off, S - P - 8); break;
87 case IMAGE_REL_AMD64_REL32_5: add32(Off, S - P - 9); break;
88 case IMAGE_REL_AMD64_SECTION: applySecIdx(Off, OS); break;
89 case IMAGE_REL_AMD64_SECREL: applySecRel(this, Off, OS, S); break;
90 default:
91 fatal("unsupported relocation type 0x" + Twine::utohexstr(Type));
92 }
93}
94
95void SectionChunk::applyRelX86(uint8_t *Off, uint16_t Type, OutputSection *OS,
96 uint64_t S, uint64_t P) const {
97 switch (Type) {
98 case IMAGE_REL_I386_ABSOLUTE: break;
99 case IMAGE_REL_I386_DIR32: add32(Off, S + Config->ImageBase); break;
100 case IMAGE_REL_I386_DIR32NB: add32(Off, S); break;
101 case IMAGE_REL_I386_REL32: add32(Off, S - P - 4); break;
102 case IMAGE_REL_I386_SECTION: applySecIdx(Off, OS); break;
103 case IMAGE_REL_I386_SECREL: applySecRel(this, Off, OS, S); break;
104 default:
105 fatal("unsupported relocation type 0x" + Twine::utohexstr(Type));
106 }
107}
108
109static void applyMOV(uint8_t *Off, uint16_t V) {
110 write16le(Off, (read16le(Off) & 0xfbf0) | ((V & 0x800) >> 1) | ((V >> 12) & 0xf));
111 write16le(Off + 2, (read16le(Off + 2) & 0x8f00) | ((V & 0x700) << 4) | (V & 0xff));
112}
113
114static uint16_t readMOV(uint8_t *Off) {
115 uint16_t Opcode1 = read16le(Off);
116 uint16_t Opcode2 = read16le(Off + 2);
117 uint16_t Imm = (Opcode2 & 0x00ff) | ((Opcode2 >> 4) & 0x0700);
118 Imm |= ((Opcode1 << 1) & 0x0800) | ((Opcode1 & 0x000f) << 12);
119 return Imm;
120}
121
122static void applyMOV32T(uint8_t *Off, uint32_t V) {
123 uint16_t ImmW = readMOV(Off); // read MOVW operand
124 uint16_t ImmT = readMOV(Off + 4); // read MOVT operand
125 uint32_t Imm = ImmW | (ImmT << 16);
126 V += Imm; // add the immediate offset
127 applyMOV(Off, V); // set MOVW operand
128 applyMOV(Off + 4, V >> 16); // set MOVT operand
129}
130
131static void applyBranch20T(uint8_t *Off, int32_t V) {
132 uint32_t S = V < 0 ? 1 : 0;
133 uint32_t J1 = (V >> 19) & 1;
134 uint32_t J2 = (V >> 18) & 1;
135 or16(Off, (S << 10) | ((V >> 12) & 0x3f));
136 or16(Off + 2, (J1 << 13) | (J2 << 11) | ((V >> 1) & 0x7ff));
137}
138
139static void applyBranch24T(uint8_t *Off, int32_t V) {
140 if (!isInt<25>(V))
141 fatal("relocation out of range");
142 uint32_t S = V < 0 ? 1 : 0;
143 uint32_t J1 = ((~V >> 23) & 1) ^ S;
144 uint32_t J2 = ((~V >> 22) & 1) ^ S;
145 or16(Off, (S << 10) | ((V >> 12) & 0x3ff));
146 // Clear out the J1 and J2 bits which may be set.
147 write16le(Off + 2, (read16le(Off + 2) & 0xd000) | (J1 << 13) | (J2 << 11) | ((V >> 1) & 0x7ff));
148}
149
150void SectionChunk::applyRelARM(uint8_t *Off, uint16_t Type, OutputSection *OS,
151 uint64_t S, uint64_t P) const {
152 // Pointer to thumb code must have the LSB set.
153 uint64_t SX = S;
154 if (OS && (OS->getPermissions() & IMAGE_SCN_MEM_EXECUTE))
155 SX |= 1;
156 switch (Type) {
157 case IMAGE_REL_ARM_ADDR32: add32(Off, SX + Config->ImageBase); break;
158 case IMAGE_REL_ARM_ADDR32NB: add32(Off, SX); break;
159 case IMAGE_REL_ARM_MOV32T: applyMOV32T(Off, SX + Config->ImageBase); break;
160 case IMAGE_REL_ARM_BRANCH20T: applyBranch20T(Off, SX - P - 4); break;
161 case IMAGE_REL_ARM_BRANCH24T: applyBranch24T(Off, SX - P - 4); break;
162 case IMAGE_REL_ARM_BLX23T: applyBranch24T(Off, SX - P - 4); break;
163 case IMAGE_REL_ARM_SECTION: applySecIdx(Off, OS); break;
164 case IMAGE_REL_ARM_SECREL: applySecRel(this, Off, OS, S); break;
165 default:
166 fatal("unsupported relocation type 0x" + Twine::utohexstr(Type));
167 }
168}
169
170static void applyArm64Addr(uint8_t *Off, uint64_t Imm) {
171 uint32_t ImmLo = (Imm & 0x3) << 29;
172 uint32_t ImmHi = (Imm & 0x1FFFFC) << 3;
173 uint64_t Mask = (0x3 << 29) | (0x1FFFFC << 3);
174 write32le(Off, (read32le(Off) & ~Mask) | ImmLo | ImmHi);
175}
176
177// Update the immediate field in a AARCH64 ldr, str, and add instruction.
178static void applyArm64Imm(uint8_t *Off, uint64_t Imm) {
179 uint32_t Orig = read32le(Off);
180 Imm += (Orig >> 10) & 0xFFF;
181 Orig &= ~(0xFFF << 10);
182 write32le(Off, Orig | ((Imm & 0xFFF) << 10));
183}
184
185static void applyArm64Ldr(uint8_t *Off, uint64_t Imm) {
186 int Size = read32le(Off) >> 30;
187 Imm >>= Size;
188 applyArm64Imm(Off, Imm);
189}
190
191void SectionChunk::applyRelARM64(uint8_t *Off, uint16_t Type, OutputSection *OS,
192 uint64_t S, uint64_t P) const {
193 switch (Type) {
194 case IMAGE_REL_ARM64_PAGEBASE_REL21: applyArm64Addr(Off, (S >> 12) - (P >> 12)); break;
195 case IMAGE_REL_ARM64_PAGEOFFSET_12A: applyArm64Imm(Off, S & 0xfff); break;
196 case IMAGE_REL_ARM64_PAGEOFFSET_12L: applyArm64Ldr(Off, S & 0xfff); break;
197 case IMAGE_REL_ARM64_BRANCH26: or32(Off, ((S - P) & 0x0FFFFFFC) >> 2); break;
198 case IMAGE_REL_ARM64_ADDR32: add32(Off, S + Config->ImageBase); break;
199 case IMAGE_REL_ARM64_ADDR64: add64(Off, S + Config->ImageBase); break;
200 default:
201 fatal("unsupported relocation type 0x" + Twine::utohexstr(Type));
202 }
203}
204
205void SectionChunk::writeTo(uint8_t *Buf) const {
206 if (!hasData())
207 return;
208 // Copy section contents from source object file to output file.
209 ArrayRef<uint8_t> A = getContents();
210 memcpy(Buf + OutputSectionOff, A.data(), A.size());
211
212 // Apply relocations.
213 size_t InputSize = getSize();
214 for (const coff_relocation &Rel : Relocs) {
215 // Check for an invalid relocation offset. This check isn't perfect, because
216 // we don't have the relocation size, which is only known after checking the
217 // machine and relocation type. As a result, a relocation may overwrite the
218 // beginning of the following input section.
219 if (Rel.VirtualAddress >= InputSize)
220 fatal("relocation points beyond the end of its parent section");
221
222 uint8_t *Off = Buf + OutputSectionOff + Rel.VirtualAddress;
223
224 // Get the output section of the symbol for this relocation. The output
225 // section is needed to compute SECREL and SECTION relocations used in debug
226 // info.
227 SymbolBody *Body = File->getSymbolBody(Rel.SymbolTableIndex);
228 Defined *Sym = cast<Defined>(Body);
229 Chunk *C = Sym->getChunk();
230 OutputSection *OS = C ? C->getOutputSection() : nullptr;
231
232 // Only absolute and __ImageBase symbols lack an output section. For any
233 // other symbol, this indicates that the chunk was discarded. Normally
234 // relocations against discarded sections are an error. However, debug info
235 // sections are not GC roots and can end up with these kinds of relocations.
236 // Skip these relocations.
237 if (!OS && !isa<DefinedAbsolute>(Sym) && !isa<DefinedSynthetic>(Sym)) {
238 if (isCodeView() || isDWARF())
239 continue;
240 fatal("relocation against symbol in discarded section: " +
241 Sym->getName());
242 }
243 uint64_t S = Sym->getRVA();
244
245 // Compute the RVA of the relocation for relative relocations.
246 uint64_t P = RVA + Rel.VirtualAddress;
247 switch (Config->Machine) {
248 case AMD64:
249 applyRelX64(Off, Rel.Type, OS, S, P);
250 break;
251 case I386:
252 applyRelX86(Off, Rel.Type, OS, S, P);
253 break;
254 case ARMNT:
255 applyRelARM(Off, Rel.Type, OS, S, P);
256 break;
257 case ARM64:
258 applyRelARM64(Off, Rel.Type, OS, S, P);
259 break;
260 default:
261 llvm_unreachable("unknown machine type");
262 }
263 }
264}
265
266void SectionChunk::addAssociative(SectionChunk *Child) {
267 AssocChildren.push_back(Child);
268}
269
270static uint8_t getBaserelType(const coff_relocation &Rel) {
271 switch (Config->Machine) {
272 case AMD64:
273 if (Rel.Type == IMAGE_REL_AMD64_ADDR64)
274 return IMAGE_REL_BASED_DIR64;
275 return IMAGE_REL_BASED_ABSOLUTE;
276 case I386:
277 if (Rel.Type == IMAGE_REL_I386_DIR32)
278 return IMAGE_REL_BASED_HIGHLOW;
279 return IMAGE_REL_BASED_ABSOLUTE;
280 case ARMNT:
281 if (Rel.Type == IMAGE_REL_ARM_ADDR32)
282 return IMAGE_REL_BASED_HIGHLOW;
283 if (Rel.Type == IMAGE_REL_ARM_MOV32T)
284 return IMAGE_REL_BASED_ARM_MOV32T;
285 return IMAGE_REL_BASED_ABSOLUTE;
286 case ARM64:
287 if (Rel.Type == IMAGE_REL_ARM64_ADDR64)
288 return IMAGE_REL_BASED_DIR64;
289 return IMAGE_REL_BASED_ABSOLUTE;
290 default:
291 llvm_unreachable("unknown machine type");
292 }
293}
294
295// Windows-specific.
296// Collect all locations that contain absolute addresses, which need to be
297// fixed by the loader if load-time relocation is needed.
298// Only called when base relocation is enabled.
299void SectionChunk::getBaserels(std::vector<Baserel> *Res) {
300 for (const coff_relocation &Rel : Relocs) {
301 uint8_t Ty = getBaserelType(Rel);
302 if (Ty == IMAGE_REL_BASED_ABSOLUTE)
303 continue;
304 SymbolBody *Body = File->getSymbolBody(Rel.SymbolTableIndex);
305 if (isa<DefinedAbsolute>(Body))
306 continue;
307 Res->emplace_back(RVA + Rel.VirtualAddress, Ty);
308 }
309}
310
311bool SectionChunk::hasData() const {
312 return !(Header->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA);
313}
314
315uint32_t SectionChunk::getPermissions() const {
316 return Header->Characteristics & PermMask;
317}
318
319bool SectionChunk::isCOMDAT() const {
320 return Header->Characteristics & IMAGE_SCN_LNK_COMDAT;
321}
322
323void SectionChunk::printDiscardedMessage() const {
324 // Removed by dead-stripping. If it's removed by ICF, ICF already
325 // printed out the name, so don't repeat that here.
326 if (Sym && this == Repl) {
327 if (Discarded)
328 message("Discarded comdat symbol " + Sym->getName());
329 else if (!Live)
330 message("Discarded " + Sym->getName());
331 }
332}
333
334StringRef SectionChunk::getDebugName() {
335 if (Sym)
336 return Sym->getName();
337 return "";
338}
339
340ArrayRef<uint8_t> SectionChunk::getContents() const {
341 ArrayRef<uint8_t> A;
342 File->getCOFFObj()->getSectionContents(Header, A);
343 return A;
344}
345
346void SectionChunk::replace(SectionChunk *Other) {
347 Other->Repl = Repl;
348 Other->Live = false;
349}
350
351CommonChunk::CommonChunk(const COFFSymbolRef S) : Sym(S) {
352 // Common symbols are aligned on natural boundaries up to 32 bytes.
353 // This is what MSVC link.exe does.
354 Align = std::min(uint64_t(32), PowerOf2Ceil(Sym.getValue()));
355}
356
357uint32_t CommonChunk::getPermissions() const {
358 return IMAGE_SCN_CNT_UNINITIALIZED_DATA | IMAGE_SCN_MEM_READ |
359 IMAGE_SCN_MEM_WRITE;
360}
361
362void StringChunk::writeTo(uint8_t *Buf) const {
363 memcpy(Buf + OutputSectionOff, Str.data(), Str.size());
364}
365
366ImportThunkChunkX64::ImportThunkChunkX64(Defined *S) : ImpSymbol(S) {
367 // Intel Optimization Manual says that all branch targets
368 // should be 16-byte aligned. MSVC linker does this too.
369 Align = 16;
370}
371
372void ImportThunkChunkX64::writeTo(uint8_t *Buf) const {
373 memcpy(Buf + OutputSectionOff, ImportThunkX86, sizeof(ImportThunkX86));
374 // The first two bytes is a JMP instruction. Fill its operand.
375 write32le(Buf + OutputSectionOff + 2, ImpSymbol->getRVA() - RVA - getSize());
376}
377
378void ImportThunkChunkX86::getBaserels(std::vector<Baserel> *Res) {
379 Res->emplace_back(getRVA() + 2);
380}
381
382void ImportThunkChunkX86::writeTo(uint8_t *Buf) const {
383 memcpy(Buf + OutputSectionOff, ImportThunkX86, sizeof(ImportThunkX86));
384 // The first two bytes is a JMP instruction. Fill its operand.
385 write32le(Buf + OutputSectionOff + 2,
386 ImpSymbol->getRVA() + Config->ImageBase);
387}
388
389void ImportThunkChunkARM::getBaserels(std::vector<Baserel> *Res) {
390 Res->emplace_back(getRVA(), IMAGE_REL_BASED_ARM_MOV32T);
391}
392
393void ImportThunkChunkARM::writeTo(uint8_t *Buf) const {
394 memcpy(Buf + OutputSectionOff, ImportThunkARM, sizeof(ImportThunkARM));
395 // Fix mov.w and mov.t operands.
396 applyMOV32T(Buf + OutputSectionOff, ImpSymbol->getRVA() + Config->ImageBase);
397}
398
399void ImportThunkChunkARM64::writeTo(uint8_t *Buf) const {
400 int64_t PageOff = (ImpSymbol->getRVA() >> 12) - (RVA >> 12);
401 int64_t Off = ImpSymbol->getRVA() & 0xfff;
402 memcpy(Buf + OutputSectionOff, ImportThunkARM64, sizeof(ImportThunkARM64));
403 applyArm64Addr(Buf + OutputSectionOff, PageOff);
404 applyArm64Ldr(Buf + OutputSectionOff + 4, Off);
405}
406
407void LocalImportChunk::getBaserels(std::vector<Baserel> *Res) {
408 Res->emplace_back(getRVA());
409}
410
411size_t LocalImportChunk::getSize() const {
412 return Config->is64() ? 8 : 4;
413}
414
415void LocalImportChunk::writeTo(uint8_t *Buf) const {
416 if (Config->is64()) {
417 write64le(Buf + OutputSectionOff, Sym->getRVA() + Config->ImageBase);
418 } else {
419 write32le(Buf + OutputSectionOff, Sym->getRVA() + Config->ImageBase);
420 }
421}
422
423void SEHTableChunk::writeTo(uint8_t *Buf) const {
424 ulittle32_t *Begin = reinterpret_cast<ulittle32_t *>(Buf + OutputSectionOff);
425 size_t Cnt = 0;
426 for (Defined *D : Syms)
427 Begin[Cnt++] = D->getRVA();
428 std::sort(Begin, Begin + Cnt);
429}
430
431// Windows-specific. This class represents a block in .reloc section.
432// The format is described here.
433//
434// On Windows, each DLL is linked against a fixed base address and
435// usually loaded to that address. However, if there's already another
436// DLL that overlaps, the loader has to relocate it. To do that, DLLs
437// contain .reloc sections which contain offsets that need to be fixed
438// up at runtime. If the loader finds that a DLL cannot be loaded to its
439// desired base address, it loads it to somewhere else, and add <actual
440// base address> - <desired base address> to each offset that is
441// specified by the .reloc section. In ELF terms, .reloc sections
442// contain relative relocations in REL format (as opposed to RELA.)
443//
444// This already significantly reduces the size of relocations compared
445// to ELF .rel.dyn, but Windows does more to reduce it (probably because
446// it was invented for PCs in the late '80s or early '90s.) Offsets in
447// .reloc are grouped by page where the page size is 12 bits, and
448// offsets sharing the same page address are stored consecutively to
449// represent them with less space. This is very similar to the page
450// table which is grouped by (multiple stages of) pages.
451//
452// For example, let's say we have 0x00030, 0x00500, 0x00700, 0x00A00,
453// 0x20004, and 0x20008 in a .reloc section for x64. The uppermost 4
454// bits have a type IMAGE_REL_BASED_DIR64 or 0xA. In the section, they
455// are represented like this:
456//
457// 0x00000 -- page address (4 bytes)
458// 16 -- size of this block (4 bytes)
459// 0xA030 -- entries (2 bytes each)
460// 0xA500
461// 0xA700
462// 0xAA00
463// 0x20000 -- page address (4 bytes)
464// 12 -- size of this block (4 bytes)
465// 0xA004 -- entries (2 bytes each)
466// 0xA008
467//
468// Usually we have a lot of relocations for each page, so the number of
469// bytes for one .reloc entry is close to 2 bytes on average.
470BaserelChunk::BaserelChunk(uint32_t Page, Baserel *Begin, Baserel *End) {
471 // Block header consists of 4 byte page RVA and 4 byte block size.
472 // Each entry is 2 byte. Last entry may be padding.
473 Data.resize(alignTo((End - Begin) * 2 + 8, 4));
474 uint8_t *P = Data.data();
475 write32le(P, Page);
476 write32le(P + 4, Data.size());
477 P += 8;
478 for (Baserel *I = Begin; I != End; ++I) {
479 write16le(P, (I->Type << 12) | (I->RVA - Page));
480 P += 2;
481 }
482}
483
484void BaserelChunk::writeTo(uint8_t *Buf) const {
485 memcpy(Buf + OutputSectionOff, Data.data(), Data.size());
486}
487
488uint8_t Baserel::getDefaultType() {
489 switch (Config->Machine) {
490 case AMD64:
491 return IMAGE_REL_BASED_DIR64;
492 case I386:
493 return IMAGE_REL_BASED_HIGHLOW;
494 default:
495 llvm_unreachable("unknown machine type");
496 }
497}
498
499} // namespace coff
500} // namespace lld
deps/lld/COFF/Chunks.h created+375
......@@ -0,0 +1,375 @@
1//===- Chunks.h -------------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_COFF_CHUNKS_H
11#define LLD_COFF_CHUNKS_H
12
13#include "Config.h"
14#include "InputFiles.h"
15#include "lld/Core/LLVM.h"
16#include "llvm/ADT/ArrayRef.h"
17#include "llvm/ADT/iterator.h"
18#include "llvm/ADT/iterator_range.h"
19#include "llvm/Object/COFF.h"
20#include <utility>
21#include <vector>
22
23namespace lld {
24namespace coff {
25
26using llvm::COFF::ImportDirectoryTableEntry;
27using llvm::object::COFFSymbolRef;
28using llvm::object::SectionRef;
29using llvm::object::coff_relocation;
30using llvm::object::coff_section;
31
32class Baserel;
33class Defined;
34class DefinedImportData;
35class DefinedRegular;
36class ObjectFile;
37class OutputSection;
38class SymbolBody;
39
40// Mask for section types (code, data, bss, disacardable, etc.)
41// and permissions (writable, readable or executable).
42const uint32_t PermMask = 0xFF0000F0;
43
44// A Chunk represents a chunk of data that will occupy space in the
45// output (if the resolver chose that). It may or may not be backed by
46// a section of an input file. It could be linker-created data, or
47// doesn't even have actual data (if common or bss).
48class Chunk {
49public:
50 enum Kind { SectionKind, OtherKind };
51 Kind kind() const { return ChunkKind; }
52 virtual ~Chunk() = default;
53
54 // Returns the size of this chunk (even if this is a common or BSS.)
55 virtual size_t getSize() const = 0;
56
57 // Write this chunk to a mmap'ed file, assuming Buf is pointing to
58 // beginning of the file. Because this function may use RVA values
59 // of other chunks for relocations, you need to set them properly
60 // before calling this function.
61 virtual void writeTo(uint8_t *Buf) const {}
62
63 // The writer sets and uses the addresses.
64 uint64_t getRVA() const { return RVA; }
65 uint32_t getAlign() const { return Align; }
66 void setRVA(uint64_t V) { RVA = V; }
67
68 // Returns true if this has non-zero data. BSS chunks return
69 // false. If false is returned, the space occupied by this chunk
70 // will be filled with zeros.
71 virtual bool hasData() const { return true; }
72
73 // Returns readable/writable/executable bits.
74 virtual uint32_t getPermissions() const { return 0; }
75
76 // Returns the section name if this is a section chunk.
77 // It is illegal to call this function on non-section chunks.
78 virtual StringRef getSectionName() const {
79 llvm_unreachable("unimplemented getSectionName");
80 }
81
82 // An output section has pointers to chunks in the section, and each
83 // chunk has a back pointer to an output section.
84 void setOutputSection(OutputSection *O) { Out = O; }
85 OutputSection *getOutputSection() { return Out; }
86
87 // Windows-specific.
88 // Collect all locations that contain absolute addresses for base relocations.
89 virtual void getBaserels(std::vector<Baserel> *Res) {}
90
91 // Returns a human-readable name of this chunk. Chunks are unnamed chunks of
92 // bytes, so this is used only for logging or debugging.
93 virtual StringRef getDebugName() { return ""; }
94
95protected:
96 Chunk(Kind K = OtherKind) : ChunkKind(K) {}
97 const Kind ChunkKind;
98
99 // The alignment of this chunk. The writer uses the value.
100 uint32_t Align = 1;
101
102 // The RVA of this chunk in the output. The writer sets a value.
103 uint64_t RVA = 0;
104
105public:
106 // The offset from beginning of the output section. The writer sets a value.
107 uint64_t OutputSectionOff = 0;
108
109protected:
110 // The output section for this chunk.
111 OutputSection *Out = nullptr;
112};
113
114// A chunk corresponding a section of an input file.
115class SectionChunk final : public Chunk {
116 // Identical COMDAT Folding feature accesses section internal data.
117 friend class ICF;
118
119public:
120 class symbol_iterator : public llvm::iterator_adaptor_base<
121 symbol_iterator, const coff_relocation *,
122 std::random_access_iterator_tag, SymbolBody *> {
123 friend SectionChunk;
124
125 ObjectFile *File;
126
127 symbol_iterator(ObjectFile *File, const coff_relocation *I)
128 : symbol_iterator::iterator_adaptor_base(I), File(File) {}
129
130 public:
131 symbol_iterator() = default;
132
133 SymbolBody *operator*() const {
134 return File->getSymbolBody(I->SymbolTableIndex);
135 }
136 };
137
138 SectionChunk(ObjectFile *File, const coff_section *Header);
139 static bool classof(const Chunk *C) { return C->kind() == SectionKind; }
140 size_t getSize() const override { return Header->SizeOfRawData; }
141 ArrayRef<uint8_t> getContents() const;
142 void writeTo(uint8_t *Buf) const override;
143 bool hasData() const override;
144 uint32_t getPermissions() const override;
145 StringRef getSectionName() const override { return SectionName; }
146 void getBaserels(std::vector<Baserel> *Res) override;
147 bool isCOMDAT() const;
148 void applyRelX64(uint8_t *Off, uint16_t Type, OutputSection *OS, uint64_t S,
149 uint64_t P) const;
150 void applyRelX86(uint8_t *Off, uint16_t Type, OutputSection *OS, uint64_t S,
151 uint64_t P) const;
152 void applyRelARM(uint8_t *Off, uint16_t Type, OutputSection *OS, uint64_t S,
153 uint64_t P) const;
154 void applyRelARM64(uint8_t *Off, uint16_t Type, OutputSection *OS, uint64_t S,
155 uint64_t P) const;
156
157 // Called if the garbage collector decides to not include this chunk
158 // in a final output. It's supposed to print out a log message to stdout.
159 void printDiscardedMessage() const;
160
161 // Adds COMDAT associative sections to this COMDAT section. A chunk
162 // and its children are treated as a group by the garbage collector.
163 void addAssociative(SectionChunk *Child);
164
165 StringRef getDebugName() override;
166 void setSymbol(DefinedRegular *S) { if (!Sym) Sym = S; }
167
168 // Returns true if the chunk was not dropped by GC or COMDAT deduplication.
169 bool isLive() { return Live && !Discarded; }
170
171 // Used by the garbage collector.
172 void markLive() {
173 assert(Config->DoGC && "should only mark things live from GC");
174 assert(!isLive() && "Cannot mark an already live section!");
175 Live = true;
176 }
177
178 // Returns true if this chunk was dropped by COMDAT deduplication.
179 bool isDiscarded() const { return Discarded; }
180
181 // Used by the SymbolTable when discarding unused comdat sections. This is
182 // redundant when GC is enabled, as all comdat sections will start out dead.
183 void markDiscarded() { Discarded = true; }
184
185 // True if this is a codeview debug info chunk. These will not be laid out in
186 // the image. Instead they will end up in the PDB, if one is requested.
187 bool isCodeView() const {
188 return SectionName == ".debug" || SectionName.startswith(".debug$");
189 }
190
191 // True if this is a DWARF debug info chunk.
192 bool isDWARF() const { return SectionName.startswith(".debug_"); }
193
194 // Allow iteration over the bodies of this chunk's relocated symbols.
195 llvm::iterator_range<symbol_iterator> symbols() const {
196 return llvm::make_range(symbol_iterator(File, Relocs.begin()),
197 symbol_iterator(File, Relocs.end()));
198 }
199
200 // Allow iteration over the associated child chunks for this section.
201 ArrayRef<SectionChunk *> children() const { return AssocChildren; }
202
203 // A pointer pointing to a replacement for this chunk.
204 // Initially it points to "this" object. If this chunk is merged
205 // with other chunk by ICF, it points to another chunk,
206 // and this chunk is considrered as dead.
207 SectionChunk *Repl;
208
209 // The CRC of the contents as described in the COFF spec 4.5.5.
210 // Auxiliary Format 5: Section Definitions. Used for ICF.
211 uint32_t Checksum = 0;
212
213 const coff_section *Header;
214
215 // The file that this chunk was created from.
216 ObjectFile *File;
217
218private:
219 StringRef SectionName;
220 std::vector<SectionChunk *> AssocChildren;
221 llvm::iterator_range<const coff_relocation *> Relocs;
222 size_t NumRelocs;
223
224 // True if this chunk was discarded because it was a duplicate comdat section.
225 bool Discarded;
226
227 // Used by the garbage collector.
228 bool Live;
229
230 // Used for ICF (Identical COMDAT Folding)
231 void replace(SectionChunk *Other);
232 uint32_t Class[2] = {0, 0};
233
234 // Sym points to a section symbol if this is a COMDAT chunk.
235 DefinedRegular *Sym = nullptr;
236};
237
238// A chunk for common symbols. Common chunks don't have actual data.
239class CommonChunk : public Chunk {
240public:
241 CommonChunk(const COFFSymbolRef Sym);
242 size_t getSize() const override { return Sym.getValue(); }
243 bool hasData() const override { return false; }
244 uint32_t getPermissions() const override;
245 StringRef getSectionName() const override { return ".bss"; }
246
247private:
248 const COFFSymbolRef Sym;
249};
250
251// A chunk for linker-created strings.
252class StringChunk : public Chunk {
253public:
254 explicit StringChunk(StringRef S) : Str(S) {}
255 size_t getSize() const override { return Str.size() + 1; }
256 void writeTo(uint8_t *Buf) const override;
257
258private:
259 StringRef Str;
260};
261
262static const uint8_t ImportThunkX86[] = {
263 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // JMP *0x0
264};
265
266static const uint8_t ImportThunkARM[] = {
267 0x40, 0xf2, 0x00, 0x0c, // mov.w ip, #0
268 0xc0, 0xf2, 0x00, 0x0c, // mov.t ip, #0
269 0xdc, 0xf8, 0x00, 0xf0, // ldr.w pc, [ip]
270};
271
272static const uint8_t ImportThunkARM64[] = {
273 0x10, 0x00, 0x00, 0x90, // adrp x16, #0
274 0x10, 0x02, 0x40, 0xf9, // ldr x16, [x16]
275 0x00, 0x02, 0x1f, 0xd6, // br x16
276};
277
278// Windows-specific.
279// A chunk for DLL import jump table entry. In a final output, it's
280// contents will be a JMP instruction to some __imp_ symbol.
281class ImportThunkChunkX64 : public Chunk {
282public:
283 explicit ImportThunkChunkX64(Defined *S);
284 size_t getSize() const override { return sizeof(ImportThunkX86); }
285 void writeTo(uint8_t *Buf) const override;
286
287private:
288 Defined *ImpSymbol;
289};
290
291class ImportThunkChunkX86 : public Chunk {
292public:
293 explicit ImportThunkChunkX86(Defined *S) : ImpSymbol(S) {}
294 size_t getSize() const override { return sizeof(ImportThunkX86); }
295 void getBaserels(std::vector<Baserel> *Res) override;
296 void writeTo(uint8_t *Buf) const override;
297
298private:
299 Defined *ImpSymbol;
300};
301
302class ImportThunkChunkARM : public Chunk {
303public:
304 explicit ImportThunkChunkARM(Defined *S) : ImpSymbol(S) {}
305 size_t getSize() const override { return sizeof(ImportThunkARM); }
306 void getBaserels(std::vector<Baserel> *Res) override;
307 void writeTo(uint8_t *Buf) const override;
308
309private:
310 Defined *ImpSymbol;
311};
312
313class ImportThunkChunkARM64 : public Chunk {
314public:
315 explicit ImportThunkChunkARM64(Defined *S) : ImpSymbol(S) {}
316 size_t getSize() const override { return sizeof(ImportThunkARM64); }
317 void writeTo(uint8_t *Buf) const override;
318
319private:
320 Defined *ImpSymbol;
321};
322
323// Windows-specific.
324// See comments for DefinedLocalImport class.
325class LocalImportChunk : public Chunk {
326public:
327 explicit LocalImportChunk(Defined *S) : Sym(S) {}
328 size_t getSize() const override;
329 void getBaserels(std::vector<Baserel> *Res) override;
330 void writeTo(uint8_t *Buf) const override;
331
332private:
333 Defined *Sym;
334};
335
336// Windows-specific.
337// A chunk for SEH table which contains RVAs of safe exception handler
338// functions. x86-only.
339class SEHTableChunk : public Chunk {
340public:
341 explicit SEHTableChunk(std::set<Defined *> S) : Syms(std::move(S)) {}
342 size_t getSize() const override { return Syms.size() * 4; }
343 void writeTo(uint8_t *Buf) const override;
344
345private:
346 std::set<Defined *> Syms;
347};
348
349// Windows-specific.
350// This class represents a block in .reloc section.
351// See the PE/COFF spec 5.6 for details.
352class BaserelChunk : public Chunk {
353public:
354 BaserelChunk(uint32_t Page, Baserel *Begin, Baserel *End);
355 size_t getSize() const override { return Data.size(); }
356 void writeTo(uint8_t *Buf) const override;
357
358private:
359 std::vector<uint8_t> Data;
360};
361
362class Baserel {
363public:
364 Baserel(uint32_t V, uint8_t Ty) : RVA(V), Type(Ty) {}
365 explicit Baserel(uint32_t V) : Baserel(V, getDefaultType()) {}
366 uint8_t getDefaultType();
367
368 uint32_t RVA;
369 uint8_t Type;
370};
371
372} // namespace coff
373} // namespace lld
374
375#endif
deps/lld/COFF/Config.h created+174
......@@ -0,0 +1,174 @@
1//===- Config.h -------------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_COFF_CONFIG_H
11#define LLD_COFF_CONFIG_H
12
13#include "llvm/ADT/StringRef.h"
14#include "llvm/Object/COFF.h"
15#include <cstdint>
16#include <map>
17#include <set>
18#include <string>
19
20namespace lld {
21namespace coff {
22
23using llvm::COFF::IMAGE_FILE_MACHINE_UNKNOWN;
24using llvm::COFF::WindowsSubsystem;
25using llvm::StringRef;
26class DefinedAbsolute;
27class DefinedRelative;
28class StringChunk;
29struct Symbol;
30class SymbolBody;
31
32// Short aliases.
33static const auto AMD64 = llvm::COFF::IMAGE_FILE_MACHINE_AMD64;
34static const auto ARM64 = llvm::COFF::IMAGE_FILE_MACHINE_ARM64;
35static const auto ARMNT = llvm::COFF::IMAGE_FILE_MACHINE_ARMNT;
36static const auto I386 = llvm::COFF::IMAGE_FILE_MACHINE_I386;
37
38// Represents an /export option.
39struct Export {
40 StringRef Name; // N in /export:N or /export:E=N
41 StringRef ExtName; // E in /export:E=N
42 SymbolBody *Sym = nullptr;
43 uint16_t Ordinal = 0;
44 bool Noname = false;
45 bool Data = false;
46 bool Private = false;
47 bool Constant = false;
48
49 // If an export is a form of /export:foo=dllname.bar, that means
50 // that foo should be exported as an alias to bar in the DLL.
51 // ForwardTo is set to "dllname.bar" part. Usually empty.
52 StringRef ForwardTo;
53 StringChunk *ForwardChunk = nullptr;
54
55 // True if this /export option was in .drectves section.
56 bool Directives = false;
57 StringRef SymbolName;
58 StringRef ExportName; // Name in DLL
59
60 bool operator==(const Export &E) {
61 return (Name == E.Name && ExtName == E.ExtName &&
62 Ordinal == E.Ordinal && Noname == E.Noname &&
63 Data == E.Data && Private == E.Private);
64 }
65};
66
67enum class DebugType {
68 None = 0x0,
69 CV = 0x1, /// CodeView
70 PData = 0x2, /// Procedure Data
71 Fixup = 0x4, /// Relocation Table
72};
73
74// Global configuration.
75struct Configuration {
76 enum ManifestKind { SideBySide, Embed, No };
77 bool is64() { return Machine == AMD64 || Machine == ARM64; }
78
79 llvm::COFF::MachineTypes Machine = IMAGE_FILE_MACHINE_UNKNOWN;
80 bool Verbose = false;
81 WindowsSubsystem Subsystem = llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN;
82 SymbolBody *Entry = nullptr;
83 bool NoEntry = false;
84 std::string OutputFile;
85 std::string ImportName;
86 bool ColorDiagnostics;
87 bool DoGC = true;
88 bool DoICF = true;
89 uint64_t ErrorLimit = 20;
90 bool Relocatable = true;
91 bool Force = false;
92 bool Debug = false;
93 bool WriteSymtab = true;
94 unsigned DebugTypes = static_cast<unsigned>(DebugType::None);
95 llvm::SmallString<128> PDBPath;
96 std::vector<llvm::StringRef> Argv;
97
98 // Symbols in this set are considered as live by the garbage collector.
99 std::set<SymbolBody *> GCRoot;
100
101 std::set<StringRef> NoDefaultLibs;
102 bool NoDefaultLibAll = false;
103
104 // True if we are creating a DLL.
105 bool DLL = false;
106 StringRef Implib;
107 std::vector<Export> Exports;
108 std::set<std::string> DelayLoads;
109 std::map<std::string, int> DLLOrder;
110 SymbolBody *DelayLoadHelper = nullptr;
111
112 bool SaveTemps = false;
113
114 // Used for SafeSEH.
115 Symbol *SEHTable = nullptr;
116 Symbol *SEHCount = nullptr;
117
118 // Used for /opt:lldlto=N
119 unsigned LTOOptLevel = 2;
120
121 // Used for /opt:lldltojobs=N
122 unsigned LTOJobs = 0;
123 // Used for /opt:lldltopartitions=N
124 unsigned LTOPartitions = 1;
125
126 // Used for /merge:from=to (e.g. /merge:.rdata=.text)
127 std::map<StringRef, StringRef> Merge;
128
129 // Used for /section=.name,{DEKPRSW} to set section attributes.
130 std::map<StringRef, uint32_t> Section;
131
132 // Options for manifest files.
133 ManifestKind Manifest = No;
134 int ManifestID = 1;
135 StringRef ManifestDependency;
136 bool ManifestUAC = true;
137 std::vector<std::string> ManifestInput;
138 StringRef ManifestLevel = "'asInvoker'";
139 StringRef ManifestUIAccess = "'false'";
140 StringRef ManifestFile;
141
142 // Used for /failifmismatch.
143 std::map<StringRef, StringRef> MustMatch;
144
145 // Used for /alternatename.
146 std::map<StringRef, StringRef> AlternateNames;
147
148 // Used for /lldmap.
149 std::string MapFile;
150
151 uint64_t ImageBase = -1;
152 uint64_t StackReserve = 1024 * 1024;
153 uint64_t StackCommit = 4096;
154 uint64_t HeapReserve = 1024 * 1024;
155 uint64_t HeapCommit = 4096;
156 uint32_t MajorImageVersion = 0;
157 uint32_t MinorImageVersion = 0;
158 uint32_t MajorOSVersion = 6;
159 uint32_t MinorOSVersion = 0;
160 bool DynamicBase = true;
161 bool NxCompat = true;
162 bool AllowIsolation = true;
163 bool TerminalServerAware = true;
164 bool LargeAddressAware = false;
165 bool HighEntropyVA = false;
166 bool AppContainer = false;
167};
168
169extern Configuration *Config;
170
171} // namespace coff
172} // namespace lld
173
174#endif
deps/lld/COFF/DLL.cpp created+548
......@@ -0,0 +1,548 @@
1//===- DLL.cpp ------------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines various types of chunks for the DLL import or export
11// descriptor tables. They are inherently Windows-specific.
12// You need to read Microsoft PE/COFF spec to understand details
13// about the data structures.
14//
15// If you are not particularly interested in linking against Windows
16// DLL, you can skip this file, and you should still be able to
17// understand the rest of the linker.
18//
19//===----------------------------------------------------------------------===//
20
21#include "Chunks.h"
22#include "DLL.h"
23#include "llvm/Object/COFF.h"
24#include "llvm/Support/Endian.h"
25#include "llvm/Support/Path.h"
26
27using namespace llvm;
28using namespace llvm::object;
29using namespace llvm::support::endian;
30using namespace llvm::COFF;
31
32namespace lld {
33namespace coff {
34namespace {
35
36// Import table
37
38static int ptrSize() { return Config->is64() ? 8 : 4; }
39
40// A chunk for the import descriptor table.
41class HintNameChunk : public Chunk {
42public:
43 HintNameChunk(StringRef N, uint16_t H) : Name(N), Hint(H) {}
44
45 size_t getSize() const override {
46 // Starts with 2 byte Hint field, followed by a null-terminated string,
47 // ends with 0 or 1 byte padding.
48 return alignTo(Name.size() + 3, 2);
49 }
50
51 void writeTo(uint8_t *Buf) const override {
52 write16le(Buf + OutputSectionOff, Hint);
53 memcpy(Buf + OutputSectionOff + 2, Name.data(), Name.size());
54 }
55
56private:
57 StringRef Name;
58 uint16_t Hint;
59};
60
61// A chunk for the import descriptor table.
62class LookupChunk : public Chunk {
63public:
64 explicit LookupChunk(Chunk *C) : HintName(C) {}
65 size_t getSize() const override { return ptrSize(); }
66
67 void writeTo(uint8_t *Buf) const override {
68 write32le(Buf + OutputSectionOff, HintName->getRVA());
69 }
70
71 Chunk *HintName;
72};
73
74// A chunk for the import descriptor table.
75// This chunk represent import-by-ordinal symbols.
76// See Microsoft PE/COFF spec 7.1. Import Header for details.
77class OrdinalOnlyChunk : public Chunk {
78public:
79 explicit OrdinalOnlyChunk(uint16_t V) : Ordinal(V) {}
80 size_t getSize() const override { return ptrSize(); }
81
82 void writeTo(uint8_t *Buf) const override {
83 // An import-by-ordinal slot has MSB 1 to indicate that
84 // this is import-by-ordinal (and not import-by-name).
85 if (Config->is64()) {
86 write64le(Buf + OutputSectionOff, (1ULL << 63) | Ordinal);
87 } else {
88 write32le(Buf + OutputSectionOff, (1ULL << 31) | Ordinal);
89 }
90 }
91
92 uint16_t Ordinal;
93};
94
95// A chunk for the import descriptor table.
96class ImportDirectoryChunk : public Chunk {
97public:
98 explicit ImportDirectoryChunk(Chunk *N) : DLLName(N) {}
99 size_t getSize() const override { return sizeof(ImportDirectoryTableEntry); }
100
101 void writeTo(uint8_t *Buf) const override {
102 auto *E = (coff_import_directory_table_entry *)(Buf + OutputSectionOff);
103 E->ImportLookupTableRVA = LookupTab->getRVA();
104 E->NameRVA = DLLName->getRVA();
105 E->ImportAddressTableRVA = AddressTab->getRVA();
106 }
107
108 Chunk *DLLName;
109 Chunk *LookupTab;
110 Chunk *AddressTab;
111};
112
113// A chunk representing null terminator in the import table.
114// Contents of this chunk is always null bytes.
115class NullChunk : public Chunk {
116public:
117 explicit NullChunk(size_t N) : Size(N) {}
118 bool hasData() const override { return false; }
119 size_t getSize() const override { return Size; }
120 void setAlign(size_t N) { Align = N; }
121
122private:
123 size_t Size;
124};
125
126static std::vector<std::vector<DefinedImportData *>>
127binImports(const std::vector<DefinedImportData *> &Imports) {
128 // Group DLL-imported symbols by DLL name because that's how
129 // symbols are layed out in the import descriptor table.
130 auto Less = [](const std::string &A, const std::string &B) {
131 return Config->DLLOrder[A] < Config->DLLOrder[B];
132 };
133 std::map<std::string, std::vector<DefinedImportData *>,
134 bool(*)(const std::string &, const std::string &)> M(Less);
135 for (DefinedImportData *Sym : Imports)
136 M[Sym->getDLLName().lower()].push_back(Sym);
137
138 std::vector<std::vector<DefinedImportData *>> V;
139 for (auto &KV : M) {
140 // Sort symbols by name for each group.
141 std::vector<DefinedImportData *> &Syms = KV.second;
142 std::sort(Syms.begin(), Syms.end(),
143 [](DefinedImportData *A, DefinedImportData *B) {
144 return A->getName() < B->getName();
145 });
146 V.push_back(std::move(Syms));
147 }
148 return V;
149}
150
151// Export table
152// See Microsoft PE/COFF spec 4.3 for details.
153
154// A chunk for the delay import descriptor table etnry.
155class DelayDirectoryChunk : public Chunk {
156public:
157 explicit DelayDirectoryChunk(Chunk *N) : DLLName(N) {}
158
159 size_t getSize() const override {
160 return sizeof(delay_import_directory_table_entry);
161 }
162
163 void writeTo(uint8_t *Buf) const override {
164 auto *E = (delay_import_directory_table_entry *)(Buf + OutputSectionOff);
165 E->Attributes = 1;
166 E->Name = DLLName->getRVA();
167 E->ModuleHandle = ModuleHandle->getRVA();
168 E->DelayImportAddressTable = AddressTab->getRVA();
169 E->DelayImportNameTable = NameTab->getRVA();
170 }
171
172 Chunk *DLLName;
173 Chunk *ModuleHandle;
174 Chunk *AddressTab;
175 Chunk *NameTab;
176};
177
178// Initial contents for delay-loaded functions.
179// This code calls __delayLoadHelper2 function to resolve a symbol
180// and then overwrites its jump table slot with the result
181// for subsequent function calls.
182static const uint8_t ThunkX64[] = {
183 0x51, // push rcx
184 0x52, // push rdx
185 0x41, 0x50, // push r8
186 0x41, 0x51, // push r9
187 0x48, 0x83, 0xEC, 0x48, // sub rsp, 48h
188 0x66, 0x0F, 0x7F, 0x04, 0x24, // movdqa xmmword ptr [rsp], xmm0
189 0x66, 0x0F, 0x7F, 0x4C, 0x24, 0x10, // movdqa xmmword ptr [rsp+10h], xmm1
190 0x66, 0x0F, 0x7F, 0x54, 0x24, 0x20, // movdqa xmmword ptr [rsp+20h], xmm2
191 0x66, 0x0F, 0x7F, 0x5C, 0x24, 0x30, // movdqa xmmword ptr [rsp+30h], xmm3
192 0x48, 0x8D, 0x15, 0, 0, 0, 0, // lea rdx, [__imp_<FUNCNAME>]
193 0x48, 0x8D, 0x0D, 0, 0, 0, 0, // lea rcx, [___DELAY_IMPORT_...]
194 0xE8, 0, 0, 0, 0, // call __delayLoadHelper2
195 0x66, 0x0F, 0x6F, 0x04, 0x24, // movdqa xmm0, xmmword ptr [rsp]
196 0x66, 0x0F, 0x6F, 0x4C, 0x24, 0x10, // movdqa xmm1, xmmword ptr [rsp+10h]
197 0x66, 0x0F, 0x6F, 0x54, 0x24, 0x20, // movdqa xmm2, xmmword ptr [rsp+20h]
198 0x66, 0x0F, 0x6F, 0x5C, 0x24, 0x30, // movdqa xmm3, xmmword ptr [rsp+30h]
199 0x48, 0x83, 0xC4, 0x48, // add rsp, 48h
200 0x41, 0x59, // pop r9
201 0x41, 0x58, // pop r8
202 0x5A, // pop rdx
203 0x59, // pop rcx
204 0xFF, 0xE0, // jmp rax
205};
206
207static const uint8_t ThunkX86[] = {
208 0x51, // push ecx
209 0x52, // push edx
210 0x68, 0, 0, 0, 0, // push offset ___imp__<FUNCNAME>
211 0x68, 0, 0, 0, 0, // push offset ___DELAY_IMPORT_DESCRIPTOR_<DLLNAME>_dll
212 0xE8, 0, 0, 0, 0, // call ___delayLoadHelper2@8
213 0x5A, // pop edx
214 0x59, // pop ecx
215 0xFF, 0xE0, // jmp eax
216};
217
218// A chunk for the delay import thunk.
219class ThunkChunkX64 : public Chunk {
220public:
221 ThunkChunkX64(Defined *I, Chunk *D, Defined *H)
222 : Imp(I), Desc(D), Helper(H) {}
223
224 size_t getSize() const override { return sizeof(ThunkX64); }
225
226 void writeTo(uint8_t *Buf) const override {
227 memcpy(Buf + OutputSectionOff, ThunkX64, sizeof(ThunkX64));
228 write32le(Buf + OutputSectionOff + 36, Imp->getRVA() - RVA - 40);
229 write32le(Buf + OutputSectionOff + 43, Desc->getRVA() - RVA - 47);
230 write32le(Buf + OutputSectionOff + 48, Helper->getRVA() - RVA - 52);
231 }
232
233 Defined *Imp = nullptr;
234 Chunk *Desc = nullptr;
235 Defined *Helper = nullptr;
236};
237
238class ThunkChunkX86 : public Chunk {
239public:
240 ThunkChunkX86(Defined *I, Chunk *D, Defined *H)
241 : Imp(I), Desc(D), Helper(H) {}
242
243 size_t getSize() const override { return sizeof(ThunkX86); }
244
245 void writeTo(uint8_t *Buf) const override {
246 memcpy(Buf + OutputSectionOff, ThunkX86, sizeof(ThunkX86));
247 write32le(Buf + OutputSectionOff + 3, Imp->getRVA() + Config->ImageBase);
248 write32le(Buf + OutputSectionOff + 8, Desc->getRVA() + Config->ImageBase);
249 write32le(Buf + OutputSectionOff + 13, Helper->getRVA() - RVA - 17);
250 }
251
252 void getBaserels(std::vector<Baserel> *Res) override {
253 Res->emplace_back(RVA + 3);
254 Res->emplace_back(RVA + 8);
255 }
256
257 Defined *Imp = nullptr;
258 Chunk *Desc = nullptr;
259 Defined *Helper = nullptr;
260};
261
262// A chunk for the import descriptor table.
263class DelayAddressChunk : public Chunk {
264public:
265 explicit DelayAddressChunk(Chunk *C) : Thunk(C) {}
266 size_t getSize() const override { return ptrSize(); }
267
268 void writeTo(uint8_t *Buf) const override {
269 if (Config->is64()) {
270 write64le(Buf + OutputSectionOff, Thunk->getRVA() + Config->ImageBase);
271 } else {
272 write32le(Buf + OutputSectionOff, Thunk->getRVA() + Config->ImageBase);
273 }
274 }
275
276 void getBaserels(std::vector<Baserel> *Res) override {
277 Res->emplace_back(RVA);
278 }
279
280 Chunk *Thunk;
281};
282
283// Export table
284// Read Microsoft PE/COFF spec 5.3 for details.
285
286// A chunk for the export descriptor table.
287class ExportDirectoryChunk : public Chunk {
288public:
289 ExportDirectoryChunk(int I, int J, Chunk *D, Chunk *A, Chunk *N, Chunk *O)
290 : MaxOrdinal(I), NameTabSize(J), DLLName(D), AddressTab(A), NameTab(N),
291 OrdinalTab(O) {}
292
293 size_t getSize() const override {
294 return sizeof(export_directory_table_entry);
295 }
296
297 void writeTo(uint8_t *Buf) const override {
298 auto *E = (export_directory_table_entry *)(Buf + OutputSectionOff);
299 E->NameRVA = DLLName->getRVA();
300 E->OrdinalBase = 0;
301 E->AddressTableEntries = MaxOrdinal + 1;
302 E->NumberOfNamePointers = NameTabSize;
303 E->ExportAddressTableRVA = AddressTab->getRVA();
304 E->NamePointerRVA = NameTab->getRVA();
305 E->OrdinalTableRVA = OrdinalTab->getRVA();
306 }
307
308 uint16_t MaxOrdinal;
309 uint16_t NameTabSize;
310 Chunk *DLLName;
311 Chunk *AddressTab;
312 Chunk *NameTab;
313 Chunk *OrdinalTab;
314};
315
316class AddressTableChunk : public Chunk {
317public:
318 explicit AddressTableChunk(size_t MaxOrdinal) : Size(MaxOrdinal + 1) {}
319 size_t getSize() const override { return Size * 4; }
320
321 void writeTo(uint8_t *Buf) const override {
322 for (Export &E : Config->Exports) {
323 uint8_t *P = Buf + OutputSectionOff + E.Ordinal * 4;
324 if (E.ForwardChunk) {
325 write32le(P, E.ForwardChunk->getRVA());
326 } else {
327 write32le(P, cast<Defined>(E.Sym)->getRVA());
328 }
329 }
330 }
331
332private:
333 size_t Size;
334};
335
336class NamePointersChunk : public Chunk {
337public:
338 explicit NamePointersChunk(std::vector<Chunk *> &V) : Chunks(V) {}
339 size_t getSize() const override { return Chunks.size() * 4; }
340
341 void writeTo(uint8_t *Buf) const override {
342 uint8_t *P = Buf + OutputSectionOff;
343 for (Chunk *C : Chunks) {
344 write32le(P, C->getRVA());
345 P += 4;
346 }
347 }
348
349private:
350 std::vector<Chunk *> Chunks;
351};
352
353class ExportOrdinalChunk : public Chunk {
354public:
355 explicit ExportOrdinalChunk(size_t I) : Size(I) {}
356 size_t getSize() const override { return Size * 2; }
357
358 void writeTo(uint8_t *Buf) const override {
359 uint8_t *P = Buf + OutputSectionOff;
360 for (Export &E : Config->Exports) {
361 if (E.Noname)
362 continue;
363 write16le(P, E.Ordinal);
364 P += 2;
365 }
366 }
367
368private:
369 size_t Size;
370};
371
372} // anonymous namespace
373
374uint64_t IdataContents::getDirSize() {
375 return Dirs.size() * sizeof(ImportDirectoryTableEntry);
376}
377
378uint64_t IdataContents::getIATSize() {
379 return Addresses.size() * ptrSize();
380}
381
382// Returns a list of .idata contents.
383// See Microsoft PE/COFF spec 5.4 for details.
384std::vector<Chunk *> IdataContents::getChunks() {
385 create();
386
387 // The loader assumes a specific order of data.
388 // Add each type in the correct order.
389 std::vector<Chunk *> V;
390 V.insert(V.end(), Dirs.begin(), Dirs.end());
391 V.insert(V.end(), Lookups.begin(), Lookups.end());
392 V.insert(V.end(), Addresses.begin(), Addresses.end());
393 V.insert(V.end(), Hints.begin(), Hints.end());
394 V.insert(V.end(), DLLNames.begin(), DLLNames.end());
395 return V;
396}
397
398void IdataContents::create() {
399 std::vector<std::vector<DefinedImportData *>> V = binImports(Imports);
400
401 // Create .idata contents for each DLL.
402 for (std::vector<DefinedImportData *> &Syms : V) {
403 // Create lookup and address tables. If they have external names,
404 // we need to create HintName chunks to store the names.
405 // If they don't (if they are import-by-ordinals), we store only
406 // ordinal values to the table.
407 size_t Base = Lookups.size();
408 for (DefinedImportData *S : Syms) {
409 uint16_t Ord = S->getOrdinal();
410 if (S->getExternalName().empty()) {
411 Lookups.push_back(make<OrdinalOnlyChunk>(Ord));
412 Addresses.push_back(make<OrdinalOnlyChunk>(Ord));
413 continue;
414 }
415 auto *C = make<HintNameChunk>(S->getExternalName(), Ord);
416 Lookups.push_back(make<LookupChunk>(C));
417 Addresses.push_back(make<LookupChunk>(C));
418 Hints.push_back(C);
419 }
420 // Terminate with null values.
421 Lookups.push_back(make<NullChunk>(ptrSize()));
422 Addresses.push_back(make<NullChunk>(ptrSize()));
423
424 for (int I = 0, E = Syms.size(); I < E; ++I)
425 Syms[I]->setLocation(Addresses[Base + I]);
426
427 // Create the import table header.
428 DLLNames.push_back(make<StringChunk>(Syms[0]->getDLLName()));
429 auto *Dir = make<ImportDirectoryChunk>(DLLNames.back());
430 Dir->LookupTab = Lookups[Base];
431 Dir->AddressTab = Addresses[Base];
432 Dirs.push_back(Dir);
433 }
434 // Add null terminator.
435 Dirs.push_back(make<NullChunk>(sizeof(ImportDirectoryTableEntry)));
436}
437
438std::vector<Chunk *> DelayLoadContents::getChunks() {
439 std::vector<Chunk *> V;
440 V.insert(V.end(), Dirs.begin(), Dirs.end());
441 V.insert(V.end(), Names.begin(), Names.end());
442 V.insert(V.end(), HintNames.begin(), HintNames.end());
443 V.insert(V.end(), DLLNames.begin(), DLLNames.end());
444 return V;
445}
446
447std::vector<Chunk *> DelayLoadContents::getDataChunks() {
448 std::vector<Chunk *> V;
449 V.insert(V.end(), ModuleHandles.begin(), ModuleHandles.end());
450 V.insert(V.end(), Addresses.begin(), Addresses.end());
451 return V;
452}
453
454uint64_t DelayLoadContents::getDirSize() {
455 return Dirs.size() * sizeof(delay_import_directory_table_entry);
456}
457
458void DelayLoadContents::create(Defined *H) {
459 Helper = H;
460 std::vector<std::vector<DefinedImportData *>> V = binImports(Imports);
461
462 // Create .didat contents for each DLL.
463 for (std::vector<DefinedImportData *> &Syms : V) {
464 // Create the delay import table header.
465 DLLNames.push_back(make<StringChunk>(Syms[0]->getDLLName()));
466 auto *Dir = make<DelayDirectoryChunk>(DLLNames.back());
467
468 size_t Base = Addresses.size();
469 for (DefinedImportData *S : Syms) {
470 Chunk *T = newThunkChunk(S, Dir);
471 auto *A = make<DelayAddressChunk>(T);
472 Addresses.push_back(A);
473 Thunks.push_back(T);
474 StringRef ExtName = S->getExternalName();
475 if (ExtName.empty()) {
476 Names.push_back(make<OrdinalOnlyChunk>(S->getOrdinal()));
477 } else {
478 auto *C = make<HintNameChunk>(ExtName, 0);
479 Names.push_back(make<LookupChunk>(C));
480 HintNames.push_back(C);
481 }
482 }
483 // Terminate with null values.
484 Addresses.push_back(make<NullChunk>(8));
485 Names.push_back(make<NullChunk>(8));
486
487 for (int I = 0, E = Syms.size(); I < E; ++I)
488 Syms[I]->setLocation(Addresses[Base + I]);
489 auto *MH = make<NullChunk>(8);
490 MH->setAlign(8);
491 ModuleHandles.push_back(MH);
492
493 // Fill the delay import table header fields.
494 Dir->ModuleHandle = MH;
495 Dir->AddressTab = Addresses[Base];
496 Dir->NameTab = Names[Base];
497 Dirs.push_back(Dir);
498 }
499 // Add null terminator.
500 Dirs.push_back(make<NullChunk>(sizeof(delay_import_directory_table_entry)));
501}
502
503Chunk *DelayLoadContents::newThunkChunk(DefinedImportData *S, Chunk *Dir) {
504 switch (Config->Machine) {
505 case AMD64:
506 return make<ThunkChunkX64>(S, Dir, Helper);
507 case I386:
508 return make<ThunkChunkX86>(S, Dir, Helper);
509 default:
510 llvm_unreachable("unsupported machine type");
511 }
512}
513
514EdataContents::EdataContents() {
515 uint16_t MaxOrdinal = 0;
516 for (Export &E : Config->Exports)
517 MaxOrdinal = std::max(MaxOrdinal, E.Ordinal);
518
519 auto *DLLName = make<StringChunk>(sys::path::filename(Config->OutputFile));
520 auto *AddressTab = make<AddressTableChunk>(MaxOrdinal);
521 std::vector<Chunk *> Names;
522 for (Export &E : Config->Exports)
523 if (!E.Noname)
524 Names.push_back(make<StringChunk>(E.ExportName));
525
526 std::vector<Chunk *> Forwards;
527 for (Export &E : Config->Exports) {
528 if (E.ForwardTo.empty())
529 continue;
530 E.ForwardChunk = make<StringChunk>(E.ForwardTo);
531 Forwards.push_back(E.ForwardChunk);
532 }
533
534 auto *NameTab = make<NamePointersChunk>(Names);
535 auto *OrdinalTab = make<ExportOrdinalChunk>(Names.size());
536 auto *Dir = make<ExportDirectoryChunk>(MaxOrdinal, Names.size(), DLLName,
537 AddressTab, NameTab, OrdinalTab);
538 Chunks.push_back(Dir);
539 Chunks.push_back(DLLName);
540 Chunks.push_back(AddressTab);
541 Chunks.push_back(NameTab);
542 Chunks.push_back(OrdinalTab);
543 Chunks.insert(Chunks.end(), Names.begin(), Names.end());
544 Chunks.insert(Chunks.end(), Forwards.begin(), Forwards.end());
545}
546
547} // namespace coff
548} // namespace lld
deps/lld/COFF/DLL.h created+84
......@@ -0,0 +1,84 @@
1//===- DLL.h ----------------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_COFF_DLL_H
11#define LLD_COFF_DLL_H
12
13#include "Chunks.h"
14#include "Symbols.h"
15
16namespace lld {
17namespace coff {
18
19// Windows-specific.
20// IdataContents creates all chunks for the DLL import table.
21// You are supposed to call add() to add symbols and then
22// call getChunks() to get a list of chunks.
23class IdataContents {
24public:
25 void add(DefinedImportData *Sym) { Imports.push_back(Sym); }
26 bool empty() { return Imports.empty(); }
27 std::vector<Chunk *> getChunks();
28
29 uint64_t getDirRVA() { return Dirs[0]->getRVA(); }
30 uint64_t getDirSize();
31 uint64_t getIATRVA() { return Addresses[0]->getRVA(); }
32 uint64_t getIATSize();
33
34private:
35 void create();
36
37 std::vector<DefinedImportData *> Imports;
38 std::vector<Chunk *> Dirs;
39 std::vector<Chunk *> Lookups;
40 std::vector<Chunk *> Addresses;
41 std::vector<Chunk *> Hints;
42 std::vector<Chunk *> DLLNames;
43};
44
45// Windows-specific.
46// DelayLoadContents creates all chunks for the delay-load DLL import table.
47class DelayLoadContents {
48public:
49 void add(DefinedImportData *Sym) { Imports.push_back(Sym); }
50 bool empty() { return Imports.empty(); }
51 void create(Defined *Helper);
52 std::vector<Chunk *> getChunks();
53 std::vector<Chunk *> getDataChunks();
54 ArrayRef<Chunk *> getCodeChunks() { return Thunks; }
55
56 uint64_t getDirRVA() { return Dirs[0]->getRVA(); }
57 uint64_t getDirSize();
58
59private:
60 Chunk *newThunkChunk(DefinedImportData *S, Chunk *Dir);
61
62 Defined *Helper;
63 std::vector<DefinedImportData *> Imports;
64 std::vector<Chunk *> Dirs;
65 std::vector<Chunk *> ModuleHandles;
66 std::vector<Chunk *> Addresses;
67 std::vector<Chunk *> Names;
68 std::vector<Chunk *> HintNames;
69 std::vector<Chunk *> Thunks;
70 std::vector<Chunk *> DLLNames;
71};
72
73// Windows-specific.
74// EdataContents creates all chunks for the DLL export table.
75class EdataContents {
76public:
77 EdataContents();
78 std::vector<Chunk *> Chunks;
79};
80
81} // namespace coff
82} // namespace lld
83
84#endif
deps/lld/COFF/Driver.cpp created+1181
......@@ -0,0 +1,1181 @@
1//===- Driver.cpp ---------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "Driver.h"
11#include "Config.h"
12#include "Error.h"
13#include "InputFiles.h"
14#include "Memory.h"
15#include "SymbolTable.h"
16#include "Symbols.h"
17#include "Writer.h"
18#include "lld/Driver/Driver.h"
19#include "llvm/ADT/Optional.h"
20#include "llvm/ADT/StringSwitch.h"
21#include "llvm/BinaryFormat/Magic.h"
22#include "llvm/Object/ArchiveWriter.h"
23#include "llvm/Object/COFFImportFile.h"
24#include "llvm/Object/COFFModuleDefinition.h"
25#include "llvm/Option/Arg.h"
26#include "llvm/Option/ArgList.h"
27#include "llvm/Option/Option.h"
28#include "llvm/Support/Debug.h"
29#include "llvm/Support/Path.h"
30#include "llvm/Support/Process.h"
31#include "llvm/Support/TarWriter.h"
32#include "llvm/Support/TargetSelect.h"
33#include "llvm/Support/raw_ostream.h"
34#include "llvm/ToolDrivers/llvm-lib/LibDriver.h"
35#include <algorithm>
36#include <memory>
37
38#include <future>
39
40using namespace llvm;
41using namespace llvm::object;
42using namespace llvm::COFF;
43using llvm::sys::Process;
44
45namespace lld {
46namespace coff {
47
48Configuration *Config;
49LinkerDriver *Driver;
50
51BumpPtrAllocator BAlloc;
52StringSaver Saver{BAlloc};
53std::vector<SpecificAllocBase *> SpecificAllocBase::Instances;
54
55bool link(ArrayRef<const char *> Args, raw_ostream &Diag) {
56 ErrorCount = 0;
57 ErrorOS = &Diag;
58 Config = make<Configuration>();
59 Config->Argv = {Args.begin(), Args.end()};
60 Config->ColorDiagnostics =
61 (ErrorOS == &llvm::errs() && Process::StandardErrHasColors());
62 Driver = make<LinkerDriver>();
63 Driver->link(Args);
64 return !ErrorCount;
65}
66
67// Drop directory components and replace extension with ".exe" or ".dll".
68static std::string getOutputPath(StringRef Path) {
69 auto P = Path.find_last_of("\\/");
70 StringRef S = (P == StringRef::npos) ? Path : Path.substr(P + 1);
71 const char* E = Config->DLL ? ".dll" : ".exe";
72 return (S.substr(0, S.rfind('.')) + E).str();
73}
74
75// ErrorOr is not default constructible, so it cannot be used as the type
76// parameter of a future.
77// FIXME: We could open the file in createFutureForFile and avoid needing to
78// return an error here, but for the moment that would cost us a file descriptor
79// (a limited resource on Windows) for the duration that the future is pending.
80typedef std::pair<std::unique_ptr<MemoryBuffer>, std::error_code> MBErrPair;
81
82// Create a std::future that opens and maps a file using the best strategy for
83// the host platform.
84static std::future<MBErrPair> createFutureForFile(std::string Path) {
85#if LLVM_ON_WIN32
86 // On Windows, file I/O is relatively slow so it is best to do this
87 // asynchronously.
88 auto Strategy = std::launch::async;
89#else
90 auto Strategy = std::launch::deferred;
91#endif
92 return std::async(Strategy, [=]() {
93 auto MBOrErr = MemoryBuffer::getFile(Path);
94 if (!MBOrErr)
95 return MBErrPair{nullptr, MBOrErr.getError()};
96 return MBErrPair{std::move(*MBOrErr), std::error_code()};
97 });
98}
99
100MemoryBufferRef LinkerDriver::takeBuffer(std::unique_ptr<MemoryBuffer> MB) {
101 MemoryBufferRef MBRef = *MB;
102 make<std::unique_ptr<MemoryBuffer>>(std::move(MB)); // take ownership
103
104 if (Driver->Tar)
105 Driver->Tar->append(relativeToRoot(MBRef.getBufferIdentifier()),
106 MBRef.getBuffer());
107 return MBRef;
108}
109
110void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> MB) {
111 MemoryBufferRef MBRef = takeBuffer(std::move(MB));
112
113 // File type is detected by contents, not by file extension.
114 file_magic Magic = identify_magic(MBRef.getBuffer());
115 if (Magic == file_magic::windows_resource) {
116 Resources.push_back(MBRef);
117 return;
118 }
119
120 FilePaths.push_back(MBRef.getBufferIdentifier());
121 if (Magic == file_magic::archive)
122 return Symtab.addFile(make<ArchiveFile>(MBRef));
123 if (Magic == file_magic::bitcode)
124 return Symtab.addFile(make<BitcodeFile>(MBRef));
125
126 if (Magic == file_magic::coff_cl_gl_object)
127 error(MBRef.getBufferIdentifier() + ": is not a native COFF file. "
128 "Recompile without /GL");
129 else
130 Symtab.addFile(make<ObjectFile>(MBRef));
131}
132
133void LinkerDriver::enqueuePath(StringRef Path) {
134 auto Future =
135 std::make_shared<std::future<MBErrPair>>(createFutureForFile(Path));
136 std::string PathStr = Path;
137 enqueueTask([=]() {
138 auto MBOrErr = Future->get();
139 if (MBOrErr.second)
140 error("could not open " + PathStr + ": " + MBOrErr.second.message());
141 else
142 Driver->addBuffer(std::move(MBOrErr.first));
143 });
144}
145
146void LinkerDriver::addArchiveBuffer(MemoryBufferRef MB, StringRef SymName,
147 StringRef ParentName) {
148 file_magic Magic = identify_magic(MB.getBuffer());
149 if (Magic == file_magic::coff_import_library) {
150 Symtab.addFile(make<ImportFile>(MB));
151 return;
152 }
153
154 InputFile *Obj;
155 if (Magic == file_magic::coff_object) {
156 Obj = make<ObjectFile>(MB);
157 } else if (Magic == file_magic::bitcode) {
158 Obj = make<BitcodeFile>(MB);
159 } else {
160 error("unknown file type: " + MB.getBufferIdentifier());
161 return;
162 }
163
164 Obj->ParentName = ParentName;
165 Symtab.addFile(Obj);
166 log("Loaded " + toString(Obj) + " for " + SymName);
167}
168
169void LinkerDriver::enqueueArchiveMember(const Archive::Child &C,
170 StringRef SymName,
171 StringRef ParentName) {
172 if (!C.getParent()->isThin()) {
173 MemoryBufferRef MB = check(
174 C.getMemoryBufferRef(),
175 "could not get the buffer for the member defining symbol " + SymName);
176 enqueueTask([=]() { Driver->addArchiveBuffer(MB, SymName, ParentName); });
177 return;
178 }
179
180 auto Future = std::make_shared<std::future<MBErrPair>>(createFutureForFile(
181 check(C.getFullName(),
182 "could not get the filename for the member defining symbol " +
183 SymName)));
184 enqueueTask([=]() {
185 auto MBOrErr = Future->get();
186 if (MBOrErr.second)
187 fatal(MBOrErr.second,
188 "could not get the buffer for the member defining " + SymName);
189 Driver->addArchiveBuffer(takeBuffer(std::move(MBOrErr.first)), SymName,
190 ParentName);
191 });
192}
193
194static bool isDecorated(StringRef Sym) {
195 return Sym.startswith("_") || Sym.startswith("@") || Sym.startswith("?");
196}
197
198// Parses .drectve section contents and returns a list of files
199// specified by /defaultlib.
200void LinkerDriver::parseDirectives(StringRef S) {
201 opt::InputArgList Args = Parser.parse(S);
202
203 for (auto *Arg : Args) {
204 switch (Arg->getOption().getID()) {
205 case OPT_alternatename:
206 parseAlternateName(Arg->getValue());
207 break;
208 case OPT_defaultlib:
209 if (Optional<StringRef> Path = findLib(Arg->getValue()))
210 enqueuePath(*Path);
211 break;
212 case OPT_export: {
213 Export E = parseExport(Arg->getValue());
214 E.Directives = true;
215 Config->Exports.push_back(E);
216 break;
217 }
218 case OPT_failifmismatch:
219 checkFailIfMismatch(Arg->getValue());
220 break;
221 case OPT_incl:
222 addUndefined(Arg->getValue());
223 break;
224 case OPT_merge:
225 parseMerge(Arg->getValue());
226 break;
227 case OPT_nodefaultlib:
228 Config->NoDefaultLibs.insert(doFindLib(Arg->getValue()));
229 break;
230 case OPT_section:
231 parseSection(Arg->getValue());
232 break;
233 case OPT_editandcontinue:
234 case OPT_fastfail:
235 case OPT_guardsym:
236 case OPT_throwingnew:
237 break;
238 default:
239 error(Arg->getSpelling() + " is not allowed in .drectve");
240 }
241 }
242}
243
244// Find file from search paths. You can omit ".obj", this function takes
245// care of that. Note that the returned path is not guaranteed to exist.
246StringRef LinkerDriver::doFindFile(StringRef Filename) {
247 bool HasPathSep = (Filename.find_first_of("/\\") != StringRef::npos);
248 if (HasPathSep)
249 return Filename;
250 bool HasExt = (Filename.find('.') != StringRef::npos);
251 for (StringRef Dir : SearchPaths) {
252 SmallString<128> Path = Dir;
253 sys::path::append(Path, Filename);
254 if (sys::fs::exists(Path.str()))
255 return Saver.save(Path.str());
256 if (!HasExt) {
257 Path.append(".obj");
258 if (sys::fs::exists(Path.str()))
259 return Saver.save(Path.str());
260 }
261 }
262 return Filename;
263}
264
265// Resolves a file path. This never returns the same path
266// (in that case, it returns None).
267Optional<StringRef> LinkerDriver::findFile(StringRef Filename) {
268 StringRef Path = doFindFile(Filename);
269 bool Seen = !VisitedFiles.insert(Path.lower()).second;
270 if (Seen)
271 return None;
272 return Path;
273}
274
275// Find library file from search path.
276StringRef LinkerDriver::doFindLib(StringRef Filename) {
277 // Add ".lib" to Filename if that has no file extension.
278 bool HasExt = (Filename.find('.') != StringRef::npos);
279 if (!HasExt)
280 Filename = Saver.save(Filename + ".lib");
281 return doFindFile(Filename);
282}
283
284// Resolves a library path. /nodefaultlib options are taken into
285// consideration. This never returns the same path (in that case,
286// it returns None).
287Optional<StringRef> LinkerDriver::findLib(StringRef Filename) {
288 if (Config->NoDefaultLibAll)
289 return None;
290 if (!VisitedLibs.insert(Filename.lower()).second)
291 return None;
292 StringRef Path = doFindLib(Filename);
293 if (Config->NoDefaultLibs.count(Path))
294 return None;
295 if (!VisitedFiles.insert(Path.lower()).second)
296 return None;
297 return Path;
298}
299
300// Parses LIB environment which contains a list of search paths.
301void LinkerDriver::addLibSearchPaths() {
302 Optional<std::string> EnvOpt = Process::GetEnv("LIB");
303 if (!EnvOpt.hasValue())
304 return;
305 StringRef Env = Saver.save(*EnvOpt);
306 while (!Env.empty()) {
307 StringRef Path;
308 std::tie(Path, Env) = Env.split(';');
309 SearchPaths.push_back(Path);
310 }
311}
312
313SymbolBody *LinkerDriver::addUndefined(StringRef Name) {
314 SymbolBody *B = Symtab.addUndefined(Name);
315 Config->GCRoot.insert(B);
316 return B;
317}
318
319// Symbol names are mangled by appending "_" prefix on x86.
320StringRef LinkerDriver::mangle(StringRef Sym) {
321 assert(Config->Machine != IMAGE_FILE_MACHINE_UNKNOWN);
322 if (Config->Machine == I386)
323 return Saver.save("_" + Sym);
324 return Sym;
325}
326
327// Windows specific -- find default entry point name.
328StringRef LinkerDriver::findDefaultEntry() {
329 // User-defined main functions and their corresponding entry points.
330 static const char *Entries[][2] = {
331 {"main", "mainCRTStartup"},
332 {"wmain", "wmainCRTStartup"},
333 {"WinMain", "WinMainCRTStartup"},
334 {"wWinMain", "wWinMainCRTStartup"},
335 };
336 for (auto E : Entries) {
337 StringRef Entry = Symtab.findMangle(mangle(E[0]));
338 if (!Entry.empty() && !isa<Undefined>(Symtab.find(Entry)->body()))
339 return mangle(E[1]);
340 }
341 return "";
342}
343
344WindowsSubsystem LinkerDriver::inferSubsystem() {
345 if (Config->DLL)
346 return IMAGE_SUBSYSTEM_WINDOWS_GUI;
347 if (Symtab.findUnderscore("main") || Symtab.findUnderscore("wmain"))
348 return IMAGE_SUBSYSTEM_WINDOWS_CUI;
349 if (Symtab.findUnderscore("WinMain") || Symtab.findUnderscore("wWinMain"))
350 return IMAGE_SUBSYSTEM_WINDOWS_GUI;
351 return IMAGE_SUBSYSTEM_UNKNOWN;
352}
353
354static uint64_t getDefaultImageBase() {
355 if (Config->is64())
356 return Config->DLL ? 0x180000000 : 0x140000000;
357 return Config->DLL ? 0x10000000 : 0x400000;
358}
359
360static std::string createResponseFile(const opt::InputArgList &Args,
361 ArrayRef<StringRef> FilePaths,
362 ArrayRef<StringRef> SearchPaths) {
363 SmallString<0> Data;
364 raw_svector_ostream OS(Data);
365
366 for (auto *Arg : Args) {
367 switch (Arg->getOption().getID()) {
368 case OPT_linkrepro:
369 case OPT_INPUT:
370 case OPT_defaultlib:
371 case OPT_libpath:
372 break;
373 default:
374 OS << toString(Arg) << "\n";
375 }
376 }
377
378 for (StringRef Path : SearchPaths) {
379 std::string RelPath = relativeToRoot(Path);
380 OS << "/libpath:" << quote(RelPath) << "\n";
381 }
382
383 for (StringRef Path : FilePaths)
384 OS << quote(relativeToRoot(Path)) << "\n";
385
386 return Data.str();
387}
388
389static unsigned getDefaultDebugType(const opt::InputArgList &Args) {
390 unsigned DebugTypes = static_cast<unsigned>(DebugType::CV);
391 if (Args.hasArg(OPT_driver))
392 DebugTypes |= static_cast<unsigned>(DebugType::PData);
393 if (Args.hasArg(OPT_profile))
394 DebugTypes |= static_cast<unsigned>(DebugType::Fixup);
395 return DebugTypes;
396}
397
398static unsigned parseDebugType(StringRef Arg) {
399 SmallVector<StringRef, 3> Types;
400 Arg.split(Types, ',', /*KeepEmpty=*/false);
401
402 unsigned DebugTypes = static_cast<unsigned>(DebugType::None);
403 for (StringRef Type : Types)
404 DebugTypes |= StringSwitch<unsigned>(Type.lower())
405 .Case("cv", static_cast<unsigned>(DebugType::CV))
406 .Case("pdata", static_cast<unsigned>(DebugType::PData))
407 .Case("fixup", static_cast<unsigned>(DebugType::Fixup))
408 .Default(0);
409 return DebugTypes;
410}
411
412static std::string getMapFile(const opt::InputArgList &Args) {
413 auto *Arg = Args.getLastArg(OPT_lldmap, OPT_lldmap_file);
414 if (!Arg)
415 return "";
416 if (Arg->getOption().getID() == OPT_lldmap_file)
417 return Arg->getValue();
418
419 assert(Arg->getOption().getID() == OPT_lldmap);
420 StringRef OutFile = Config->OutputFile;
421 return (OutFile.substr(0, OutFile.rfind('.')) + ".map").str();
422}
423
424static std::string getImplibPath() {
425 if (!Config->Implib.empty())
426 return Config->Implib;
427 SmallString<128> Out = StringRef(Config->OutputFile);
428 sys::path::replace_extension(Out, ".lib");
429 return Out.str();
430}
431
432//
433// The import name is caculated as the following:
434//
435// | LIBRARY w/ ext | LIBRARY w/o ext | no LIBRARY
436// -----+----------------+---------------------+------------------
437// LINK | {value} | {value}.{.dll/.exe} | {output name}
438// LIB | {value} | {value}.dll | {output name}.dll
439//
440static std::string getImportName(bool AsLib) {
441 SmallString<128> Out;
442
443 if (Config->ImportName.empty()) {
444 Out.assign(sys::path::filename(Config->OutputFile));
445 if (AsLib)
446 sys::path::replace_extension(Out, ".dll");
447 } else {
448 Out.assign(Config->ImportName);
449 if (!sys::path::has_extension(Out))
450 sys::path::replace_extension(Out,
451 (Config->DLL || AsLib) ? ".dll" : ".exe");
452 }
453
454 return Out.str();
455}
456
457static void createImportLibrary(bool AsLib) {
458 std::vector<COFFShortExport> Exports;
459 for (Export &E1 : Config->Exports) {
460 COFFShortExport E2;
461 E2.Name = E1.Name;
462 E2.SymbolName = E1.SymbolName;
463 E2.ExtName = E1.ExtName;
464 E2.Ordinal = E1.Ordinal;
465 E2.Noname = E1.Noname;
466 E2.Data = E1.Data;
467 E2.Private = E1.Private;
468 E2.Constant = E1.Constant;
469 Exports.push_back(E2);
470 }
471
472 writeImportLibrary(getImportName(AsLib), getImplibPath(), Exports,
473 Config->Machine, false);
474}
475
476static void parseModuleDefs(StringRef Path) {
477 std::unique_ptr<MemoryBuffer> MB = check(
478 MemoryBuffer::getFile(Path, -1, false, true), "could not open " + Path);
479 COFFModuleDefinition M =
480 check(parseCOFFModuleDefinition(MB->getMemBufferRef(), Config->Machine));
481
482 if (Config->OutputFile.empty())
483 Config->OutputFile = Saver.save(M.OutputFile);
484 Config->ImportName = Saver.save(M.ImportName);
485 if (M.ImageBase)
486 Config->ImageBase = M.ImageBase;
487 if (M.StackReserve)
488 Config->StackReserve = M.StackReserve;
489 if (M.StackCommit)
490 Config->StackCommit = M.StackCommit;
491 if (M.HeapReserve)
492 Config->HeapReserve = M.HeapReserve;
493 if (M.HeapCommit)
494 Config->HeapCommit = M.HeapCommit;
495 if (M.MajorImageVersion)
496 Config->MajorImageVersion = M.MajorImageVersion;
497 if (M.MinorImageVersion)
498 Config->MinorImageVersion = M.MinorImageVersion;
499 if (M.MajorOSVersion)
500 Config->MajorOSVersion = M.MajorOSVersion;
501 if (M.MinorOSVersion)
502 Config->MinorOSVersion = M.MinorOSVersion;
503
504 for (COFFShortExport E1 : M.Exports) {
505 Export E2;
506 E2.Name = Saver.save(E1.Name);
507 if (E1.isWeak())
508 E2.ExtName = Saver.save(E1.ExtName);
509 E2.Ordinal = E1.Ordinal;
510 E2.Noname = E1.Noname;
511 E2.Data = E1.Data;
512 E2.Private = E1.Private;
513 E2.Constant = E1.Constant;
514 Config->Exports.push_back(E2);
515 }
516}
517
518std::vector<MemoryBufferRef> getArchiveMembers(Archive *File) {
519 std::vector<MemoryBufferRef> V;
520 Error Err = Error::success();
521 for (const ErrorOr<Archive::Child> &COrErr : File->children(Err)) {
522 Archive::Child C =
523 check(COrErr,
524 File->getFileName() + ": could not get the child of the archive");
525 MemoryBufferRef MBRef =
526 check(C.getMemoryBufferRef(),
527 File->getFileName() +
528 ": could not get the buffer for a child of the archive");
529 V.push_back(MBRef);
530 }
531 if (Err)
532 fatal(File->getFileName() +
533 ": Archive::children failed: " + toString(std::move(Err)));
534 return V;
535}
536
537// A helper function for filterBitcodeFiles.
538static bool needsRebuilding(MemoryBufferRef MB) {
539 // The MSVC linker doesn't support thin archives, so if it's a thin
540 // archive, we always need to rebuild it.
541 std::unique_ptr<Archive> File =
542 check(Archive::create(MB), "Failed to read " + MB.getBufferIdentifier());
543 if (File->isThin())
544 return true;
545
546 // Returns true if the archive contains at least one bitcode file.
547 for (MemoryBufferRef Member : getArchiveMembers(File.get()))
548 if (identify_magic(Member.getBuffer()) == file_magic::bitcode)
549 return true;
550 return false;
551}
552
553// Opens a given path as an archive file and removes bitcode files
554// from them if exists. This function is to appease the MSVC linker as
555// their linker doesn't like archive files containing non-native
556// object files.
557//
558// If a given archive doesn't contain bitcode files, the archive path
559// is returned as-is. Otherwise, a new temporary file is created and
560// its path is returned.
561static Optional<std::string>
562filterBitcodeFiles(StringRef Path, std::vector<std::string> &TemporaryFiles) {
563 std::unique_ptr<MemoryBuffer> MB = check(
564 MemoryBuffer::getFile(Path, -1, false, true), "could not open " + Path);
565 MemoryBufferRef MBRef = MB->getMemBufferRef();
566 file_magic Magic = identify_magic(MBRef.getBuffer());
567
568 if (Magic == file_magic::bitcode)
569 return None;
570 if (Magic != file_magic::archive)
571 return Path.str();
572 if (!needsRebuilding(MBRef))
573 return Path.str();
574
575 std::unique_ptr<Archive> File =
576 check(Archive::create(MBRef),
577 MBRef.getBufferIdentifier() + ": failed to parse archive");
578
579 std::vector<NewArchiveMember> New;
580 for (MemoryBufferRef Member : getArchiveMembers(File.get()))
581 if (identify_magic(Member.getBuffer()) != file_magic::bitcode)
582 New.emplace_back(Member);
583
584 if (New.empty())
585 return None;
586
587 log("Creating a temporary archive for " + Path + " to remove bitcode files");
588
589 SmallString<128> S;
590 if (auto EC = sys::fs::createTemporaryFile("lld-" + sys::path::stem(Path),
591 ".lib", S))
592 fatal(EC, "cannot create a temporary file");
593 std::string Temp = S.str();
594 TemporaryFiles.push_back(Temp);
595
596 std::pair<StringRef, std::error_code> Ret =
597 llvm::writeArchive(Temp, New, /*WriteSymtab=*/true, Archive::Kind::K_GNU,
598 /*Deterministics=*/true,
599 /*Thin=*/false);
600 if (Ret.second)
601 error("failed to create a new archive " + S.str() + ": " + Ret.first);
602 return Temp;
603}
604
605// Create response file contents and invoke the MSVC linker.
606void LinkerDriver::invokeMSVC(opt::InputArgList &Args) {
607 std::string Rsp = "/nologo\n";
608 std::vector<std::string> Temps;
609
610 // Write out archive members that we used in symbol resolution and pass these
611 // to MSVC before any archives, so that MSVC uses the same objects to satisfy
612 // references.
613 for (const auto *O : Symtab.ObjectFiles) {
614 if (O->ParentName.empty())
615 continue;
616 SmallString<128> S;
617 int Fd;
618 if (auto EC = sys::fs::createTemporaryFile(
619 "lld-" + sys::path::filename(O->ParentName), ".obj", Fd, S))
620 fatal(EC, "cannot create a temporary file");
621 raw_fd_ostream OS(Fd, /*shouldClose*/ true);
622 OS << O->MB.getBuffer();
623 Temps.push_back(S.str());
624 Rsp += quote(S) + "\n";
625 }
626
627 for (auto *Arg : Args) {
628 switch (Arg->getOption().getID()) {
629 case OPT_linkrepro:
630 case OPT_lldmap:
631 case OPT_lldmap_file:
632 case OPT_lldsavetemps:
633 case OPT_msvclto:
634 // LLD-specific options are stripped.
635 break;
636 case OPT_opt:
637 if (!StringRef(Arg->getValue()).startswith("lld"))
638 Rsp += toString(Arg) + " ";
639 break;
640 case OPT_INPUT: {
641 if (Optional<StringRef> Path = doFindFile(Arg->getValue())) {
642 if (Optional<std::string> S = filterBitcodeFiles(*Path, Temps))
643 Rsp += quote(*S) + "\n";
644 continue;
645 }
646 Rsp += quote(Arg->getValue()) + "\n";
647 break;
648 }
649 default:
650 Rsp += toString(Arg) + "\n";
651 }
652 }
653
654 std::vector<StringRef> ObjectFiles = Symtab.compileBitcodeFiles();
655 runMSVCLinker(Rsp, ObjectFiles);
656
657 for (StringRef Path : Temps)
658 sys::fs::remove(Path);
659}
660
661void LinkerDriver::enqueueTask(std::function<void()> Task) {
662 TaskQueue.push_back(std::move(Task));
663}
664
665bool LinkerDriver::run() {
666 bool DidWork = !TaskQueue.empty();
667 while (!TaskQueue.empty()) {
668 TaskQueue.front()();
669 TaskQueue.pop_front();
670 }
671 return DidWork;
672}
673
674void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
675 // If the first command line argument is "/lib", link.exe acts like lib.exe.
676 // We call our own implementation of lib.exe that understands bitcode files.
677 if (ArgsArr.size() > 1 && StringRef(ArgsArr[1]).equals_lower("/lib")) {
678 if (llvm::libDriverMain(ArgsArr.slice(1)) != 0)
679 fatal("lib failed");
680 return;
681 }
682
683 // Needed for LTO.
684 InitializeAllTargetInfos();
685 InitializeAllTargets();
686 InitializeAllTargetMCs();
687 InitializeAllAsmParsers();
688 InitializeAllAsmPrinters();
689 InitializeAllDisassemblers();
690
691 // Parse command line options.
692 opt::InputArgList Args = Parser.parseLINK(ArgsArr.slice(1));
693
694 // Parse and evaluate -mllvm options.
695 std::vector<const char *> V;
696 V.push_back("lld-link (LLVM option parsing)");
697 for (auto *Arg : Args.filtered(OPT_mllvm))
698 V.push_back(Arg->getValue());
699 cl::ParseCommandLineOptions(V.size(), V.data());
700
701 // Handle /errorlimit early, because error() depends on it.
702 if (auto *Arg = Args.getLastArg(OPT_errorlimit)) {
703 int N = 20;
704 StringRef S = Arg->getValue();
705 if (S.getAsInteger(10, N))
706 error(Arg->getSpelling() + " number expected, but got " + S);
707 Config->ErrorLimit = N;
708 }
709
710 // Handle /help
711 if (Args.hasArg(OPT_help)) {
712 printHelp(ArgsArr[0]);
713 return;
714 }
715
716 if (auto *Arg = Args.getLastArg(OPT_linkrepro)) {
717 SmallString<64> Path = StringRef(Arg->getValue());
718 sys::path::append(Path, "repro.tar");
719
720 Expected<std::unique_ptr<TarWriter>> ErrOrWriter =
721 TarWriter::create(Path, "repro");
722
723 if (ErrOrWriter) {
724 Tar = std::move(*ErrOrWriter);
725 } else {
726 error("/linkrepro: failed to open " + Path + ": " +
727 toString(ErrOrWriter.takeError()));
728 }
729 }
730
731 if (!Args.hasArgNoClaim(OPT_INPUT)) {
732 if (Args.hasArgNoClaim(OPT_deffile))
733 Config->NoEntry = true;
734 else
735 fatal("no input files");
736 }
737
738 // Construct search path list.
739 SearchPaths.push_back("");
740 for (auto *Arg : Args.filtered(OPT_libpath))
741 SearchPaths.push_back(Arg->getValue());
742 addLibSearchPaths();
743
744 // Handle /out
745 if (auto *Arg = Args.getLastArg(OPT_out))
746 Config->OutputFile = Arg->getValue();
747
748 // Handle /verbose
749 if (Args.hasArg(OPT_verbose))
750 Config->Verbose = true;
751
752 // Handle /force or /force:unresolved
753 if (Args.hasArg(OPT_force) || Args.hasArg(OPT_force_unresolved))
754 Config->Force = true;
755
756 // Handle /debug
757 if (Args.hasArg(OPT_debug)) {
758 Config->Debug = true;
759 Config->DebugTypes =
760 Args.hasArg(OPT_debugtype)
761 ? parseDebugType(Args.getLastArg(OPT_debugtype)->getValue())
762 : getDefaultDebugType(Args);
763 }
764
765 // Create a dummy PDB file to satisfy build sytem rules.
766 if (auto *Arg = Args.getLastArg(OPT_pdb))
767 Config->PDBPath = Arg->getValue();
768
769 // Handle /noentry
770 if (Args.hasArg(OPT_noentry)) {
771 if (Args.hasArg(OPT_dll))
772 Config->NoEntry = true;
773 else
774 error("/noentry must be specified with /dll");
775 }
776
777 // Handle /dll
778 if (Args.hasArg(OPT_dll)) {
779 Config->DLL = true;
780 Config->ManifestID = 2;
781 }
782
783 // Handle /fixed
784 if (Args.hasArg(OPT_fixed)) {
785 if (Args.hasArg(OPT_dynamicbase)) {
786 error("/fixed must not be specified with /dynamicbase");
787 } else {
788 Config->Relocatable = false;
789 Config->DynamicBase = false;
790 }
791 }
792
793 if (Args.hasArg(OPT_appcontainer))
794 Config->AppContainer = true;
795
796 // Handle /machine
797 if (auto *Arg = Args.getLastArg(OPT_machine))
798 Config->Machine = getMachineType(Arg->getValue());
799
800 // Handle /nodefaultlib:<filename>
801 for (auto *Arg : Args.filtered(OPT_nodefaultlib))
802 Config->NoDefaultLibs.insert(doFindLib(Arg->getValue()));
803
804 // Handle /nodefaultlib
805 if (Args.hasArg(OPT_nodefaultlib_all))
806 Config->NoDefaultLibAll = true;
807
808 // Handle /base
809 if (auto *Arg = Args.getLastArg(OPT_base))
810 parseNumbers(Arg->getValue(), &Config->ImageBase);
811
812 // Handle /stack
813 if (auto *Arg = Args.getLastArg(OPT_stack))
814 parseNumbers(Arg->getValue(), &Config->StackReserve, &Config->StackCommit);
815
816 // Handle /heap
817 if (auto *Arg = Args.getLastArg(OPT_heap))
818 parseNumbers(Arg->getValue(), &Config->HeapReserve, &Config->HeapCommit);
819
820 // Handle /version
821 if (auto *Arg = Args.getLastArg(OPT_version))
822 parseVersion(Arg->getValue(), &Config->MajorImageVersion,
823 &Config->MinorImageVersion);
824
825 // Handle /subsystem
826 if (auto *Arg = Args.getLastArg(OPT_subsystem))
827 parseSubsystem(Arg->getValue(), &Config->Subsystem, &Config->MajorOSVersion,
828 &Config->MinorOSVersion);
829
830 // Handle /alternatename
831 for (auto *Arg : Args.filtered(OPT_alternatename))
832 parseAlternateName(Arg->getValue());
833
834 // Handle /include
835 for (auto *Arg : Args.filtered(OPT_incl))
836 addUndefined(Arg->getValue());
837
838 // Handle /implib
839 if (auto *Arg = Args.getLastArg(OPT_implib))
840 Config->Implib = Arg->getValue();
841
842 // Handle /opt
843 for (auto *Arg : Args.filtered(OPT_opt)) {
844 std::string Str = StringRef(Arg->getValue()).lower();
845 SmallVector<StringRef, 1> Vec;
846 StringRef(Str).split(Vec, ',');
847 for (StringRef S : Vec) {
848 if (S == "noref") {
849 Config->DoGC = false;
850 Config->DoICF = false;
851 continue;
852 }
853 if (S == "icf" || StringRef(S).startswith("icf=")) {
854 Config->DoICF = true;
855 continue;
856 }
857 if (S == "noicf") {
858 Config->DoICF = false;
859 continue;
860 }
861 if (StringRef(S).startswith("lldlto=")) {
862 StringRef OptLevel = StringRef(S).substr(7);
863 if (OptLevel.getAsInteger(10, Config->LTOOptLevel) ||
864 Config->LTOOptLevel > 3)
865 error("/opt:lldlto: invalid optimization level: " + OptLevel);
866 continue;
867 }
868 if (StringRef(S).startswith("lldltojobs=")) {
869 StringRef Jobs = StringRef(S).substr(11);
870 if (Jobs.getAsInteger(10, Config->LTOJobs) || Config->LTOJobs == 0)
871 error("/opt:lldltojobs: invalid job count: " + Jobs);
872 continue;
873 }
874 if (StringRef(S).startswith("lldltopartitions=")) {
875 StringRef N = StringRef(S).substr(17);
876 if (N.getAsInteger(10, Config->LTOPartitions) ||
877 Config->LTOPartitions == 0)
878 error("/opt:lldltopartitions: invalid partition count: " + N);
879 continue;
880 }
881 if (S != "ref" && S != "lbr" && S != "nolbr")
882 error("/opt: unknown option: " + S);
883 }
884 }
885
886 // Handle /lldsavetemps
887 if (Args.hasArg(OPT_lldsavetemps))
888 Config->SaveTemps = true;
889
890 // Handle /failifmismatch
891 for (auto *Arg : Args.filtered(OPT_failifmismatch))
892 checkFailIfMismatch(Arg->getValue());
893
894 // Handle /merge
895 for (auto *Arg : Args.filtered(OPT_merge))
896 parseMerge(Arg->getValue());
897
898 // Handle /section
899 for (auto *Arg : Args.filtered(OPT_section))
900 parseSection(Arg->getValue());
901
902 // Handle /manifestdependency. This enables /manifest unless /manifest:no is
903 // also passed.
904 if (auto *Arg = Args.getLastArg(OPT_manifestdependency)) {
905 Config->ManifestDependency = Arg->getValue();
906 Config->Manifest = Configuration::SideBySide;
907 }
908
909 // Handle /manifest and /manifest:
910 if (auto *Arg = Args.getLastArg(OPT_manifest, OPT_manifest_colon)) {
911 if (Arg->getOption().getID() == OPT_manifest)
912 Config->Manifest = Configuration::SideBySide;
913 else
914 parseManifest(Arg->getValue());
915 }
916
917 // Handle /manifestuac
918 if (auto *Arg = Args.getLastArg(OPT_manifestuac))
919 parseManifestUAC(Arg->getValue());
920
921 // Handle /manifestfile
922 if (auto *Arg = Args.getLastArg(OPT_manifestfile))
923 Config->ManifestFile = Arg->getValue();
924
925 // Handle /manifestinput
926 for (auto *Arg : Args.filtered(OPT_manifestinput))
927 Config->ManifestInput.push_back(Arg->getValue());
928
929 if (!Config->ManifestInput.empty() &&
930 Config->Manifest != Configuration::Embed) {
931 fatal("/MANIFESTINPUT: requires /MANIFEST:EMBED");
932 }
933
934 // Handle miscellaneous boolean flags.
935 if (Args.hasArg(OPT_allowisolation_no))
936 Config->AllowIsolation = false;
937 if (Args.hasArg(OPT_dynamicbase_no))
938 Config->DynamicBase = false;
939 if (Args.hasArg(OPT_nxcompat_no))
940 Config->NxCompat = false;
941 if (Args.hasArg(OPT_tsaware_no))
942 Config->TerminalServerAware = false;
943 if (Args.hasArg(OPT_nosymtab))
944 Config->WriteSymtab = false;
945
946 Config->MapFile = getMapFile(Args);
947
948 if (ErrorCount)
949 return;
950
951 // Create a list of input files. Files can be given as arguments
952 // for /defaultlib option.
953 std::vector<MemoryBufferRef> MBs;
954 for (auto *Arg : Args.filtered(OPT_INPUT))
955 if (Optional<StringRef> Path = findFile(Arg->getValue()))
956 enqueuePath(*Path);
957 for (auto *Arg : Args.filtered(OPT_defaultlib))
958 if (Optional<StringRef> Path = findLib(Arg->getValue()))
959 enqueuePath(*Path);
960
961 // Windows specific -- Create a resource file containing a manifest file.
962 if (Config->Manifest == Configuration::Embed)
963 addBuffer(createManifestRes());
964
965 // Read all input files given via the command line.
966 run();
967
968 // We should have inferred a machine type by now from the input files, but if
969 // not we assume x64.
970 if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) {
971 warn("/machine is not specified. x64 is assumed");
972 Config->Machine = AMD64;
973 }
974
975 // Input files can be Windows resource files (.res files). We use
976 // WindowsResource to convert resource files to a regular COFF file,
977 // then link the resulting file normally.
978 if (!Resources.empty())
979 addBuffer(convertResToCOFF(Resources));
980
981 if (Tar)
982 Tar->append("response.txt",
983 createResponseFile(Args, FilePaths,
984 ArrayRef<StringRef>(SearchPaths).slice(1)));
985
986 // Handle /largeaddressaware
987 if (Config->is64() || Args.hasArg(OPT_largeaddressaware))
988 Config->LargeAddressAware = true;
989
990 // Handle /highentropyva
991 if (Config->is64() && !Args.hasArg(OPT_highentropyva_no))
992 Config->HighEntropyVA = true;
993
994 // Handle /entry and /dll
995 if (auto *Arg = Args.getLastArg(OPT_entry)) {
996 Config->Entry = addUndefined(mangle(Arg->getValue()));
997 } else if (Args.hasArg(OPT_dll) && !Config->NoEntry) {
998 StringRef S = (Config->Machine == I386) ? "__DllMainCRTStartup@12"
999 : "_DllMainCRTStartup";
1000 Config->Entry = addUndefined(S);
1001 } else if (!Config->NoEntry) {
1002 // Windows specific -- If entry point name is not given, we need to
1003 // infer that from user-defined entry name.
1004 StringRef S = findDefaultEntry();
1005 if (S.empty())
1006 fatal("entry point must be defined");
1007 Config->Entry = addUndefined(S);
1008 log("Entry name inferred: " + S);
1009 }
1010
1011 // Handle /export
1012 for (auto *Arg : Args.filtered(OPT_export)) {
1013 Export E = parseExport(Arg->getValue());
1014 if (Config->Machine == I386) {
1015 if (!isDecorated(E.Name))
1016 E.Name = Saver.save("_" + E.Name);
1017 if (!E.ExtName.empty() && !isDecorated(E.ExtName))
1018 E.ExtName = Saver.save("_" + E.ExtName);
1019 }
1020 Config->Exports.push_back(E);
1021 }
1022
1023 // Handle /def
1024 if (auto *Arg = Args.getLastArg(OPT_deffile)) {
1025 // parseModuleDefs mutates Config object.
1026 parseModuleDefs(Arg->getValue());
1027 }
1028
1029 // Handle generation of import library from a def file.
1030 if (!Args.hasArgNoClaim(OPT_INPUT)) {
1031 fixupExports();
1032 createImportLibrary(/*AsLib=*/true);
1033 exit(0);
1034 }
1035
1036 // Handle /delayload
1037 for (auto *Arg : Args.filtered(OPT_delayload)) {
1038 Config->DelayLoads.insert(StringRef(Arg->getValue()).lower());
1039 if (Config->Machine == I386) {
1040 Config->DelayLoadHelper = addUndefined("___delayLoadHelper2@8");
1041 } else {
1042 Config->DelayLoadHelper = addUndefined("__delayLoadHelper2");
1043 }
1044 }
1045
1046 // Set default image name if neither /out or /def set it.
1047 if (Config->OutputFile.empty()) {
1048 Config->OutputFile =
1049 getOutputPath((*Args.filtered(OPT_INPUT).begin())->getValue());
1050 }
1051
1052 // Put the PDB next to the image if no /pdb flag was passed.
1053 if (Config->Debug && Config->PDBPath.empty()) {
1054 Config->PDBPath = Config->OutputFile;
1055 sys::path::replace_extension(Config->PDBPath, ".pdb");
1056 }
1057
1058 // Disable PDB generation if the user requested it.
1059 if (Args.hasArg(OPT_nopdb))
1060 Config->PDBPath = "";
1061
1062 // Set default image base if /base is not given.
1063 if (Config->ImageBase == uint64_t(-1))
1064 Config->ImageBase = getDefaultImageBase();
1065
1066 Symtab.addSynthetic(mangle("__ImageBase"), nullptr);
1067 if (Config->Machine == I386) {
1068 Symtab.addAbsolute("___safe_se_handler_table", 0);
1069 Symtab.addAbsolute("___safe_se_handler_count", 0);
1070 }
1071
1072 // We do not support /guard:cf (control flow protection) yet.
1073 // Define CFG symbols anyway so that we can link MSVC 2015 CRT.
1074 Symtab.addAbsolute(mangle("__guard_fids_count"), 0);
1075 Symtab.addAbsolute(mangle("__guard_fids_table"), 0);
1076 Symtab.addAbsolute(mangle("__guard_flags"), 0x100);
1077 Symtab.addAbsolute(mangle("__guard_iat_count"), 0);
1078 Symtab.addAbsolute(mangle("__guard_iat_table"), 0);
1079 Symtab.addAbsolute(mangle("__guard_longjmp_count"), 0);
1080 Symtab.addAbsolute(mangle("__guard_longjmp_table"), 0);
1081
1082 // This code may add new undefined symbols to the link, which may enqueue more
1083 // symbol resolution tasks, so we need to continue executing tasks until we
1084 // converge.
1085 do {
1086 // Windows specific -- if entry point is not found,
1087 // search for its mangled names.
1088 if (Config->Entry)
1089 Symtab.mangleMaybe(Config->Entry);
1090
1091 // Windows specific -- Make sure we resolve all dllexported symbols.
1092 for (Export &E : Config->Exports) {
1093 if (!E.ForwardTo.empty())
1094 continue;
1095 E.Sym = addUndefined(E.Name);
1096 if (!E.Directives)
1097 Symtab.mangleMaybe(E.Sym);
1098 }
1099
1100 // Add weak aliases. Weak aliases is a mechanism to give remaining
1101 // undefined symbols final chance to be resolved successfully.
1102 for (auto Pair : Config->AlternateNames) {
1103 StringRef From = Pair.first;
1104 StringRef To = Pair.second;
1105 Symbol *Sym = Symtab.find(From);
1106 if (!Sym)
1107 continue;
1108 if (auto *U = dyn_cast<Undefined>(Sym->body()))
1109 if (!U->WeakAlias)
1110 U->WeakAlias = Symtab.addUndefined(To);
1111 }
1112
1113 // Windows specific -- if __load_config_used can be resolved, resolve it.
1114 if (Symtab.findUnderscore("_load_config_used"))
1115 addUndefined(mangle("_load_config_used"));
1116 } while (run());
1117
1118 if (ErrorCount)
1119 return;
1120
1121 // If /msvclto is given, we use the MSVC linker to link LTO output files.
1122 // This is useful because MSVC link.exe can generate complete PDBs.
1123 if (Args.hasArg(OPT_msvclto)) {
1124 invokeMSVC(Args);
1125 exit(0);
1126 }
1127
1128 // Do LTO by compiling bitcode input files to a set of native COFF files then
1129 // link those files.
1130 Symtab.addCombinedLTOObjects();
1131 run();
1132
1133 // Make sure we have resolved all symbols.
1134 Symtab.reportRemainingUndefines();
1135
1136 // Windows specific -- if no /subsystem is given, we need to infer
1137 // that from entry point name.
1138 if (Config->Subsystem == IMAGE_SUBSYSTEM_UNKNOWN) {
1139 Config->Subsystem = inferSubsystem();
1140 if (Config->Subsystem == IMAGE_SUBSYSTEM_UNKNOWN)
1141 fatal("subsystem must be defined");
1142 }
1143
1144 // Handle /safeseh.
1145 if (Args.hasArg(OPT_safeseh)) {
1146 for (ObjectFile *File : Symtab.ObjectFiles)
1147 if (!File->SEHCompat)
1148 error("/safeseh: " + File->getName() + " is not compatible with SEH");
1149 if (ErrorCount)
1150 return;
1151 }
1152
1153 // Windows specific -- when we are creating a .dll file, we also
1154 // need to create a .lib file.
1155 if (!Config->Exports.empty() || Config->DLL) {
1156 fixupExports();
1157 createImportLibrary(/*AsLib=*/false);
1158 assignExportOrdinals();
1159 }
1160
1161 // Windows specific -- Create a side-by-side manifest file.
1162 if (Config->Manifest == Configuration::SideBySide)
1163 createSideBySideManifest();
1164
1165 // Identify unreferenced COMDAT sections.
1166 if (Config->DoGC)
1167 markLive(Symtab.getChunks());
1168
1169 // Identify identical COMDAT sections to merge them.
1170 if (Config->DoICF)
1171 doICF(Symtab.getChunks());
1172
1173 // Write the result.
1174 writeResult(&Symtab);
1175
1176 // Call exit to avoid calling destructors.
1177 exit(0);
1178}
1179
1180} // namespace coff
1181} // namespace lld
deps/lld/COFF/Driver.h created+188
......@@ -0,0 +1,188 @@
1//===- Driver.h -------------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_COFF_DRIVER_H
11#define LLD_COFF_DRIVER_H
12
13#include "Config.h"
14#include "SymbolTable.h"
15#include "lld/Core/LLVM.h"
16#include "lld/Core/Reproduce.h"
17#include "llvm/ADT/Optional.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/Object/Archive.h"
20#include "llvm/Object/COFF.h"
21#include "llvm/Option/Arg.h"
22#include "llvm/Option/ArgList.h"
23#include "llvm/Support/TarWriter.h"
24#include <memory>
25#include <set>
26#include <vector>
27
28namespace lld {
29namespace coff {
30
31class LinkerDriver;
32extern LinkerDriver *Driver;
33
34using llvm::COFF::MachineTypes;
35using llvm::COFF::WindowsSubsystem;
36using llvm::Optional;
37
38// Implemented in MarkLive.cpp.
39void markLive(const std::vector<Chunk *> &Chunks);
40
41// Implemented in ICF.cpp.
42void doICF(const std::vector<Chunk *> &Chunks);
43
44class ArgParser {
45public:
46 // Parses command line options.
47 llvm::opt::InputArgList parse(llvm::ArrayRef<const char *> Args);
48
49 // Concatenate LINK environment varirable and given arguments and parse them.
50 llvm::opt::InputArgList parseLINK(std::vector<const char *> Args);
51
52 // Tokenizes a given string and then parses as command line options.
53 llvm::opt::InputArgList parse(StringRef S) { return parse(tokenize(S)); }
54
55private:
56 std::vector<const char *> tokenize(StringRef S);
57
58 std::vector<const char *> replaceResponseFiles(std::vector<const char *>);
59};
60
61class LinkerDriver {
62public:
63 LinkerDriver() { coff::Symtab = &Symtab; }
64 void link(llvm::ArrayRef<const char *> Args);
65
66 // Used by the resolver to parse .drectve section contents.
67 void parseDirectives(StringRef S);
68
69 // Used by ArchiveFile to enqueue members.
70 void enqueueArchiveMember(const Archive::Child &C, StringRef SymName,
71 StringRef ParentName);
72
73private:
74 ArgParser Parser;
75 SymbolTable Symtab;
76
77 std::unique_ptr<llvm::TarWriter> Tar; // for /linkrepro
78
79 // Opens a file. Path has to be resolved already.
80 MemoryBufferRef openFile(StringRef Path);
81
82 // Searches a file from search paths.
83 Optional<StringRef> findFile(StringRef Filename);
84 Optional<StringRef> findLib(StringRef Filename);
85 StringRef doFindFile(StringRef Filename);
86 StringRef doFindLib(StringRef Filename);
87
88 // Parses LIB environment which contains a list of search paths.
89 void addLibSearchPaths();
90
91 // Library search path. The first element is always "" (current directory).
92 std::vector<StringRef> SearchPaths;
93 std::set<std::string> VisitedFiles;
94 std::set<std::string> VisitedLibs;
95
96 SymbolBody *addUndefined(StringRef Sym);
97 StringRef mangle(StringRef Sym);
98
99 // Windows specific -- "main" is not the only main function in Windows.
100 // You can choose one from these four -- {w,}{WinMain,main}.
101 // There are four different entry point functions for them,
102 // {w,}{WinMain,main}CRTStartup, respectively. The linker needs to
103 // choose the right one depending on which "main" function is defined.
104 // This function looks up the symbol table and resolve corresponding
105 // entry point name.
106 StringRef findDefaultEntry();
107 WindowsSubsystem inferSubsystem();
108
109 void invokeMSVC(llvm::opt::InputArgList &Args);
110
111 MemoryBufferRef takeBuffer(std::unique_ptr<MemoryBuffer> MB);
112 void addBuffer(std::unique_ptr<MemoryBuffer> MB);
113 void addArchiveBuffer(MemoryBufferRef MBRef, StringRef SymName,
114 StringRef ParentName);
115
116 void enqueuePath(StringRef Path);
117
118 void enqueueTask(std::function<void()> Task);
119 bool run();
120
121 std::list<std::function<void()>> TaskQueue;
122 std::vector<StringRef> FilePaths;
123 std::vector<MemoryBufferRef> Resources;
124};
125
126// Functions below this line are defined in DriverUtils.cpp.
127
128void printHelp(const char *Argv0);
129
130// For /machine option.
131MachineTypes getMachineType(StringRef Arg);
132StringRef machineToStr(MachineTypes MT);
133
134// Parses a string in the form of "<integer>[,<integer>]".
135void parseNumbers(StringRef Arg, uint64_t *Addr, uint64_t *Size = nullptr);
136
137// Parses a string in the form of "<integer>[.<integer>]".
138// Minor's default value is 0.
139void parseVersion(StringRef Arg, uint32_t *Major, uint32_t *Minor);
140
141// Parses a string in the form of "<subsystem>[,<integer>[.<integer>]]".
142void parseSubsystem(StringRef Arg, WindowsSubsystem *Sys, uint32_t *Major,
143 uint32_t *Minor);
144
145void parseAlternateName(StringRef);
146void parseMerge(StringRef);
147void parseSection(StringRef);
148
149// Parses a string in the form of "EMBED[,=<integer>]|NO".
150void parseManifest(StringRef Arg);
151
152// Parses a string in the form of "level=<string>|uiAccess=<string>"
153void parseManifestUAC(StringRef Arg);
154
155// Create a resource file containing a manifest XML.
156std::unique_ptr<MemoryBuffer> createManifestRes();
157void createSideBySideManifest();
158
159// Used for dllexported symbols.
160Export parseExport(StringRef Arg);
161void fixupExports();
162void assignExportOrdinals();
163
164// Parses a string in the form of "key=value" and check
165// if value matches previous values for the key.
166// This feature used in the directive section to reject
167// incompatible objects.
168void checkFailIfMismatch(StringRef Arg);
169
170// Convert Windows resource files (.res files) to a .obj file
171// using cvtres.exe.
172std::unique_ptr<MemoryBuffer>
173convertResToCOFF(const std::vector<MemoryBufferRef> &MBs);
174
175void runMSVCLinker(std::string Rsp, ArrayRef<StringRef> Objects);
176
177// Create enum with OPT_xxx values for each option in Options.td
178enum {
179 OPT_INVALID = 0,
180#define OPTION(_1, _2, ID, _4, _5, _6, _7, _8, _9, _10, _11, _12) OPT_##ID,
181#include "Options.inc"
182#undef OPTION
183};
184
185} // namespace coff
186} // namespace lld
187
188#endif
deps/lld/COFF/DriverUtils.cpp created+730
......@@ -0,0 +1,730 @@
1//===- DriverUtils.cpp ----------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains utility functions for the driver. Because there
11// are so many small functions, we created this separate file to make
12// Driver.cpp less cluttered.
13//
14//===----------------------------------------------------------------------===//
15
16#include "Config.h"
17#include "Driver.h"
18#include "Error.h"
19#include "Memory.h"
20#include "Symbols.h"
21#include "llvm/ADT/Optional.h"
22#include "llvm/ADT/StringSwitch.h"
23#include "llvm/BinaryFormat/COFF.h"
24#include "llvm/Object/COFF.h"
25#include "llvm/Object/WindowsResource.h"
26#include "llvm/Option/Arg.h"
27#include "llvm/Option/ArgList.h"
28#include "llvm/Option/Option.h"
29#include "llvm/Support/CommandLine.h"
30#include "llvm/Support/FileUtilities.h"
31#include "llvm/Support/MathExtras.h"
32#include "llvm/Support/Process.h"
33#include "llvm/Support/Program.h"
34#include "llvm/Support/raw_ostream.h"
35#include <memory>
36
37using namespace llvm::COFF;
38using namespace llvm;
39using llvm::cl::ExpandResponseFiles;
40using llvm::cl::TokenizeWindowsCommandLine;
41using llvm::sys::Process;
42
43namespace lld {
44namespace coff {
45namespace {
46
47const uint16_t SUBLANG_ENGLISH_US = 0x0409;
48const uint16_t RT_MANIFEST = 24;
49
50class Executor {
51public:
52 explicit Executor(StringRef S) : Prog(Saver.save(S)) {}
53 void add(StringRef S) { Args.push_back(Saver.save(S)); }
54 void add(std::string &S) { Args.push_back(Saver.save(S)); }
55 void add(Twine S) { Args.push_back(Saver.save(S)); }
56 void add(const char *S) { Args.push_back(Saver.save(S)); }
57
58 void run() {
59 ErrorOr<std::string> ExeOrErr = sys::findProgramByName(Prog);
60 if (auto EC = ExeOrErr.getError())
61 fatal(EC, "unable to find " + Prog + " in PATH: ");
62 StringRef Exe = Saver.save(*ExeOrErr);
63 Args.insert(Args.begin(), Exe);
64
65 std::vector<const char *> Vec;
66 for (StringRef S : Args)
67 Vec.push_back(S.data());
68 Vec.push_back(nullptr);
69
70 if (sys::ExecuteAndWait(Args[0], Vec.data()) != 0)
71 fatal("ExecuteAndWait failed: " +
72 llvm::join(Args.begin(), Args.end(), " "));
73 }
74
75private:
76 StringRef Prog;
77 std::vector<StringRef> Args;
78};
79
80} // anonymous namespace
81
82// Returns /machine's value.
83MachineTypes getMachineType(StringRef S) {
84 MachineTypes MT = StringSwitch<MachineTypes>(S.lower())
85 .Cases("x64", "amd64", AMD64)
86 .Cases("x86", "i386", I386)
87 .Case("arm", ARMNT)
88 .Case("arm64", ARM64)
89 .Default(IMAGE_FILE_MACHINE_UNKNOWN);
90 if (MT != IMAGE_FILE_MACHINE_UNKNOWN)
91 return MT;
92 fatal("unknown /machine argument: " + S);
93}
94
95StringRef machineToStr(MachineTypes MT) {
96 switch (MT) {
97 case ARMNT:
98 return "arm";
99 case ARM64:
100 return "arm64";
101 case AMD64:
102 return "x64";
103 case I386:
104 return "x86";
105 default:
106 llvm_unreachable("unknown machine type");
107 }
108}
109
110// Parses a string in the form of "<integer>[,<integer>]".
111void parseNumbers(StringRef Arg, uint64_t *Addr, uint64_t *Size) {
112 StringRef S1, S2;
113 std::tie(S1, S2) = Arg.split(',');
114 if (S1.getAsInteger(0, *Addr))
115 fatal("invalid number: " + S1);
116 if (Size && !S2.empty() && S2.getAsInteger(0, *Size))
117 fatal("invalid number: " + S2);
118}
119
120// Parses a string in the form of "<integer>[.<integer>]".
121// If second number is not present, Minor is set to 0.
122void parseVersion(StringRef Arg, uint32_t *Major, uint32_t *Minor) {
123 StringRef S1, S2;
124 std::tie(S1, S2) = Arg.split('.');
125 if (S1.getAsInteger(0, *Major))
126 fatal("invalid number: " + S1);
127 *Minor = 0;
128 if (!S2.empty() && S2.getAsInteger(0, *Minor))
129 fatal("invalid number: " + S2);
130}
131
132// Parses a string in the form of "<subsystem>[,<integer>[.<integer>]]".
133void parseSubsystem(StringRef Arg, WindowsSubsystem *Sys, uint32_t *Major,
134 uint32_t *Minor) {
135 StringRef SysStr, Ver;
136 std::tie(SysStr, Ver) = Arg.split(',');
137 *Sys = StringSwitch<WindowsSubsystem>(SysStr.lower())
138 .Case("boot_application", IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION)
139 .Case("console", IMAGE_SUBSYSTEM_WINDOWS_CUI)
140 .Case("efi_application", IMAGE_SUBSYSTEM_EFI_APPLICATION)
141 .Case("efi_boot_service_driver", IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER)
142 .Case("efi_rom", IMAGE_SUBSYSTEM_EFI_ROM)
143 .Case("efi_runtime_driver", IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER)
144 .Case("native", IMAGE_SUBSYSTEM_NATIVE)
145 .Case("posix", IMAGE_SUBSYSTEM_POSIX_CUI)
146 .Case("windows", IMAGE_SUBSYSTEM_WINDOWS_GUI)
147 .Default(IMAGE_SUBSYSTEM_UNKNOWN);
148 if (*Sys == IMAGE_SUBSYSTEM_UNKNOWN)
149 fatal("unknown subsystem: " + SysStr);
150 if (!Ver.empty())
151 parseVersion(Ver, Major, Minor);
152}
153
154// Parse a string of the form of "<from>=<to>".
155// Results are directly written to Config.
156void parseAlternateName(StringRef S) {
157 StringRef From, To;
158 std::tie(From, To) = S.split('=');
159 if (From.empty() || To.empty())
160 fatal("/alternatename: invalid argument: " + S);
161 auto It = Config->AlternateNames.find(From);
162 if (It != Config->AlternateNames.end() && It->second != To)
163 fatal("/alternatename: conflicts: " + S);
164 Config->AlternateNames.insert(It, std::make_pair(From, To));
165}
166
167// Parse a string of the form of "<from>=<to>".
168// Results are directly written to Config.
169void parseMerge(StringRef S) {
170 StringRef From, To;
171 std::tie(From, To) = S.split('=');
172 if (From.empty() || To.empty())
173 fatal("/merge: invalid argument: " + S);
174 auto Pair = Config->Merge.insert(std::make_pair(From, To));
175 bool Inserted = Pair.second;
176 if (!Inserted) {
177 StringRef Existing = Pair.first->second;
178 if (Existing != To)
179 warn(S + ": already merged into " + Existing);
180 }
181}
182
183static uint32_t parseSectionAttributes(StringRef S) {
184 uint32_t Ret = 0;
185 for (char C : S.lower()) {
186 switch (C) {
187 case 'd':
188 Ret |= IMAGE_SCN_MEM_DISCARDABLE;
189 break;
190 case 'e':
191 Ret |= IMAGE_SCN_MEM_EXECUTE;
192 break;
193 case 'k':
194 Ret |= IMAGE_SCN_MEM_NOT_CACHED;
195 break;
196 case 'p':
197 Ret |= IMAGE_SCN_MEM_NOT_PAGED;
198 break;
199 case 'r':
200 Ret |= IMAGE_SCN_MEM_READ;
201 break;
202 case 's':
203 Ret |= IMAGE_SCN_MEM_SHARED;
204 break;
205 case 'w':
206 Ret |= IMAGE_SCN_MEM_WRITE;
207 break;
208 default:
209 fatal("/section: invalid argument: " + S);
210 }
211 }
212 return Ret;
213}
214
215// Parses /section option argument.
216void parseSection(StringRef S) {
217 StringRef Name, Attrs;
218 std::tie(Name, Attrs) = S.split(',');
219 if (Name.empty() || Attrs.empty())
220 fatal("/section: invalid argument: " + S);
221 Config->Section[Name] = parseSectionAttributes(Attrs);
222}
223
224// Parses a string in the form of "EMBED[,=<integer>]|NO".
225// Results are directly written to Config.
226void parseManifest(StringRef Arg) {
227 if (Arg.equals_lower("no")) {
228 Config->Manifest = Configuration::No;
229 return;
230 }
231 if (!Arg.startswith_lower("embed"))
232 fatal("invalid option " + Arg);
233 Config->Manifest = Configuration::Embed;
234 Arg = Arg.substr(strlen("embed"));
235 if (Arg.empty())
236 return;
237 if (!Arg.startswith_lower(",id="))
238 fatal("invalid option " + Arg);
239 Arg = Arg.substr(strlen(",id="));
240 if (Arg.getAsInteger(0, Config->ManifestID))
241 fatal("invalid option " + Arg);
242}
243
244// Parses a string in the form of "level=<string>|uiAccess=<string>|NO".
245// Results are directly written to Config.
246void parseManifestUAC(StringRef Arg) {
247 if (Arg.equals_lower("no")) {
248 Config->ManifestUAC = false;
249 return;
250 }
251 for (;;) {
252 Arg = Arg.ltrim();
253 if (Arg.empty())
254 return;
255 if (Arg.startswith_lower("level=")) {
256 Arg = Arg.substr(strlen("level="));
257 std::tie(Config->ManifestLevel, Arg) = Arg.split(" ");
258 continue;
259 }
260 if (Arg.startswith_lower("uiaccess=")) {
261 Arg = Arg.substr(strlen("uiaccess="));
262 std::tie(Config->ManifestUIAccess, Arg) = Arg.split(" ");
263 continue;
264 }
265 fatal("invalid option " + Arg);
266 }
267}
268
269// An RAII temporary file class that automatically removes a temporary file.
270namespace {
271class TemporaryFile {
272public:
273 TemporaryFile(StringRef Prefix, StringRef Extn, StringRef Contents = "") {
274 SmallString<128> S;
275 if (auto EC = sys::fs::createTemporaryFile("lld-" + Prefix, Extn, S))
276 fatal(EC, "cannot create a temporary file");
277 Path = S.str();
278
279 if (!Contents.empty()) {
280 std::error_code EC;
281 raw_fd_ostream OS(Path, EC, sys::fs::F_None);
282 if (EC)
283 fatal(EC, "failed to open " + Path);
284 OS << Contents;
285 }
286 }
287
288 TemporaryFile(TemporaryFile &&Obj) {
289 std::swap(Path, Obj.Path);
290 }
291
292 ~TemporaryFile() {
293 if (Path.empty())
294 return;
295 if (sys::fs::remove(Path))
296 fatal("failed to remove " + Path);
297 }
298
299 // Returns a memory buffer of this temporary file.
300 // Note that this function does not leave the file open,
301 // so it is safe to remove the file immediately after this function
302 // is called (you cannot remove an opened file on Windows.)
303 std::unique_ptr<MemoryBuffer> getMemoryBuffer() {
304 // IsVolatileSize=true forces MemoryBuffer to not use mmap().
305 return check(MemoryBuffer::getFile(Path, /*FileSize=*/-1,
306 /*RequiresNullTerminator=*/false,
307 /*IsVolatileSize=*/true),
308 "could not open " + Path);
309 }
310
311 std::string Path;
312};
313}
314
315// Create the default manifest file as a temporary file.
316TemporaryFile createDefaultXml() {
317 // Create a temporary file.
318 TemporaryFile File("defaultxml", "manifest");
319
320 // Open the temporary file for writing.
321 std::error_code EC;
322 raw_fd_ostream OS(File.Path, EC, sys::fs::F_Text);
323 if (EC)
324 fatal(EC, "failed to open " + File.Path);
325
326 // Emit the XML. Note that we do *not* verify that the XML attributes are
327 // syntactically correct. This is intentional for link.exe compatibility.
328 OS << "<?xml version=\"1.0\" standalone=\"yes\"?>\n"
329 << "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\"\n"
330 << " manifestVersion=\"1.0\">\n";
331 if (Config->ManifestUAC) {
332 OS << " <trustInfo>\n"
333 << " <security>\n"
334 << " <requestedPrivileges>\n"
335 << " <requestedExecutionLevel level=" << Config->ManifestLevel
336 << " uiAccess=" << Config->ManifestUIAccess << "/>\n"
337 << " </requestedPrivileges>\n"
338 << " </security>\n"
339 << " </trustInfo>\n";
340 if (!Config->ManifestDependency.empty()) {
341 OS << " <dependency>\n"
342 << " <dependentAssembly>\n"
343 << " <assemblyIdentity " << Config->ManifestDependency << " />\n"
344 << " </dependentAssembly>\n"
345 << " </dependency>\n";
346 }
347 }
348 OS << "</assembly>\n";
349 OS.close();
350 return File;
351}
352
353static std::string readFile(StringRef Path) {
354 std::unique_ptr<MemoryBuffer> MB =
355 check(MemoryBuffer::getFile(Path), "could not open " + Path);
356 return MB->getBuffer();
357}
358
359static std::string createManifestXml() {
360 // Create the default manifest file.
361 TemporaryFile File1 = createDefaultXml();
362 if (Config->ManifestInput.empty())
363 return readFile(File1.Path);
364
365 // If manifest files are supplied by the user using /MANIFESTINPUT
366 // option, we need to merge them with the default manifest.
367 TemporaryFile File2("user", "manifest");
368
369 Executor E("mt.exe");
370 E.add("/manifest");
371 E.add(File1.Path);
372 for (StringRef Filename : Config->ManifestInput) {
373 E.add("/manifest");
374 E.add(Filename);
375 }
376 E.add("/nologo");
377 E.add("/out:" + StringRef(File2.Path));
378 E.run();
379 return readFile(File2.Path);
380}
381
382static std::unique_ptr<MemoryBuffer>
383createMemoryBufferForManifestRes(size_t ManifestSize) {
384 size_t ResSize = alignTo(
385 object::WIN_RES_MAGIC_SIZE + object::WIN_RES_NULL_ENTRY_SIZE +
386 sizeof(object::WinResHeaderPrefix) + sizeof(object::WinResIDs) +
387 sizeof(object::WinResHeaderSuffix) + ManifestSize,
388 object::WIN_RES_DATA_ALIGNMENT);
389 return MemoryBuffer::getNewMemBuffer(ResSize);
390}
391
392static void writeResFileHeader(char *&Buf) {
393 memcpy(Buf, COFF::WinResMagic, sizeof(COFF::WinResMagic));
394 Buf += sizeof(COFF::WinResMagic);
395 memset(Buf, 0, object::WIN_RES_NULL_ENTRY_SIZE);
396 Buf += object::WIN_RES_NULL_ENTRY_SIZE;
397}
398
399static void writeResEntryHeader(char *&Buf, size_t ManifestSize) {
400 // Write the prefix.
401 auto *Prefix = reinterpret_cast<object::WinResHeaderPrefix *>(Buf);
402 Prefix->DataSize = ManifestSize;
403 Prefix->HeaderSize = sizeof(object::WinResHeaderPrefix) +
404 sizeof(object::WinResIDs) +
405 sizeof(object::WinResHeaderSuffix);
406 Buf += sizeof(object::WinResHeaderPrefix);
407
408 // Write the Type/Name IDs.
409 auto *IDs = reinterpret_cast<object::WinResIDs *>(Buf);
410 IDs->setType(RT_MANIFEST);
411 IDs->setName(Config->ManifestID);
412 Buf += sizeof(object::WinResIDs);
413
414 // Write the suffix.
415 auto *Suffix = reinterpret_cast<object::WinResHeaderSuffix *>(Buf);
416 Suffix->DataVersion = 0;
417 Suffix->MemoryFlags = object::WIN_RES_PURE_MOVEABLE;
418 Suffix->Language = SUBLANG_ENGLISH_US;
419 Suffix->Version = 0;
420 Suffix->Characteristics = 0;
421 Buf += sizeof(object::WinResHeaderSuffix);
422}
423
424// Create a resource file containing a manifest XML.
425std::unique_ptr<MemoryBuffer> createManifestRes() {
426 std::string Manifest = createManifestXml();
427
428 std::unique_ptr<MemoryBuffer> Res =
429 createMemoryBufferForManifestRes(Manifest.size());
430
431 char *Buf = const_cast<char *>(Res->getBufferStart());
432 writeResFileHeader(Buf);
433 writeResEntryHeader(Buf, Manifest.size());
434
435 // Copy the manifest data into the .res file.
436 std::copy(Manifest.begin(), Manifest.end(), Buf);
437 return Res;
438}
439
440void createSideBySideManifest() {
441 std::string Path = Config->ManifestFile;
442 if (Path == "")
443 Path = Config->OutputFile + ".manifest";
444 std::error_code EC;
445 raw_fd_ostream Out(Path, EC, sys::fs::F_Text);
446 if (EC)
447 fatal(EC, "failed to create manifest");
448 Out << createManifestXml();
449}
450
451// Parse a string in the form of
452// "<name>[=<internalname>][,@ordinal[,NONAME]][,DATA][,PRIVATE]"
453// or "<name>=<dllname>.<name>".
454// Used for parsing /export arguments.
455Export parseExport(StringRef Arg) {
456 Export E;
457 StringRef Rest;
458 std::tie(E.Name, Rest) = Arg.split(",");
459 if (E.Name.empty())
460 goto err;
461
462 if (E.Name.find('=') != StringRef::npos) {
463 StringRef X, Y;
464 std::tie(X, Y) = E.Name.split("=");
465
466 // If "<name>=<dllname>.<name>".
467 if (Y.find(".") != StringRef::npos) {
468 E.Name = X;
469 E.ForwardTo = Y;
470 return E;
471 }
472
473 E.ExtName = X;
474 E.Name = Y;
475 if (E.Name.empty())
476 goto err;
477 }
478
479 // If "<name>=<internalname>[,@ordinal[,NONAME]][,DATA][,PRIVATE]"
480 while (!Rest.empty()) {
481 StringRef Tok;
482 std::tie(Tok, Rest) = Rest.split(",");
483 if (Tok.equals_lower("noname")) {
484 if (E.Ordinal == 0)
485 goto err;
486 E.Noname = true;
487 continue;
488 }
489 if (Tok.equals_lower("data")) {
490 E.Data = true;
491 continue;
492 }
493 if (Tok.equals_lower("constant")) {
494 E.Constant = true;
495 continue;
496 }
497 if (Tok.equals_lower("private")) {
498 E.Private = true;
499 continue;
500 }
501 if (Tok.startswith("@")) {
502 int32_t Ord;
503 if (Tok.substr(1).getAsInteger(0, Ord))
504 goto err;
505 if (Ord <= 0 || 65535 < Ord)
506 goto err;
507 E.Ordinal = Ord;
508 continue;
509 }
510 goto err;
511 }
512 return E;
513
514err:
515 fatal("invalid /export: " + Arg);
516}
517
518static StringRef undecorate(StringRef Sym) {
519 if (Config->Machine != I386)
520 return Sym;
521 return Sym.startswith("_") ? Sym.substr(1) : Sym;
522}
523
524// Performs error checking on all /export arguments.
525// It also sets ordinals.
526void fixupExports() {
527 // Symbol ordinals must be unique.
528 std::set<uint16_t> Ords;
529 for (Export &E : Config->Exports) {
530 if (E.Ordinal == 0)
531 continue;
532 if (!Ords.insert(E.Ordinal).second)
533 fatal("duplicate export ordinal: " + E.Name);
534 }
535
536 for (Export &E : Config->Exports) {
537 SymbolBody *Sym = E.Sym;
538 if (!E.ForwardTo.empty() || !Sym) {
539 E.SymbolName = E.Name;
540 } else {
541 if (auto *U = dyn_cast<Undefined>(Sym))
542 if (U->WeakAlias)
543 Sym = U->WeakAlias;
544 E.SymbolName = Sym->getName();
545 }
546 }
547
548 for (Export &E : Config->Exports) {
549 if (!E.ForwardTo.empty()) {
550 E.ExportName = undecorate(E.Name);
551 } else {
552 E.ExportName = undecorate(E.ExtName.empty() ? E.Name : E.ExtName);
553 }
554 }
555
556 // Uniquefy by name.
557 std::map<StringRef, Export *> Map;
558 std::vector<Export> V;
559 for (Export &E : Config->Exports) {
560 auto Pair = Map.insert(std::make_pair(E.ExportName, &E));
561 bool Inserted = Pair.second;
562 if (Inserted) {
563 V.push_back(E);
564 continue;
565 }
566 Export *Existing = Pair.first->second;
567 if (E == *Existing || E.Name != Existing->Name)
568 continue;
569 warn("duplicate /export option: " + E.Name);
570 }
571 Config->Exports = std::move(V);
572
573 // Sort by name.
574 std::sort(Config->Exports.begin(), Config->Exports.end(),
575 [](const Export &A, const Export &B) {
576 return A.ExportName < B.ExportName;
577 });
578}
579
580void assignExportOrdinals() {
581 // Assign unique ordinals if default (= 0).
582 uint16_t Max = 0;
583 for (Export &E : Config->Exports)
584 Max = std::max(Max, E.Ordinal);
585 for (Export &E : Config->Exports)
586 if (E.Ordinal == 0)
587 E.Ordinal = ++Max;
588}
589
590// Parses a string in the form of "key=value" and check
591// if value matches previous values for the same key.
592void checkFailIfMismatch(StringRef Arg) {
593 StringRef K, V;
594 std::tie(K, V) = Arg.split('=');
595 if (K.empty() || V.empty())
596 fatal("/failifmismatch: invalid argument: " + Arg);
597 StringRef Existing = Config->MustMatch[K];
598 if (!Existing.empty() && V != Existing)
599 fatal("/failifmismatch: mismatch detected: " + Existing + " and " + V +
600 " for key " + K);
601 Config->MustMatch[K] = V;
602}
603
604// Convert Windows resource files (.res files) to a .obj file
605// using cvtres.exe.
606std::unique_ptr<MemoryBuffer>
607convertResToCOFF(const std::vector<MemoryBufferRef> &MBs) {
608 object::WindowsResourceParser Parser;
609
610 for (MemoryBufferRef MB : MBs) {
611 std::unique_ptr<object::Binary> Bin = check(object::createBinary(MB));
612 object::WindowsResource *RF = dyn_cast<object::WindowsResource>(Bin.get());
613 if (!RF)
614 fatal("cannot compile non-resource file as resource");
615 if (auto EC = Parser.parse(RF))
616 fatal(EC, "failed to parse .res file");
617 }
618
619 Expected<std::unique_ptr<MemoryBuffer>> E =
620 llvm::object::writeWindowsResourceCOFF(Config->Machine, Parser);
621 if (!E)
622 fatal(errorToErrorCode(E.takeError()), "failed to write .res to COFF");
623 return std::move(E.get());
624}
625
626// Run MSVC link.exe for given in-memory object files.
627// Command line options are copied from those given to LLD.
628// This is for the /msvclto option.
629void runMSVCLinker(std::string Rsp, ArrayRef<StringRef> Objects) {
630 // Write the in-memory object files to disk.
631 std::vector<TemporaryFile> Temps;
632 for (StringRef S : Objects) {
633 Temps.emplace_back("lto", "obj", S);
634 Rsp += quote(Temps.back().Path) + "\n";
635 }
636
637 log("link.exe " + Rsp);
638
639 // Run MSVC link.exe.
640 Temps.emplace_back("lto", "rsp", Rsp);
641 Executor E("link.exe");
642 E.add(Twine("@" + Temps.back().Path));
643 E.run();
644}
645
646// Create OptTable
647
648// Create prefix string literals used in Options.td
649#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
650#include "Options.inc"
651#undef PREFIX
652
653// Create table mapping all options defined in Options.td
654static const llvm::opt::OptTable::Info infoTable[] = {
655#define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \
656 {X1, X2, X10, X11, OPT_##ID, llvm::opt::Option::KIND##Class, \
657 X9, X8, OPT_##GROUP, OPT_##ALIAS, X7, X12},
658#include "Options.inc"
659#undef OPTION
660};
661
662class COFFOptTable : public llvm::opt::OptTable {
663public:
664 COFFOptTable() : OptTable(infoTable, true) {}
665};
666
667// Parses a given list of options.
668opt::InputArgList ArgParser::parse(ArrayRef<const char *> ArgsArr) {
669 // First, replace respnose files (@<file>-style options).
670 std::vector<const char *> Argv = replaceResponseFiles(ArgsArr);
671
672 // Make InputArgList from string vectors.
673 COFFOptTable Table;
674 unsigned MissingIndex;
675 unsigned MissingCount;
676 opt::InputArgList Args = Table.ParseArgs(Argv, MissingIndex, MissingCount);
677
678 // Print the real command line if response files are expanded.
679 if (Args.hasArg(OPT_verbose) && ArgsArr.size() != Argv.size()) {
680 std::string Msg = "Command line:";
681 for (const char *S : Argv)
682 Msg += " " + std::string(S);
683 message(Msg);
684 }
685
686 if (MissingCount)
687 fatal(Twine(Args.getArgString(MissingIndex)) + ": missing argument");
688 for (auto *Arg : Args.filtered(OPT_UNKNOWN))
689 warn("ignoring unknown argument: " + Arg->getSpelling());
690 return Args;
691}
692
693// link.exe has an interesting feature. If LINK or _LINK_ environment
694// variables exist, their contents are handled as command line strings.
695// So you can pass extra arguments using them.
696opt::InputArgList ArgParser::parseLINK(std::vector<const char *> Args) {
697 // Concatenate LINK env and command line arguments, and then parse them.
698 if (Optional<std::string> S = Process::GetEnv("LINK")) {
699 std::vector<const char *> V = tokenize(*S);
700 Args.insert(Args.begin(), V.begin(), V.end());
701 }
702 if (Optional<std::string> S = Process::GetEnv("_LINK_")) {
703 std::vector<const char *> V = tokenize(*S);
704 Args.insert(Args.begin(), V.begin(), V.end());
705 }
706 return parse(Args);
707}
708
709std::vector<const char *> ArgParser::tokenize(StringRef S) {
710 SmallVector<const char *, 16> Tokens;
711 cl::TokenizeWindowsCommandLine(S, Saver, Tokens);
712 return std::vector<const char *>(Tokens.begin(), Tokens.end());
713}
714
715// Creates a new command line by replacing options starting with '@'
716// character. '@<filename>' is replaced by the file's contents.
717std::vector<const char *>
718ArgParser::replaceResponseFiles(std::vector<const char *> Argv) {
719 SmallVector<const char *, 256> Tokens(Argv.data(), Argv.data() + Argv.size());
720 ExpandResponseFiles(Saver, TokenizeWindowsCommandLine, Tokens);
721 return std::vector<const char *>(Tokens.begin(), Tokens.end());
722}
723
724void printHelp(const char *Argv0) {
725 COFFOptTable Table;
726 Table.PrintHelp(outs(), Argv0, "LLVM Linker", false);
727}
728
729} // namespace coff
730} // namespace lld
deps/lld/COFF/Error.cpp created+114
......@@ -0,0 +1,114 @@
1//===- Error.cpp ----------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "Error.h"
11#include "Config.h"
12
13#include "llvm/ADT/Twine.h"
14#include "llvm/Support/Error.h"
15#include "llvm/Support/ManagedStatic.h"
16#include "llvm/Support/Process.h"
17#include "llvm/Support/raw_ostream.h"
18#include <mutex>
19
20#if !defined(_MSC_VER) && !defined(__MINGW32__)
21#include <unistd.h>
22#endif
23
24using namespace llvm;
25
26namespace lld {
27// The functions defined in this file can be called from multiple threads,
28// but outs() or errs() are not thread-safe. We protect them using a mutex.
29static std::mutex Mu;
30
31namespace coff {
32uint64_t ErrorCount;
33raw_ostream *ErrorOS;
34
35static LLVM_ATTRIBUTE_NORETURN void exitLld(int Val) {
36 // Dealloc/destroy ManagedStatic variables before calling
37 // _exit(). In a non-LTO build, this is a nop. In an LTO
38 // build allows us to get the output of -time-passes.
39 llvm_shutdown();
40
41 outs().flush();
42 errs().flush();
43 _exit(Val);
44}
45
46static void print(StringRef S, raw_ostream::Colors C) {
47 *ErrorOS << Config->Argv[0] << ": ";
48 if (Config->ColorDiagnostics) {
49 ErrorOS->changeColor(C, true);
50 *ErrorOS << S;
51 ErrorOS->resetColor();
52 } else {
53 *ErrorOS << S;
54 }
55}
56
57void log(const Twine &Msg) {
58 if (Config->Verbose) {
59 std::lock_guard<std::mutex> Lock(Mu);
60 outs() << Config->Argv[0] << ": " << Msg << "\n";
61 outs().flush();
62 }
63}
64
65void message(const Twine &Msg) {
66 std::lock_guard<std::mutex> Lock(Mu);
67 outs() << Msg << "\n";
68 outs().flush();
69}
70
71void error(const Twine &Msg) {
72 std::lock_guard<std::mutex> Lock(Mu);
73
74 if (Config->ErrorLimit == 0 || ErrorCount < Config->ErrorLimit) {
75 print("error: ", raw_ostream::RED);
76 *ErrorOS << Msg << "\n";
77 } else if (ErrorCount == Config->ErrorLimit) {
78 print("error: ", raw_ostream::RED);
79 *ErrorOS << "too many errors emitted, stopping now"
80 << " (use /ERRORLIMIT:0 to see all errors)\n";
81 exitLld(1);
82 }
83
84 ++ErrorCount;
85}
86
87void fatal(const Twine &Msg) {
88 if (Config->ColorDiagnostics) {
89 errs().changeColor(raw_ostream::RED, /*bold=*/true);
90 errs() << "error: ";
91 errs().resetColor();
92 } else {
93 errs() << "error: ";
94 }
95 errs() << Msg << "\n";
96 exitLld(1);
97}
98
99void fatal(std::error_code EC, const Twine &Msg) {
100 fatal(Msg + ": " + EC.message());
101}
102
103void fatal(llvm::Error &Err, const Twine &Msg) {
104 fatal(errorToErrorCode(std::move(Err)), Msg);
105}
106
107void warn(const Twine &Msg) {
108 std::lock_guard<std::mutex> Lock(Mu);
109 print("warning: ", raw_ostream::MAGENTA);
110 *ErrorOS << Msg << "\n";
111}
112
113} // namespace coff
114} // namespace lld
deps/lld/COFF/Error.h created+62
......@@ -0,0 +1,62 @@
1//===- Error.h --------------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_COFF_ERROR_H
11#define LLD_COFF_ERROR_H
12
13#include "lld/Core/LLVM.h"
14#include "llvm/Support/Error.h"
15
16namespace lld {
17namespace coff {
18
19extern uint64_t ErrorCount;
20extern llvm::raw_ostream *ErrorOS;
21
22void log(const Twine &Msg);
23void message(const Twine &Msg);
24void warn(const Twine &Msg);
25void error(const Twine &Msg);
26LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg);
27LLVM_ATTRIBUTE_NORETURN void fatal(std::error_code EC, const Twine &Prefix);
28LLVM_ATTRIBUTE_NORETURN void fatal(llvm::Error &Err, const Twine &Prefix);
29
30template <class T> T check(ErrorOr<T> V, const Twine &Prefix) {
31 if (auto EC = V.getError())
32 fatal(EC, Prefix);
33 return std::move(*V);
34}
35
36template <class T> T check(Expected<T> E, const Twine &Prefix) {
37 if (llvm::Error Err = E.takeError())
38 fatal(Err, Prefix);
39 return std::move(*E);
40}
41
42template <class T> T check(ErrorOr<T> EO) {
43 if (!EO)
44 fatal(EO.getError().message());
45 return std::move(*EO);
46}
47
48template <class T> T check(Expected<T> E) {
49 if (!E) {
50 std::string Buf;
51 llvm::raw_string_ostream OS(Buf);
52 logAllUnhandledErrors(E.takeError(), OS, "");
53 OS.flush();
54 fatal(Buf);
55 }
56 return std::move(*E);
57}
58
59} // namespace coff
60} // namespace lld
61
62#endif
deps/lld/COFF/ICF.cpp created+258
......@@ -0,0 +1,258 @@
1//===- ICF.cpp ------------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// ICF is short for Identical Code Folding. That is a size optimization to
11// identify and merge two or more read-only sections (typically functions)
12// that happened to have the same contents. It usually reduces output size
13// by a few percent.
14//
15// On Windows, ICF is enabled by default.
16//
17// See ELF/ICF.cpp for the details about the algortihm.
18//
19//===----------------------------------------------------------------------===//
20
21#include "Chunks.h"
22#include "Error.h"
23#include "Symbols.h"
24#include "llvm/ADT/Hashing.h"
25#include "llvm/Support/Debug.h"
26#include "llvm/Support/Parallel.h"
27#include "llvm/Support/raw_ostream.h"
28#include <algorithm>
29#include <atomic>
30#include <vector>
31
32using namespace llvm;
33
34namespace lld {
35namespace coff {
36
37class ICF {
38public:
39 void run(const std::vector<Chunk *> &V);
40
41private:
42 void segregate(size_t Begin, size_t End, bool Constant);
43
44 bool equalsConstant(const SectionChunk *A, const SectionChunk *B);
45 bool equalsVariable(const SectionChunk *A, const SectionChunk *B);
46
47 uint32_t getHash(SectionChunk *C);
48 bool isEligible(SectionChunk *C);
49
50 size_t findBoundary(size_t Begin, size_t End);
51
52 void forEachClassRange(size_t Begin, size_t End,
53 std::function<void(size_t, size_t)> Fn);
54
55 void forEachClass(std::function<void(size_t, size_t)> Fn);
56
57 std::vector<SectionChunk *> Chunks;
58 int Cnt = 0;
59 std::atomic<bool> Repeat = {false};
60};
61
62// Returns a hash value for S.
63uint32_t ICF::getHash(SectionChunk *C) {
64 return hash_combine(C->getPermissions(),
65 hash_value(C->SectionName),
66 C->NumRelocs,
67 C->getAlign(),
68 uint32_t(C->Header->SizeOfRawData),
69 C->Checksum);
70}
71
72// Returns true if section S is subject of ICF.
73//
74// Microsoft's documentation
75// (https://msdn.microsoft.com/en-us/library/bxwfs976.aspx; visited April
76// 2017) says that /opt:icf folds both functions and read-only data.
77// Despite that, the MSVC linker folds only functions. We found
78// a few instances of programs that are not safe for data merging.
79// Therefore, we merge only functions just like the MSVC tool.
80bool ICF::isEligible(SectionChunk *C) {
81 bool Global = C->Sym && C->Sym->isExternal();
82 bool Executable = C->getPermissions() & llvm::COFF::IMAGE_SCN_MEM_EXECUTE;
83 bool Writable = C->getPermissions() & llvm::COFF::IMAGE_SCN_MEM_WRITE;
84 return C->isCOMDAT() && C->isLive() && Global && Executable && !Writable;
85}
86
87// Split an equivalence class into smaller classes.
88void ICF::segregate(size_t Begin, size_t End, bool Constant) {
89 while (Begin < End) {
90 // Divide [Begin, End) into two. Let Mid be the start index of the
91 // second group.
92 auto Bound = std::stable_partition(
93 Chunks.begin() + Begin + 1, Chunks.begin() + End, [&](SectionChunk *S) {
94 if (Constant)
95 return equalsConstant(Chunks[Begin], S);
96 return equalsVariable(Chunks[Begin], S);
97 });
98 size_t Mid = Bound - Chunks.begin();
99
100 // Split [Begin, End) into [Begin, Mid) and [Mid, End). We use Mid as an
101 // equivalence class ID because every group ends with a unique index.
102 for (size_t I = Begin; I < Mid; ++I)
103 Chunks[I]->Class[(Cnt + 1) % 2] = Mid;
104
105 // If we created a group, we need to iterate the main loop again.
106 if (Mid != End)
107 Repeat = true;
108
109 Begin = Mid;
110 }
111}
112
113// Compare "non-moving" part of two sections, namely everything
114// except relocation targets.
115bool ICF::equalsConstant(const SectionChunk *A, const SectionChunk *B) {
116 if (A->NumRelocs != B->NumRelocs)
117 return false;
118
119 // Compare relocations.
120 auto Eq = [&](const coff_relocation &R1, const coff_relocation &R2) {
121 if (R1.Type != R2.Type ||
122 R1.VirtualAddress != R2.VirtualAddress) {
123 return false;
124 }
125 SymbolBody *B1 = A->File->getSymbolBody(R1.SymbolTableIndex);
126 SymbolBody *B2 = B->File->getSymbolBody(R2.SymbolTableIndex);
127 if (B1 == B2)
128 return true;
129 if (auto *D1 = dyn_cast<DefinedRegular>(B1))
130 if (auto *D2 = dyn_cast<DefinedRegular>(B2))
131 return D1->getValue() == D2->getValue() &&
132 D1->getChunk()->Class[Cnt % 2] == D2->getChunk()->Class[Cnt % 2];
133 return false;
134 };
135 if (!std::equal(A->Relocs.begin(), A->Relocs.end(), B->Relocs.begin(), Eq))
136 return false;
137
138 // Compare section attributes and contents.
139 return A->getPermissions() == B->getPermissions() &&
140 A->SectionName == B->SectionName &&
141 A->getAlign() == B->getAlign() &&
142 A->Header->SizeOfRawData == B->Header->SizeOfRawData &&
143 A->Checksum == B->Checksum &&
144 A->getContents() == B->getContents();
145}
146
147// Compare "moving" part of two sections, namely relocation targets.
148bool ICF::equalsVariable(const SectionChunk *A, const SectionChunk *B) {
149 // Compare relocations.
150 auto Eq = [&](const coff_relocation &R1, const coff_relocation &R2) {
151 SymbolBody *B1 = A->File->getSymbolBody(R1.SymbolTableIndex);
152 SymbolBody *B2 = B->File->getSymbolBody(R2.SymbolTableIndex);
153 if (B1 == B2)
154 return true;
155 if (auto *D1 = dyn_cast<DefinedRegular>(B1))
156 if (auto *D2 = dyn_cast<DefinedRegular>(B2))
157 return D1->getChunk()->Class[Cnt % 2] == D2->getChunk()->Class[Cnt % 2];
158 return false;
159 };
160 return std::equal(A->Relocs.begin(), A->Relocs.end(), B->Relocs.begin(), Eq);
161}
162
163size_t ICF::findBoundary(size_t Begin, size_t End) {
164 for (size_t I = Begin + 1; I < End; ++I)
165 if (Chunks[Begin]->Class[Cnt % 2] != Chunks[I]->Class[Cnt % 2])
166 return I;
167 return End;
168}
169
170void ICF::forEachClassRange(size_t Begin, size_t End,
171 std::function<void(size_t, size_t)> Fn) {
172 if (Begin > 0)
173 Begin = findBoundary(Begin - 1, End);
174
175 while (Begin < End) {
176 size_t Mid = findBoundary(Begin, Chunks.size());
177 Fn(Begin, Mid);
178 Begin = Mid;
179 }
180}
181
182// Call Fn on each class group.
183void ICF::forEachClass(std::function<void(size_t, size_t)> Fn) {
184 // If the number of sections are too small to use threading,
185 // call Fn sequentially.
186 if (Chunks.size() < 1024) {
187 forEachClassRange(0, Chunks.size(), Fn);
188 ++Cnt;
189 return;
190 }
191
192 // Split sections into 256 shards and call Fn in parallel.
193 size_t NumShards = 256;
194 size_t Step = Chunks.size() / NumShards;
195 for_each_n(parallel::par, size_t(0), NumShards, [&](size_t I) {
196 size_t End = (I == NumShards - 1) ? Chunks.size() : (I + 1) * Step;
197 forEachClassRange(I * Step, End, Fn);
198 });
199 ++Cnt;
200}
201
202// Merge identical COMDAT sections.
203// Two sections are considered the same if their section headers,
204// contents and relocations are all the same.
205void ICF::run(const std::vector<Chunk *> &Vec) {
206 // Collect only mergeable sections and group by hash value.
207 uint32_t NextId = 1;
208 for (Chunk *C : Vec) {
209 if (auto *SC = dyn_cast<SectionChunk>(C)) {
210 if (isEligible(SC))
211 Chunks.push_back(SC);
212 else
213 SC->Class[0] = NextId++;
214 }
215 }
216
217 // Initially, we use hash values to partition sections.
218 for (SectionChunk *SC : Chunks)
219 // Set MSB to 1 to avoid collisions with non-hash classs.
220 SC->Class[0] = getHash(SC) | (1 << 31);
221
222 // From now on, sections in Chunks are ordered so that sections in
223 // the same group are consecutive in the vector.
224 std::stable_sort(Chunks.begin(), Chunks.end(),
225 [](SectionChunk *A, SectionChunk *B) {
226 return A->Class[0] < B->Class[0];
227 });
228
229 // Compare static contents and assign unique IDs for each static content.
230 forEachClass([&](size_t Begin, size_t End) { segregate(Begin, End, true); });
231
232 // Split groups by comparing relocations until convergence is obtained.
233 do {
234 Repeat = false;
235 forEachClass(
236 [&](size_t Begin, size_t End) { segregate(Begin, End, false); });
237 } while (Repeat);
238
239 log("ICF needed " + Twine(Cnt) + " iterations");
240
241 // Merge sections in the same classs.
242 forEachClass([&](size_t Begin, size_t End) {
243 if (End - Begin == 1)
244 return;
245
246 log("Selected " + Chunks[Begin]->getDebugName());
247 for (size_t I = Begin + 1; I < End; ++I) {
248 log(" Removed " + Chunks[I]->getDebugName());
249 Chunks[Begin]->replace(Chunks[I]);
250 }
251 });
252}
253
254// Entry point to ICF.
255void doICF(const std::vector<Chunk *> &Chunks) { ICF().run(Chunks); }
256
257} // namespace coff
258} // namespace lld
deps/lld/COFF/InputFiles.cpp created+411
......@@ -0,0 +1,411 @@
1//===- InputFiles.cpp -----------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "InputFiles.h"
11#include "Chunks.h"
12#include "Config.h"
13#include "Driver.h"
14#include "Error.h"
15#include "Memory.h"
16#include "SymbolTable.h"
17#include "Symbols.h"
18#include "llvm-c/lto.h"
19#include "llvm/ADT/SmallVector.h"
20#include "llvm/ADT/Triple.h"
21#include "llvm/ADT/Twine.h"
22#include "llvm/BinaryFormat/COFF.h"
23#include "llvm/Object/Binary.h"
24#include "llvm/Object/COFF.h"
25#include "llvm/Support/Casting.h"
26#include "llvm/Support/Endian.h"
27#include "llvm/Support/Error.h"
28#include "llvm/Support/ErrorOr.h"
29#include "llvm/Support/FileSystem.h"
30#include "llvm/Target/TargetOptions.h"
31#include <cstring>
32#include <system_error>
33#include <utility>
34
35using namespace llvm;
36using namespace llvm::COFF;
37using namespace llvm::object;
38using namespace llvm::support::endian;
39
40using llvm::Triple;
41using llvm::support::ulittle32_t;
42
43namespace lld {
44namespace coff {
45
46/// Checks that Source is compatible with being a weak alias to Target.
47/// If Source is Undefined and has no weak alias set, makes it a weak
48/// alias to Target.
49static void checkAndSetWeakAlias(SymbolTable *Symtab, InputFile *F,
50 SymbolBody *Source, SymbolBody *Target) {
51 if (auto *U = dyn_cast<Undefined>(Source)) {
52 if (U->WeakAlias && U->WeakAlias != Target)
53 Symtab->reportDuplicate(Source->symbol(), F);
54 U->WeakAlias = Target;
55 }
56}
57
58ArchiveFile::ArchiveFile(MemoryBufferRef M) : InputFile(ArchiveKind, M) {}
59
60void ArchiveFile::parse() {
61 // Parse a MemoryBufferRef as an archive file.
62 File = check(Archive::create(MB), toString(this));
63
64 // Read the symbol table to construct Lazy objects.
65 for (const Archive::Symbol &Sym : File->symbols())
66 Symtab->addLazy(this, Sym);
67}
68
69// Returns a buffer pointing to a member file containing a given symbol.
70void ArchiveFile::addMember(const Archive::Symbol *Sym) {
71 const Archive::Child &C =
72 check(Sym->getMember(),
73 "could not get the member for symbol " + Sym->getName());
74
75 // Return an empty buffer if we have already returned the same buffer.
76 if (!Seen.insert(C.getChildOffset()).second)
77 return;
78
79 Driver->enqueueArchiveMember(C, Sym->getName(), getName());
80}
81
82void ObjectFile::parse() {
83 // Parse a memory buffer as a COFF file.
84 std::unique_ptr<Binary> Bin = check(createBinary(MB), toString(this));
85
86 if (auto *Obj = dyn_cast<COFFObjectFile>(Bin.get())) {
87 Bin.release();
88 COFFObj.reset(Obj);
89 } else {
90 fatal(toString(this) + " is not a COFF file");
91 }
92
93 // Read section and symbol tables.
94 initializeChunks();
95 initializeSymbols();
96 initializeSEH();
97}
98
99void ObjectFile::initializeChunks() {
100 uint32_t NumSections = COFFObj->getNumberOfSections();
101 Chunks.reserve(NumSections);
102 SparseChunks.resize(NumSections + 1);
103 for (uint32_t I = 1; I < NumSections + 1; ++I) {
104 const coff_section *Sec;
105 StringRef Name;
106 if (auto EC = COFFObj->getSection(I, Sec))
107 fatal(EC, "getSection failed: #" + Twine(I));
108 if (auto EC = COFFObj->getSectionName(Sec, Name))
109 fatal(EC, "getSectionName failed: #" + Twine(I));
110 if (Name == ".sxdata") {
111 SXData = Sec;
112 continue;
113 }
114 if (Name == ".drectve") {
115 ArrayRef<uint8_t> Data;
116 COFFObj->getSectionContents(Sec, Data);
117 Directives = std::string((const char *)Data.data(), Data.size());
118 continue;
119 }
120
121 // Object files may have DWARF debug info or MS CodeView debug info
122 // (or both).
123 //
124 // DWARF sections don't need any special handling from the perspective
125 // of the linker; they are just a data section containing relocations.
126 // We can just link them to complete debug info.
127 //
128 // CodeView needs a linker support. We need to interpret and debug
129 // info, and then write it to a separate .pdb file.
130
131 // Ignore debug info unless /debug is given.
132 if (!Config->Debug && Name.startswith(".debug"))
133 continue;
134
135 if (Sec->Characteristics & llvm::COFF::IMAGE_SCN_LNK_REMOVE)
136 continue;
137 auto *C = make<SectionChunk>(this, Sec);
138
139 // CodeView sections are stored to a different vector because they are not
140 // linked in the regular manner.
141 if (C->isCodeView())
142 DebugChunks.push_back(C);
143 else
144 Chunks.push_back(C);
145
146 SparseChunks[I] = C;
147 }
148}
149
150void ObjectFile::initializeSymbols() {
151 uint32_t NumSymbols = COFFObj->getNumberOfSymbols();
152 SymbolBodies.reserve(NumSymbols);
153 SparseSymbolBodies.resize(NumSymbols);
154
155 SmallVector<std::pair<SymbolBody *, uint32_t>, 8> WeakAliases;
156 int32_t LastSectionNumber = 0;
157
158 for (uint32_t I = 0; I < NumSymbols; ++I) {
159 // Get a COFFSymbolRef object.
160 ErrorOr<COFFSymbolRef> SymOrErr = COFFObj->getSymbol(I);
161 if (!SymOrErr)
162 fatal(SymOrErr.getError(), "broken object file: " + toString(this));
163 COFFSymbolRef Sym = *SymOrErr;
164
165 const void *AuxP = nullptr;
166 if (Sym.getNumberOfAuxSymbols())
167 AuxP = COFFObj->getSymbol(I + 1)->getRawPtr();
168 bool IsFirst = (LastSectionNumber != Sym.getSectionNumber());
169
170 SymbolBody *Body = nullptr;
171 if (Sym.isUndefined()) {
172 Body = createUndefined(Sym);
173 } else if (Sym.isWeakExternal()) {
174 Body = createUndefined(Sym);
175 uint32_t TagIndex =
176 static_cast<const coff_aux_weak_external *>(AuxP)->TagIndex;
177 WeakAliases.emplace_back(Body, TagIndex);
178 } else {
179 Body = createDefined(Sym, AuxP, IsFirst);
180 }
181 if (Body) {
182 SymbolBodies.push_back(Body);
183 SparseSymbolBodies[I] = Body;
184 }
185 I += Sym.getNumberOfAuxSymbols();
186 LastSectionNumber = Sym.getSectionNumber();
187 }
188
189 for (auto &KV : WeakAliases) {
190 SymbolBody *Sym = KV.first;
191 uint32_t Idx = KV.second;
192 checkAndSetWeakAlias(Symtab, this, Sym, SparseSymbolBodies[Idx]);
193 }
194}
195
196SymbolBody *ObjectFile::createUndefined(COFFSymbolRef Sym) {
197 StringRef Name;
198 COFFObj->getSymbolName(Sym, Name);
199 return Symtab->addUndefined(Name, this, Sym.isWeakExternal())->body();
200}
201
202SymbolBody *ObjectFile::createDefined(COFFSymbolRef Sym, const void *AuxP,
203 bool IsFirst) {
204 StringRef Name;
205 if (Sym.isCommon()) {
206 auto *C = make<CommonChunk>(Sym);
207 Chunks.push_back(C);
208 COFFObj->getSymbolName(Sym, Name);
209 Symbol *S =
210 Symtab->addCommon(this, Name, Sym.getValue(), Sym.getGeneric(), C);
211 return S->body();
212 }
213 if (Sym.isAbsolute()) {
214 COFFObj->getSymbolName(Sym, Name);
215 // Skip special symbols.
216 if (Name == "@comp.id")
217 return nullptr;
218 // COFF spec 5.10.1. The .sxdata section.
219 if (Name == "@feat.00") {
220 if (Sym.getValue() & 1)
221 SEHCompat = true;
222 return nullptr;
223 }
224 if (Sym.isExternal())
225 return Symtab->addAbsolute(Name, Sym)->body();
226 else
227 return make<DefinedAbsolute>(Name, Sym);
228 }
229 int32_t SectionNumber = Sym.getSectionNumber();
230 if (SectionNumber == llvm::COFF::IMAGE_SYM_DEBUG)
231 return nullptr;
232
233 // Reserved sections numbers don't have contents.
234 if (llvm::COFF::isReservedSectionNumber(SectionNumber))
235 fatal("broken object file: " + toString(this));
236
237 // This symbol references a section which is not present in the section
238 // header.
239 if ((uint32_t)SectionNumber >= SparseChunks.size())
240 fatal("broken object file: " + toString(this));
241
242 // Nothing else to do without a section chunk.
243 auto *SC = cast_or_null<SectionChunk>(SparseChunks[SectionNumber]);
244 if (!SC)
245 return nullptr;
246
247 // Handle section definitions
248 if (IsFirst && AuxP) {
249 auto *Aux = reinterpret_cast<const coff_aux_section_definition *>(AuxP);
250 if (Aux->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE)
251 if (auto *ParentSC = cast_or_null<SectionChunk>(
252 SparseChunks[Aux->getNumber(Sym.isBigObj())])) {
253 ParentSC->addAssociative(SC);
254 // If we already discarded the parent, discard the child.
255 if (ParentSC->isDiscarded())
256 SC->markDiscarded();
257 }
258 SC->Checksum = Aux->CheckSum;
259 }
260
261 DefinedRegular *B;
262 if (Sym.isExternal()) {
263 COFFObj->getSymbolName(Sym, Name);
264 Symbol *S =
265 Symtab->addRegular(this, Name, SC->isCOMDAT(), Sym.getGeneric(), SC);
266 B = cast<DefinedRegular>(S->body());
267 } else
268 B = make<DefinedRegular>(this, /*Name*/ "", SC->isCOMDAT(),
269 /*IsExternal*/ false, Sym.getGeneric(), SC);
270 if (SC->isCOMDAT() && Sym.getValue() == 0 && !AuxP)
271 SC->setSymbol(B);
272
273 return B;
274}
275
276void ObjectFile::initializeSEH() {
277 if (!SEHCompat || !SXData)
278 return;
279 ArrayRef<uint8_t> A;
280 COFFObj->getSectionContents(SXData, A);
281 if (A.size() % 4 != 0)
282 fatal(".sxdata must be an array of symbol table indices");
283 auto *I = reinterpret_cast<const ulittle32_t *>(A.data());
284 auto *E = reinterpret_cast<const ulittle32_t *>(A.data() + A.size());
285 for (; I != E; ++I)
286 SEHandlers.insert(SparseSymbolBodies[*I]);
287}
288
289MachineTypes ObjectFile::getMachineType() {
290 if (COFFObj)
291 return static_cast<MachineTypes>(COFFObj->getMachine());
292 return IMAGE_FILE_MACHINE_UNKNOWN;
293}
294
295StringRef ltrim1(StringRef S, const char *Chars) {
296 if (!S.empty() && strchr(Chars, S[0]))
297 return S.substr(1);
298 return S;
299}
300
301void ImportFile::parse() {
302 const char *Buf = MB.getBufferStart();
303 const char *End = MB.getBufferEnd();
304 const auto *Hdr = reinterpret_cast<const coff_import_header *>(Buf);
305
306 // Check if the total size is valid.
307 if ((size_t)(End - Buf) != (sizeof(*Hdr) + Hdr->SizeOfData))
308 fatal("broken import library");
309
310 // Read names and create an __imp_ symbol.
311 StringRef Name = Saver.save(StringRef(Buf + sizeof(*Hdr)));
312 StringRef ImpName = Saver.save("__imp_" + Name);
313 const char *NameStart = Buf + sizeof(coff_import_header) + Name.size() + 1;
314 DLLName = StringRef(NameStart);
315 StringRef ExtName;
316 switch (Hdr->getNameType()) {
317 case IMPORT_ORDINAL:
318 ExtName = "";
319 break;
320 case IMPORT_NAME:
321 ExtName = Name;
322 break;
323 case IMPORT_NAME_NOPREFIX:
324 ExtName = ltrim1(Name, "?@_");
325 break;
326 case IMPORT_NAME_UNDECORATE:
327 ExtName = ltrim1(Name, "?@_");
328 ExtName = ExtName.substr(0, ExtName.find('@'));
329 break;
330 }
331
332 this->Hdr = Hdr;
333 ExternalName = ExtName;
334
335 ImpSym = cast<DefinedImportData>(
336 Symtab->addImportData(ImpName, this)->body());
337 if (Hdr->getType() == llvm::COFF::IMPORT_CONST)
338 ConstSym =
339 cast<DefinedImportData>(Symtab->addImportData(Name, this)->body());
340
341 // If type is function, we need to create a thunk which jump to an
342 // address pointed by the __imp_ symbol. (This allows you to call
343 // DLL functions just like regular non-DLL functions.)
344 if (Hdr->getType() != llvm::COFF::IMPORT_CODE)
345 return;
346 ThunkSym = cast<DefinedImportThunk>(
347 Symtab->addImportThunk(Name, ImpSym, Hdr->Machine)->body());
348}
349
350void BitcodeFile::parse() {
351 Obj = check(lto::InputFile::create(MemoryBufferRef(
352 MB.getBuffer(), Saver.save(ParentName + MB.getBufferIdentifier()))));
353 for (const lto::InputFile::Symbol &ObjSym : Obj->symbols()) {
354 StringRef SymName = Saver.save(ObjSym.getName());
355 Symbol *Sym;
356 if (ObjSym.isUndefined()) {
357 Sym = Symtab->addUndefined(SymName, this, false);
358 } else if (ObjSym.isCommon()) {
359 Sym = Symtab->addCommon(this, SymName, ObjSym.getCommonSize());
360 } else if (ObjSym.isWeak() && ObjSym.isIndirect()) {
361 // Weak external.
362 Sym = Symtab->addUndefined(SymName, this, true);
363 std::string Fallback = ObjSym.getCOFFWeakExternalFallback();
364 SymbolBody *Alias = Symtab->addUndefined(Saver.save(Fallback));
365 checkAndSetWeakAlias(Symtab, this, Sym->body(), Alias);
366 } else {
367 bool IsCOMDAT = ObjSym.getComdatIndex() != -1;
368 Sym = Symtab->addRegular(this, SymName, IsCOMDAT);
369 }
370 SymbolBodies.push_back(Sym->body());
371 }
372 Directives = Obj->getCOFFLinkerOpts();
373}
374
375MachineTypes BitcodeFile::getMachineType() {
376 switch (Triple(Obj->getTargetTriple()).getArch()) {
377 case Triple::x86_64:
378 return AMD64;
379 case Triple::x86:
380 return I386;
381 case Triple::arm:
382 return ARMNT;
383 case Triple::aarch64:
384 return ARM64;
385 default:
386 return IMAGE_FILE_MACHINE_UNKNOWN;
387 }
388}
389} // namespace coff
390} // namespace lld
391
392// Returns the last element of a path, which is supposed to be a filename.
393static StringRef getBasename(StringRef Path) {
394 size_t Pos = Path.find_last_of("\\/");
395 if (Pos == StringRef::npos)
396 return Path;
397 return Path.substr(Pos + 1);
398}
399
400// Returns a string in the format of "foo.obj" or "foo.obj(bar.lib)".
401std::string lld::toString(coff::InputFile *File) {
402 if (!File)
403 return "(internal)";
404 if (File->ParentName.empty())
405 return File->getName().lower();
406
407 std::string Res =
408 (getBasename(File->ParentName) + "(" + getBasename(File->getName()) + ")")
409 .str();
410 return StringRef(Res).lower();
411}
deps/lld/COFF/InputFiles.h created+223
......@@ -0,0 +1,223 @@
1//===- InputFiles.h ---------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_COFF_INPUT_FILES_H
11#define LLD_COFF_INPUT_FILES_H
12
13#include "Config.h"
14#include "lld/Core/LLVM.h"
15#include "llvm/ADT/ArrayRef.h"
16#include "llvm/ADT/DenseSet.h"
17#include "llvm/LTO/LTO.h"
18#include "llvm/Object/Archive.h"
19#include "llvm/Object/COFF.h"
20#include "llvm/Support/StringSaver.h"
21#include <memory>
22#include <set>
23#include <vector>
24
25namespace llvm {
26namespace pdb {
27class DbiModuleDescriptorBuilder;
28}
29}
30
31namespace lld {
32namespace coff {
33
34using llvm::COFF::IMAGE_FILE_MACHINE_UNKNOWN;
35using llvm::COFF::MachineTypes;
36using llvm::object::Archive;
37using llvm::object::COFFObjectFile;
38using llvm::object::COFFSymbolRef;
39using llvm::object::coff_import_header;
40using llvm::object::coff_section;
41
42class Chunk;
43class Defined;
44class DefinedImportData;
45class DefinedImportThunk;
46class Lazy;
47class SectionChunk;
48struct Symbol;
49class SymbolBody;
50class Undefined;
51
52// The root class of input files.
53class InputFile {
54public:
55 enum Kind { ArchiveKind, ObjectKind, ImportKind, BitcodeKind };
56 Kind kind() const { return FileKind; }
57 virtual ~InputFile() {}
58
59 // Returns the filename.
60 StringRef getName() { return MB.getBufferIdentifier(); }
61
62 // Reads a file (the constructor doesn't do that).
63 virtual void parse() = 0;
64
65 // Returns the CPU type this file was compiled to.
66 virtual MachineTypes getMachineType() { return IMAGE_FILE_MACHINE_UNKNOWN; }
67
68 MemoryBufferRef MB;
69
70 // An archive file name if this file is created from an archive.
71 StringRef ParentName;
72
73 // Returns .drectve section contents if exist.
74 StringRef getDirectives() { return StringRef(Directives).trim(); }
75
76protected:
77 InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) {}
78
79 std::string Directives;
80
81private:
82 const Kind FileKind;
83};
84
85// .lib or .a file.
86class ArchiveFile : public InputFile {
87public:
88 explicit ArchiveFile(MemoryBufferRef M);
89 static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; }
90 void parse() override;
91
92 // Enqueues an archive member load for the given symbol. If we've already
93 // enqueued a load for the same archive member, this function does nothing,
94 // which ensures that we don't load the same member more than once.
95 void addMember(const Archive::Symbol *Sym);
96
97private:
98 std::unique_ptr<Archive> File;
99 std::string Filename;
100 llvm::DenseSet<uint64_t> Seen;
101};
102
103// .obj or .o file. This may be a member of an archive file.
104class ObjectFile : public InputFile {
105public:
106 explicit ObjectFile(MemoryBufferRef M) : InputFile(ObjectKind, M) {}
107 static bool classof(const InputFile *F) { return F->kind() == ObjectKind; }
108 void parse() override;
109 MachineTypes getMachineType() override;
110 std::vector<Chunk *> &getChunks() { return Chunks; }
111 std::vector<SectionChunk *> &getDebugChunks() { return DebugChunks; }
112 std::vector<SymbolBody *> &getSymbols() { return SymbolBodies; }
113
114 // Returns a SymbolBody object for the SymbolIndex'th symbol in the
115 // underlying object file.
116 SymbolBody *getSymbolBody(uint32_t SymbolIndex) {
117 return SparseSymbolBodies[SymbolIndex];
118 }
119
120 // Returns the underying COFF file.
121 COFFObjectFile *getCOFFObj() { return COFFObj.get(); }
122
123 // True if this object file is compatible with SEH.
124 // COFF-specific and x86-only.
125 bool SEHCompat = false;
126
127 // The list of safe exception handlers listed in .sxdata section.
128 // COFF-specific and x86-only.
129 std::set<SymbolBody *> SEHandlers;
130
131 // Pointer to the PDB module descriptor builder. Various debug info records
132 // will reference object files by "module index", which is here. Things like
133 // source files and section contributions are also recorded here. Will be null
134 // if we are not producing a PDB.
135 llvm::pdb::DbiModuleDescriptorBuilder *ModuleDBI = nullptr;
136
137private:
138 void initializeChunks();
139 void initializeSymbols();
140 void initializeSEH();
141
142 SymbolBody *createDefined(COFFSymbolRef Sym, const void *Aux, bool IsFirst);
143 SymbolBody *createUndefined(COFFSymbolRef Sym);
144
145 std::unique_ptr<COFFObjectFile> COFFObj;
146 const coff_section *SXData = nullptr;
147
148 // List of all chunks defined by this file. This includes both section
149 // chunks and non-section chunks for common symbols.
150 std::vector<Chunk *> Chunks;
151
152 // CodeView debug info sections.
153 std::vector<SectionChunk *> DebugChunks;
154
155 // This vector contains the same chunks as Chunks, but they are
156 // indexed such that you can get a SectionChunk by section index.
157 // Nonexistent section indices are filled with null pointers.
158 // (Because section number is 1-based, the first slot is always a
159 // null pointer.)
160 std::vector<Chunk *> SparseChunks;
161
162 // List of all symbols referenced or defined by this file.
163 std::vector<SymbolBody *> SymbolBodies;
164
165 // This vector contains the same symbols as SymbolBodies, but they
166 // are indexed such that you can get a SymbolBody by symbol
167 // index. Nonexistent indices (which are occupied by auxiliary
168 // symbols in the real symbol table) are filled with null pointers.
169 std::vector<SymbolBody *> SparseSymbolBodies;
170};
171
172// This type represents import library members that contain DLL names
173// and symbols exported from the DLLs. See Microsoft PE/COFF spec. 7
174// for details about the format.
175class ImportFile : public InputFile {
176public:
177 explicit ImportFile(MemoryBufferRef M)
178 : InputFile(ImportKind, M), Live(!Config->DoGC) {}
179
180 static bool classof(const InputFile *F) { return F->kind() == ImportKind; }
181
182 DefinedImportData *ImpSym = nullptr;
183 DefinedImportData *ConstSym = nullptr;
184 DefinedImportThunk *ThunkSym = nullptr;
185 std::string DLLName;
186
187private:
188 void parse() override;
189
190public:
191 StringRef ExternalName;
192 const coff_import_header *Hdr;
193 Chunk *Location = nullptr;
194
195 // We want to eliminate dllimported symbols if no one actually refers them.
196 // This "Live" bit is used to keep track of which import library members
197 // are actually in use.
198 //
199 // If the Live bit is turned off by MarkLive, Writer will ignore dllimported
200 // symbols provided by this import library member.
201 bool Live;
202};
203
204// Used for LTO.
205class BitcodeFile : public InputFile {
206public:
207 explicit BitcodeFile(MemoryBufferRef M) : InputFile(BitcodeKind, M) {}
208 static bool classof(const InputFile *F) { return F->kind() == BitcodeKind; }
209 std::vector<SymbolBody *> &getSymbols() { return SymbolBodies; }
210 MachineTypes getMachineType() override;
211 std::unique_ptr<llvm::lto::InputFile> Obj;
212
213private:
214 void parse() override;
215
216 std::vector<SymbolBody *> SymbolBodies;
217};
218} // namespace coff
219
220std::string toString(coff::InputFile *File);
221} // namespace lld
222
223#endif
deps/lld/COFF/LTO.cpp created+140
......@@ -0,0 +1,140 @@
1//===- LTO.cpp ------------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "LTO.h"
11#include "Config.h"
12#include "Error.h"
13#include "InputFiles.h"
14#include "Symbols.h"
15#include "lld/Core/TargetOptionsCommandFlags.h"
16#include "llvm/ADT/STLExtras.h"
17#include "llvm/ADT/SmallString.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/ADT/Twine.h"
20#include "llvm/IR/DiagnosticPrinter.h"
21#include "llvm/LTO/Config.h"
22#include "llvm/LTO/LTO.h"
23#include "llvm/Object/SymbolicFile.h"
24#include "llvm/Support/CodeGen.h"
25#include "llvm/Support/Error.h"
26#include "llvm/Support/FileSystem.h"
27#include "llvm/Support/MemoryBuffer.h"
28#include "llvm/Support/raw_ostream.h"
29#include <algorithm>
30#include <cstddef>
31#include <memory>
32#include <string>
33#include <system_error>
34#include <vector>
35
36using namespace llvm;
37using namespace llvm::object;
38
39using namespace lld;
40using namespace lld::coff;
41
42static void diagnosticHandler(const DiagnosticInfo &DI) {
43 SmallString<128> ErrStorage;
44 raw_svector_ostream OS(ErrStorage);
45 DiagnosticPrinterRawOStream DP(OS);
46 DI.print(DP);
47 warn(ErrStorage);
48}
49
50static void checkError(Error E) {
51 handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) -> Error {
52 error(EIB.message());
53 return Error::success();
54 });
55}
56
57static void saveBuffer(StringRef Buffer, const Twine &Path) {
58 std::error_code EC;
59 raw_fd_ostream OS(Path.str(), EC, sys::fs::OpenFlags::F_None);
60 if (EC)
61 error("cannot create " + Path + ": " + EC.message());
62 OS << Buffer;
63}
64
65static std::unique_ptr<lto::LTO> createLTO() {
66 lto::Config Conf;
67 Conf.Options = InitTargetOptionsFromCodeGenFlags();
68 Conf.RelocModel = Reloc::PIC_;
69 Conf.DisableVerify = true;
70 Conf.DiagHandler = diagnosticHandler;
71 Conf.OptLevel = Config->LTOOptLevel;
72 if (Config->SaveTemps)
73 checkError(Conf.addSaveTemps(std::string(Config->OutputFile) + ".",
74 /*UseInputModulePath*/ true));
75 lto::ThinBackend Backend;
76 if (Config->LTOJobs != 0)
77 Backend = lto::createInProcessThinBackend(Config->LTOJobs);
78 return llvm::make_unique<lto::LTO>(std::move(Conf), Backend,
79 Config->LTOPartitions);
80}
81
82BitcodeCompiler::BitcodeCompiler() : LTOObj(createLTO()) {}
83
84BitcodeCompiler::~BitcodeCompiler() = default;
85
86static void undefine(Symbol *S) {
87 replaceBody<Undefined>(S, S->body()->getName());
88}
89
90void BitcodeCompiler::add(BitcodeFile &F) {
91 lto::InputFile &Obj = *F.Obj;
92 unsigned SymNum = 0;
93 std::vector<SymbolBody *> SymBodies = F.getSymbols();
94 std::vector<lto::SymbolResolution> Resols(SymBodies.size());
95
96 // Provide a resolution to the LTO API for each symbol.
97 for (const lto::InputFile::Symbol &ObjSym : Obj.symbols()) {
98 SymbolBody *B = SymBodies[SymNum];
99 Symbol *Sym = B->symbol();
100 lto::SymbolResolution &R = Resols[SymNum];
101 ++SymNum;
102
103 // Ideally we shouldn't check for SF_Undefined but currently IRObjectFile
104 // reports two symbols for module ASM defined. Without this check, lld
105 // flags an undefined in IR with a definition in ASM as prevailing.
106 // Once IRObjectFile is fixed to report only one symbol this hack can
107 // be removed.
108 R.Prevailing = !ObjSym.isUndefined() && B->getFile() == &F;
109 R.VisibleToRegularObj = Sym->IsUsedInRegularObj;
110 if (R.Prevailing)
111 undefine(Sym);
112 }
113 checkError(LTOObj->add(std::move(F.Obj), Resols));
114}
115
116// Merge all the bitcode files we have seen, codegen the result
117// and return the resulting objects.
118std::vector<StringRef> BitcodeCompiler::compile() {
119 unsigned MaxTasks = LTOObj->getMaxTasks();
120 Buff.resize(MaxTasks);
121
122 checkError(LTOObj->run([&](size_t Task) {
123 return llvm::make_unique<lto::NativeObjectStream>(
124 llvm::make_unique<raw_svector_ostream>(Buff[Task]));
125 }));
126
127 std::vector<StringRef> Ret;
128 for (unsigned I = 0; I != MaxTasks; ++I) {
129 if (Buff[I].empty())
130 continue;
131 if (Config->SaveTemps) {
132 if (I == 0)
133 saveBuffer(Buff[I], Config->OutputFile + ".lto.obj");
134 else
135 saveBuffer(Buff[I], Config->OutputFile + Twine(I) + ".lto.obj");
136 }
137 Ret.emplace_back(Buff[I].data(), Buff[I].size());
138 }
139 return Ret;
140}
deps/lld/COFF/LTO.h created+56
......@@ -0,0 +1,56 @@
1//===- LTO.h ----------------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file provides a way to combine bitcode files into one COFF
11// file by compiling them using LLVM.
12//
13// If LTO is in use, your input files are not in regular COFF files
14// but instead LLVM bitcode files. In that case, the linker has to
15// convert bitcode files into the native format so that we can create
16// a COFF file that contains native code. This file provides that
17// functionality.
18//
19//===----------------------------------------------------------------------===//
20
21#ifndef LLD_COFF_LTO_H
22#define LLD_COFF_LTO_H
23
24#include "lld/Core/LLVM.h"
25#include "llvm/ADT/SmallString.h"
26#include <memory>
27#include <vector>
28
29namespace llvm {
30namespace lto {
31class LTO;
32}
33}
34
35namespace lld {
36namespace coff {
37
38class BitcodeFile;
39class InputFile;
40
41class BitcodeCompiler {
42public:
43 BitcodeCompiler();
44 ~BitcodeCompiler();
45
46 void add(BitcodeFile &F);
47 std::vector<StringRef> compile();
48
49private:
50 std::unique_ptr<llvm::lto::LTO> LTOObj;
51 std::vector<SmallString<0>> Buff;
52};
53}
54}
55
56#endif
deps/lld/COFF/MapFile.cpp created+125
......@@ -0,0 +1,125 @@
1//===- MapFile.cpp --------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the /lldmap option. It shows lists in order and
11// hierarchically the output sections, input sections, input files and
12// symbol:
13//
14// Address Size Align Out File Symbol
15// 00201000 00000015 4 .text
16// 00201000 0000000e 4 test.o:(.text)
17// 0020100e 00000000 0 local
18// 00201005 00000000 0 f(int)
19//
20//===----------------------------------------------------------------------===//
21
22#include "MapFile.h"
23#include "Error.h"
24#include "SymbolTable.h"
25#include "Symbols.h"
26#include "Writer.h"
27
28#include "llvm/Support/Parallel.h"
29#include "llvm/Support/raw_ostream.h"
30
31using namespace llvm;
32using namespace llvm::object;
33
34using namespace lld;
35using namespace lld::coff;
36
37typedef DenseMap<const SectionChunk *, SmallVector<DefinedRegular *, 4>>
38 SymbolMapTy;
39
40// Print out the first three columns of a line.
41static void writeHeader(raw_ostream &OS, uint64_t Addr, uint64_t Size,
42 uint64_t Align) {
43 OS << format("%08llx %08llx %5lld ", Addr, Size, Align);
44}
45
46static std::string indent(int Depth) { return std::string(Depth * 8, ' '); }
47
48// Returns a list of all symbols that we want to print out.
49static std::vector<DefinedRegular *> getSymbols() {
50 std::vector<DefinedRegular *> V;
51 for (coff::ObjectFile *File : Symtab->ObjectFiles)
52 for (SymbolBody *B : File->getSymbols())
53 if (auto *Sym = dyn_cast<DefinedRegular>(B))
54 if (Sym && !Sym->getCOFFSymbol().isSectionDefinition())
55 V.push_back(Sym);
56 return V;
57}
58
59// Returns a map from sections to their symbols.
60static SymbolMapTy getSectionSyms(ArrayRef<DefinedRegular *> Syms) {
61 SymbolMapTy Ret;
62 for (DefinedRegular *S : Syms)
63 Ret[S->getChunk()].push_back(S);
64
65 // Sort symbols by address.
66 for (auto &It : Ret) {
67 SmallVectorImpl<DefinedRegular *> &V = It.second;
68 std::sort(V.begin(), V.end(), [](DefinedRegular *A, DefinedRegular *B) {
69 return A->getRVA() < B->getRVA();
70 });
71 }
72 return Ret;
73}
74
75// Construct a map from symbols to their stringified representations.
76static DenseMap<DefinedRegular *, std::string>
77getSymbolStrings(ArrayRef<DefinedRegular *> Syms) {
78 std::vector<std::string> Str(Syms.size());
79 for_each_n(parallel::par, (size_t)0, Syms.size(), [&](size_t I) {
80 raw_string_ostream OS(Str[I]);
81 writeHeader(OS, Syms[I]->getRVA(), 0, 0);
82 OS << indent(2) << toString(*Syms[I]);
83 });
84
85 DenseMap<DefinedRegular *, std::string> Ret;
86 for (size_t I = 0, E = Syms.size(); I < E; ++I)
87 Ret[Syms[I]] = std::move(Str[I]);
88 return Ret;
89}
90
91void coff::writeMapFile(ArrayRef<OutputSection *> OutputSections) {
92 if (Config->MapFile.empty())
93 return;
94
95 std::error_code EC;
96 raw_fd_ostream OS(Config->MapFile, EC, sys::fs::F_None);
97 if (EC)
98 fatal("cannot open " + Config->MapFile + ": " + EC.message());
99
100 // Collect symbol info that we want to print out.
101 std::vector<DefinedRegular *> Syms = getSymbols();
102 SymbolMapTy SectionSyms = getSectionSyms(Syms);
103 DenseMap<DefinedRegular *, std::string> SymStr = getSymbolStrings(Syms);
104
105 // Print out the header line.
106 OS << "Address Size Align Out In Symbol\n";
107
108 // Print out file contents.
109 for (OutputSection *Sec : OutputSections) {
110 writeHeader(OS, Sec->getRVA(), Sec->getVirtualSize(), /*Align=*/PageSize);
111 OS << Sec->getName() << '\n';
112
113 for (Chunk *C : Sec->getChunks()) {
114 auto *SC = dyn_cast<SectionChunk>(C);
115 if (!SC)
116 continue;
117
118 writeHeader(OS, SC->getRVA(), SC->getSize(), SC->getAlign());
119 OS << indent(1) << SC->File->getName() << ":(" << SC->getSectionName()
120 << ")\n";
121 for (DefinedRegular *Sym : SectionSyms[SC])
122 OS << SymStr[Sym] << '\n';
123 }
124 }
125}
deps/lld/COFF/MapFile.h created+22
......@@ -0,0 +1,22 @@
1//===- MapFile.h ------------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_COFF_MAPFILE_H
11#define LLD_COFF_MAPFILE_H
12
13#include "llvm/ADT/ArrayRef.h"
14
15namespace lld {
16namespace coff {
17class OutputSection;
18void writeMapFile(llvm::ArrayRef<OutputSection *> OutputSections);
19}
20}
21
22#endif
deps/lld/COFF/MarkLive.cpp created+75
......@@ -0,0 +1,75 @@
1//===- MarkLive.cpp -------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "Chunks.h"
11#include "Symbols.h"
12#include "llvm/ADT/STLExtras.h"
13#include <vector>
14
15namespace lld {
16namespace coff {
17
18// Set live bit on for each reachable chunk. Unmarked (unreachable)
19// COMDAT chunks will be ignored by Writer, so they will be excluded
20// from the final output.
21void markLive(const std::vector<Chunk *> &Chunks) {
22 // We build up a worklist of sections which have been marked as live. We only
23 // push into the worklist when we discover an unmarked section, and we mark
24 // as we push, so sections never appear twice in the list.
25 SmallVector<SectionChunk *, 256> Worklist;
26
27 // COMDAT section chunks are dead by default. Add non-COMDAT chunks.
28 for (Chunk *C : Chunks)
29 if (auto *SC = dyn_cast<SectionChunk>(C))
30 if (SC->isLive())
31 Worklist.push_back(SC);
32
33 auto Enqueue = [&](SectionChunk *C) {
34 if (C->isLive())
35 return;
36 C->markLive();
37 Worklist.push_back(C);
38 };
39
40 auto AddSym = [&](SymbolBody *B) {
41 if (auto *Sym = dyn_cast<DefinedRegular>(B))
42 Enqueue(Sym->getChunk());
43 else if (auto *Sym = dyn_cast<DefinedImportData>(B))
44 Sym->File->Live = true;
45 else if (auto *Sym = dyn_cast<DefinedImportThunk>(B))
46 Sym->WrappedSym->File->Live = true;
47 };
48
49 // Add GC root chunks.
50 for (SymbolBody *B : Config->GCRoot)
51 AddSym(B);
52
53 while (!Worklist.empty()) {
54 SectionChunk *SC = Worklist.pop_back_val();
55
56 // If this section was discarded, there are relocations referring to
57 // discarded sections. Ignore these sections to avoid crashing. They will be
58 // diagnosed during relocation processing.
59 if (SC->isDiscarded())
60 continue;
61
62 assert(SC->isLive() && "We mark as live when pushing onto the worklist!");
63
64 // Mark all symbols listed in the relocation table for this section.
65 for (SymbolBody *B : SC->symbols())
66 AddSym(B);
67
68 // Mark associative sections if any.
69 for (SectionChunk *C : SC->children())
70 Enqueue(C);
71 }
72}
73
74}
75}
deps/lld/COFF/Memory.h created+52
......@@ -0,0 +1,52 @@
1//===- Memory.h -------------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// See ELF/Memory.h
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLD_COFF_MEMORY_H
15#define LLD_COFF_MEMORY_H
16
17#include "llvm/Support/Allocator.h"
18#include "llvm/Support/StringSaver.h"
19#include <vector>
20
21namespace lld {
22namespace coff {
23
24extern llvm::BumpPtrAllocator BAlloc;
25extern llvm::StringSaver Saver;
26
27struct SpecificAllocBase {
28 SpecificAllocBase() { Instances.push_back(this); }
29 virtual ~SpecificAllocBase() = default;
30 virtual void reset() = 0;
31 static std::vector<SpecificAllocBase *> Instances;
32};
33
34template <class T> struct SpecificAlloc : public SpecificAllocBase {
35 void reset() override { Alloc.DestroyAll(); }
36 llvm::SpecificBumpPtrAllocator<T> Alloc;
37};
38
39template <typename T, typename... U> T *make(U &&... Args) {
40 static SpecificAlloc<T> Alloc;
41 return new (Alloc.Alloc.Allocate()) T(std::forward<U>(Args)...);
42}
43
44inline void freeArena() {
45 for (SpecificAllocBase *Alloc : SpecificAllocBase::Instances)
46 Alloc->reset();
47 BAlloc.Reset();
48}
49}
50}
51
52#endif
deps/lld/COFF/Options.td created+139
......@@ -0,0 +1,139 @@
1include "llvm/Option/OptParser.td"
2
3// link.exe accepts options starting with either a dash or a slash.
4
5// Flag that takes no arguments.
6class F<string name> : Flag<["/", "-", "-?"], name>;
7
8// Flag that takes one argument after ":".
9class P<string name, string help> :
10 Joined<["/", "-", "-?"], name#":">, HelpText<help>;
11
12// Boolean flag suffixed by ":no".
13multiclass B<string name, string help> {
14 def "" : F<name>;
15 def _no : F<name#":no">, HelpText<help>;
16}
17
18def align : P<"align", "Section alignment">;
19def alternatename : P<"alternatename", "Define weak alias">;
20def base : P<"base", "Base address of the program">;
21def defaultlib : P<"defaultlib", "Add the library to the list of input files">;
22def delayload : P<"delayload", "Delay loaded DLL name">;
23def entry : P<"entry", "Name of entry point symbol">;
24def errorlimit : P<"errorlimit",
25 "Maximum number of errors to emit before stopping (0 = no limit)">;
26def export : P<"export", "Export a function">;
27// No help text because /failifmismatch is not intended to be used by the user.
28def failifmismatch : P<"failifmismatch", "">;
29def heap : P<"heap", "Size of the heap">;
30def implib : P<"implib", "Import library name">;
31def libpath : P<"libpath", "Additional library search path">;
32def linkrepro : P<"linkrepro", "Dump linker invocation and input files for debugging">;
33def lldsavetemps : F<"lldsavetemps">,
34 HelpText<"Save temporary files instead of deleting them">;
35def machine : P<"machine", "Specify target platform">;
36def merge : P<"merge", "Combine sections">;
37def mllvm : P<"mllvm", "Options to pass to LLVM">;
38def nodefaultlib : P<"nodefaultlib", "Remove a default library">;
39def opt : P<"opt", "Control optimizations">;
40def out : P<"out", "Path to file to write output">;
41def pdb : P<"pdb", "PDB file path">;
42def section : P<"section", "Specify section attributes">;
43def stack : P<"stack", "Size of the stack">;
44def stub : P<"stub", "Specify DOS stub file">;
45def subsystem : P<"subsystem", "Specify subsystem">;
46def version : P<"version", "Specify a version number in the PE header">;
47
48def disallowlib : Joined<["/", "-", "-?"], "disallowlib:">, Alias<nodefaultlib>;
49
50def manifest : F<"manifest">;
51def manifest_colon : P<"manifest", "Create manifest file">;
52def manifestuac : P<"manifestuac", "User access control">;
53def manifestfile : P<"manifestfile", "Manifest file path">;
54def manifestdependency : P<"manifestdependency",
55 "Attributes for <dependency> in manifest file">;
56def manifestinput : P<"manifestinput", "Specify manifest file">;
57
58// We cannot use multiclass P because class name "incl" is different
59// from its command line option name. We do this because "include" is
60// a reserved keyword in tablegen.
61def incl : Joined<["/", "-"], "include:">,
62 HelpText<"Force symbol to be added to symbol table as undefined one">;
63
64// "def" is also a keyword.
65def deffile : Joined<["/", "-"], "def:">,
66 HelpText<"Use module-definition file">;
67
68def debug : F<"debug">, HelpText<"Embed a symbol table in the image">;
69def debugtype : P<"debugtype", "Debug Info Options">;
70def dll : F<"dll">, HelpText<"Create a DLL">;
71def driver : P<"driver", "Generate a Windows NT Kernel Mode Driver">;
72def nodefaultlib_all : F<"nodefaultlib">;
73def noentry : F<"noentry">;
74def profile : F<"profile">;
75def swaprun_cd : F<"swaprun:cd">;
76def swaprun_net : F<"swaprun:net">;
77def verbose : F<"verbose">;
78
79def force : F<"force">,
80 HelpText<"Allow undefined symbols when creating executables">;
81def force_unresolved : F<"force:unresolved">;
82
83defm allowbind: B<"allowbind", "Disable DLL binding">;
84defm allowisolation : B<"allowisolation", "Set NO_ISOLATION bit">;
85defm appcontainer : B<"appcontainer",
86 "Image can only be run in an app container">;
87defm dynamicbase : B<"dynamicbase",
88 "Disable address space layout randomization">;
89defm fixed : B<"fixed", "Enable base relocations">;
90defm highentropyva : B<"highentropyva", "Set HIGH_ENTROPY_VA bit">;
91defm largeaddressaware : B<"largeaddressaware", "Disable large addresses">;
92defm nxcompat : B<"nxcompat", "Disable data execution provention">;
93defm safeseh : B<"safeseh", "Produce an image with Safe Exception Handler">;
94defm tsaware : B<"tsaware", "Create non-Terminal Server aware executable">;
95
96def help : F<"help">;
97def help_q : Flag<["/?", "-?"], "">, Alias<help>;
98
99// LLD extensions
100def nopdb : F<"nopdb">, HelpText<"Disable PDB generation for DWARF users">;
101def nosymtab : F<"nosymtab">;
102def msvclto : F<"msvclto">;
103
104// Flags for debugging
105def lldmap : F<"lldmap">;
106def lldmap_file : Joined<["/", "-"], "lldmap:">;
107
108//==============================================================================
109// The flags below do nothing. They are defined only for link.exe compatibility.
110//==============================================================================
111
112class QF<string name> : Joined<["/", "-", "-?"], name#":">;
113
114multiclass QB<string name> {
115 def "" : F<name>;
116 def _no : F<name#":no">;
117}
118
119def functionpadmin : F<"functionpadmin">;
120def ignoreidl : F<"ignoreidl">;
121def incremental : F<"incremental">;
122def no_incremental : F<"incremental:no">;
123def nologo : F<"nologo">;
124def throwingnew : F<"throwingnew">;
125def editandcontinue : F<"editandcontinue">;
126def fastfail : F<"fastfail">;
127
128def delay : QF<"delay">;
129def errorreport : QF<"errorreport">;
130def idlout : QF<"idlout">;
131def ignore : QF<"ignore">;
132def maxilksize : QF<"maxilksize">;
133def pdbaltpath : QF<"pdbaltpath">;
134def tlbid : QF<"tlbid">;
135def tlbout : QF<"tlbout">;
136def verbose_all : QF<"verbose">;
137def guardsym : QF<"guardsym">;
138
139defm wx : QB<"wx">;
deps/lld/COFF/PDB.cpp created+672
......@@ -0,0 +1,672 @@
1//===- PDB.cpp ------------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "PDB.h"
11#include "Chunks.h"
12#include "Config.h"
13#include "Error.h"
14#include "SymbolTable.h"
15#include "Symbols.h"
16#include "llvm/DebugInfo/CodeView/CVDebugRecord.h"
17#include "llvm/DebugInfo/CodeView/DebugSubsectionRecord.h"
18#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
19#include "llvm/DebugInfo/CodeView/SymbolSerializer.h"
20#include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
21#include "llvm/DebugInfo/CodeView/TypeDumpVisitor.h"
22#include "llvm/DebugInfo/CodeView/TypeIndexDiscovery.h"
23#include "llvm/DebugInfo/CodeView/TypeStreamMerger.h"
24#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
25#include "llvm/DebugInfo/MSF/MSFBuilder.h"
26#include "llvm/DebugInfo/MSF/MSFCommon.h"
27#include "llvm/DebugInfo/PDB/GenericError.h"
28#include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptorBuilder.h"
29#include "llvm/DebugInfo/PDB/Native/DbiStream.h"
30#include "llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h"
31#include "llvm/DebugInfo/PDB/Native/InfoStream.h"
32#include "llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h"
33#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
34#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
35#include "llvm/DebugInfo/PDB/Native/PDBFileBuilder.h"
36#include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h"
37#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
38#include "llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h"
39#include "llvm/DebugInfo/PDB/PDB.h"
40#include "llvm/Object/COFF.h"
41#include "llvm/Support/BinaryByteStream.h"
42#include "llvm/Support/Endian.h"
43#include "llvm/Support/FileOutputBuffer.h"
44#include "llvm/Support/Path.h"
45#include "llvm/Support/ScopedPrinter.h"
46#include <memory>
47
48using namespace lld;
49using namespace lld::coff;
50using namespace llvm;
51using namespace llvm::codeview;
52
53using llvm::object::coff_section;
54
55static ExitOnError ExitOnErr;
56
57namespace {
58/// Map from type index and item index in a type server PDB to the
59/// corresponding index in the destination PDB.
60struct CVIndexMap {
61 SmallVector<TypeIndex, 0> TPIMap;
62 SmallVector<TypeIndex, 0> IPIMap;
63 bool IsTypeServerMap = false;
64};
65
66class PDBLinker {
67public:
68 PDBLinker(SymbolTable *Symtab)
69 : Alloc(), Symtab(Symtab), Builder(Alloc), TypeTable(Alloc),
70 IDTable(Alloc) {}
71
72 /// Emit the basic PDB structure: initial streams, headers, etc.
73 void initialize(const llvm::codeview::DebugInfo *DI);
74
75 /// Link CodeView from each object file in the symbol table into the PDB.
76 void addObjectsToPDB();
77
78 /// Link CodeView from a single object file into the PDB.
79 void addObjectFile(ObjectFile *File);
80
81 /// Produce a mapping from the type and item indices used in the object
82 /// file to those in the destination PDB.
83 ///
84 /// If the object file uses a type server PDB (compiled with /Zi), merge TPI
85 /// and IPI from the type server PDB and return a map for it. Each unique type
86 /// server PDB is merged at most once, so this may return an existing index
87 /// mapping.
88 ///
89 /// If the object does not use a type server PDB (compiled with /Z7), we merge
90 /// all the type and item records from the .debug$S stream and fill in the
91 /// caller-provided ObjectIndexMap.
92 const CVIndexMap &mergeDebugT(ObjectFile *File, CVIndexMap &ObjectIndexMap);
93
94 const CVIndexMap &maybeMergeTypeServerPDB(ObjectFile *File,
95 TypeServer2Record &TS);
96
97 /// Add the section map and section contributions to the PDB.
98 void addSections(ArrayRef<uint8_t> SectionTable);
99
100 /// Write the PDB to disk.
101 void commit();
102
103private:
104 BumpPtrAllocator Alloc;
105
106 SymbolTable *Symtab;
107
108 pdb::PDBFileBuilder Builder;
109
110 /// Type records that will go into the PDB TPI stream.
111 TypeTableBuilder TypeTable;
112
113 /// Item records that will go into the PDB IPI stream.
114 TypeTableBuilder IDTable;
115
116 /// PDBs use a single global string table for filenames in the file checksum
117 /// table.
118 DebugStringTableSubsection PDBStrTab;
119
120 llvm::SmallString<128> NativePath;
121
122 std::vector<pdb::SecMapEntry> SectionMap;
123
124 /// Type index mappings of type server PDBs that we've loaded so far.
125 std::map<GUID, CVIndexMap> TypeServerIndexMappings;
126};
127}
128
129// Returns a list of all SectionChunks.
130static void addSectionContribs(SymbolTable *Symtab,
131 pdb::DbiStreamBuilder &DbiBuilder) {
132 for (Chunk *C : Symtab->getChunks())
133 if (auto *SC = dyn_cast<SectionChunk>(C))
134 DbiBuilder.addSectionContrib(SC->File->ModuleDBI, SC->Header);
135}
136
137static SectionChunk *findByName(std::vector<SectionChunk *> &Sections,
138 StringRef Name) {
139 for (SectionChunk *C : Sections)
140 if (C->getSectionName() == Name)
141 return C;
142 return nullptr;
143}
144
145static ArrayRef<uint8_t> consumeDebugMagic(ArrayRef<uint8_t> Data,
146 StringRef SecName) {
147 // First 4 bytes are section magic.
148 if (Data.size() < 4)
149 fatal(SecName + " too short");
150 if (support::endian::read32le(Data.data()) != COFF::DEBUG_SECTION_MAGIC)
151 fatal(SecName + " has an invalid magic");
152 return Data.slice(4);
153}
154
155static ArrayRef<uint8_t> getDebugSection(ObjectFile *File, StringRef SecName) {
156 if (SectionChunk *Sec = findByName(File->getDebugChunks(), SecName))
157 return consumeDebugMagic(Sec->getContents(), SecName);
158 return {};
159}
160
161static void addTypeInfo(pdb::TpiStreamBuilder &TpiBuilder,
162 TypeTableBuilder &TypeTable) {
163 // Start the TPI or IPI stream header.
164 TpiBuilder.setVersionHeader(pdb::PdbTpiV80);
165
166 // Flatten the in memory type table.
167 TypeTable.ForEachRecord([&](TypeIndex TI, ArrayRef<uint8_t> Rec) {
168 // FIXME: Hash types.
169 TpiBuilder.addTypeRecord(Rec, None);
170 });
171}
172
173static Optional<TypeServer2Record>
174maybeReadTypeServerRecord(CVTypeArray &Types) {
175 auto I = Types.begin();
176 if (I == Types.end())
177 return None;
178 const CVType &Type = *I;
179 if (Type.kind() != LF_TYPESERVER2)
180 return None;
181 TypeServer2Record TS;
182 if (auto EC = TypeDeserializer::deserializeAs(const_cast<CVType &>(Type), TS))
183 fatal(EC, "error reading type server record");
184 return std::move(TS);
185}
186
187const CVIndexMap &PDBLinker::mergeDebugT(ObjectFile *File,
188 CVIndexMap &ObjectIndexMap) {
189 ArrayRef<uint8_t> Data = getDebugSection(File, ".debug$T");
190 if (Data.empty())
191 return ObjectIndexMap;
192
193 BinaryByteStream Stream(Data, support::little);
194 CVTypeArray Types;
195 BinaryStreamReader Reader(Stream);
196 if (auto EC = Reader.readArray(Types, Reader.getLength()))
197 fatal(EC, "Reader::readArray failed");
198
199 // Look through type servers. If we've already seen this type server, don't
200 // merge any type information.
201 if (Optional<TypeServer2Record> TS = maybeReadTypeServerRecord(Types))
202 return maybeMergeTypeServerPDB(File, *TS);
203
204 // This is a /Z7 object. Fill in the temporary, caller-provided
205 // ObjectIndexMap.
206 if (auto Err = mergeTypeAndIdRecords(IDTable, TypeTable,
207 ObjectIndexMap.TPIMap, Types))
208 fatal(Err, "codeview::mergeTypeAndIdRecords failed");
209 return ObjectIndexMap;
210}
211
212static Expected<std::unique_ptr<pdb::NativeSession>>
213tryToLoadPDB(const GUID &GuidFromObj, StringRef TSPath) {
214 std::unique_ptr<pdb::IPDBSession> ThisSession;
215 if (auto EC =
216 pdb::loadDataForPDB(pdb::PDB_ReaderType::Native, TSPath, ThisSession))
217 return std::move(EC);
218
219 std::unique_ptr<pdb::NativeSession> NS(
220 static_cast<pdb::NativeSession *>(ThisSession.release()));
221 pdb::PDBFile &File = NS->getPDBFile();
222 auto ExpectedInfo = File.getPDBInfoStream();
223 // All PDB Files should have an Info stream.
224 if (!ExpectedInfo)
225 return ExpectedInfo.takeError();
226
227 // Just because a file with a matching name was found and it was an actual
228 // PDB file doesn't mean it matches. For it to match the InfoStream's GUID
229 // must match the GUID specified in the TypeServer2 record.
230 if (ExpectedInfo->getGuid() != GuidFromObj)
231 return make_error<pdb::GenericError>(
232 pdb::generic_error_code::type_server_not_found, TSPath);
233
234 return std::move(NS);
235}
236
237const CVIndexMap &PDBLinker::maybeMergeTypeServerPDB(ObjectFile *File,
238 TypeServer2Record &TS) {
239 // First, check if we already loaded a PDB with this GUID. Return the type
240 // index mapping if we have it.
241 auto Insertion = TypeServerIndexMappings.insert({TS.getGuid(), CVIndexMap()});
242 CVIndexMap &IndexMap = Insertion.first->second;
243 if (!Insertion.second)
244 return IndexMap;
245
246 // Mark this map as a type server map.
247 IndexMap.IsTypeServerMap = true;
248
249 // Check for a PDB at:
250 // 1. The given file path
251 // 2. Next to the object file or archive file
252 auto ExpectedSession = tryToLoadPDB(TS.getGuid(), TS.getName());
253 if (!ExpectedSession) {
254 consumeError(ExpectedSession.takeError());
255 StringRef LocalPath =
256 !File->ParentName.empty() ? File->ParentName : File->getName();
257 SmallString<128> Path = sys::path::parent_path(LocalPath);
258 sys::path::append(
259 Path, sys::path::filename(TS.getName(), sys::path::Style::windows));
260 ExpectedSession = tryToLoadPDB(TS.getGuid(), Path);
261 }
262 if (auto E = ExpectedSession.takeError())
263 fatal(E, "Type server PDB was not found");
264
265 // Merge TPI first, because the IPI stream will reference type indices.
266 auto ExpectedTpi = (*ExpectedSession)->getPDBFile().getPDBTpiStream();
267 if (auto E = ExpectedTpi.takeError())
268 fatal(E, "Type server does not have TPI stream");
269 if (auto Err = mergeTypeRecords(TypeTable, IndexMap.TPIMap,
270 ExpectedTpi->typeArray()))
271 fatal(Err, "codeview::mergeTypeRecords failed");
272
273 // Merge IPI.
274 auto ExpectedIpi = (*ExpectedSession)->getPDBFile().getPDBIpiStream();
275 if (auto E = ExpectedIpi.takeError())
276 fatal(E, "Type server does not have TPI stream");
277 if (auto Err = mergeIdRecords(IDTable, IndexMap.TPIMap, IndexMap.IPIMap,
278 ExpectedIpi->typeArray()))
279 fatal(Err, "codeview::mergeIdRecords failed");
280
281 return IndexMap;
282}
283
284static bool remapTypeIndex(TypeIndex &TI, ArrayRef<TypeIndex> TypeIndexMap) {
285 if (TI.isSimple())
286 return true;
287 if (TI.toArrayIndex() >= TypeIndexMap.size())
288 return false;
289 TI = TypeIndexMap[TI.toArrayIndex()];
290 return true;
291}
292
293static void remapTypesInSymbolRecord(ObjectFile *File,
294 MutableArrayRef<uint8_t> Contents,
295 const CVIndexMap &IndexMap,
296 ArrayRef<TiReference> TypeRefs) {
297 for (const TiReference &Ref : TypeRefs) {
298 unsigned ByteSize = Ref.Count * sizeof(TypeIndex);
299 if (Contents.size() < Ref.Offset + ByteSize)
300 fatal("symbol record too short");
301
302 // This can be an item index or a type index. Choose the appropriate map.
303 ArrayRef<TypeIndex> TypeOrItemMap = IndexMap.TPIMap;
304 if (Ref.Kind == TiRefKind::IndexRef && IndexMap.IsTypeServerMap)
305 TypeOrItemMap = IndexMap.IPIMap;
306
307 MutableArrayRef<TypeIndex> TIs(
308 reinterpret_cast<TypeIndex *>(Contents.data() + Ref.Offset), Ref.Count);
309 for (TypeIndex &TI : TIs) {
310 if (!remapTypeIndex(TI, TypeOrItemMap)) {
311 TI = TypeIndex(SimpleTypeKind::NotTranslated);
312 log("ignoring symbol record in " + File->getName() +
313 " with bad type index 0x" + utohexstr(TI.getIndex()));
314 continue;
315 }
316 }
317 }
318}
319
320/// MSVC translates S_PROC_ID_END to S_END.
321uint16_t canonicalizeSymbolKind(SymbolKind Kind) {
322 if (Kind == SymbolKind::S_PROC_ID_END)
323 return SymbolKind::S_END;
324 return Kind;
325}
326
327/// Copy the symbol record. In a PDB, symbol records must be 4 byte aligned.
328/// The object file may not be aligned.
329static MutableArrayRef<uint8_t> copySymbolForPdb(const CVSymbol &Sym,
330 BumpPtrAllocator &Alloc) {
331 size_t Size = alignTo(Sym.length(), alignOf(CodeViewContainer::Pdb));
332 assert(Size >= 4 && "record too short");
333 assert(Size <= MaxRecordLength && "record too long");
334 void *Mem = Alloc.Allocate(Size, 4);
335
336 // Copy the symbol record and zero out any padding bytes.
337 MutableArrayRef<uint8_t> NewData(reinterpret_cast<uint8_t *>(Mem), Size);
338 memcpy(NewData.data(), Sym.data().data(), Sym.length());
339 memset(NewData.data() + Sym.length(), 0, Size - Sym.length());
340
341 // Update the record prefix length. It should point to the beginning of the
342 // next record. MSVC does some canonicalization of the record kind, so we do
343 // that as well.
344 auto *Prefix = reinterpret_cast<RecordPrefix *>(Mem);
345 Prefix->RecordKind = canonicalizeSymbolKind(Sym.kind());
346 Prefix->RecordLen = Size - 2;
347 return NewData;
348}
349
350/// Return true if this symbol opens a scope. This implies that the symbol has
351/// "parent" and "end" fields, which contain the offset of the S_END or
352/// S_INLINESITE_END record.
353static bool symbolOpensScope(SymbolKind Kind) {
354 switch (Kind) {
355 case SymbolKind::S_GPROC32:
356 case SymbolKind::S_LPROC32:
357 case SymbolKind::S_LPROC32_ID:
358 case SymbolKind::S_GPROC32_ID:
359 case SymbolKind::S_BLOCK32:
360 case SymbolKind::S_SEPCODE:
361 case SymbolKind::S_THUNK32:
362 case SymbolKind::S_INLINESITE:
363 case SymbolKind::S_INLINESITE2:
364 return true;
365 default:
366 break;
367 }
368 return false;
369}
370
371static bool symbolEndsScope(SymbolKind Kind) {
372 switch (Kind) {
373 case SymbolKind::S_END:
374 case SymbolKind::S_PROC_ID_END:
375 case SymbolKind::S_INLINESITE_END:
376 return true;
377 default:
378 break;
379 }
380 return false;
381}
382
383struct ScopeRecord {
384 ulittle32_t PtrParent;
385 ulittle32_t PtrEnd;
386};
387
388struct SymbolScope {
389 ScopeRecord *OpeningRecord;
390 uint32_t ScopeOffset;
391};
392
393static void scopeStackOpen(SmallVectorImpl<SymbolScope> &Stack,
394 uint32_t CurOffset, CVSymbol &Sym) {
395 assert(symbolOpensScope(Sym.kind()));
396 SymbolScope S;
397 S.ScopeOffset = CurOffset;
398 S.OpeningRecord = const_cast<ScopeRecord *>(
399 reinterpret_cast<const ScopeRecord *>(Sym.content().data()));
400 S.OpeningRecord->PtrParent = Stack.empty() ? 0 : Stack.back().ScopeOffset;
401 Stack.push_back(S);
402}
403
404static void scopeStackClose(SmallVectorImpl<SymbolScope> &Stack,
405 uint32_t CurOffset, ObjectFile *File) {
406 if (Stack.empty()) {
407 warn("symbol scopes are not balanced in " + File->getName());
408 return;
409 }
410 SymbolScope S = Stack.pop_back_val();
411 S.OpeningRecord->PtrEnd = CurOffset;
412}
413
414static void mergeSymbolRecords(BumpPtrAllocator &Alloc, ObjectFile *File,
415 const CVIndexMap &IndexMap,
416 BinaryStreamRef SymData) {
417 // FIXME: Improve error recovery by warning and skipping records when
418 // possible.
419 CVSymbolArray Syms;
420 BinaryStreamReader Reader(SymData);
421 ExitOnErr(Reader.readArray(Syms, Reader.getLength()));
422 SmallVector<SymbolScope, 4> Scopes;
423 for (const CVSymbol &Sym : Syms) {
424 // Discover type index references in the record. Skip it if we don't know
425 // where they are.
426 SmallVector<TiReference, 32> TypeRefs;
427 if (!discoverTypeIndices(Sym, TypeRefs)) {
428 log("ignoring unknown symbol record with kind 0x" + utohexstr(Sym.kind()));
429 continue;
430 }
431
432 // Copy the symbol record so we can mutate it.
433 MutableArrayRef<uint8_t> NewData = copySymbolForPdb(Sym, Alloc);
434
435 // Re-map all the type index references.
436 MutableArrayRef<uint8_t> Contents =
437 NewData.drop_front(sizeof(RecordPrefix));
438 remapTypesInSymbolRecord(File, Contents, IndexMap, TypeRefs);
439
440 // Fill in "Parent" and "End" fields by maintaining a stack of scopes.
441 CVSymbol NewSym(Sym.kind(), NewData);
442 if (symbolOpensScope(Sym.kind()))
443 scopeStackOpen(Scopes, File->ModuleDBI->getNextSymbolOffset(), NewSym);
444 else if (symbolEndsScope(Sym.kind()))
445 scopeStackClose(Scopes, File->ModuleDBI->getNextSymbolOffset(), File);
446
447 // Add the symbol to the module.
448 File->ModuleDBI->addSymbol(NewSym);
449 }
450}
451
452// Allocate memory for a .debug$S section and relocate it.
453static ArrayRef<uint8_t> relocateDebugChunk(BumpPtrAllocator &Alloc,
454 SectionChunk *DebugChunk) {
455 uint8_t *Buffer = Alloc.Allocate<uint8_t>(DebugChunk->getSize());
456 assert(DebugChunk->OutputSectionOff == 0 &&
457 "debug sections should not be in output sections");
458 DebugChunk->writeTo(Buffer);
459 return consumeDebugMagic(makeArrayRef(Buffer, DebugChunk->getSize()),
460 ".debug$S");
461}
462
463void PDBLinker::addObjectFile(ObjectFile *File) {
464 // Add a module descriptor for every object file. We need to put an absolute
465 // path to the object into the PDB. If this is a plain object, we make its
466 // path absolute. If it's an object in an archive, we make the archive path
467 // absolute.
468 bool InArchive = !File->ParentName.empty();
469 SmallString<128> Path = InArchive ? File->ParentName : File->getName();
470 sys::fs::make_absolute(Path);
471 sys::path::native(Path, sys::path::Style::windows);
472 StringRef Name = InArchive ? File->getName() : StringRef(Path);
473
474 File->ModuleDBI = &ExitOnErr(Builder.getDbiBuilder().addModuleInfo(Name));
475 File->ModuleDBI->setObjFileName(Path);
476
477 // Before we can process symbol substreams from .debug$S, we need to process
478 // type information, file checksums, and the string table. Add type info to
479 // the PDB first, so that we can get the map from object file type and item
480 // indices to PDB type and item indices.
481 CVIndexMap ObjectIndexMap;
482 const CVIndexMap &IndexMap = mergeDebugT(File, ObjectIndexMap);
483
484 // Now do all live .debug$S sections.
485 for (SectionChunk *DebugChunk : File->getDebugChunks()) {
486 if (!DebugChunk->isLive() || DebugChunk->getSectionName() != ".debug$S")
487 continue;
488
489 ArrayRef<uint8_t> RelocatedDebugContents =
490 relocateDebugChunk(Alloc, DebugChunk);
491 if (RelocatedDebugContents.empty())
492 continue;
493
494 DebugSubsectionArray Subsections;
495 BinaryStreamReader Reader(RelocatedDebugContents, support::little);
496 ExitOnErr(Reader.readArray(Subsections, RelocatedDebugContents.size()));
497
498 DebugStringTableSubsectionRef CVStrTab;
499 DebugChecksumsSubsectionRef Checksums;
500 for (const DebugSubsectionRecord &SS : Subsections) {
501 switch (SS.kind()) {
502 case DebugSubsectionKind::StringTable:
503 ExitOnErr(CVStrTab.initialize(SS.getRecordData()));
504 break;
505 case DebugSubsectionKind::FileChecksums:
506 ExitOnErr(Checksums.initialize(SS.getRecordData()));
507 break;
508 case DebugSubsectionKind::Lines:
509 // We can add the relocated line table directly to the PDB without
510 // modification because the file checksum offsets will stay the same.
511 File->ModuleDBI->addDebugSubsection(SS);
512 break;
513 case DebugSubsectionKind::Symbols:
514 mergeSymbolRecords(Alloc, File, IndexMap, SS.getRecordData());
515 break;
516 default:
517 // FIXME: Process the rest of the subsections.
518 break;
519 }
520 }
521
522 if (Checksums.valid()) {
523 // Make a new file checksum table that refers to offsets in the PDB-wide
524 // string table. Generally the string table subsection appears after the
525 // checksum table, so we have to do this after looping over all the
526 // subsections.
527 if (!CVStrTab.valid())
528 fatal(".debug$S sections must have both a string table subsection "
529 "and a checksum subsection table or neither");
530 auto NewChecksums = make_unique<DebugChecksumsSubsection>(PDBStrTab);
531 for (FileChecksumEntry &FC : Checksums) {
532 StringRef FileName = ExitOnErr(CVStrTab.getString(FC.FileNameOffset));
533 ExitOnErr(Builder.getDbiBuilder().addModuleSourceFile(*File->ModuleDBI,
534 FileName));
535 NewChecksums->addChecksum(FileName, FC.Kind, FC.Checksum);
536 }
537 File->ModuleDBI->addDebugSubsection(std::move(NewChecksums));
538 }
539 }
540}
541
542// Add all object files to the PDB. Merge .debug$T sections into IpiData and
543// TpiData.
544void PDBLinker::addObjectsToPDB() {
545 for (ObjectFile *File : Symtab->ObjectFiles)
546 addObjectFile(File);
547
548 Builder.getStringTableBuilder().setStrings(PDBStrTab);
549
550 // Construct TPI stream contents.
551 addTypeInfo(Builder.getTpiBuilder(), TypeTable);
552
553 // Construct IPI stream contents.
554 addTypeInfo(Builder.getIpiBuilder(), IDTable);
555
556 // Add public and symbol records stream.
557
558 // For now we don't actually write any thing useful to the publics stream, but
559 // the act of "getting" it also creates it lazily so that we write an empty
560 // stream.
561 (void)Builder.getPublicsBuilder();
562}
563
564static void addLinkerModuleSymbols(StringRef Path,
565 pdb::DbiModuleDescriptorBuilder &Mod,
566 BumpPtrAllocator &Allocator) {
567 codeview::SymbolSerializer Serializer(Allocator, CodeViewContainer::Pdb);
568 codeview::ObjNameSym ONS(SymbolRecordKind::ObjNameSym);
569 codeview::Compile3Sym CS(SymbolRecordKind::Compile3Sym);
570 codeview::EnvBlockSym EBS(SymbolRecordKind::EnvBlockSym);
571
572 ONS.Name = "* Linker *";
573 ONS.Signature = 0;
574
575 CS.Machine = Config->is64() ? CPUType::X64 : CPUType::Intel80386;
576 CS.Flags = CompileSym3Flags::None;
577 CS.VersionBackendBuild = 0;
578 CS.VersionBackendMajor = 0;
579 CS.VersionBackendMinor = 0;
580 CS.VersionBackendQFE = 0;
581 CS.VersionFrontendBuild = 0;
582 CS.VersionFrontendMajor = 0;
583 CS.VersionFrontendMinor = 0;
584 CS.VersionFrontendQFE = 0;
585 CS.Version = "LLVM Linker";
586 CS.setLanguage(SourceLanguage::Link);
587
588 ArrayRef<StringRef> Args = makeArrayRef(Config->Argv).drop_front();
589 std::string ArgStr = llvm::join(Args, " ");
590 EBS.Fields.push_back("cwd");
591 SmallString<64> cwd;
592 sys::fs::current_path(cwd);
593 EBS.Fields.push_back(cwd);
594 EBS.Fields.push_back("exe");
595 EBS.Fields.push_back(Config->Argv[0]);
596 EBS.Fields.push_back("pdb");
597 EBS.Fields.push_back(Path);
598 EBS.Fields.push_back("cmd");
599 EBS.Fields.push_back(ArgStr);
600 Mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol(
601 ONS, Allocator, CodeViewContainer::Pdb));
602 Mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol(
603 CS, Allocator, CodeViewContainer::Pdb));
604 Mod.addSymbol(codeview::SymbolSerializer::writeOneSymbol(
605 EBS, Allocator, CodeViewContainer::Pdb));
606}
607
608// Creates a PDB file.
609void coff::createPDB(SymbolTable *Symtab, ArrayRef<uint8_t> SectionTable,
610 const llvm::codeview::DebugInfo *DI) {
611 PDBLinker PDB(Symtab);
612 PDB.initialize(DI);
613 PDB.addObjectsToPDB();
614 PDB.addSections(SectionTable);
615 PDB.commit();
616}
617
618void PDBLinker::initialize(const llvm::codeview::DebugInfo *DI) {
619 ExitOnErr(Builder.initialize(4096)); // 4096 is blocksize
620
621 // Create streams in MSF for predefined streams, namely
622 // PDB, TPI, DBI and IPI.
623 for (int I = 0; I < (int)pdb::kSpecialStreamCount; ++I)
624 ExitOnErr(Builder.getMsfBuilder().addStream(0));
625
626 // Add an Info stream.
627 auto &InfoBuilder = Builder.getInfoBuilder();
628 InfoBuilder.setAge(DI ? DI->PDB70.Age : 0);
629
630 GUID uuid{};
631 if (DI)
632 memcpy(&uuid, &DI->PDB70.Signature, sizeof(uuid));
633 InfoBuilder.setGuid(uuid);
634 InfoBuilder.setSignature(time(nullptr));
635 InfoBuilder.setVersion(pdb::PdbRaw_ImplVer::PdbImplVC70);
636
637 // Add an empty DBI stream.
638 pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder();
639 DbiBuilder.setVersionHeader(pdb::PdbDbiV70);
640 ExitOnErr(DbiBuilder.addDbgStream(pdb::DbgHeaderType::NewFPO, {}));
641}
642
643void PDBLinker::addSections(ArrayRef<uint8_t> SectionTable) {
644 // Add Section Contributions.
645 pdb::DbiStreamBuilder &DbiBuilder = Builder.getDbiBuilder();
646 addSectionContribs(Symtab, DbiBuilder);
647
648 // Add Section Map stream.
649 ArrayRef<object::coff_section> Sections = {
650 (const object::coff_section *)SectionTable.data(),
651 SectionTable.size() / sizeof(object::coff_section)};
652 SectionMap = pdb::DbiStreamBuilder::createSectionMap(Sections);
653 DbiBuilder.setSectionMap(SectionMap);
654
655 // It's not entirely clear what this is, but the * Linker * module uses it.
656 NativePath = Config->PDBPath;
657 sys::fs::make_absolute(NativePath);
658 sys::path::native(NativePath, sys::path::Style::windows);
659 uint32_t PdbFilePathNI = DbiBuilder.addECName(NativePath);
660 auto &LinkerModule = ExitOnErr(DbiBuilder.addModuleInfo("* Linker *"));
661 LinkerModule.setPdbFilePathNI(PdbFilePathNI);
662 addLinkerModuleSymbols(NativePath, LinkerModule, Alloc);
663
664 // Add COFF section header stream.
665 ExitOnErr(
666 DbiBuilder.addDbgStream(pdb::DbgHeaderType::SectionHdr, SectionTable));
667}
668
669void PDBLinker::commit() {
670 // Write to a file.
671 ExitOnErr(Builder.commit(Config->PDBPath));
672}
deps/lld/COFF/PDB.h created+31
......@@ -0,0 +1,31 @@
1//===- PDB.h ----------------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_COFF_PDB_H
11#define LLD_COFF_PDB_H
12
13#include "llvm/ADT/ArrayRef.h"
14#include "llvm/ADT/StringRef.h"
15
16namespace llvm {
17namespace codeview {
18union DebugInfo;
19}
20}
21
22namespace lld {
23namespace coff {
24class SymbolTable;
25
26void createPDB(SymbolTable *Symtab, llvm::ArrayRef<uint8_t> SectionTable,
27 const llvm::codeview::DebugInfo *DI);
28}
29}
30
31#endif
deps/lld/COFF/README.md created+1
......@@ -0,0 +1 @@
1See docs/NewLLD.rst
deps/lld/COFF/Strings.cpp created+35
......@@ -0,0 +1,35 @@
1//===- Strings.cpp -------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "Strings.h"
11#include <mutex>
12
13#if defined(_MSC_VER)
14#include <Windows.h>
15#include <DbgHelp.h>
16#pragma comment(lib, "dbghelp.lib")
17#endif
18
19using namespace lld;
20using namespace lld::coff;
21using namespace llvm;
22
23Optional<std::string> coff::demangle(StringRef S) {
24#if defined(_MSC_VER)
25 // UnDecorateSymbolName is not thread-safe, so we need a mutex.
26 static std::mutex Mu;
27 std::lock_guard<std::mutex> Lock(Mu);
28
29 char Buf[4096];
30 if (S.startswith("?"))
31 if (size_t Len = UnDecorateSymbolName(S.str().c_str(), Buf, sizeof(Buf), 0))
32 return std::string(Buf, Len);
33#endif
34 return None;
35}
deps/lld/COFF/Strings.h created+23
......@@ -0,0 +1,23 @@
1//===- Strings.h ------------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_COFF_STRINGS_H
11#define LLD_COFF_STRINGS_H
12
13#include "llvm/ADT/Optional.h"
14#include "llvm/ADT/StringRef.h"
15#include <string>
16
17namespace lld {
18namespace coff {
19llvm::Optional<std::string> demangle(llvm::StringRef S);
20}
21}
22
23#endif
deps/lld/COFF/SymbolTable.cpp created+375
......@@ -0,0 +1,375 @@
1//===- SymbolTable.cpp ----------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "SymbolTable.h"
11#include "Config.h"
12#include "Driver.h"
13#include "Error.h"
14#include "LTO.h"
15#include "Memory.h"
16#include "Symbols.h"
17#include "llvm/IR/LLVMContext.h"
18#include "llvm/Support/Debug.h"
19#include "llvm/Support/raw_ostream.h"
20#include <utility>
21
22using namespace llvm;
23
24namespace lld {
25namespace coff {
26
27enum SymbolPreference {
28 SP_EXISTING = -1,
29 SP_CONFLICT = 0,
30 SP_NEW = 1,
31};
32
33/// Checks if an existing symbol S should be kept or replaced by a new symbol.
34/// Returns SP_EXISTING when S should be kept, SP_NEW when the new symbol
35/// should be kept, and SP_CONFLICT if no valid resolution exists.
36static SymbolPreference compareDefined(Symbol *S, bool WasInserted,
37 bool NewIsCOMDAT) {
38 // If the symbol wasn't previously known, the new symbol wins by default.
39 if (WasInserted || !isa<Defined>(S->body()))
40 return SP_NEW;
41
42 // If the existing symbol is a DefinedRegular, both it and the new symbol
43 // must be comdats. In that case, we have no reason to prefer one symbol
44 // over the other, and we keep the existing one. If one of the symbols
45 // is not a comdat, we report a conflict.
46 if (auto *R = dyn_cast<DefinedRegular>(S->body())) {
47 if (NewIsCOMDAT && R->isCOMDAT())
48 return SP_EXISTING;
49 else
50 return SP_CONFLICT;
51 }
52
53 // Existing symbol is not a DefinedRegular; new symbol wins.
54 return SP_NEW;
55}
56
57SymbolTable *Symtab;
58
59void SymbolTable::addFile(InputFile *File) {
60 log("Reading " + toString(File));
61 File->parse();
62
63 MachineTypes MT = File->getMachineType();
64 if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) {
65 Config->Machine = MT;
66 } else if (MT != IMAGE_FILE_MACHINE_UNKNOWN && Config->Machine != MT) {
67 fatal(toString(File) + ": machine type " + machineToStr(MT) +
68 " conflicts with " + machineToStr(Config->Machine));
69 }
70
71 if (auto *F = dyn_cast<ObjectFile>(File)) {
72 ObjectFiles.push_back(F);
73 } else if (auto *F = dyn_cast<BitcodeFile>(File)) {
74 BitcodeFiles.push_back(F);
75 } else if (auto *F = dyn_cast<ImportFile>(File)) {
76 ImportFiles.push_back(F);
77 }
78
79 StringRef S = File->getDirectives();
80 if (S.empty())
81 return;
82
83 log("Directives: " + toString(File) + ": " + S);
84 Driver->parseDirectives(S);
85}
86
87void SymbolTable::reportRemainingUndefines() {
88 SmallPtrSet<SymbolBody *, 8> Undefs;
89 for (auto &I : Symtab) {
90 Symbol *Sym = I.second;
91 auto *Undef = dyn_cast<Undefined>(Sym->body());
92 if (!Undef)
93 continue;
94 if (!Sym->IsUsedInRegularObj)
95 continue;
96 StringRef Name = Undef->getName();
97 // A weak alias may have been resolved, so check for that.
98 if (Defined *D = Undef->getWeakAlias()) {
99 // We resolve weak aliases by replacing the alias's SymbolBody with the
100 // target's SymbolBody. This causes all SymbolBody pointers referring to
101 // the old symbol to instead refer to the new symbol. However, we can't
102 // just blindly copy sizeof(Symbol::Body) bytes from D to Sym->Body
103 // because D may be an internal symbol, and internal symbols are stored as
104 // "unparented" SymbolBodies. For that reason we need to check which type
105 // of symbol we are dealing with and copy the correct number of bytes.
106 if (isa<DefinedRegular>(D))
107 memcpy(Sym->Body.buffer, D, sizeof(DefinedRegular));
108 else if (isa<DefinedAbsolute>(D))
109 memcpy(Sym->Body.buffer, D, sizeof(DefinedAbsolute));
110 else
111 // No other internal symbols are possible.
112 Sym->Body = D->symbol()->Body;
113 continue;
114 }
115 // If we can resolve a symbol by removing __imp_ prefix, do that.
116 // This odd rule is for compatibility with MSVC linker.
117 if (Name.startswith("__imp_")) {
118 Symbol *Imp = find(Name.substr(strlen("__imp_")));
119 if (Imp && isa<Defined>(Imp->body())) {
120 auto *D = cast<Defined>(Imp->body());
121 replaceBody<DefinedLocalImport>(Sym, Name, D);
122 LocalImportChunks.push_back(
123 cast<DefinedLocalImport>(Sym->body())->getChunk());
124 continue;
125 }
126 }
127 // Remaining undefined symbols are not fatal if /force is specified.
128 // They are replaced with dummy defined symbols.
129 if (Config->Force)
130 replaceBody<DefinedAbsolute>(Sym, Name, 0);
131 Undefs.insert(Sym->body());
132 }
133 if (Undefs.empty())
134 return;
135 for (SymbolBody *B : Config->GCRoot)
136 if (Undefs.count(B))
137 warn("<root>: undefined symbol: " + B->getName());
138 for (ObjectFile *File : ObjectFiles)
139 for (SymbolBody *Sym : File->getSymbols())
140 if (Undefs.count(Sym))
141 warn(toString(File) + ": undefined symbol: " + Sym->getName());
142 if (!Config->Force)
143 fatal("link failed");
144}
145
146std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) {
147 Symbol *&Sym = Symtab[CachedHashStringRef(Name)];
148 if (Sym)
149 return {Sym, false};
150 Sym = make<Symbol>();
151 Sym->IsUsedInRegularObj = false;
152 Sym->PendingArchiveLoad = false;
153 return {Sym, true};
154}
155
156Symbol *SymbolTable::addUndefined(StringRef Name, InputFile *F,
157 bool IsWeakAlias) {
158 Symbol *S;
159 bool WasInserted;
160 std::tie(S, WasInserted) = insert(Name);
161 if (!F || !isa<BitcodeFile>(F))
162 S->IsUsedInRegularObj = true;
163 if (WasInserted || (isa<Lazy>(S->body()) && IsWeakAlias)) {
164 replaceBody<Undefined>(S, Name);
165 return S;
166 }
167 if (auto *L = dyn_cast<Lazy>(S->body())) {
168 if (!S->PendingArchiveLoad) {
169 S->PendingArchiveLoad = true;
170 L->File->addMember(&L->Sym);
171 }
172 }
173 return S;
174}
175
176void SymbolTable::addLazy(ArchiveFile *F, const Archive::Symbol Sym) {
177 StringRef Name = Sym.getName();
178 Symbol *S;
179 bool WasInserted;
180 std::tie(S, WasInserted) = insert(Name);
181 if (WasInserted) {
182 replaceBody<Lazy>(S, F, Sym);
183 return;
184 }
185 auto *U = dyn_cast<Undefined>(S->body());
186 if (!U || U->WeakAlias || S->PendingArchiveLoad)
187 return;
188 S->PendingArchiveLoad = true;
189 F->addMember(&Sym);
190}
191
192void SymbolTable::reportDuplicate(Symbol *Existing, InputFile *NewFile) {
193 error("duplicate symbol: " + toString(*Existing->body()) + " in " +
194 toString(Existing->body()->getFile()) + " and in " +
195 (NewFile ? toString(NewFile) : "(internal)"));
196}
197
198Symbol *SymbolTable::addAbsolute(StringRef N, COFFSymbolRef Sym) {
199 Symbol *S;
200 bool WasInserted;
201 std::tie(S, WasInserted) = insert(N);
202 S->IsUsedInRegularObj = true;
203 if (WasInserted || isa<Undefined>(S->body()) || isa<Lazy>(S->body()))
204 replaceBody<DefinedAbsolute>(S, N, Sym);
205 else if (!isa<DefinedCOFF>(S->body()))
206 reportDuplicate(S, nullptr);
207 return S;
208}
209
210Symbol *SymbolTable::addAbsolute(StringRef N, uint64_t VA) {
211 Symbol *S;
212 bool WasInserted;
213 std::tie(S, WasInserted) = insert(N);
214 S->IsUsedInRegularObj = true;
215 if (WasInserted || isa<Undefined>(S->body()) || isa<Lazy>(S->body()))
216 replaceBody<DefinedAbsolute>(S, N, VA);
217 else if (!isa<DefinedCOFF>(S->body()))
218 reportDuplicate(S, nullptr);
219 return S;
220}
221
222Symbol *SymbolTable::addSynthetic(StringRef N, Chunk *C) {
223 Symbol *S;
224 bool WasInserted;
225 std::tie(S, WasInserted) = insert(N);
226 S->IsUsedInRegularObj = true;
227 if (WasInserted || isa<Undefined>(S->body()) || isa<Lazy>(S->body()))
228 replaceBody<DefinedSynthetic>(S, N, C);
229 else if (!isa<DefinedCOFF>(S->body()))
230 reportDuplicate(S, nullptr);
231 return S;
232}
233
234Symbol *SymbolTable::addRegular(InputFile *F, StringRef N, bool IsCOMDAT,
235 const coff_symbol_generic *Sym,
236 SectionChunk *C) {
237 Symbol *S;
238 bool WasInserted;
239 std::tie(S, WasInserted) = insert(N);
240 if (!isa<BitcodeFile>(F))
241 S->IsUsedInRegularObj = true;
242 SymbolPreference SP = compareDefined(S, WasInserted, IsCOMDAT);
243 if (SP == SP_CONFLICT) {
244 reportDuplicate(S, F);
245 } else if (SP == SP_NEW) {
246 replaceBody<DefinedRegular>(S, F, N, IsCOMDAT, /*IsExternal*/ true, Sym, C);
247 } else if (SP == SP_EXISTING && IsCOMDAT && C) {
248 C->markDiscarded();
249 // Discard associative chunks that we've parsed so far. No need to recurse
250 // because an associative section cannot have children.
251 for (SectionChunk *Child : C->children())
252 Child->markDiscarded();
253 }
254 return S;
255}
256
257Symbol *SymbolTable::addCommon(InputFile *F, StringRef N, uint64_t Size,
258 const coff_symbol_generic *Sym, CommonChunk *C) {
259 Symbol *S;
260 bool WasInserted;
261 std::tie(S, WasInserted) = insert(N);
262 if (!isa<BitcodeFile>(F))
263 S->IsUsedInRegularObj = true;
264 if (WasInserted || !isa<DefinedCOFF>(S->body()))
265 replaceBody<DefinedCommon>(S, F, N, Size, Sym, C);
266 else if (auto *DC = dyn_cast<DefinedCommon>(S->body()))
267 if (Size > DC->getSize())
268 replaceBody<DefinedCommon>(S, F, N, Size, Sym, C);
269 return S;
270}
271
272Symbol *SymbolTable::addImportData(StringRef N, ImportFile *F) {
273 Symbol *S;
274 bool WasInserted;
275 std::tie(S, WasInserted) = insert(N);
276 S->IsUsedInRegularObj = true;
277 if (WasInserted || isa<Undefined>(S->body()) || isa<Lazy>(S->body()))
278 replaceBody<DefinedImportData>(S, N, F);
279 else if (!isa<DefinedCOFF>(S->body()))
280 reportDuplicate(S, nullptr);
281 return S;
282}
283
284Symbol *SymbolTable::addImportThunk(StringRef Name, DefinedImportData *ID,
285 uint16_t Machine) {
286 Symbol *S;
287 bool WasInserted;
288 std::tie(S, WasInserted) = insert(Name);
289 S->IsUsedInRegularObj = true;
290 if (WasInserted || isa<Undefined>(S->body()) || isa<Lazy>(S->body()))
291 replaceBody<DefinedImportThunk>(S, Name, ID, Machine);
292 else if (!isa<DefinedCOFF>(S->body()))
293 reportDuplicate(S, nullptr);
294 return S;
295}
296
297std::vector<Chunk *> SymbolTable::getChunks() {
298 std::vector<Chunk *> Res;
299 for (ObjectFile *File : ObjectFiles) {
300 std::vector<Chunk *> &V = File->getChunks();
301 Res.insert(Res.end(), V.begin(), V.end());
302 }
303 return Res;
304}
305
306Symbol *SymbolTable::find(StringRef Name) {
307 auto It = Symtab.find(CachedHashStringRef(Name));
308 if (It == Symtab.end())
309 return nullptr;
310 return It->second;
311}
312
313Symbol *SymbolTable::findUnderscore(StringRef Name) {
314 if (Config->Machine == I386)
315 return find(("_" + Name).str());
316 return find(Name);
317}
318
319StringRef SymbolTable::findByPrefix(StringRef Prefix) {
320 for (auto Pair : Symtab) {
321 StringRef Name = Pair.first.val();
322 if (Name.startswith(Prefix))
323 return Name;
324 }
325 return "";
326}
327
328StringRef SymbolTable::findMangle(StringRef Name) {
329 if (Symbol *Sym = find(Name))
330 if (!isa<Undefined>(Sym->body()))
331 return Name;
332 if (Config->Machine != I386)
333 return findByPrefix(("?" + Name + "@@Y").str());
334 if (!Name.startswith("_"))
335 return "";
336 // Search for x86 C function.
337 StringRef S = findByPrefix((Name + "@").str());
338 if (!S.empty())
339 return S;
340 // Search for x86 C++ non-member function.
341 return findByPrefix(("?" + Name.substr(1) + "@@Y").str());
342}
343
344void SymbolTable::mangleMaybe(SymbolBody *B) {
345 auto *U = dyn_cast<Undefined>(B);
346 if (!U || U->WeakAlias)
347 return;
348 StringRef Alias = findMangle(U->getName());
349 if (!Alias.empty())
350 U->WeakAlias = addUndefined(Alias);
351}
352
353SymbolBody *SymbolTable::addUndefined(StringRef Name) {
354 return addUndefined(Name, nullptr, false)->body();
355}
356
357std::vector<StringRef> SymbolTable::compileBitcodeFiles() {
358 LTO.reset(new BitcodeCompiler);
359 for (BitcodeFile *F : BitcodeFiles)
360 LTO->add(*F);
361 return LTO->compile();
362}
363
364void SymbolTable::addCombinedLTOObjects() {
365 if (BitcodeFiles.empty())
366 return;
367 for (StringRef Object : compileBitcodeFiles()) {
368 auto *Obj = make<ObjectFile>(MemoryBufferRef(Object, "lto.tmp"));
369 Obj->parse();
370 ObjectFiles.push_back(Obj);
371 }
372}
373
374} // namespace coff
375} // namespace lld
deps/lld/COFF/SymbolTable.h created+124
......@@ -0,0 +1,124 @@
1//===- SymbolTable.h --------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_COFF_SYMBOL_TABLE_H
11#define LLD_COFF_SYMBOL_TABLE_H
12
13#include "InputFiles.h"
14#include "LTO.h"
15#include "llvm/ADT/CachedHashString.h"
16#include "llvm/ADT/DenseMap.h"
17#include "llvm/ADT/DenseMapInfo.h"
18#include "llvm/Support/raw_ostream.h"
19
20namespace llvm {
21struct LTOCodeGenerator;
22}
23
24namespace lld {
25namespace coff {
26
27class Chunk;
28class CommonChunk;
29class Defined;
30class DefinedAbsolute;
31class DefinedRelative;
32class Lazy;
33class SectionChunk;
34class SymbolBody;
35struct Symbol;
36
37// SymbolTable is a bucket of all known symbols, including defined,
38// undefined, or lazy symbols (the last one is symbols in archive
39// files whose archive members are not yet loaded).
40//
41// We put all symbols of all files to a SymbolTable, and the
42// SymbolTable selects the "best" symbols if there are name
43// conflicts. For example, obviously, a defined symbol is better than
44// an undefined symbol. Or, if there's a conflict between a lazy and a
45// undefined, it'll read an archive member to read a real definition
46// to replace the lazy symbol. The logic is implemented in the
47// add*() functions, which are called by input files as they are parsed.
48// There is one add* function per symbol type.
49class SymbolTable {
50public:
51 void addFile(InputFile *File);
52
53 // Try to resolve any undefined symbols and update the symbol table
54 // accordingly, then print an error message for any remaining undefined
55 // symbols.
56 void reportRemainingUndefines();
57
58 // Returns a list of chunks of selected symbols.
59 std::vector<Chunk *> getChunks();
60
61 // Returns a symbol for a given name. Returns a nullptr if not found.
62 Symbol *find(StringRef Name);
63 Symbol *findUnderscore(StringRef Name);
64
65 // Occasionally we have to resolve an undefined symbol to its
66 // mangled symbol. This function tries to find a mangled name
67 // for U from the symbol table, and if found, set the symbol as
68 // a weak alias for U.
69 void mangleMaybe(SymbolBody *B);
70 StringRef findMangle(StringRef Name);
71
72 // Build a set of COFF objects representing the combined contents of
73 // BitcodeFiles and add them to the symbol table. Called after all files are
74 // added and before the writer writes results to a file.
75 void addCombinedLTOObjects();
76 std::vector<StringRef> compileBitcodeFiles();
77
78 // The writer needs to handle DLL import libraries specially in
79 // order to create the import descriptor table.
80 std::vector<ImportFile *> ImportFiles;
81
82 // The writer needs to infer the machine type from the object files.
83 std::vector<ObjectFile *> ObjectFiles;
84
85 // Creates an Undefined symbol for a given name.
86 SymbolBody *addUndefined(StringRef Name);
87
88 Symbol *addSynthetic(StringRef N, Chunk *C);
89 Symbol *addAbsolute(StringRef N, uint64_t VA);
90
91 Symbol *addUndefined(StringRef Name, InputFile *F, bool IsWeakAlias);
92 void addLazy(ArchiveFile *F, const Archive::Symbol Sym);
93 Symbol *addAbsolute(StringRef N, COFFSymbolRef S);
94 Symbol *addRegular(InputFile *F, StringRef N, bool IsCOMDAT,
95 const llvm::object::coff_symbol_generic *S = nullptr,
96 SectionChunk *C = nullptr);
97 Symbol *addCommon(InputFile *F, StringRef N, uint64_t Size,
98 const llvm::object::coff_symbol_generic *S = nullptr,
99 CommonChunk *C = nullptr);
100 Symbol *addImportData(StringRef N, ImportFile *F);
101 Symbol *addImportThunk(StringRef Name, DefinedImportData *S,
102 uint16_t Machine);
103
104 void reportDuplicate(Symbol *Existing, InputFile *NewFile);
105
106 // A list of chunks which to be added to .rdata.
107 std::vector<Chunk *> LocalImportChunks;
108
109private:
110 std::pair<Symbol *, bool> insert(StringRef Name);
111 StringRef findByPrefix(StringRef Prefix);
112
113 llvm::DenseMap<llvm::CachedHashStringRef, Symbol *> Symtab;
114
115 std::vector<BitcodeFile *> BitcodeFiles;
116 std::unique_ptr<BitcodeCompiler> LTO;
117};
118
119extern SymbolTable *Symtab;
120
121} // namespace coff
122} // namespace lld
123
124#endif
deps/lld/COFF/Symbols.cpp created+90
......@@ -0,0 +1,90 @@
1//===- Symbols.cpp --------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "Symbols.h"
11#include "Error.h"
12#include "InputFiles.h"
13#include "Memory.h"
14#include "Strings.h"
15#include "llvm/ADT/STLExtras.h"
16#include "llvm/Support/Debug.h"
17#include "llvm/Support/raw_ostream.h"
18
19using namespace llvm;
20using namespace llvm::object;
21
22// Returns a symbol name for an error message.
23std::string lld::toString(coff::SymbolBody &B) {
24 if (Optional<std::string> S = coff::demangle(B.getName()))
25 return ("\"" + *S + "\" (" + B.getName() + ")").str();
26 return B.getName();
27}
28
29namespace lld {
30namespace coff {
31
32StringRef SymbolBody::getName() {
33 // COFF symbol names are read lazily for a performance reason.
34 // Non-external symbol names are never used by the linker except for logging
35 // or debugging. Their internal references are resolved not by name but by
36 // symbol index. And because they are not external, no one can refer them by
37 // name. Object files contain lots of non-external symbols, and creating
38 // StringRefs for them (which involves lots of strlen() on the string table)
39 // is a waste of time.
40 if (Name.empty()) {
41 auto *D = cast<DefinedCOFF>(this);
42 cast<ObjectFile>(D->File)->getCOFFObj()->getSymbolName(D->Sym, Name);
43 }
44 return Name;
45}
46
47InputFile *SymbolBody::getFile() {
48 if (auto *Sym = dyn_cast<DefinedCOFF>(this))
49 return Sym->File;
50 if (auto *Sym = dyn_cast<Lazy>(this))
51 return Sym->File;
52 return nullptr;
53}
54
55COFFSymbolRef DefinedCOFF::getCOFFSymbol() {
56 size_t SymSize =
57 cast<ObjectFile>(File)->getCOFFObj()->getSymbolTableEntrySize();
58 if (SymSize == sizeof(coff_symbol16))
59 return COFFSymbolRef(reinterpret_cast<const coff_symbol16 *>(Sym));
60 assert(SymSize == sizeof(coff_symbol32));
61 return COFFSymbolRef(reinterpret_cast<const coff_symbol32 *>(Sym));
62}
63
64uint16_t DefinedAbsolute::OutputSectionIndex = 0;
65
66static Chunk *makeImportThunk(DefinedImportData *S, uint16_t Machine) {
67 if (Machine == AMD64)
68 return make<ImportThunkChunkX64>(S);
69 if (Machine == I386)
70 return make<ImportThunkChunkX86>(S);
71 if (Machine == ARM64)
72 return make<ImportThunkChunkARM64>(S);
73 assert(Machine == ARMNT);
74 return make<ImportThunkChunkARM>(S);
75}
76
77DefinedImportThunk::DefinedImportThunk(StringRef Name, DefinedImportData *S,
78 uint16_t Machine)
79 : Defined(DefinedImportThunkKind, Name), WrappedSym(S),
80 Data(makeImportThunk(S, Machine)) {}
81
82Defined *Undefined::getWeakAlias() {
83 // A weak alias may be a weak alias to another symbol, so check recursively.
84 for (SymbolBody *A = WeakAlias; A; A = cast<Undefined>(A)->WeakAlias)
85 if (auto *D = dyn_cast<Defined>(A))
86 return D;
87 return nullptr;
88}
89} // namespace coff
90} // namespace lld
deps/lld/COFF/Symbols.h created+443
......@@ -0,0 +1,443 @@
1//===- Symbols.h ------------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_COFF_SYMBOLS_H
11#define LLD_COFF_SYMBOLS_H
12
13#include "Chunks.h"
14#include "Config.h"
15#include "Memory.h"
16#include "lld/Core/LLVM.h"
17#include "llvm/ADT/ArrayRef.h"
18#include "llvm/Object/Archive.h"
19#include "llvm/Object/COFF.h"
20#include <atomic>
21#include <memory>
22#include <vector>
23
24namespace lld {
25namespace coff {
26
27using llvm::object::Archive;
28using llvm::object::COFFSymbolRef;
29using llvm::object::coff_import_header;
30using llvm::object::coff_symbol_generic;
31
32class ArchiveFile;
33class InputFile;
34class ObjectFile;
35struct Symbol;
36class SymbolTable;
37
38// The base class for real symbol classes.
39class SymbolBody {
40public:
41 enum Kind {
42 // The order of these is significant. We start with the regular defined
43 // symbols as those are the most prevelant and the zero tag is the cheapest
44 // to set. Among the defined kinds, the lower the kind is preferred over
45 // the higher kind when testing wether one symbol should take precedence
46 // over another.
47 DefinedRegularKind = 0,
48 DefinedCommonKind,
49 DefinedLocalImportKind,
50 DefinedImportThunkKind,
51 DefinedImportDataKind,
52 DefinedAbsoluteKind,
53 DefinedSyntheticKind,
54
55 UndefinedKind,
56 LazyKind,
57
58 LastDefinedCOFFKind = DefinedCommonKind,
59 LastDefinedKind = DefinedSyntheticKind,
60 };
61
62 Kind kind() const { return static_cast<Kind>(SymbolKind); }
63
64 // Returns true if this is an external symbol.
65 bool isExternal() { return IsExternal; }
66
67 // Returns the symbol name.
68 StringRef getName();
69
70 // Returns the file from which this symbol was created.
71 InputFile *getFile();
72
73 Symbol *symbol();
74 const Symbol *symbol() const {
75 return const_cast<SymbolBody *>(this)->symbol();
76 }
77
78protected:
79 friend SymbolTable;
80 explicit SymbolBody(Kind K, StringRef N = "")
81 : SymbolKind(K), IsExternal(true), IsCOMDAT(false),
82 WrittenToSymtab(false), Name(N) {}
83
84 const unsigned SymbolKind : 8;
85 unsigned IsExternal : 1;
86
87 // This bit is used by the \c DefinedRegular subclass.
88 unsigned IsCOMDAT : 1;
89
90public:
91 // This bit is used by Writer::createSymbolAndStringTable() to prevent
92 // symbols from being written to the symbol table more than once.
93 unsigned WrittenToSymtab : 1;
94
95protected:
96 StringRef Name;
97};
98
99// The base class for any defined symbols, including absolute symbols,
100// etc.
101class Defined : public SymbolBody {
102public:
103 Defined(Kind K, StringRef N) : SymbolBody(K, N) {}
104
105 static bool classof(const SymbolBody *S) {
106 return S->kind() <= LastDefinedKind;
107 }
108
109 // Returns the RVA (relative virtual address) of this symbol. The
110 // writer sets and uses RVAs.
111 uint64_t getRVA();
112
113 // Returns the chunk containing this symbol. Absolute symbols and __ImageBase
114 // do not have chunks, so this may return null.
115 Chunk *getChunk();
116};
117
118// Symbols defined via a COFF object file or bitcode file. For COFF files, this
119// stores a coff_symbol_generic*, and names of internal symbols are lazily
120// loaded through that. For bitcode files, Sym is nullptr and the name is stored
121// as a StringRef.
122class DefinedCOFF : public Defined {
123 friend SymbolBody;
124public:
125 DefinedCOFF(Kind K, InputFile *F, StringRef N, const coff_symbol_generic *S)
126 : Defined(K, N), File(F), Sym(S) {}
127
128 static bool classof(const SymbolBody *S) {
129 return S->kind() <= LastDefinedCOFFKind;
130 }
131
132 InputFile *getFile() { return File; }
133
134 COFFSymbolRef getCOFFSymbol();
135
136 InputFile *File;
137
138protected:
139 const coff_symbol_generic *Sym;
140};
141
142// Regular defined symbols read from object file symbol tables.
143class DefinedRegular : public DefinedCOFF {
144public:
145 DefinedRegular(InputFile *F, StringRef N, bool IsCOMDAT,
146 bool IsExternal = false,
147 const coff_symbol_generic *S = nullptr,
148 SectionChunk *C = nullptr)
149 : DefinedCOFF(DefinedRegularKind, F, N, S), Data(C ? &C->Repl : nullptr) {
150 this->IsExternal = IsExternal;
151 this->IsCOMDAT = IsCOMDAT;
152 }
153
154 static bool classof(const SymbolBody *S) {
155 return S->kind() == DefinedRegularKind;
156 }
157
158 uint64_t getRVA() { return (*Data)->getRVA() + Sym->Value; }
159 bool isCOMDAT() { return IsCOMDAT; }
160 SectionChunk *getChunk() { return *Data; }
161 uint32_t getValue() { return Sym->Value; }
162
163private:
164 SectionChunk **Data;
165};
166
167class DefinedCommon : public DefinedCOFF {
168public:
169 DefinedCommon(InputFile *F, StringRef N, uint64_t Size,
170 const coff_symbol_generic *S = nullptr,
171 CommonChunk *C = nullptr)
172 : DefinedCOFF(DefinedCommonKind, F, N, S), Data(C), Size(Size) {
173 this->IsExternal = true;
174 }
175
176 static bool classof(const SymbolBody *S) {
177 return S->kind() == DefinedCommonKind;
178 }
179
180 uint64_t getRVA() { return Data->getRVA(); }
181 Chunk *getChunk() { return Data; }
182
183private:
184 friend SymbolTable;
185 uint64_t getSize() const { return Size; }
186 CommonChunk *Data;
187 uint64_t Size;
188};
189
190// Absolute symbols.
191class DefinedAbsolute : public Defined {
192public:
193 DefinedAbsolute(StringRef N, COFFSymbolRef S)
194 : Defined(DefinedAbsoluteKind, N), VA(S.getValue()) {
195 IsExternal = S.isExternal();
196 }
197
198 DefinedAbsolute(StringRef N, uint64_t V)
199 : Defined(DefinedAbsoluteKind, N), VA(V) {}
200
201 static bool classof(const SymbolBody *S) {
202 return S->kind() == DefinedAbsoluteKind;
203 }
204
205 uint64_t getRVA() { return VA - Config->ImageBase; }
206 void setVA(uint64_t V) { VA = V; }
207
208 // The sentinel absolute symbol section index. Section index relocations
209 // against absolute symbols resolve to this 16 bit number, and it is the
210 // largest valid section index plus one. This is written by the Writer.
211 static uint16_t OutputSectionIndex;
212 uint16_t getSecIdx() { return OutputSectionIndex; }
213
214private:
215 uint64_t VA;
216};
217
218// This symbol is used for linker-synthesized symbols like __ImageBase and
219// __safe_se_handler_table.
220class DefinedSynthetic : public Defined {
221public:
222 explicit DefinedSynthetic(StringRef Name, Chunk *C)
223 : Defined(DefinedSyntheticKind, Name), C(C) {}
224
225 static bool classof(const SymbolBody *S) {
226 return S->kind() == DefinedSyntheticKind;
227 }
228
229 // A null chunk indicates that this is __ImageBase. Otherwise, this is some
230 // other synthesized chunk, like SEHTableChunk.
231 uint32_t getRVA() { return C ? C->getRVA() : 0; }
232 Chunk *getChunk() { return C; }
233
234private:
235 Chunk *C;
236};
237
238// This class represents a symbol defined in an archive file. It is
239// created from an archive file header, and it knows how to load an
240// object file from an archive to replace itself with a defined
241// symbol. If the resolver finds both Undefined and Lazy for
242// the same name, it will ask the Lazy to load a file.
243class Lazy : public SymbolBody {
244public:
245 Lazy(ArchiveFile *F, const Archive::Symbol S)
246 : SymbolBody(LazyKind, S.getName()), File(F), Sym(S) {}
247
248 static bool classof(const SymbolBody *S) { return S->kind() == LazyKind; }
249
250 ArchiveFile *File;
251
252private:
253 friend SymbolTable;
254
255private:
256 const Archive::Symbol Sym;
257};
258
259// Undefined symbols.
260class Undefined : public SymbolBody {
261public:
262 explicit Undefined(StringRef N) : SymbolBody(UndefinedKind, N) {}
263
264 static bool classof(const SymbolBody *S) {
265 return S->kind() == UndefinedKind;
266 }
267
268 // An undefined symbol can have a fallback symbol which gives an
269 // undefined symbol a second chance if it would remain undefined.
270 // If it remains undefined, it'll be replaced with whatever the
271 // Alias pointer points to.
272 SymbolBody *WeakAlias = nullptr;
273
274 // If this symbol is external weak, try to resolve it to a defined
275 // symbol by searching the chain of fallback symbols. Returns the symbol if
276 // successful, otherwise returns null.
277 Defined *getWeakAlias();
278};
279
280// Windows-specific classes.
281
282// This class represents a symbol imported from a DLL. This has two
283// names for internal use and external use. The former is used for
284// name resolution, and the latter is used for the import descriptor
285// table in an output. The former has "__imp_" prefix.
286class DefinedImportData : public Defined {
287public:
288 DefinedImportData(StringRef N, ImportFile *F)
289 : Defined(DefinedImportDataKind, N), File(F) {
290 }
291
292 static bool classof(const SymbolBody *S) {
293 return S->kind() == DefinedImportDataKind;
294 }
295
296 uint64_t getRVA() { return File->Location->getRVA(); }
297 Chunk *getChunk() { return File->Location; }
298 void setLocation(Chunk *AddressTable) { File->Location = AddressTable; }
299
300 StringRef getDLLName() { return File->DLLName; }
301 StringRef getExternalName() { return File->ExternalName; }
302 uint16_t getOrdinal() { return File->Hdr->OrdinalHint; }
303
304 ImportFile *File;
305};
306
307// This class represents a symbol for a jump table entry which jumps
308// to a function in a DLL. Linker are supposed to create such symbols
309// without "__imp_" prefix for all function symbols exported from
310// DLLs, so that you can call DLL functions as regular functions with
311// a regular name. A function pointer is given as a DefinedImportData.
312class DefinedImportThunk : public Defined {
313public:
314 DefinedImportThunk(StringRef Name, DefinedImportData *S, uint16_t Machine);
315
316 static bool classof(const SymbolBody *S) {
317 return S->kind() == DefinedImportThunkKind;
318 }
319
320 uint64_t getRVA() { return Data->getRVA(); }
321 Chunk *getChunk() { return Data; }
322
323 DefinedImportData *WrappedSym;
324
325private:
326 Chunk *Data;
327};
328
329// If you have a symbol "__imp_foo" in your object file, a symbol name
330// "foo" becomes automatically available as a pointer to "__imp_foo".
331// This class is for such automatically-created symbols.
332// Yes, this is an odd feature. We didn't intend to implement that.
333// This is here just for compatibility with MSVC.
334class DefinedLocalImport : public Defined {
335public:
336 DefinedLocalImport(StringRef N, Defined *S)
337 : Defined(DefinedLocalImportKind, N), Data(make<LocalImportChunk>(S)) {}
338
339 static bool classof(const SymbolBody *S) {
340 return S->kind() == DefinedLocalImportKind;
341 }
342
343 uint64_t getRVA() { return Data->getRVA(); }
344 Chunk *getChunk() { return Data; }
345
346private:
347 LocalImportChunk *Data;
348};
349
350inline uint64_t Defined::getRVA() {
351 switch (kind()) {
352 case DefinedAbsoluteKind:
353 return cast<DefinedAbsolute>(this)->getRVA();
354 case DefinedSyntheticKind:
355 return cast<DefinedSynthetic>(this)->getRVA();
356 case DefinedImportDataKind:
357 return cast<DefinedImportData>(this)->getRVA();
358 case DefinedImportThunkKind:
359 return cast<DefinedImportThunk>(this)->getRVA();
360 case DefinedLocalImportKind:
361 return cast<DefinedLocalImport>(this)->getRVA();
362 case DefinedCommonKind:
363 return cast<DefinedCommon>(this)->getRVA();
364 case DefinedRegularKind:
365 return cast<DefinedRegular>(this)->getRVA();
366 case LazyKind:
367 case UndefinedKind:
368 llvm_unreachable("Cannot get the address for an undefined symbol.");
369 }
370 llvm_unreachable("unknown symbol kind");
371}
372
373inline Chunk *Defined::getChunk() {
374 switch (kind()) {
375 case DefinedRegularKind:
376 return cast<DefinedRegular>(this)->getChunk();
377 case DefinedAbsoluteKind:
378 return nullptr;
379 case DefinedSyntheticKind:
380 return cast<DefinedSynthetic>(this)->getChunk();
381 case DefinedImportDataKind:
382 return cast<DefinedImportData>(this)->getChunk();
383 case DefinedImportThunkKind:
384 return cast<DefinedImportThunk>(this)->getChunk();
385 case DefinedLocalImportKind:
386 return cast<DefinedLocalImport>(this)->getChunk();
387 case DefinedCommonKind:
388 return cast<DefinedCommon>(this)->getChunk();
389 case LazyKind:
390 case UndefinedKind:
391 llvm_unreachable("Cannot get the chunk of an undefined symbol.");
392 }
393 llvm_unreachable("unknown symbol kind");
394}
395
396// A real symbol object, SymbolBody, is usually stored within a Symbol. There's
397// always one Symbol for each symbol name. The resolver updates the SymbolBody
398// stored in the Body field of this object as it resolves symbols. Symbol also
399// holds computed properties of symbol names.
400struct Symbol {
401 // True if this symbol was referenced by a regular (non-bitcode) object.
402 unsigned IsUsedInRegularObj : 1;
403
404 // True if we've seen both a lazy and an undefined symbol with this symbol
405 // name, which means that we have enqueued an archive member load and should
406 // not load any more archive members to resolve the same symbol.
407 unsigned PendingArchiveLoad : 1;
408
409 // This field is used to store the Symbol's SymbolBody. This instantiation of
410 // AlignedCharArrayUnion gives us a struct with a char array field that is
411 // large and aligned enough to store any derived class of SymbolBody.
412 llvm::AlignedCharArrayUnion<
413 DefinedRegular, DefinedCommon, DefinedAbsolute, DefinedSynthetic, Lazy,
414 Undefined, DefinedImportData, DefinedImportThunk, DefinedLocalImport>
415 Body;
416
417 SymbolBody *body() {
418 return reinterpret_cast<SymbolBody *>(Body.buffer);
419 }
420 const SymbolBody *body() const { return const_cast<Symbol *>(this)->body(); }
421};
422
423template <typename T, typename... ArgT>
424void replaceBody(Symbol *S, ArgT &&... Arg) {
425 static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
426 static_assert(alignof(T) <= alignof(decltype(S->Body)),
427 "Body not aligned enough");
428 assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
429 "Not a SymbolBody");
430 new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
431}
432
433inline Symbol *SymbolBody::symbol() {
434 assert(isExternal());
435 return reinterpret_cast<Symbol *>(reinterpret_cast<char *>(this) -
436 offsetof(Symbol, Body));
437}
438} // namespace coff
439
440std::string toString(coff::SymbolBody &B);
441} // namespace lld
442
443#endif
deps/lld/COFF/Writer.cpp created+900
......@@ -0,0 +1,900 @@
1//===- Writer.cpp ---------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "Writer.h"
11#include "Config.h"
12#include "DLL.h"
13#include "Error.h"
14#include "InputFiles.h"
15#include "MapFile.h"
16#include "Memory.h"
17#include "PDB.h"
18#include "SymbolTable.h"
19#include "Symbols.h"
20#include "llvm/ADT/DenseMap.h"
21#include "llvm/ADT/STLExtras.h"
22#include "llvm/ADT/StringSwitch.h"
23#include "llvm/Support/Debug.h"
24#include "llvm/Support/Endian.h"
25#include "llvm/Support/FileOutputBuffer.h"
26#include "llvm/Support/Parallel.h"
27#include "llvm/Support/RandomNumberGenerator.h"
28#include "llvm/Support/raw_ostream.h"
29#include <algorithm>
30#include <cstdio>
31#include <map>
32#include <memory>
33#include <utility>
34
35using namespace llvm;
36using namespace llvm::COFF;
37using namespace llvm::object;
38using namespace llvm::support;
39using namespace llvm::support::endian;
40using namespace lld;
41using namespace lld::coff;
42
43static const int SectorSize = 512;
44static const int DOSStubSize = 64;
45static const int NumberfOfDataDirectory = 16;
46
47namespace {
48
49class DebugDirectoryChunk : public Chunk {
50public:
51 DebugDirectoryChunk(const std::vector<Chunk *> &R) : Records(R) {}
52
53 size_t getSize() const override {
54 return Records.size() * sizeof(debug_directory);
55 }
56
57 void writeTo(uint8_t *B) const override {
58 auto *D = reinterpret_cast<debug_directory *>(B + OutputSectionOff);
59
60 for (const Chunk *Record : Records) {
61 D->Characteristics = 0;
62 D->TimeDateStamp = 0;
63 D->MajorVersion = 0;
64 D->MinorVersion = 0;
65 D->Type = COFF::IMAGE_DEBUG_TYPE_CODEVIEW;
66 D->SizeOfData = Record->getSize();
67 D->AddressOfRawData = Record->getRVA();
68 // TODO(compnerd) get the file offset
69 D->PointerToRawData = 0;
70
71 ++D;
72 }
73 }
74
75private:
76 const std::vector<Chunk *> &Records;
77};
78
79class CVDebugRecordChunk : public Chunk {
80 size_t getSize() const override {
81 return sizeof(codeview::DebugInfo) + Config->PDBPath.size() + 1;
82 }
83
84 void writeTo(uint8_t *B) const override {
85 // Save off the DebugInfo entry to backfill the file signature (build id)
86 // in Writer::writeBuildId
87 DI = reinterpret_cast<codeview::DebugInfo *>(B + OutputSectionOff);
88
89 DI->Signature.CVSignature = OMF::Signature::PDB70;
90
91 // variable sized field (PDB Path)
92 auto *P = reinterpret_cast<char *>(B + OutputSectionOff + sizeof(*DI));
93 if (!Config->PDBPath.empty())
94 memcpy(P, Config->PDBPath.data(), Config->PDBPath.size());
95 P[Config->PDBPath.size()] = '\0';
96 }
97
98public:
99 mutable codeview::DebugInfo *DI = nullptr;
100};
101
102// The writer writes a SymbolTable result to a file.
103class Writer {
104public:
105 Writer(SymbolTable *T) : Symtab(T) {}
106 void run();
107
108private:
109 void createSections();
110 void createMiscChunks();
111 void createImportTables();
112 void createExportTable();
113 void assignAddresses();
114 void removeEmptySections();
115 void createSymbolAndStringTable();
116 void openFile(StringRef OutputPath);
117 template <typename PEHeaderTy> void writeHeader();
118 void fixSafeSEHSymbols();
119 void setSectionPermissions();
120 void writeSections();
121 void sortExceptionTable();
122 void writeBuildId();
123
124 llvm::Optional<coff_symbol16> createSymbol(Defined *D);
125 size_t addEntryToStringTable(StringRef Str);
126
127 OutputSection *findSection(StringRef Name);
128 OutputSection *createSection(StringRef Name);
129 void addBaserels(OutputSection *Dest);
130 void addBaserelBlocks(OutputSection *Dest, std::vector<Baserel> &V);
131
132 uint32_t getSizeOfInitializedData();
133 std::map<StringRef, std::vector<DefinedImportData *>> binImports();
134
135 SymbolTable *Symtab;
136 std::unique_ptr<FileOutputBuffer> Buffer;
137 std::vector<OutputSection *> OutputSections;
138 std::vector<char> Strtab;
139 std::vector<llvm::object::coff_symbol16> OutputSymtab;
140 IdataContents Idata;
141 DelayLoadContents DelayIdata;
142 EdataContents Edata;
143 SEHTableChunk *SEHTable = nullptr;
144
145 Chunk *DebugDirectory = nullptr;
146 std::vector<Chunk *> DebugRecords;
147 CVDebugRecordChunk *BuildId = nullptr;
148 ArrayRef<uint8_t> SectionTable;
149
150 uint64_t FileSize;
151 uint32_t PointerToSymbolTable = 0;
152 uint64_t SizeOfImage;
153 uint64_t SizeOfHeaders;
154};
155} // anonymous namespace
156
157namespace lld {
158namespace coff {
159
160void writeResult(SymbolTable *T) { Writer(T).run(); }
161
162void OutputSection::setRVA(uint64_t RVA) {
163 Header.VirtualAddress = RVA;
164 for (Chunk *C : Chunks)
165 C->setRVA(C->getRVA() + RVA);
166}
167
168void OutputSection::setFileOffset(uint64_t Off) {
169 // If a section has no actual data (i.e. BSS section), we want to
170 // set 0 to its PointerToRawData. Otherwise the output is rejected
171 // by the loader.
172 if (Header.SizeOfRawData == 0)
173 return;
174 Header.PointerToRawData = Off;
175}
176
177void OutputSection::addChunk(Chunk *C) {
178 Chunks.push_back(C);
179 C->setOutputSection(this);
180 uint64_t Off = Header.VirtualSize;
181 Off = alignTo(Off, C->getAlign());
182 C->setRVA(Off);
183 C->OutputSectionOff = Off;
184 Off += C->getSize();
185 Header.VirtualSize = Off;
186 if (C->hasData())
187 Header.SizeOfRawData = alignTo(Off, SectorSize);
188}
189
190void OutputSection::addPermissions(uint32_t C) {
191 Header.Characteristics |= C & PermMask;
192}
193
194void OutputSection::setPermissions(uint32_t C) {
195 Header.Characteristics = C & PermMask;
196}
197
198// Write the section header to a given buffer.
199void OutputSection::writeHeaderTo(uint8_t *Buf) {
200 auto *Hdr = reinterpret_cast<coff_section *>(Buf);
201 *Hdr = Header;
202 if (StringTableOff) {
203 // If name is too long, write offset into the string table as a name.
204 sprintf(Hdr->Name, "/%d", StringTableOff);
205 } else {
206 assert(!Config->Debug || Name.size() <= COFF::NameSize);
207 strncpy(Hdr->Name, Name.data(),
208 std::min(Name.size(), (size_t)COFF::NameSize));
209 }
210}
211
212} // namespace coff
213} // namespace lld
214
215// The main function of the writer.
216void Writer::run() {
217 createSections();
218 createMiscChunks();
219 createImportTables();
220 createExportTable();
221 if (Config->Relocatable)
222 createSection(".reloc");
223 assignAddresses();
224 removeEmptySections();
225 setSectionPermissions();
226 createSymbolAndStringTable();
227 openFile(Config->OutputFile);
228 if (Config->is64()) {
229 writeHeader<pe32plus_header>();
230 } else {
231 writeHeader<pe32_header>();
232 }
233 fixSafeSEHSymbols();
234 writeSections();
235 sortExceptionTable();
236 writeBuildId();
237
238 if (!Config->PDBPath.empty() && Config->Debug) {
239 const llvm::codeview::DebugInfo *DI = nullptr;
240 if (Config->DebugTypes & static_cast<unsigned>(coff::DebugType::CV))
241 DI = BuildId->DI;
242 createPDB(Symtab, SectionTable, DI);
243 }
244
245 writeMapFile(OutputSections);
246
247 if (auto EC = Buffer->commit())
248 fatal(EC, "failed to write the output file");
249}
250
251static StringRef getOutputSection(StringRef Name) {
252 StringRef S = Name.split('$').first;
253 auto It = Config->Merge.find(S);
254 if (It == Config->Merge.end())
255 return S;
256 return It->second;
257}
258
259// Create output section objects and add them to OutputSections.
260void Writer::createSections() {
261 // First, bin chunks by name.
262 std::map<StringRef, std::vector<Chunk *>> Map;
263 for (Chunk *C : Symtab->getChunks()) {
264 auto *SC = dyn_cast<SectionChunk>(C);
265 if (SC && !SC->isLive()) {
266 if (Config->Verbose)
267 SC->printDiscardedMessage();
268 continue;
269 }
270 Map[C->getSectionName()].push_back(C);
271 }
272
273 // Then create an OutputSection for each section.
274 // '$' and all following characters in input section names are
275 // discarded when determining output section. So, .text$foo
276 // contributes to .text, for example. See PE/COFF spec 3.2.
277 SmallDenseMap<StringRef, OutputSection *> Sections;
278 for (auto Pair : Map) {
279 StringRef Name = getOutputSection(Pair.first);
280 OutputSection *&Sec = Sections[Name];
281 if (!Sec) {
282 Sec = make<OutputSection>(Name);
283 OutputSections.push_back(Sec);
284 }
285 std::vector<Chunk *> &Chunks = Pair.second;
286 for (Chunk *C : Chunks) {
287 Sec->addChunk(C);
288 Sec->addPermissions(C->getPermissions());
289 }
290 }
291}
292
293void Writer::createMiscChunks() {
294 OutputSection *RData = createSection(".rdata");
295
296 // Create thunks for locally-dllimported symbols.
297 if (!Symtab->LocalImportChunks.empty()) {
298 for (Chunk *C : Symtab->LocalImportChunks)
299 RData->addChunk(C);
300 }
301
302 // Create Debug Information Chunks
303 if (Config->Debug) {
304 DebugDirectory = make<DebugDirectoryChunk>(DebugRecords);
305
306 // TODO(compnerd) create a coffgrp entry if DebugType::CV is not enabled
307 if (Config->DebugTypes & static_cast<unsigned>(coff::DebugType::CV)) {
308 auto *Chunk = make<CVDebugRecordChunk>();
309
310 BuildId = Chunk;
311 DebugRecords.push_back(Chunk);
312 }
313
314 RData->addChunk(DebugDirectory);
315 for (Chunk *C : DebugRecords)
316 RData->addChunk(C);
317 }
318
319 // Create SEH table. x86-only.
320 if (Config->Machine != I386)
321 return;
322
323 std::set<Defined *> Handlers;
324
325 for (lld::coff::ObjectFile *File : Symtab->ObjectFiles) {
326 if (!File->SEHCompat)
327 return;
328 for (SymbolBody *B : File->SEHandlers) {
329 // Make sure the handler is still live. Assume all handlers are regular
330 // symbols.
331 auto *D = dyn_cast<DefinedRegular>(B);
332 if (D && D->getChunk()->isLive())
333 Handlers.insert(D);
334 }
335 }
336
337 if (!Handlers.empty()) {
338 SEHTable = make<SEHTableChunk>(Handlers);
339 RData->addChunk(SEHTable);
340 }
341}
342
343// Create .idata section for the DLL-imported symbol table.
344// The format of this section is inherently Windows-specific.
345// IdataContents class abstracted away the details for us,
346// so we just let it create chunks and add them to the section.
347void Writer::createImportTables() {
348 if (Symtab->ImportFiles.empty())
349 return;
350
351 // Initialize DLLOrder so that import entries are ordered in
352 // the same order as in the command line. (That affects DLL
353 // initialization order, and this ordering is MSVC-compatible.)
354 for (ImportFile *File : Symtab->ImportFiles) {
355 if (!File->Live)
356 continue;
357
358 std::string DLL = StringRef(File->DLLName).lower();
359 if (Config->DLLOrder.count(DLL) == 0)
360 Config->DLLOrder[DLL] = Config->DLLOrder.size();
361 }
362
363 OutputSection *Text = createSection(".text");
364 for (ImportFile *File : Symtab->ImportFiles) {
365 if (!File->Live)
366 continue;
367
368 if (DefinedImportThunk *Thunk = File->ThunkSym)
369 Text->addChunk(Thunk->getChunk());
370
371 if (Config->DelayLoads.count(StringRef(File->DLLName).lower())) {
372 if (!File->ThunkSym)
373 fatal("cannot delay-load " + toString(File) +
374 " due to import of data: " + toString(*File->ImpSym));
375 DelayIdata.add(File->ImpSym);
376 } else {
377 Idata.add(File->ImpSym);
378 }
379 }
380
381 if (!Idata.empty()) {
382 OutputSection *Sec = createSection(".idata");
383 for (Chunk *C : Idata.getChunks())
384 Sec->addChunk(C);
385 }
386
387 if (!DelayIdata.empty()) {
388 Defined *Helper = cast<Defined>(Config->DelayLoadHelper);
389 DelayIdata.create(Helper);
390 OutputSection *Sec = createSection(".didat");
391 for (Chunk *C : DelayIdata.getChunks())
392 Sec->addChunk(C);
393 Sec = createSection(".data");
394 for (Chunk *C : DelayIdata.getDataChunks())
395 Sec->addChunk(C);
396 Sec = createSection(".text");
397 for (Chunk *C : DelayIdata.getCodeChunks())
398 Sec->addChunk(C);
399 }
400}
401
402void Writer::createExportTable() {
403 if (Config->Exports.empty())
404 return;
405 OutputSection *Sec = createSection(".edata");
406 for (Chunk *C : Edata.Chunks)
407 Sec->addChunk(C);
408}
409
410// The Windows loader doesn't seem to like empty sections,
411// so we remove them if any.
412void Writer::removeEmptySections() {
413 auto IsEmpty = [](OutputSection *S) { return S->getVirtualSize() == 0; };
414 OutputSections.erase(
415 std::remove_if(OutputSections.begin(), OutputSections.end(), IsEmpty),
416 OutputSections.end());
417 uint32_t Idx = 1;
418 for (OutputSection *Sec : OutputSections)
419 Sec->SectionIndex = Idx++;
420}
421
422size_t Writer::addEntryToStringTable(StringRef Str) {
423 assert(Str.size() > COFF::NameSize);
424 size_t OffsetOfEntry = Strtab.size() + 4; // +4 for the size field
425 Strtab.insert(Strtab.end(), Str.begin(), Str.end());
426 Strtab.push_back('\0');
427 return OffsetOfEntry;
428}
429
430Optional<coff_symbol16> Writer::createSymbol(Defined *Def) {
431 // Relative symbols are unrepresentable in a COFF symbol table.
432 if (isa<DefinedSynthetic>(Def))
433 return None;
434
435 if (auto *D = dyn_cast<DefinedRegular>(Def)) {
436 // Don't write dead symbols or symbols in codeview sections to the symbol
437 // table.
438 if (!D->getChunk()->isLive() || D->getChunk()->isCodeView())
439 return None;
440 }
441
442 if (auto *Sym = dyn_cast<DefinedImportData>(Def))
443 if (!Sym->File->Live)
444 return None;
445
446 if (auto *Sym = dyn_cast<DefinedImportThunk>(Def))
447 if (!Sym->WrappedSym->File->Live)
448 return None;
449
450 coff_symbol16 Sym;
451 StringRef Name = Def->getName();
452 if (Name.size() > COFF::NameSize) {
453 Sym.Name.Offset.Zeroes = 0;
454 Sym.Name.Offset.Offset = addEntryToStringTable(Name);
455 } else {
456 memset(Sym.Name.ShortName, 0, COFF::NameSize);
457 memcpy(Sym.Name.ShortName, Name.data(), Name.size());
458 }
459
460 if (auto *D = dyn_cast<DefinedCOFF>(Def)) {
461 COFFSymbolRef Ref = D->getCOFFSymbol();
462 Sym.Type = Ref.getType();
463 Sym.StorageClass = Ref.getStorageClass();
464 } else {
465 Sym.Type = IMAGE_SYM_TYPE_NULL;
466 Sym.StorageClass = IMAGE_SYM_CLASS_EXTERNAL;
467 }
468 Sym.NumberOfAuxSymbols = 0;
469
470 switch (Def->kind()) {
471 case SymbolBody::DefinedAbsoluteKind:
472 Sym.Value = Def->getRVA();
473 Sym.SectionNumber = IMAGE_SYM_ABSOLUTE;
474 break;
475 default: {
476 uint64_t RVA = Def->getRVA();
477 OutputSection *Sec = nullptr;
478 for (OutputSection *S : OutputSections) {
479 if (S->getRVA() > RVA)
480 break;
481 Sec = S;
482 }
483 Sym.Value = RVA - Sec->getRVA();
484 Sym.SectionNumber = Sec->SectionIndex;
485 break;
486 }
487 }
488 return Sym;
489}
490
491void Writer::createSymbolAndStringTable() {
492 if (!Config->Debug || !Config->WriteSymtab)
493 return;
494
495 // Name field in the section table is 8 byte long. Longer names need
496 // to be written to the string table. First, construct string table.
497 for (OutputSection *Sec : OutputSections) {
498 StringRef Name = Sec->getName();
499 if (Name.size() <= COFF::NameSize)
500 continue;
501 Sec->setStringTableOff(addEntryToStringTable(Name));
502 }
503
504 for (lld::coff::ObjectFile *File : Symtab->ObjectFiles) {
505 for (SymbolBody *B : File->getSymbols()) {
506 auto *D = dyn_cast<Defined>(B);
507 if (!D || D->WrittenToSymtab)
508 continue;
509 D->WrittenToSymtab = true;
510
511 if (Optional<coff_symbol16> Sym = createSymbol(D))
512 OutputSymtab.push_back(*Sym);
513 }
514 }
515
516 OutputSection *LastSection = OutputSections.back();
517 // We position the symbol table to be adjacent to the end of the last section.
518 uint64_t FileOff = LastSection->getFileOff() +
519 alignTo(LastSection->getRawSize(), SectorSize);
520 if (!OutputSymtab.empty()) {
521 PointerToSymbolTable = FileOff;
522 FileOff += OutputSymtab.size() * sizeof(coff_symbol16);
523 }
524 if (!Strtab.empty())
525 FileOff += Strtab.size() + 4;
526 FileSize = alignTo(FileOff, SectorSize);
527}
528
529// Visits all sections to assign incremental, non-overlapping RVAs and
530// file offsets.
531void Writer::assignAddresses() {
532 SizeOfHeaders = DOSStubSize + sizeof(PEMagic) + sizeof(coff_file_header) +
533 sizeof(data_directory) * NumberfOfDataDirectory +
534 sizeof(coff_section) * OutputSections.size();
535 SizeOfHeaders +=
536 Config->is64() ? sizeof(pe32plus_header) : sizeof(pe32_header);
537 SizeOfHeaders = alignTo(SizeOfHeaders, SectorSize);
538 uint64_t RVA = 0x1000; // The first page is kept unmapped.
539 FileSize = SizeOfHeaders;
540 // Move DISCARDABLE (or non-memory-mapped) sections to the end of file because
541 // the loader cannot handle holes.
542 std::stable_partition(
543 OutputSections.begin(), OutputSections.end(), [](OutputSection *S) {
544 return (S->getPermissions() & IMAGE_SCN_MEM_DISCARDABLE) == 0;
545 });
546 for (OutputSection *Sec : OutputSections) {
547 if (Sec->getName() == ".reloc")
548 addBaserels(Sec);
549 Sec->setRVA(RVA);
550 Sec->setFileOffset(FileSize);
551 RVA += alignTo(Sec->getVirtualSize(), PageSize);
552 FileSize += alignTo(Sec->getRawSize(), SectorSize);
553 }
554 SizeOfImage = SizeOfHeaders + alignTo(RVA - 0x1000, PageSize);
555}
556
557template <typename PEHeaderTy> void Writer::writeHeader() {
558 // Write DOS stub
559 uint8_t *Buf = Buffer->getBufferStart();
560 auto *DOS = reinterpret_cast<dos_header *>(Buf);
561 Buf += DOSStubSize;
562 DOS->Magic[0] = 'M';
563 DOS->Magic[1] = 'Z';
564 DOS->AddressOfRelocationTable = sizeof(dos_header);
565 DOS->AddressOfNewExeHeader = DOSStubSize;
566
567 // Write PE magic
568 memcpy(Buf, PEMagic, sizeof(PEMagic));
569 Buf += sizeof(PEMagic);
570
571 // Write COFF header
572 auto *COFF = reinterpret_cast<coff_file_header *>(Buf);
573 Buf += sizeof(*COFF);
574 COFF->Machine = Config->Machine;
575 COFF->NumberOfSections = OutputSections.size();
576 COFF->Characteristics = IMAGE_FILE_EXECUTABLE_IMAGE;
577 if (Config->LargeAddressAware)
578 COFF->Characteristics |= IMAGE_FILE_LARGE_ADDRESS_AWARE;
579 if (!Config->is64())
580 COFF->Characteristics |= IMAGE_FILE_32BIT_MACHINE;
581 if (Config->DLL)
582 COFF->Characteristics |= IMAGE_FILE_DLL;
583 if (!Config->Relocatable)
584 COFF->Characteristics |= IMAGE_FILE_RELOCS_STRIPPED;
585 COFF->SizeOfOptionalHeader =
586 sizeof(PEHeaderTy) + sizeof(data_directory) * NumberfOfDataDirectory;
587
588 // Write PE header
589 auto *PE = reinterpret_cast<PEHeaderTy *>(Buf);
590 Buf += sizeof(*PE);
591 PE->Magic = Config->is64() ? PE32Header::PE32_PLUS : PE32Header::PE32;
592
593 // If {Major,Minor}LinkerVersion is left at 0.0, then for some
594 // reason signing the resulting PE file with Authenticode produces a
595 // signature that fails to validate on Windows 7 (but is OK on 10).
596 // Set it to 14.0, which is what VS2015 outputs, and which avoids
597 // that problem.
598 PE->MajorLinkerVersion = 14;
599 PE->MinorLinkerVersion = 0;
600
601 PE->ImageBase = Config->ImageBase;
602 PE->SectionAlignment = PageSize;
603 PE->FileAlignment = SectorSize;
604 PE->MajorImageVersion = Config->MajorImageVersion;
605 PE->MinorImageVersion = Config->MinorImageVersion;
606 PE->MajorOperatingSystemVersion = Config->MajorOSVersion;
607 PE->MinorOperatingSystemVersion = Config->MinorOSVersion;
608 PE->MajorSubsystemVersion = Config->MajorOSVersion;
609 PE->MinorSubsystemVersion = Config->MinorOSVersion;
610 PE->Subsystem = Config->Subsystem;
611 PE->SizeOfImage = SizeOfImage;
612 PE->SizeOfHeaders = SizeOfHeaders;
613 if (!Config->NoEntry) {
614 Defined *Entry = cast<Defined>(Config->Entry);
615 PE->AddressOfEntryPoint = Entry->getRVA();
616 // Pointer to thumb code must have the LSB set, so adjust it.
617 if (Config->Machine == ARMNT)
618 PE->AddressOfEntryPoint |= 1;
619 }
620 PE->SizeOfStackReserve = Config->StackReserve;
621 PE->SizeOfStackCommit = Config->StackCommit;
622 PE->SizeOfHeapReserve = Config->HeapReserve;
623 PE->SizeOfHeapCommit = Config->HeapCommit;
624
625 // Import Descriptor Tables and Import Address Tables are merged
626 // in our output. That's not compatible with the Binding feature
627 // that is sort of prelinking. Setting this flag to make it clear
628 // that our outputs are not for the Binding.
629 PE->DLLCharacteristics = IMAGE_DLL_CHARACTERISTICS_NO_BIND;
630
631 if (Config->AppContainer)
632 PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_APPCONTAINER;
633 if (Config->DynamicBase)
634 PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE;
635 if (Config->HighEntropyVA)
636 PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA;
637 if (Config->NxCompat)
638 PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NX_COMPAT;
639 if (!Config->AllowIsolation)
640 PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION;
641 if (Config->TerminalServerAware)
642 PE->DLLCharacteristics |= IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE;
643 PE->NumberOfRvaAndSize = NumberfOfDataDirectory;
644 if (OutputSection *Text = findSection(".text")) {
645 PE->BaseOfCode = Text->getRVA();
646 PE->SizeOfCode = Text->getRawSize();
647 }
648 PE->SizeOfInitializedData = getSizeOfInitializedData();
649
650 // Write data directory
651 auto *Dir = reinterpret_cast<data_directory *>(Buf);
652 Buf += sizeof(*Dir) * NumberfOfDataDirectory;
653 if (OutputSection *Sec = findSection(".edata")) {
654 Dir[EXPORT_TABLE].RelativeVirtualAddress = Sec->getRVA();
655 Dir[EXPORT_TABLE].Size = Sec->getVirtualSize();
656 }
657 if (!Idata.empty()) {
658 Dir[IMPORT_TABLE].RelativeVirtualAddress = Idata.getDirRVA();
659 Dir[IMPORT_TABLE].Size = Idata.getDirSize();
660 Dir[IAT].RelativeVirtualAddress = Idata.getIATRVA();
661 Dir[IAT].Size = Idata.getIATSize();
662 }
663 if (OutputSection *Sec = findSection(".rsrc")) {
664 Dir[RESOURCE_TABLE].RelativeVirtualAddress = Sec->getRVA();
665 Dir[RESOURCE_TABLE].Size = Sec->getVirtualSize();
666 }
667 if (OutputSection *Sec = findSection(".pdata")) {
668 Dir[EXCEPTION_TABLE].RelativeVirtualAddress = Sec->getRVA();
669 Dir[EXCEPTION_TABLE].Size = Sec->getVirtualSize();
670 }
671 if (OutputSection *Sec = findSection(".reloc")) {
672 Dir[BASE_RELOCATION_TABLE].RelativeVirtualAddress = Sec->getRVA();
673 Dir[BASE_RELOCATION_TABLE].Size = Sec->getVirtualSize();
674 }
675 if (Symbol *Sym = Symtab->findUnderscore("_tls_used")) {
676 if (Defined *B = dyn_cast<Defined>(Sym->body())) {
677 Dir[TLS_TABLE].RelativeVirtualAddress = B->getRVA();
678 Dir[TLS_TABLE].Size = Config->is64()
679 ? sizeof(object::coff_tls_directory64)
680 : sizeof(object::coff_tls_directory32);
681 }
682 }
683 if (Config->Debug) {
684 Dir[DEBUG_DIRECTORY].RelativeVirtualAddress = DebugDirectory->getRVA();
685 Dir[DEBUG_DIRECTORY].Size = DebugDirectory->getSize();
686 }
687 if (Symbol *Sym = Symtab->findUnderscore("_load_config_used")) {
688 if (auto *B = dyn_cast<DefinedRegular>(Sym->body())) {
689 SectionChunk *SC = B->getChunk();
690 assert(B->getRVA() >= SC->getRVA());
691 uint64_t OffsetInChunk = B->getRVA() - SC->getRVA();
692 if (!SC->hasData() || OffsetInChunk + 4 > SC->getSize())
693 fatal("_load_config_used is malformed");
694
695 ArrayRef<uint8_t> SecContents = SC->getContents();
696 uint32_t LoadConfigSize =
697 *reinterpret_cast<const ulittle32_t *>(&SecContents[OffsetInChunk]);
698 if (OffsetInChunk + LoadConfigSize > SC->getSize())
699 fatal("_load_config_used is too large");
700 Dir[LOAD_CONFIG_TABLE].RelativeVirtualAddress = B->getRVA();
701 Dir[LOAD_CONFIG_TABLE].Size = LoadConfigSize;
702 }
703 }
704 if (!DelayIdata.empty()) {
705 Dir[DELAY_IMPORT_DESCRIPTOR].RelativeVirtualAddress =
706 DelayIdata.getDirRVA();
707 Dir[DELAY_IMPORT_DESCRIPTOR].Size = DelayIdata.getDirSize();
708 }
709
710 // Write section table
711 for (OutputSection *Sec : OutputSections) {
712 Sec->writeHeaderTo(Buf);
713 Buf += sizeof(coff_section);
714 }
715 SectionTable = ArrayRef<uint8_t>(
716 Buf - OutputSections.size() * sizeof(coff_section), Buf);
717
718 if (OutputSymtab.empty())
719 return;
720
721 COFF->PointerToSymbolTable = PointerToSymbolTable;
722 uint32_t NumberOfSymbols = OutputSymtab.size();
723 COFF->NumberOfSymbols = NumberOfSymbols;
724 auto *SymbolTable = reinterpret_cast<coff_symbol16 *>(
725 Buffer->getBufferStart() + COFF->PointerToSymbolTable);
726 for (size_t I = 0; I != NumberOfSymbols; ++I)
727 SymbolTable[I] = OutputSymtab[I];
728 // Create the string table, it follows immediately after the symbol table.
729 // The first 4 bytes is length including itself.
730 Buf = reinterpret_cast<uint8_t *>(&SymbolTable[NumberOfSymbols]);
731 write32le(Buf, Strtab.size() + 4);
732 if (!Strtab.empty())
733 memcpy(Buf + 4, Strtab.data(), Strtab.size());
734}
735
736void Writer::openFile(StringRef Path) {
737 Buffer = check(
738 FileOutputBuffer::create(Path, FileSize, FileOutputBuffer::F_executable),
739 "failed to open " + Path);
740}
741
742void Writer::fixSafeSEHSymbols() {
743 if (!SEHTable)
744 return;
745 // Replace the absolute table symbol with a synthetic symbol pointing to the
746 // SEHTable chunk so that we can emit base relocations for it and resolve
747 // section relative relocations.
748 Symbol *T = Symtab->find("___safe_se_handler_table");
749 Symbol *C = Symtab->find("___safe_se_handler_count");
750 replaceBody<DefinedSynthetic>(T, T->body()->getName(), SEHTable);
751 cast<DefinedAbsolute>(C->body())->setVA(SEHTable->getSize() / 4);
752}
753
754// Handles /section options to allow users to overwrite
755// section attributes.
756void Writer::setSectionPermissions() {
757 for (auto &P : Config->Section) {
758 StringRef Name = P.first;
759 uint32_t Perm = P.second;
760 if (auto *Sec = findSection(Name))
761 Sec->setPermissions(Perm);
762 }
763}
764
765// Write section contents to a mmap'ed file.
766void Writer::writeSections() {
767 // Record the section index that should be used when resolving a section
768 // relocation against an absolute symbol.
769 DefinedAbsolute::OutputSectionIndex = OutputSections.size() + 1;
770
771 uint8_t *Buf = Buffer->getBufferStart();
772 for (OutputSection *Sec : OutputSections) {
773 uint8_t *SecBuf = Buf + Sec->getFileOff();
774 // Fill gaps between functions in .text with INT3 instructions
775 // instead of leaving as NUL bytes (which can be interpreted as
776 // ADD instructions).
777 if (Sec->getPermissions() & IMAGE_SCN_CNT_CODE)
778 memset(SecBuf, 0xCC, Sec->getRawSize());
779 for_each(parallel::par, Sec->getChunks().begin(), Sec->getChunks().end(),
780 [&](Chunk *C) { C->writeTo(SecBuf); });
781 }
782}
783
784// Sort .pdata section contents according to PE/COFF spec 5.5.
785void Writer::sortExceptionTable() {
786 OutputSection *Sec = findSection(".pdata");
787 if (!Sec)
788 return;
789 // We assume .pdata contains function table entries only.
790 uint8_t *Begin = Buffer->getBufferStart() + Sec->getFileOff();
791 uint8_t *End = Begin + Sec->getVirtualSize();
792 if (Config->Machine == AMD64) {
793 struct Entry { ulittle32_t Begin, End, Unwind; };
794 sort(parallel::par, (Entry *)Begin, (Entry *)End,
795 [](const Entry &A, const Entry &B) { return A.Begin < B.Begin; });
796 return;
797 }
798 if (Config->Machine == ARMNT) {
799 struct Entry { ulittle32_t Begin, Unwind; };
800 sort(parallel::par, (Entry *)Begin, (Entry *)End,
801 [](const Entry &A, const Entry &B) { return A.Begin < B.Begin; });
802 return;
803 }
804 errs() << "warning: don't know how to handle .pdata.\n";
805}
806
807// Backfill the CVSignature in a PDB70 Debug Record. This backfilling allows us
808// to get reproducible builds.
809void Writer::writeBuildId() {
810 // There is nothing to backfill if BuildId was not setup.
811 if (BuildId == nullptr)
812 return;
813
814 assert(BuildId->DI->Signature.CVSignature == OMF::Signature::PDB70 &&
815 "only PDB 7.0 is supported");
816 assert(sizeof(BuildId->DI->PDB70.Signature) == 16 &&
817 "signature size mismatch");
818
819 // Compute an MD5 hash.
820 ArrayRef<uint8_t> Buf(Buffer->getBufferStart(), Buffer->getBufferEnd());
821 memcpy(BuildId->DI->PDB70.Signature, MD5::hash(Buf).data(), 16);
822
823 // TODO(compnerd) track the Age
824 BuildId->DI->PDB70.Age = 1;
825}
826
827OutputSection *Writer::findSection(StringRef Name) {
828 for (OutputSection *Sec : OutputSections)
829 if (Sec->getName() == Name)
830 return Sec;
831 return nullptr;
832}
833
834uint32_t Writer::getSizeOfInitializedData() {
835 uint32_t Res = 0;
836 for (OutputSection *S : OutputSections)
837 if (S->getPermissions() & IMAGE_SCN_CNT_INITIALIZED_DATA)
838 Res += S->getRawSize();
839 return Res;
840}
841
842// Returns an existing section or create a new one if not found.
843OutputSection *Writer::createSection(StringRef Name) {
844 if (auto *Sec = findSection(Name))
845 return Sec;
846 const auto DATA = IMAGE_SCN_CNT_INITIALIZED_DATA;
847 const auto BSS = IMAGE_SCN_CNT_UNINITIALIZED_DATA;
848 const auto CODE = IMAGE_SCN_CNT_CODE;
849 const auto DISCARDABLE = IMAGE_SCN_MEM_DISCARDABLE;
850 const auto R = IMAGE_SCN_MEM_READ;
851 const auto W = IMAGE_SCN_MEM_WRITE;
852 const auto X = IMAGE_SCN_MEM_EXECUTE;
853 uint32_t Perms = StringSwitch<uint32_t>(Name)
854 .Case(".bss", BSS | R | W)
855 .Case(".data", DATA | R | W)
856 .Cases(".didat", ".edata", ".idata", ".rdata", DATA | R)
857 .Case(".reloc", DATA | DISCARDABLE | R)
858 .Case(".text", CODE | R | X)
859 .Default(0);
860 if (!Perms)
861 llvm_unreachable("unknown section name");
862 auto Sec = make<OutputSection>(Name);
863 Sec->addPermissions(Perms);
864 OutputSections.push_back(Sec);
865 return Sec;
866}
867
868// Dest is .reloc section. Add contents to that section.
869void Writer::addBaserels(OutputSection *Dest) {
870 std::vector<Baserel> V;
871 for (OutputSection *Sec : OutputSections) {
872 if (Sec == Dest)
873 continue;
874 // Collect all locations for base relocations.
875 for (Chunk *C : Sec->getChunks())
876 C->getBaserels(&V);
877 // Add the addresses to .reloc section.
878 if (!V.empty())
879 addBaserelBlocks(Dest, V);
880 V.clear();
881 }
882}
883
884// Add addresses to .reloc section. Note that addresses are grouped by page.
885void Writer::addBaserelBlocks(OutputSection *Dest, std::vector<Baserel> &V) {
886 const uint32_t Mask = ~uint32_t(PageSize - 1);
887 uint32_t Page = V[0].RVA & Mask;
888 size_t I = 0, J = 1;
889 for (size_t E = V.size(); J < E; ++J) {
890 uint32_t P = V[J].RVA & Mask;
891 if (P == Page)
892 continue;
893 Dest->addChunk(make<BaserelChunk>(Page, &V[I], &V[0] + J));
894 I = J;
895 Page = P;
896 }
897 if (I == J)
898 return;
899 Dest->addChunk(make<BaserelChunk>(Page, &V[I], &V[0] + J));
900}
deps/lld/COFF/Writer.h created+75
......@@ -0,0 +1,75 @@
1//===- Writer.h -------------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_COFF_WRITER_H
11#define LLD_COFF_WRITER_H
12
13#include "Chunks.h"
14#include "llvm/ADT/StringRef.h"
15#include "llvm/Object/COFF.h"
16#include <cstdint>
17#include <vector>
18
19namespace lld {
20namespace coff {
21class SymbolTable;
22
23static const int PageSize = 4096;
24
25void writeResult(SymbolTable *T);
26
27// OutputSection represents a section in an output file. It's a
28// container of chunks. OutputSection and Chunk are 1:N relationship.
29// Chunks cannot belong to more than one OutputSections. The writer
30// creates multiple OutputSections and assign them unique,
31// non-overlapping file offsets and RVAs.
32class OutputSection {
33public:
34 OutputSection(llvm::StringRef N) : Name(N), Header({}) {}
35 void setRVA(uint64_t);
36 void setFileOffset(uint64_t);
37 void addChunk(Chunk *C);
38 llvm::StringRef getName() { return Name; }
39 std::vector<Chunk *> &getChunks() { return Chunks; }
40 void addPermissions(uint32_t C);
41 void setPermissions(uint32_t C);
42 uint32_t getPermissions() { return Header.Characteristics & PermMask; }
43 uint32_t getCharacteristics() { return Header.Characteristics; }
44 uint64_t getRVA() { return Header.VirtualAddress; }
45 uint64_t getFileOff() { return Header.PointerToRawData; }
46 void writeHeaderTo(uint8_t *Buf);
47
48 // Returns the size of this section in an executable memory image.
49 // This may be smaller than the raw size (the raw size is multiple
50 // of disk sector size, so there may be padding at end), or may be
51 // larger (if that's the case, the loader reserves spaces after end
52 // of raw data).
53 uint64_t getVirtualSize() { return Header.VirtualSize; }
54
55 // Returns the size of the section in the output file.
56 uint64_t getRawSize() { return Header.SizeOfRawData; }
57
58 // Set offset into the string table storing this section name.
59 // Used only when the name is longer than 8 bytes.
60 void setStringTableOff(uint32_t V) { StringTableOff = V; }
61
62 // N.B. The section index is one based.
63 uint32_t SectionIndex = 0;
64
65private:
66 llvm::StringRef Name;
67 llvm::object::coff_section Header;
68 uint32_t StringTableOff = 0;
69 std::vector<Chunk *> Chunks;
70};
71
72}
73}
74
75#endif
deps/lld/ELF/Arch/AArch64.cpp created+376
......@@ -0,0 +1,376 @@
1//===- AArch64.cpp --------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "Error.h"
11#include "Symbols.h"
12#include "SyntheticSections.h"
13#include "Target.h"
14#include "Thunks.h"
15#include "llvm/Object/ELF.h"
16#include "llvm/Support/Endian.h"
17
18using namespace llvm;
19using namespace llvm::support::endian;
20using namespace llvm::ELF;
21using namespace lld;
22using namespace lld::elf;
23
24// Page(Expr) is the page address of the expression Expr, defined
25// as (Expr & ~0xFFF). (This applies even if the machine page size
26// supported by the platform has a different value.)
27uint64_t elf::getAArch64Page(uint64_t Expr) {
28 return Expr & ~static_cast<uint64_t>(0xFFF);
29}
30
31namespace {
32class AArch64 final : public TargetInfo {
33public:
34 AArch64();
35 RelExpr getRelExpr(uint32_t Type, const SymbolBody &S,
36 const uint8_t *Loc) const override;
37 bool isPicRel(uint32_t Type) const override;
38 void writeGotPlt(uint8_t *Buf, const SymbolBody &S) const override;
39 void writePltHeader(uint8_t *Buf) const override;
40 void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
41 int32_t Index, unsigned RelOff) const override;
42 bool usesOnlyLowPageBits(uint32_t Type) const override;
43 void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
44 RelExpr adjustRelaxExpr(uint32_t Type, const uint8_t *Data,
45 RelExpr Expr) const override;
46 void relaxTlsGdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
47 void relaxTlsGdToIe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
48 void relaxTlsIeToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
49};
50} // namespace
51
52AArch64::AArch64() {
53 CopyRel = R_AARCH64_COPY;
54 RelativeRel = R_AARCH64_RELATIVE;
55 IRelativeRel = R_AARCH64_IRELATIVE;
56 GotRel = R_AARCH64_GLOB_DAT;
57 PltRel = R_AARCH64_JUMP_SLOT;
58 TlsDescRel = R_AARCH64_TLSDESC;
59 TlsGotRel = R_AARCH64_TLS_TPREL64;
60 GotEntrySize = 8;
61 GotPltEntrySize = 8;
62 PltEntrySize = 16;
63 PltHeaderSize = 32;
64 DefaultMaxPageSize = 65536;
65
66 // It doesn't seem to be documented anywhere, but tls on aarch64 uses variant
67 // 1 of the tls structures and the tcb size is 16.
68 TcbSize = 16;
69}
70
71RelExpr AArch64::getRelExpr(uint32_t Type, const SymbolBody &S,
72 const uint8_t *Loc) const {
73 switch (Type) {
74 default:
75 return R_ABS;
76 case R_AARCH64_TLSDESC_ADR_PAGE21:
77 return R_TLSDESC_PAGE;
78 case R_AARCH64_TLSDESC_LD64_LO12:
79 case R_AARCH64_TLSDESC_ADD_LO12:
80 return R_TLSDESC;
81 case R_AARCH64_TLSDESC_CALL:
82 return R_TLSDESC_CALL;
83 case R_AARCH64_TLSLE_ADD_TPREL_HI12:
84 case R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
85 return R_TLS;
86 case R_AARCH64_CALL26:
87 case R_AARCH64_CONDBR19:
88 case R_AARCH64_JUMP26:
89 case R_AARCH64_TSTBR14:
90 return R_PLT_PC;
91 case R_AARCH64_PREL16:
92 case R_AARCH64_PREL32:
93 case R_AARCH64_PREL64:
94 case R_AARCH64_ADR_PREL_LO21:
95 return R_PC;
96 case R_AARCH64_ADR_PREL_PG_HI21:
97 return R_PAGE_PC;
98 case R_AARCH64_LD64_GOT_LO12_NC:
99 case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
100 return R_GOT;
101 case R_AARCH64_ADR_GOT_PAGE:
102 case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
103 return R_GOT_PAGE_PC;
104 case R_AARCH64_NONE:
105 return R_NONE;
106 }
107}
108
109RelExpr AArch64::adjustRelaxExpr(uint32_t Type, const uint8_t *Data,
110 RelExpr Expr) const {
111 if (Expr == R_RELAX_TLS_GD_TO_IE) {
112 if (Type == R_AARCH64_TLSDESC_ADR_PAGE21)
113 return R_RELAX_TLS_GD_TO_IE_PAGE_PC;
114 return R_RELAX_TLS_GD_TO_IE_ABS;
115 }
116 return Expr;
117}
118
119bool AArch64::usesOnlyLowPageBits(uint32_t Type) const {
120 switch (Type) {
121 default:
122 return false;
123 case R_AARCH64_ADD_ABS_LO12_NC:
124 case R_AARCH64_LD64_GOT_LO12_NC:
125 case R_AARCH64_LDST128_ABS_LO12_NC:
126 case R_AARCH64_LDST16_ABS_LO12_NC:
127 case R_AARCH64_LDST32_ABS_LO12_NC:
128 case R_AARCH64_LDST64_ABS_LO12_NC:
129 case R_AARCH64_LDST8_ABS_LO12_NC:
130 case R_AARCH64_TLSDESC_ADD_LO12:
131 case R_AARCH64_TLSDESC_LD64_LO12:
132 case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
133 return true;
134 }
135}
136
137bool AArch64::isPicRel(uint32_t Type) const {
138 return Type == R_AARCH64_ABS32 || Type == R_AARCH64_ABS64;
139}
140
141void AArch64::writeGotPlt(uint8_t *Buf, const SymbolBody &) const {
142 write64le(Buf, InX::Plt->getVA());
143}
144
145void AArch64::writePltHeader(uint8_t *Buf) const {
146 const uint8_t PltData[] = {
147 0xf0, 0x7b, 0xbf, 0xa9, // stp x16, x30, [sp,#-16]!
148 0x10, 0x00, 0x00, 0x90, // adrp x16, Page(&(.plt.got[2]))
149 0x11, 0x02, 0x40, 0xf9, // ldr x17, [x16, Offset(&(.plt.got[2]))]
150 0x10, 0x02, 0x00, 0x91, // add x16, x16, Offset(&(.plt.got[2]))
151 0x20, 0x02, 0x1f, 0xd6, // br x17
152 0x1f, 0x20, 0x03, 0xd5, // nop
153 0x1f, 0x20, 0x03, 0xd5, // nop
154 0x1f, 0x20, 0x03, 0xd5 // nop
155 };
156 memcpy(Buf, PltData, sizeof(PltData));
157
158 uint64_t Got = InX::GotPlt->getVA();
159 uint64_t Plt = InX::Plt->getVA();
160 relocateOne(Buf + 4, R_AARCH64_ADR_PREL_PG_HI21,
161 getAArch64Page(Got + 16) - getAArch64Page(Plt + 4));
162 relocateOne(Buf + 8, R_AARCH64_LDST64_ABS_LO12_NC, Got + 16);
163 relocateOne(Buf + 12, R_AARCH64_ADD_ABS_LO12_NC, Got + 16);
164}
165
166void AArch64::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
167 uint64_t PltEntryAddr, int32_t Index,
168 unsigned RelOff) const {
169 const uint8_t Inst[] = {
170 0x10, 0x00, 0x00, 0x90, // adrp x16, Page(&(.plt.got[n]))
171 0x11, 0x02, 0x40, 0xf9, // ldr x17, [x16, Offset(&(.plt.got[n]))]
172 0x10, 0x02, 0x00, 0x91, // add x16, x16, Offset(&(.plt.got[n]))
173 0x20, 0x02, 0x1f, 0xd6 // br x17
174 };
175 memcpy(Buf, Inst, sizeof(Inst));
176
177 relocateOne(Buf, R_AARCH64_ADR_PREL_PG_HI21,
178 getAArch64Page(GotPltEntryAddr) - getAArch64Page(PltEntryAddr));
179 relocateOne(Buf + 4, R_AARCH64_LDST64_ABS_LO12_NC, GotPltEntryAddr);
180 relocateOne(Buf + 8, R_AARCH64_ADD_ABS_LO12_NC, GotPltEntryAddr);
181}
182
183static void write32AArch64Addr(uint8_t *L, uint64_t Imm) {
184 uint32_t ImmLo = (Imm & 0x3) << 29;
185 uint32_t ImmHi = (Imm & 0x1FFFFC) << 3;
186 uint64_t Mask = (0x3 << 29) | (0x1FFFFC << 3);
187 write32le(L, (read32le(L) & ~Mask) | ImmLo | ImmHi);
188}
189
190// Return the bits [Start, End] from Val shifted Start bits.
191// For instance, getBits(0xF0, 4, 8) returns 0xF.
192static uint64_t getBits(uint64_t Val, int Start, int End) {
193 uint64_t Mask = ((uint64_t)1 << (End + 1 - Start)) - 1;
194 return (Val >> Start) & Mask;
195}
196
197static void or32le(uint8_t *P, int32_t V) { write32le(P, read32le(P) | V); }
198
199// Update the immediate field in a AARCH64 ldr, str, and add instruction.
200static void or32AArch64Imm(uint8_t *L, uint64_t Imm) {
201 or32le(L, (Imm & 0xFFF) << 10);
202}
203
204void AArch64::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const {
205 switch (Type) {
206 case R_AARCH64_ABS16:
207 case R_AARCH64_PREL16:
208 checkIntUInt<16>(Loc, Val, Type);
209 write16le(Loc, Val);
210 break;
211 case R_AARCH64_ABS32:
212 case R_AARCH64_PREL32:
213 checkIntUInt<32>(Loc, Val, Type);
214 write32le(Loc, Val);
215 break;
216 case R_AARCH64_ABS64:
217 case R_AARCH64_GLOB_DAT:
218 case R_AARCH64_PREL64:
219 write64le(Loc, Val);
220 break;
221 case R_AARCH64_ADD_ABS_LO12_NC:
222 or32AArch64Imm(Loc, Val);
223 break;
224 case R_AARCH64_ADR_GOT_PAGE:
225 case R_AARCH64_ADR_PREL_PG_HI21:
226 case R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
227 case R_AARCH64_TLSDESC_ADR_PAGE21:
228 checkInt<33>(Loc, Val, Type);
229 write32AArch64Addr(Loc, Val >> 12);
230 break;
231 case R_AARCH64_ADR_PREL_LO21:
232 checkInt<21>(Loc, Val, Type);
233 write32AArch64Addr(Loc, Val);
234 break;
235 case R_AARCH64_CALL26:
236 case R_AARCH64_JUMP26:
237 checkInt<28>(Loc, Val, Type);
238 or32le(Loc, (Val & 0x0FFFFFFC) >> 2);
239 break;
240 case R_AARCH64_CONDBR19:
241 checkInt<21>(Loc, Val, Type);
242 or32le(Loc, (Val & 0x1FFFFC) << 3);
243 break;
244 case R_AARCH64_LD64_GOT_LO12_NC:
245 case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
246 case R_AARCH64_TLSDESC_LD64_LO12:
247 checkAlignment<8>(Loc, Val, Type);
248 or32le(Loc, (Val & 0xFF8) << 7);
249 break;
250 case R_AARCH64_LDST8_ABS_LO12_NC:
251 or32AArch64Imm(Loc, getBits(Val, 0, 11));
252 break;
253 case R_AARCH64_LDST16_ABS_LO12_NC:
254 or32AArch64Imm(Loc, getBits(Val, 1, 11));
255 break;
256 case R_AARCH64_LDST32_ABS_LO12_NC:
257 or32AArch64Imm(Loc, getBits(Val, 2, 11));
258 break;
259 case R_AARCH64_LDST64_ABS_LO12_NC:
260 or32AArch64Imm(Loc, getBits(Val, 3, 11));
261 break;
262 case R_AARCH64_LDST128_ABS_LO12_NC:
263 or32AArch64Imm(Loc, getBits(Val, 4, 11));
264 break;
265 case R_AARCH64_MOVW_UABS_G0_NC:
266 or32le(Loc, (Val & 0xFFFF) << 5);
267 break;
268 case R_AARCH64_MOVW_UABS_G1_NC:
269 or32le(Loc, (Val & 0xFFFF0000) >> 11);
270 break;
271 case R_AARCH64_MOVW_UABS_G2_NC:
272 or32le(Loc, (Val & 0xFFFF00000000) >> 27);
273 break;
274 case R_AARCH64_MOVW_UABS_G3:
275 or32le(Loc, (Val & 0xFFFF000000000000) >> 43);
276 break;
277 case R_AARCH64_TSTBR14:
278 checkInt<16>(Loc, Val, Type);
279 or32le(Loc, (Val & 0xFFFC) << 3);
280 break;
281 case R_AARCH64_TLSLE_ADD_TPREL_HI12:
282 checkInt<24>(Loc, Val, Type);
283 or32AArch64Imm(Loc, Val >> 12);
284 break;
285 case R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
286 case R_AARCH64_TLSDESC_ADD_LO12:
287 or32AArch64Imm(Loc, Val);
288 break;
289 default:
290 error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type));
291 }
292}
293
294void AArch64::relaxTlsGdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const {
295 // TLSDESC Global-Dynamic relocation are in the form:
296 // adrp x0, :tlsdesc:v [R_AARCH64_TLSDESC_ADR_PAGE21]
297 // ldr x1, [x0, #:tlsdesc_lo12:v [R_AARCH64_TLSDESC_LD64_LO12]
298 // add x0, x0, :tlsdesc_los:v [R_AARCH64_TLSDESC_ADD_LO12]
299 // .tlsdesccall [R_AARCH64_TLSDESC_CALL]
300 // blr x1
301 // And it can optimized to:
302 // movz x0, #0x0, lsl #16
303 // movk x0, #0x10
304 // nop
305 // nop
306 checkUInt<32>(Loc, Val, Type);
307
308 switch (Type) {
309 case R_AARCH64_TLSDESC_ADD_LO12:
310 case R_AARCH64_TLSDESC_CALL:
311 write32le(Loc, 0xd503201f); // nop
312 return;
313 case R_AARCH64_TLSDESC_ADR_PAGE21:
314 write32le(Loc, 0xd2a00000 | (((Val >> 16) & 0xffff) << 5)); // movz
315 return;
316 case R_AARCH64_TLSDESC_LD64_LO12:
317 write32le(Loc, 0xf2800000 | ((Val & 0xffff) << 5)); // movk
318 return;
319 default:
320 llvm_unreachable("unsupported relocation for TLS GD to LE relaxation");
321 }
322}
323
324void AArch64::relaxTlsGdToIe(uint8_t *Loc, uint32_t Type, uint64_t Val) const {
325 // TLSDESC Global-Dynamic relocation are in the form:
326 // adrp x0, :tlsdesc:v [R_AARCH64_TLSDESC_ADR_PAGE21]
327 // ldr x1, [x0, #:tlsdesc_lo12:v [R_AARCH64_TLSDESC_LD64_LO12]
328 // add x0, x0, :tlsdesc_los:v [R_AARCH64_TLSDESC_ADD_LO12]
329 // .tlsdesccall [R_AARCH64_TLSDESC_CALL]
330 // blr x1
331 // And it can optimized to:
332 // adrp x0, :gottprel:v
333 // ldr x0, [x0, :gottprel_lo12:v]
334 // nop
335 // nop
336
337 switch (Type) {
338 case R_AARCH64_TLSDESC_ADD_LO12:
339 case R_AARCH64_TLSDESC_CALL:
340 write32le(Loc, 0xd503201f); // nop
341 break;
342 case R_AARCH64_TLSDESC_ADR_PAGE21:
343 write32le(Loc, 0x90000000); // adrp
344 relocateOne(Loc, R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21, Val);
345 break;
346 case R_AARCH64_TLSDESC_LD64_LO12:
347 write32le(Loc, 0xf9400000); // ldr
348 relocateOne(Loc, R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC, Val);
349 break;
350 default:
351 llvm_unreachable("unsupported relocation for TLS GD to LE relaxation");
352 }
353}
354
355void AArch64::relaxTlsIeToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const {
356 checkUInt<32>(Loc, Val, Type);
357
358 if (Type == R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21) {
359 // Generate MOVZ.
360 uint32_t RegNo = read32le(Loc) & 0x1f;
361 write32le(Loc, (0xd2a00000 | RegNo) | (((Val >> 16) & 0xffff) << 5));
362 return;
363 }
364 if (Type == R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC) {
365 // Generate MOVK.
366 uint32_t RegNo = read32le(Loc) & 0x1f;
367 write32le(Loc, (0xf2800000 | RegNo) | ((Val & 0xffff) << 5));
368 return;
369 }
370 llvm_unreachable("invalid relocation for TLS IE to LE relaxation");
371}
372
373TargetInfo *elf::getAArch64TargetInfo() {
374 static AArch64 Target;
375 return &Target;
376}
deps/lld/ELF/Arch/AMDGPU.cpp created+84
......@@ -0,0 +1,84 @@
1//===- AMDGPU.cpp ---------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "Error.h"
11#include "InputFiles.h"
12#include "Symbols.h"
13#include "Target.h"
14#include "llvm/Object/ELF.h"
15#include "llvm/Support/Endian.h"
16
17using namespace llvm;
18using namespace llvm::object;
19using namespace llvm::support::endian;
20using namespace llvm::ELF;
21using namespace lld;
22using namespace lld::elf;
23
24namespace {
25class AMDGPU final : public TargetInfo {
26public:
27 AMDGPU();
28 void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
29 RelExpr getRelExpr(uint32_t Type, const SymbolBody &S,
30 const uint8_t *Loc) const override;
31};
32} // namespace
33
34AMDGPU::AMDGPU() {
35 RelativeRel = R_AMDGPU_REL64;
36 GotRel = R_AMDGPU_ABS64;
37 GotEntrySize = 8;
38}
39
40void AMDGPU::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const {
41 switch (Type) {
42 case R_AMDGPU_ABS32:
43 case R_AMDGPU_GOTPCREL:
44 case R_AMDGPU_GOTPCREL32_LO:
45 case R_AMDGPU_REL32:
46 case R_AMDGPU_REL32_LO:
47 write32le(Loc, Val);
48 break;
49 case R_AMDGPU_ABS64:
50 write64le(Loc, Val);
51 break;
52 case R_AMDGPU_GOTPCREL32_HI:
53 case R_AMDGPU_REL32_HI:
54 write32le(Loc, Val >> 32);
55 break;
56 default:
57 error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type));
58 }
59}
60
61RelExpr AMDGPU::getRelExpr(uint32_t Type, const SymbolBody &S,
62 const uint8_t *Loc) const {
63 switch (Type) {
64 case R_AMDGPU_ABS32:
65 case R_AMDGPU_ABS64:
66 return R_ABS;
67 case R_AMDGPU_REL32:
68 case R_AMDGPU_REL32_LO:
69 case R_AMDGPU_REL32_HI:
70 return R_PC;
71 case R_AMDGPU_GOTPCREL:
72 case R_AMDGPU_GOTPCREL32_LO:
73 case R_AMDGPU_GOTPCREL32_HI:
74 return R_GOT_PC;
75 default:
76 error(toString(S.File) + ": unknown relocation type: " + toString(Type));
77 return R_HINT;
78 }
79}
80
81TargetInfo *elf::getAMDGPUTargetInfo() {
82 static AMDGPU Target;
83 return &Target;
84}
deps/lld/ELF/Arch/ARM.cpp created+480
......@@ -0,0 +1,480 @@
1//===- ARM.cpp ------------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "Error.h"
11#include "InputFiles.h"
12#include "Symbols.h"
13#include "SyntheticSections.h"
14#include "Target.h"
15#include "Thunks.h"
16#include "llvm/Object/ELF.h"
17#include "llvm/Support/Endian.h"
18
19using namespace llvm;
20using namespace llvm::support::endian;
21using namespace llvm::ELF;
22using namespace lld;
23using namespace lld::elf;
24
25namespace {
26class ARM final : public TargetInfo {
27public:
28 ARM();
29 RelExpr getRelExpr(uint32_t Type, const SymbolBody &S,
30 const uint8_t *Loc) const override;
31 bool isPicRel(uint32_t Type) const override;
32 uint32_t getDynRel(uint32_t Type) const override;
33 int64_t getImplicitAddend(const uint8_t *Buf, uint32_t Type) const override;
34 void writeGotPlt(uint8_t *Buf, const SymbolBody &S) const override;
35 void writeIgotPlt(uint8_t *Buf, const SymbolBody &S) const override;
36 void writePltHeader(uint8_t *Buf) const override;
37 void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
38 int32_t Index, unsigned RelOff) const override;
39 void addPltSymbols(InputSectionBase *IS, uint64_t Off) const override;
40 void addPltHeaderSymbols(InputSectionBase *ISD) const override;
41 bool needsThunk(RelExpr Expr, uint32_t RelocType, const InputFile *File,
42 const SymbolBody &S) const override;
43 bool inBranchRange(uint32_t RelocType, uint64_t Src,
44 uint64_t Dst) const override;
45 void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
46};
47} // namespace
48
49ARM::ARM() {
50 CopyRel = R_ARM_COPY;
51 RelativeRel = R_ARM_RELATIVE;
52 IRelativeRel = R_ARM_IRELATIVE;
53 GotRel = R_ARM_GLOB_DAT;
54 PltRel = R_ARM_JUMP_SLOT;
55 TlsGotRel = R_ARM_TLS_TPOFF32;
56 TlsModuleIndexRel = R_ARM_TLS_DTPMOD32;
57 TlsOffsetRel = R_ARM_TLS_DTPOFF32;
58 GotEntrySize = 4;
59 GotPltEntrySize = 4;
60 PltEntrySize = 16;
61 PltHeaderSize = 20;
62 TrapInstr = 0xd4d4d4d4;
63 // ARM uses Variant 1 TLS
64 TcbSize = 8;
65 NeedsThunks = true;
66}
67
68RelExpr ARM::getRelExpr(uint32_t Type, const SymbolBody &S,
69 const uint8_t *Loc) const {
70 switch (Type) {
71 default:
72 return R_ABS;
73 case R_ARM_THM_JUMP11:
74 return R_PC;
75 case R_ARM_CALL:
76 case R_ARM_JUMP24:
77 case R_ARM_PC24:
78 case R_ARM_PLT32:
79 case R_ARM_PREL31:
80 case R_ARM_THM_JUMP19:
81 case R_ARM_THM_JUMP24:
82 case R_ARM_THM_CALL:
83 return R_PLT_PC;
84 case R_ARM_GOTOFF32:
85 // (S + A) - GOT_ORG
86 return R_GOTREL;
87 case R_ARM_GOT_BREL:
88 // GOT(S) + A - GOT_ORG
89 return R_GOT_OFF;
90 case R_ARM_GOT_PREL:
91 case R_ARM_TLS_IE32:
92 // GOT(S) + A - P
93 return R_GOT_PC;
94 case R_ARM_SBREL32:
95 return R_ARM_SBREL;
96 case R_ARM_TARGET1:
97 return Config->Target1Rel ? R_PC : R_ABS;
98 case R_ARM_TARGET2:
99 if (Config->Target2 == Target2Policy::Rel)
100 return R_PC;
101 if (Config->Target2 == Target2Policy::Abs)
102 return R_ABS;
103 return R_GOT_PC;
104 case R_ARM_TLS_GD32:
105 return R_TLSGD_PC;
106 case R_ARM_TLS_LDM32:
107 return R_TLSLD_PC;
108 case R_ARM_BASE_PREL:
109 // B(S) + A - P
110 // FIXME: currently B(S) assumed to be .got, this may not hold for all
111 // platforms.
112 return R_GOTONLY_PC;
113 case R_ARM_MOVW_PREL_NC:
114 case R_ARM_MOVT_PREL:
115 case R_ARM_REL32:
116 case R_ARM_THM_MOVW_PREL_NC:
117 case R_ARM_THM_MOVT_PREL:
118 return R_PC;
119 case R_ARM_NONE:
120 return R_NONE;
121 case R_ARM_TLS_LE32:
122 return R_TLS;
123 }
124}
125
126bool ARM::isPicRel(uint32_t Type) const {
127 return (Type == R_ARM_TARGET1 && !Config->Target1Rel) ||
128 (Type == R_ARM_ABS32);
129}
130
131uint32_t ARM::getDynRel(uint32_t Type) const {
132 if (Type == R_ARM_TARGET1 && !Config->Target1Rel)
133 return R_ARM_ABS32;
134 if (Type == R_ARM_ABS32)
135 return Type;
136 // Keep it going with a dummy value so that we can find more reloc errors.
137 return R_ARM_ABS32;
138}
139
140void ARM::writeGotPlt(uint8_t *Buf, const SymbolBody &) const {
141 write32le(Buf, InX::Plt->getVA());
142}
143
144void ARM::writeIgotPlt(uint8_t *Buf, const SymbolBody &S) const {
145 // An ARM entry is the address of the ifunc resolver function.
146 write32le(Buf, S.getVA());
147}
148
149void ARM::writePltHeader(uint8_t *Buf) const {
150 const uint8_t PltData[] = {
151 0x04, 0xe0, 0x2d, 0xe5, // str lr, [sp,#-4]!
152 0x04, 0xe0, 0x9f, 0xe5, // ldr lr, L2
153 0x0e, 0xe0, 0x8f, 0xe0, // L1: add lr, pc, lr
154 0x08, 0xf0, 0xbe, 0xe5, // ldr pc, [lr, #8]
155 0x00, 0x00, 0x00, 0x00, // L2: .word &(.got.plt) - L1 - 8
156 };
157 memcpy(Buf, PltData, sizeof(PltData));
158 uint64_t GotPlt = InX::GotPlt->getVA();
159 uint64_t L1 = InX::Plt->getVA() + 8;
160 write32le(Buf + 16, GotPlt - L1 - 8);
161}
162
163void ARM::addPltHeaderSymbols(InputSectionBase *ISD) const {
164 auto *IS = cast<InputSection>(ISD);
165 addSyntheticLocal("$a", STT_NOTYPE, 0, 0, IS);
166 addSyntheticLocal("$d", STT_NOTYPE, 16, 0, IS);
167}
168
169void ARM::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
170 uint64_t PltEntryAddr, int32_t Index,
171 unsigned RelOff) const {
172 // FIXME: Using simple code sequence with simple relocations.
173 // There is a more optimal sequence but it requires support for the group
174 // relocations. See ELF for the ARM Architecture Appendix A.3
175 const uint8_t PltData[] = {
176 0x04, 0xc0, 0x9f, 0xe5, // ldr ip, L2
177 0x0f, 0xc0, 0x8c, 0xe0, // L1: add ip, ip, pc
178 0x00, 0xf0, 0x9c, 0xe5, // ldr pc, [ip]
179 0x00, 0x00, 0x00, 0x00, // L2: .word Offset(&(.plt.got) - L1 - 8
180 };
181 memcpy(Buf, PltData, sizeof(PltData));
182 uint64_t L1 = PltEntryAddr + 4;
183 write32le(Buf + 12, GotPltEntryAddr - L1 - 8);
184}
185
186void ARM::addPltSymbols(InputSectionBase *ISD, uint64_t Off) const {
187 auto *IS = cast<InputSection>(ISD);
188 addSyntheticLocal("$a", STT_NOTYPE, Off, 0, IS);
189 addSyntheticLocal("$d", STT_NOTYPE, Off + 12, 0, IS);
190}
191
192bool ARM::needsThunk(RelExpr Expr, uint32_t RelocType, const InputFile *File,
193 const SymbolBody &S) const {
194 // If S is an undefined weak symbol in an executable we don't need a Thunk.
195 // In a DSO calls to undefined symbols, including weak ones get PLT entries
196 // which may need a thunk.
197 if (S.isUndefined() && !S.isLocal() && S.symbol()->isWeak() &&
198 !Config->Shared)
199 return false;
200 // A state change from ARM to Thumb and vice versa must go through an
201 // interworking thunk if the relocation type is not R_ARM_CALL or
202 // R_ARM_THM_CALL.
203 switch (RelocType) {
204 case R_ARM_PC24:
205 case R_ARM_PLT32:
206 case R_ARM_JUMP24:
207 // Source is ARM, all PLT entries are ARM so no interworking required.
208 // Otherwise we need to interwork if Symbol has bit 0 set (Thumb).
209 if (Expr == R_PC && ((S.getVA() & 1) == 1))
210 return true;
211 break;
212 case R_ARM_THM_JUMP19:
213 case R_ARM_THM_JUMP24:
214 // Source is Thumb, all PLT entries are ARM so interworking is required.
215 // Otherwise we need to interwork if Symbol has bit 0 clear (ARM).
216 if (Expr == R_PLT_PC || ((S.getVA() & 1) == 0))
217 return true;
218 break;
219 }
220 return false;
221}
222
223bool ARM::inBranchRange(uint32_t RelocType, uint64_t Src, uint64_t Dst) const {
224 uint64_t Range;
225 uint64_t InstrSize;
226
227 switch (RelocType) {
228 case R_ARM_PC24:
229 case R_ARM_PLT32:
230 case R_ARM_JUMP24:
231 case R_ARM_CALL:
232 Range = 0x2000000;
233 InstrSize = 4;
234 break;
235 case R_ARM_THM_JUMP19:
236 Range = 0x100000;
237 InstrSize = 2;
238 break;
239 case R_ARM_THM_JUMP24:
240 case R_ARM_THM_CALL:
241 Range = 0x1000000;
242 InstrSize = 2;
243 break;
244 default:
245 return true;
246 }
247 // PC at Src is 2 instructions ahead, immediate of branch is signed
248 if (Src > Dst)
249 Range -= 2 * InstrSize;
250 else
251 Range += InstrSize;
252
253 if ((Dst & 0x1) == 0)
254 // Destination is ARM, if ARM caller then Src is already 4-byte aligned.
255 // If Thumb Caller (BLX) the Src address has bottom 2 bits cleared to ensure
256 // destination will be 4 byte aligned.
257 Src &= ~0x3;
258 else
259 // Bit 0 == 1 denotes Thumb state, it is not part of the range
260 Dst &= ~0x1;
261
262 uint64_t Distance = (Src > Dst) ? Src - Dst : Dst - Src;
263 return Distance <= Range;
264}
265
266void ARM::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const {
267 switch (Type) {
268 case R_ARM_ABS32:
269 case R_ARM_BASE_PREL:
270 case R_ARM_GLOB_DAT:
271 case R_ARM_GOTOFF32:
272 case R_ARM_GOT_BREL:
273 case R_ARM_GOT_PREL:
274 case R_ARM_REL32:
275 case R_ARM_RELATIVE:
276 case R_ARM_SBREL32:
277 case R_ARM_TARGET1:
278 case R_ARM_TARGET2:
279 case R_ARM_TLS_GD32:
280 case R_ARM_TLS_IE32:
281 case R_ARM_TLS_LDM32:
282 case R_ARM_TLS_LDO32:
283 case R_ARM_TLS_LE32:
284 case R_ARM_TLS_TPOFF32:
285 case R_ARM_TLS_DTPOFF32:
286 write32le(Loc, Val);
287 break;
288 case R_ARM_TLS_DTPMOD32:
289 write32le(Loc, 1);
290 break;
291 case R_ARM_PREL31:
292 checkInt<31>(Loc, Val, Type);
293 write32le(Loc, (read32le(Loc) & 0x80000000) | (Val & ~0x80000000));
294 break;
295 case R_ARM_CALL:
296 // R_ARM_CALL is used for BL and BLX instructions, depending on the
297 // value of bit 0 of Val, we must select a BL or BLX instruction
298 if (Val & 1) {
299 // If bit 0 of Val is 1 the target is Thumb, we must select a BLX.
300 // The BLX encoding is 0xfa:H:imm24 where Val = imm24:H:'1'
301 checkInt<26>(Loc, Val, Type);
302 write32le(Loc, 0xfa000000 | // opcode
303 ((Val & 2) << 23) | // H
304 ((Val >> 2) & 0x00ffffff)); // imm24
305 break;
306 }
307 if ((read32le(Loc) & 0xfe000000) == 0xfa000000)
308 // BLX (always unconditional) instruction to an ARM Target, select an
309 // unconditional BL.
310 write32le(Loc, 0xeb000000 | (read32le(Loc) & 0x00ffffff));
311 // fall through as BL encoding is shared with B
312 LLVM_FALLTHROUGH;
313 case R_ARM_JUMP24:
314 case R_ARM_PC24:
315 case R_ARM_PLT32:
316 checkInt<26>(Loc, Val, Type);
317 write32le(Loc, (read32le(Loc) & ~0x00ffffff) | ((Val >> 2) & 0x00ffffff));
318 break;
319 case R_ARM_THM_JUMP11:
320 checkInt<12>(Loc, Val, Type);
321 write16le(Loc, (read32le(Loc) & 0xf800) | ((Val >> 1) & 0x07ff));
322 break;
323 case R_ARM_THM_JUMP19:
324 // Encoding T3: Val = S:J2:J1:imm6:imm11:0
325 checkInt<21>(Loc, Val, Type);
326 write16le(Loc,
327 (read16le(Loc) & 0xfbc0) | // opcode cond
328 ((Val >> 10) & 0x0400) | // S
329 ((Val >> 12) & 0x003f)); // imm6
330 write16le(Loc + 2,
331 0x8000 | // opcode
332 ((Val >> 8) & 0x0800) | // J2
333 ((Val >> 5) & 0x2000) | // J1
334 ((Val >> 1) & 0x07ff)); // imm11
335 break;
336 case R_ARM_THM_CALL:
337 // R_ARM_THM_CALL is used for BL and BLX instructions, depending on the
338 // value of bit 0 of Val, we must select a BL or BLX instruction
339 if ((Val & 1) == 0) {
340 // Ensure BLX destination is 4-byte aligned. As BLX instruction may
341 // only be two byte aligned. This must be done before overflow check
342 Val = alignTo(Val, 4);
343 }
344 // Bit 12 is 0 for BLX, 1 for BL
345 write16le(Loc + 2, (read16le(Loc + 2) & ~0x1000) | (Val & 1) << 12);
346 // Fall through as rest of encoding is the same as B.W
347 LLVM_FALLTHROUGH;
348 case R_ARM_THM_JUMP24:
349 // Encoding B T4, BL T1, BLX T2: Val = S:I1:I2:imm10:imm11:0
350 // FIXME: Use of I1 and I2 require v6T2ops
351 checkInt<25>(Loc, Val, Type);
352 write16le(Loc,
353 0xf000 | // opcode
354 ((Val >> 14) & 0x0400) | // S
355 ((Val >> 12) & 0x03ff)); // imm10
356 write16le(Loc + 2,
357 (read16le(Loc + 2) & 0xd000) | // opcode
358 (((~(Val >> 10)) ^ (Val >> 11)) & 0x2000) | // J1
359 (((~(Val >> 11)) ^ (Val >> 13)) & 0x0800) | // J2
360 ((Val >> 1) & 0x07ff)); // imm11
361 break;
362 case R_ARM_MOVW_ABS_NC:
363 case R_ARM_MOVW_PREL_NC:
364 write32le(Loc, (read32le(Loc) & ~0x000f0fff) | ((Val & 0xf000) << 4) |
365 (Val & 0x0fff));
366 break;
367 case R_ARM_MOVT_ABS:
368 case R_ARM_MOVT_PREL:
369 checkInt<32>(Loc, Val, Type);
370 write32le(Loc, (read32le(Loc) & ~0x000f0fff) |
371 (((Val >> 16) & 0xf000) << 4) | ((Val >> 16) & 0xfff));
372 break;
373 case R_ARM_THM_MOVT_ABS:
374 case R_ARM_THM_MOVT_PREL:
375 // Encoding T1: A = imm4:i:imm3:imm8
376 checkInt<32>(Loc, Val, Type);
377 write16le(Loc,
378 0xf2c0 | // opcode
379 ((Val >> 17) & 0x0400) | // i
380 ((Val >> 28) & 0x000f)); // imm4
381 write16le(Loc + 2,
382 (read16le(Loc + 2) & 0x8f00) | // opcode
383 ((Val >> 12) & 0x7000) | // imm3
384 ((Val >> 16) & 0x00ff)); // imm8
385 break;
386 case R_ARM_THM_MOVW_ABS_NC:
387 case R_ARM_THM_MOVW_PREL_NC:
388 // Encoding T3: A = imm4:i:imm3:imm8
389 write16le(Loc,
390 0xf240 | // opcode
391 ((Val >> 1) & 0x0400) | // i
392 ((Val >> 12) & 0x000f)); // imm4
393 write16le(Loc + 2,
394 (read16le(Loc + 2) & 0x8f00) | // opcode
395 ((Val << 4) & 0x7000) | // imm3
396 (Val & 0x00ff)); // imm8
397 break;
398 default:
399 error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type));
400 }
401}
402
403int64_t ARM::getImplicitAddend(const uint8_t *Buf, uint32_t Type) const {
404 switch (Type) {
405 default:
406 return 0;
407 case R_ARM_ABS32:
408 case R_ARM_BASE_PREL:
409 case R_ARM_GOTOFF32:
410 case R_ARM_GOT_BREL:
411 case R_ARM_GOT_PREL:
412 case R_ARM_REL32:
413 case R_ARM_TARGET1:
414 case R_ARM_TARGET2:
415 case R_ARM_TLS_GD32:
416 case R_ARM_TLS_LDM32:
417 case R_ARM_TLS_LDO32:
418 case R_ARM_TLS_IE32:
419 case R_ARM_TLS_LE32:
420 return SignExtend64<32>(read32le(Buf));
421 case R_ARM_PREL31:
422 return SignExtend64<31>(read32le(Buf));
423 case R_ARM_CALL:
424 case R_ARM_JUMP24:
425 case R_ARM_PC24:
426 case R_ARM_PLT32:
427 return SignExtend64<26>(read32le(Buf) << 2);
428 case R_ARM_THM_JUMP11:
429 return SignExtend64<12>(read16le(Buf) << 1);
430 case R_ARM_THM_JUMP19: {
431 // Encoding T3: A = S:J2:J1:imm10:imm6:0
432 uint16_t Hi = read16le(Buf);
433 uint16_t Lo = read16le(Buf + 2);
434 return SignExtend64<20>(((Hi & 0x0400) << 10) | // S
435 ((Lo & 0x0800) << 8) | // J2
436 ((Lo & 0x2000) << 5) | // J1
437 ((Hi & 0x003f) << 12) | // imm6
438 ((Lo & 0x07ff) << 1)); // imm11:0
439 }
440 case R_ARM_THM_CALL:
441 case R_ARM_THM_JUMP24: {
442 // Encoding B T4, BL T1, BLX T2: A = S:I1:I2:imm10:imm11:0
443 // I1 = NOT(J1 EOR S), I2 = NOT(J2 EOR S)
444 // FIXME: I1 and I2 require v6T2ops
445 uint16_t Hi = read16le(Buf);
446 uint16_t Lo = read16le(Buf + 2);
447 return SignExtend64<24>(((Hi & 0x0400) << 14) | // S
448 (~((Lo ^ (Hi << 3)) << 10) & 0x00800000) | // I1
449 (~((Lo ^ (Hi << 1)) << 11) & 0x00400000) | // I2
450 ((Hi & 0x003ff) << 12) | // imm0
451 ((Lo & 0x007ff) << 1)); // imm11:0
452 }
453 // ELF for the ARM Architecture 4.6.1.1 the implicit addend for MOVW and
454 // MOVT is in the range -32768 <= A < 32768
455 case R_ARM_MOVW_ABS_NC:
456 case R_ARM_MOVT_ABS:
457 case R_ARM_MOVW_PREL_NC:
458 case R_ARM_MOVT_PREL: {
459 uint64_t Val = read32le(Buf) & 0x000f0fff;
460 return SignExtend64<16>(((Val & 0x000f0000) >> 4) | (Val & 0x00fff));
461 }
462 case R_ARM_THM_MOVW_ABS_NC:
463 case R_ARM_THM_MOVT_ABS:
464 case R_ARM_THM_MOVW_PREL_NC:
465 case R_ARM_THM_MOVT_PREL: {
466 // Encoding T3: A = imm4:i:imm3:imm8
467 uint16_t Hi = read16le(Buf);
468 uint16_t Lo = read16le(Buf + 2);
469 return SignExtend64<16>(((Hi & 0x000f) << 12) | // imm4
470 ((Hi & 0x0400) << 1) | // i
471 ((Lo & 0x7000) >> 4) | // imm3
472 (Lo & 0x00ff)); // imm8
473 }
474 }
475}
476
477TargetInfo *elf::getARMTargetInfo() {
478 static ARM Target;
479 return &Target;
480}
deps/lld/ELF/Arch/AVR.cpp created+80
......@@ -0,0 +1,80 @@
1//===- AVR.cpp ------------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// AVR is a Harvard-architecture 8-bit micrcontroller designed for small
11// baremetal programs. All AVR-family processors have 32 8-bit registers.
12// The tiniest AVR has 32 byte RAM and 1 KiB program memory, and the largest
13// one supports up to 2^24 data address space and 2^22 code address space.
14//
15// Since it is a baremetal programming, there's usually no loader to load
16// ELF files on AVRs. You are expected to link your program against address
17// 0 and pull out a .text section from the result using objcopy, so that you
18// can write the linked code to on-chip flush memory. You can do that with
19// the following commands:
20//
21// ld.lld -Ttext=0 -o foo foo.o
22// objcopy -O binary --only-section=.text foo output.bin
23//
24// Note that the current AVR support is very preliminary so you can't
25// link any useful program yet, though.
26//
27//===----------------------------------------------------------------------===//
28
29#include "Error.h"
30#include "InputFiles.h"
31#include "Symbols.h"
32#include "Target.h"
33#include "llvm/Object/ELF.h"
34#include "llvm/Support/Endian.h"
35
36using namespace llvm;
37using namespace llvm::object;
38using namespace llvm::support::endian;
39using namespace llvm::ELF;
40using namespace lld;
41using namespace lld::elf;
42
43namespace {
44class AVR final : public TargetInfo {
45public:
46 RelExpr getRelExpr(uint32_t Type, const SymbolBody &S,
47 const uint8_t *Loc) const override;
48 void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
49};
50} // namespace
51
52RelExpr AVR::getRelExpr(uint32_t Type, const SymbolBody &S,
53 const uint8_t *Loc) const {
54 switch (Type) {
55 case R_AVR_CALL:
56 return R_ABS;
57 default:
58 error(toString(S.File) + ": unknown relocation type: " + toString(Type));
59 return R_HINT;
60 }
61}
62
63void AVR::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const {
64 switch (Type) {
65 case R_AVR_CALL: {
66 uint16_t Hi = Val >> 17;
67 uint16_t Lo = Val >> 1;
68 write16le(Loc, read16le(Loc) | ((Hi >> 1) << 4) | (Hi & 1));
69 write16le(Loc + 2, Lo);
70 break;
71 }
72 default:
73 error(getErrorLocation(Loc) + "unrecognized reloc " + toString(Type));
74 }
75}
76
77TargetInfo *elf::getAVRTargetInfo() {
78 static AVR Target;
79 return &Target;
80}
deps/lld/ELF/Arch/Mips.cpp created+423
......@@ -0,0 +1,423 @@
1//===- MIPS.cpp -----------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "Error.h"
11#include "InputFiles.h"
12#include "OutputSections.h"
13#include "Symbols.h"
14#include "SyntheticSections.h"
15#include "Target.h"
16#include "Thunks.h"
17#include "llvm/Object/ELF.h"
18#include "llvm/Support/Endian.h"
19
20using namespace llvm;
21using namespace llvm::object;
22using namespace llvm::support::endian;
23using namespace llvm::ELF;
24using namespace lld;
25using namespace lld::elf;
26
27namespace {
28template <class ELFT> class MIPS final : public TargetInfo {
29public:
30 MIPS();
31 RelExpr getRelExpr(uint32_t Type, const SymbolBody &S,
32 const uint8_t *Loc) const override;
33 int64_t getImplicitAddend(const uint8_t *Buf, uint32_t Type) const override;
34 bool isPicRel(uint32_t Type) const override;
35 uint32_t getDynRel(uint32_t Type) const override;
36 void writeGotPlt(uint8_t *Buf, const SymbolBody &S) const override;
37 void writePltHeader(uint8_t *Buf) const override;
38 void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
39 int32_t Index, unsigned RelOff) const override;
40 bool needsThunk(RelExpr Expr, uint32_t RelocType, const InputFile *File,
41 const SymbolBody &S) const override;
42 void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
43 bool usesOnlyLowPageBits(uint32_t Type) const override;
44};
45} // namespace
46
47template <class ELFT> MIPS<ELFT>::MIPS() {
48 GotPltHeaderEntriesNum = 2;
49 DefaultMaxPageSize = 65536;
50 GotEntrySize = sizeof(typename ELFT::uint);
51 GotPltEntrySize = sizeof(typename ELFT::uint);
52 PltEntrySize = 16;
53 PltHeaderSize = 32;
54 CopyRel = R_MIPS_COPY;
55 PltRel = R_MIPS_JUMP_SLOT;
56 NeedsThunks = true;
57 TrapInstr = 0xefefefef;
58
59 if (ELFT::Is64Bits) {
60 RelativeRel = (R_MIPS_64 << 8) | R_MIPS_REL32;
61 TlsGotRel = R_MIPS_TLS_TPREL64;
62 TlsModuleIndexRel = R_MIPS_TLS_DTPMOD64;
63 TlsOffsetRel = R_MIPS_TLS_DTPREL64;
64 } else {
65 RelativeRel = R_MIPS_REL32;
66 TlsGotRel = R_MIPS_TLS_TPREL32;
67 TlsModuleIndexRel = R_MIPS_TLS_DTPMOD32;
68 TlsOffsetRel = R_MIPS_TLS_DTPREL32;
69 }
70}
71
72template <class ELFT>
73RelExpr MIPS<ELFT>::getRelExpr(uint32_t Type, const SymbolBody &S,
74 const uint8_t *Loc) const {
75 // See comment in the calculateMipsRelChain.
76 if (ELFT::Is64Bits || Config->MipsN32Abi)
77 Type &= 0xff;
78 switch (Type) {
79 default:
80 return R_ABS;
81 case R_MIPS_JALR:
82 return R_HINT;
83 case R_MIPS_GPREL16:
84 case R_MIPS_GPREL32:
85 return R_MIPS_GOTREL;
86 case R_MIPS_26:
87 return R_PLT;
88 case R_MIPS_HI16:
89 case R_MIPS_LO16:
90 // R_MIPS_HI16/R_MIPS_LO16 relocations against _gp_disp calculate
91 // offset between start of function and 'gp' value which by default
92 // equal to the start of .got section. In that case we consider these
93 // relocations as relative.
94 if (&S == ElfSym::MipsGpDisp)
95 return R_MIPS_GOT_GP_PC;
96 if (&S == ElfSym::MipsLocalGp)
97 return R_MIPS_GOT_GP;
98 LLVM_FALLTHROUGH;
99 case R_MIPS_GOT_OFST:
100 return R_ABS;
101 case R_MIPS_PC32:
102 case R_MIPS_PC16:
103 case R_MIPS_PC19_S2:
104 case R_MIPS_PC21_S2:
105 case R_MIPS_PC26_S2:
106 case R_MIPS_PCHI16:
107 case R_MIPS_PCLO16:
108 return R_PC;
109 case R_MIPS_GOT16:
110 if (S.isLocal())
111 return R_MIPS_GOT_LOCAL_PAGE;
112 LLVM_FALLTHROUGH;
113 case R_MIPS_CALL16:
114 case R_MIPS_GOT_DISP:
115 case R_MIPS_TLS_GOTTPREL:
116 return R_MIPS_GOT_OFF;
117 case R_MIPS_CALL_HI16:
118 case R_MIPS_CALL_LO16:
119 case R_MIPS_GOT_HI16:
120 case R_MIPS_GOT_LO16:
121 return R_MIPS_GOT_OFF32;
122 case R_MIPS_GOT_PAGE:
123 return R_MIPS_GOT_LOCAL_PAGE;
124 case R_MIPS_TLS_GD:
125 return R_MIPS_TLSGD;
126 case R_MIPS_TLS_LDM:
127 return R_MIPS_TLSLD;
128 }
129}
130
131template <class ELFT> bool MIPS<ELFT>::isPicRel(uint32_t Type) const {
132 return Type == R_MIPS_32 || Type == R_MIPS_64;
133}
134
135template <class ELFT> uint32_t MIPS<ELFT>::getDynRel(uint32_t Type) const {
136 return RelativeRel;
137}
138
139template <class ELFT>
140void MIPS<ELFT>::writeGotPlt(uint8_t *Buf, const SymbolBody &) const {
141 write32<ELFT::TargetEndianness>(Buf, InX::Plt->getVA());
142}
143
144template <endianness E, uint8_t BSIZE, uint8_t SHIFT>
145static int64_t getPcRelocAddend(const uint8_t *Loc) {
146 uint32_t Instr = read32<E>(Loc);
147 uint32_t Mask = 0xffffffff >> (32 - BSIZE);
148 return SignExtend64<BSIZE + SHIFT>((Instr & Mask) << SHIFT);
149}
150
151template <endianness E, uint8_t BSIZE, uint8_t SHIFT>
152static void applyMipsPcReloc(uint8_t *Loc, uint32_t Type, uint64_t V) {
153 uint32_t Mask = 0xffffffff >> (32 - BSIZE);
154 uint32_t Instr = read32<E>(Loc);
155 if (SHIFT > 0)
156 checkAlignment<(1 << SHIFT)>(Loc, V, Type);
157 checkInt<BSIZE + SHIFT>(Loc, V, Type);
158 write32<E>(Loc, (Instr & ~Mask) | ((V >> SHIFT) & Mask));
159}
160
161template <endianness E> static void writeMipsHi16(uint8_t *Loc, uint64_t V) {
162 uint32_t Instr = read32<E>(Loc);
163 uint16_t Res = ((V + 0x8000) >> 16) & 0xffff;
164 write32<E>(Loc, (Instr & 0xffff0000) | Res);
165}
166
167template <endianness E> static void writeMipsHigher(uint8_t *Loc, uint64_t V) {
168 uint32_t Instr = read32<E>(Loc);
169 uint16_t Res = ((V + 0x80008000) >> 32) & 0xffff;
170 write32<E>(Loc, (Instr & 0xffff0000) | Res);
171}
172
173template <endianness E> static void writeMipsHighest(uint8_t *Loc, uint64_t V) {
174 uint32_t Instr = read32<E>(Loc);
175 uint16_t Res = ((V + 0x800080008000) >> 48) & 0xffff;
176 write32<E>(Loc, (Instr & 0xffff0000) | Res);
177}
178
179template <endianness E> static void writeMipsLo16(uint8_t *Loc, uint64_t V) {
180 uint32_t Instr = read32<E>(Loc);
181 write32<E>(Loc, (Instr & 0xffff0000) | (V & 0xffff));
182}
183
184template <class ELFT> static bool isMipsR6() {
185 const auto &FirstObj = cast<ELFFileBase<ELFT>>(*Config->FirstElf);
186 uint32_t Arch = FirstObj.getObj().getHeader()->e_flags & EF_MIPS_ARCH;
187 return Arch == EF_MIPS_ARCH_32R6 || Arch == EF_MIPS_ARCH_64R6;
188}
189
190template <class ELFT> void MIPS<ELFT>::writePltHeader(uint8_t *Buf) const {
191 const endianness E = ELFT::TargetEndianness;
192 if (Config->MipsN32Abi) {
193 write32<E>(Buf, 0x3c0e0000); // lui $14, %hi(&GOTPLT[0])
194 write32<E>(Buf + 4, 0x8dd90000); // lw $25, %lo(&GOTPLT[0])($14)
195 write32<E>(Buf + 8, 0x25ce0000); // addiu $14, $14, %lo(&GOTPLT[0])
196 write32<E>(Buf + 12, 0x030ec023); // subu $24, $24, $14
197 } else {
198 write32<E>(Buf, 0x3c1c0000); // lui $28, %hi(&GOTPLT[0])
199 write32<E>(Buf + 4, 0x8f990000); // lw $25, %lo(&GOTPLT[0])($28)
200 write32<E>(Buf + 8, 0x279c0000); // addiu $28, $28, %lo(&GOTPLT[0])
201 write32<E>(Buf + 12, 0x031cc023); // subu $24, $24, $28
202 }
203
204 write32<E>(Buf + 16, 0x03e07825); // move $15, $31
205 write32<E>(Buf + 20, 0x0018c082); // srl $24, $24, 2
206 write32<E>(Buf + 24, 0x0320f809); // jalr $25
207 write32<E>(Buf + 28, 0x2718fffe); // subu $24, $24, 2
208
209 uint64_t GotPlt = InX::GotPlt->getVA();
210 writeMipsHi16<E>(Buf, GotPlt);
211 writeMipsLo16<E>(Buf + 4, GotPlt);
212 writeMipsLo16<E>(Buf + 8, GotPlt);
213}
214
215template <class ELFT>
216void MIPS<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
217 uint64_t PltEntryAddr, int32_t Index,
218 unsigned RelOff) const {
219 const endianness E = ELFT::TargetEndianness;
220 write32<E>(Buf, 0x3c0f0000); // lui $15, %hi(.got.plt entry)
221 write32<E>(Buf + 4, 0x8df90000); // l[wd] $25, %lo(.got.plt entry)($15)
222 // jr $25
223 write32<E>(Buf + 8, isMipsR6<ELFT>() ? 0x03200009 : 0x03200008);
224 write32<E>(Buf + 12, 0x25f80000); // addiu $24, $15, %lo(.got.plt entry)
225 writeMipsHi16<E>(Buf, GotPltEntryAddr);
226 writeMipsLo16<E>(Buf + 4, GotPltEntryAddr);
227 writeMipsLo16<E>(Buf + 12, GotPltEntryAddr);
228}
229
230template <class ELFT>
231bool MIPS<ELFT>::needsThunk(RelExpr Expr, uint32_t Type, const InputFile *File,
232 const SymbolBody &S) const {
233 // Any MIPS PIC code function is invoked with its address in register $t9.
234 // So if we have a branch instruction from non-PIC code to the PIC one
235 // we cannot make the jump directly and need to create a small stubs
236 // to save the target function address.
237 // See page 3-38 ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
238 if (Type != R_MIPS_26)
239 return false;
240 auto *F = dyn_cast_or_null<ELFFileBase<ELFT>>(File);
241 if (!F)
242 return false;
243 // If current file has PIC code, LA25 stub is not required.
244 if (F->getObj().getHeader()->e_flags & EF_MIPS_PIC)
245 return false;
246 auto *D = dyn_cast<DefinedRegular>(&S);
247 // LA25 is required if target file has PIC code
248 // or target symbol is a PIC symbol.
249 return D && D->isMipsPIC<ELFT>();
250}
251
252template <class ELFT>
253int64_t MIPS<ELFT>::getImplicitAddend(const uint8_t *Buf, uint32_t Type) const {
254 const endianness E = ELFT::TargetEndianness;
255 switch (Type) {
256 default:
257 return 0;
258 case R_MIPS_32:
259 case R_MIPS_GPREL32:
260 case R_MIPS_TLS_DTPREL32:
261 case R_MIPS_TLS_TPREL32:
262 return SignExtend64<32>(read32<E>(Buf));
263 case R_MIPS_26:
264 // FIXME (simon): If the relocation target symbol is not a PLT entry
265 // we should use another expression for calculation:
266 // ((A << 2) | (P & 0xf0000000)) >> 2
267 return SignExtend64<28>((read32<E>(Buf) & 0x3ffffff) << 2);
268 case R_MIPS_GPREL16:
269 case R_MIPS_LO16:
270 case R_MIPS_PCLO16:
271 case R_MIPS_TLS_DTPREL_HI16:
272 case R_MIPS_TLS_DTPREL_LO16:
273 case R_MIPS_TLS_TPREL_HI16:
274 case R_MIPS_TLS_TPREL_LO16:
275 return SignExtend64<16>(read32<E>(Buf));
276 case R_MIPS_PC16:
277 return getPcRelocAddend<E, 16, 2>(Buf);
278 case R_MIPS_PC19_S2:
279 return getPcRelocAddend<E, 19, 2>(Buf);
280 case R_MIPS_PC21_S2:
281 return getPcRelocAddend<E, 21, 2>(Buf);
282 case R_MIPS_PC26_S2:
283 return getPcRelocAddend<E, 26, 2>(Buf);
284 case R_MIPS_PC32:
285 return getPcRelocAddend<E, 32, 0>(Buf);
286 }
287}
288
289static std::pair<uint32_t, uint64_t>
290calculateMipsRelChain(uint8_t *Loc, uint32_t Type, uint64_t Val) {
291 // MIPS N64 ABI packs multiple relocations into the single relocation
292 // record. In general, all up to three relocations can have arbitrary
293 // types. In fact, Clang and GCC uses only a few combinations. For now,
294 // we support two of them. That is allow to pass at least all LLVM
295 // test suite cases.
296 // <any relocation> / R_MIPS_SUB / R_MIPS_HI16 | R_MIPS_LO16
297 // <any relocation> / R_MIPS_64 / R_MIPS_NONE
298 // The first relocation is a 'real' relocation which is calculated
299 // using the corresponding symbol's value. The second and the third
300 // relocations used to modify result of the first one: extend it to
301 // 64-bit, extract high or low part etc. For details, see part 2.9 Relocation
302 // at the https://dmz-portal.mips.com/mw/images/8/82/007-4658-001.pdf
303 uint32_t Type2 = (Type >> 8) & 0xff;
304 uint32_t Type3 = (Type >> 16) & 0xff;
305 if (Type2 == R_MIPS_NONE && Type3 == R_MIPS_NONE)
306 return std::make_pair(Type, Val);
307 if (Type2 == R_MIPS_64 && Type3 == R_MIPS_NONE)
308 return std::make_pair(Type2, Val);
309 if (Type2 == R_MIPS_SUB && (Type3 == R_MIPS_HI16 || Type3 == R_MIPS_LO16))
310 return std::make_pair(Type3, -Val);
311 error(getErrorLocation(Loc) + "unsupported relocations combination " +
312 Twine(Type));
313 return std::make_pair(Type & 0xff, Val);
314}
315
316template <class ELFT>
317void MIPS<ELFT>::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const {
318 const endianness E = ELFT::TargetEndianness;
319 // Thread pointer and DRP offsets from the start of TLS data area.
320 // https://www.linux-mips.org/wiki/NPTL
321 if (Type == R_MIPS_TLS_DTPREL_HI16 || Type == R_MIPS_TLS_DTPREL_LO16 ||
322 Type == R_MIPS_TLS_DTPREL32 || Type == R_MIPS_TLS_DTPREL64)
323 Val -= 0x8000;
324 else if (Type == R_MIPS_TLS_TPREL_HI16 || Type == R_MIPS_TLS_TPREL_LO16 ||
325 Type == R_MIPS_TLS_TPREL32 || Type == R_MIPS_TLS_TPREL64)
326 Val -= 0x7000;
327 if (ELFT::Is64Bits || Config->MipsN32Abi)
328 std::tie(Type, Val) = calculateMipsRelChain(Loc, Type, Val);
329 switch (Type) {
330 case R_MIPS_32:
331 case R_MIPS_GPREL32:
332 case R_MIPS_TLS_DTPREL32:
333 case R_MIPS_TLS_TPREL32:
334 write32<E>(Loc, Val);
335 break;
336 case R_MIPS_64:
337 case R_MIPS_TLS_DTPREL64:
338 case R_MIPS_TLS_TPREL64:
339 write64<E>(Loc, Val);
340 break;
341 case R_MIPS_26:
342 write32<E>(Loc, (read32<E>(Loc) & ~0x3ffffff) | ((Val >> 2) & 0x3ffffff));
343 break;
344 case R_MIPS_GOT16:
345 // The R_MIPS_GOT16 relocation's value in "relocatable" linking mode
346 // is updated addend (not a GOT index). In that case write high 16 bits
347 // to store a correct addend value.
348 if (Config->Relocatable)
349 writeMipsHi16<E>(Loc, Val);
350 else {
351 checkInt<16>(Loc, Val, Type);
352 writeMipsLo16<E>(Loc, Val);
353 }
354 break;
355 case R_MIPS_GOT_DISP:
356 case R_MIPS_GOT_PAGE:
357 case R_MIPS_GPREL16:
358 case R_MIPS_TLS_GD:
359 case R_MIPS_TLS_LDM:
360 checkInt<16>(Loc, Val, Type);
361 LLVM_FALLTHROUGH;
362 case R_MIPS_CALL16:
363 case R_MIPS_CALL_LO16:
364 case R_MIPS_GOT_LO16:
365 case R_MIPS_GOT_OFST:
366 case R_MIPS_LO16:
367 case R_MIPS_PCLO16:
368 case R_MIPS_TLS_DTPREL_LO16:
369 case R_MIPS_TLS_GOTTPREL:
370 case R_MIPS_TLS_TPREL_LO16:
371 writeMipsLo16<E>(Loc, Val);
372 break;
373 case R_MIPS_CALL_HI16:
374 case R_MIPS_GOT_HI16:
375 case R_MIPS_HI16:
376 case R_MIPS_PCHI16:
377 case R_MIPS_TLS_DTPREL_HI16:
378 case R_MIPS_TLS_TPREL_HI16:
379 writeMipsHi16<E>(Loc, Val);
380 break;
381 case R_MIPS_HIGHER:
382 writeMipsHigher<E>(Loc, Val);
383 break;
384 case R_MIPS_HIGHEST:
385 writeMipsHighest<E>(Loc, Val);
386 break;
387 case R_MIPS_JALR:
388 // Ignore this optimization relocation for now
389 break;
390 case R_MIPS_PC16:
391 applyMipsPcReloc<E, 16, 2>(Loc, Type, Val);
392 break;
393 case R_MIPS_PC19_S2:
394 applyMipsPcReloc<E, 19, 2>(Loc, Type, Val);
395 break;
396 case R_MIPS_PC21_S2:
397 applyMipsPcReloc<E, 21, 2>(Loc, Type, Val);
398 break;
399 case R_MIPS_PC26_S2:
400 applyMipsPcReloc<E, 26, 2>(Loc, Type, Val);
401 break;
402 case R_MIPS_PC32:
403 applyMipsPcReloc<E, 32, 0>(Loc, Type, Val);
404 break;
405 default:
406 error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type));
407 }
408}
409
410template <class ELFT>
411bool MIPS<ELFT>::usesOnlyLowPageBits(uint32_t Type) const {
412 return Type == R_MIPS_LO16 || Type == R_MIPS_GOT_OFST;
413}
414
415template <class ELFT> TargetInfo *elf::getMipsTargetInfo() {
416 static MIPS<ELFT> Target;
417 return &Target;
418}
419
420template TargetInfo *elf::getMipsTargetInfo<ELF32LE>();
421template TargetInfo *elf::getMipsTargetInfo<ELF32BE>();
422template TargetInfo *elf::getMipsTargetInfo<ELF64LE>();
423template TargetInfo *elf::getMipsTargetInfo<ELF64BE>();
deps/lld/ELF/Arch/MipsArchTree.cpp created+369
......@@ -0,0 +1,369 @@
1//===- MipsArchTree.cpp --------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===---------------------------------------------------------------------===//
9//
10// This file contains a helper function for the Writer.
11//
12//===---------------------------------------------------------------------===//
13
14#include "Error.h"
15#include "InputFiles.h"
16#include "SymbolTable.h"
17#include "Writer.h"
18
19#include "llvm/BinaryFormat/ELF.h"
20#include "llvm/Object/ELF.h"
21#include "llvm/Support/MipsABIFlags.h"
22
23using namespace llvm;
24using namespace llvm::object;
25using namespace llvm::ELF;
26
27using namespace lld;
28using namespace lld::elf;
29
30namespace {
31struct ArchTreeEdge {
32 uint32_t Child;
33 uint32_t Parent;
34};
35
36struct FileFlags {
37 StringRef Filename;
38 uint32_t Flags;
39};
40} // namespace
41
42static StringRef getAbiName(uint32_t Flags) {
43 switch (Flags) {
44 case 0:
45 return "n64";
46 case EF_MIPS_ABI2:
47 return "n32";
48 case EF_MIPS_ABI_O32:
49 return "o32";
50 case EF_MIPS_ABI_O64:
51 return "o64";
52 case EF_MIPS_ABI_EABI32:
53 return "eabi32";
54 case EF_MIPS_ABI_EABI64:
55 return "eabi64";
56 default:
57 return "unknown";
58 }
59}
60
61static StringRef getNanName(bool IsNan2008) {
62 return IsNan2008 ? "2008" : "legacy";
63}
64
65static StringRef getFpName(bool IsFp64) { return IsFp64 ? "64" : "32"; }
66
67static void checkFlags(ArrayRef<FileFlags> Files) {
68 uint32_t ABI = Files[0].Flags & (EF_MIPS_ABI | EF_MIPS_ABI2);
69 bool Nan = Files[0].Flags & EF_MIPS_NAN2008;
70 bool Fp = Files[0].Flags & EF_MIPS_FP64;
71
72 for (const FileFlags &F : Files.slice(1)) {
73 uint32_t ABI2 = F.Flags & (EF_MIPS_ABI | EF_MIPS_ABI2);
74 if (ABI != ABI2)
75 error("target ABI '" + getAbiName(ABI) + "' is incompatible with '" +
76 getAbiName(ABI2) + "': " + F.Filename);
77
78 bool Nan2 = F.Flags & EF_MIPS_NAN2008;
79 if (Nan != Nan2)
80 error("target -mnan=" + getNanName(Nan) + " is incompatible with -mnan=" +
81 getNanName(Nan2) + ": " + F.Filename);
82
83 bool Fp2 = F.Flags & EF_MIPS_FP64;
84 if (Fp != Fp2)
85 error("target -mfp" + getFpName(Fp) + " is incompatible with -mfp" +
86 getFpName(Fp2) + ": " + F.Filename);
87 }
88}
89
90static uint32_t getMiscFlags(ArrayRef<FileFlags> Files) {
91 uint32_t Ret = 0;
92 for (const FileFlags &F : Files)
93 Ret |= F.Flags &
94 (EF_MIPS_ABI | EF_MIPS_ABI2 | EF_MIPS_ARCH_ASE | EF_MIPS_NOREORDER |
95 EF_MIPS_MICROMIPS | EF_MIPS_NAN2008 | EF_MIPS_32BITMODE);
96 return Ret;
97}
98
99static uint32_t getPicFlags(ArrayRef<FileFlags> Files) {
100 // Check PIC/non-PIC compatibility.
101 bool IsPic = Files[0].Flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
102 for (const FileFlags &F : Files.slice(1)) {
103 bool IsPic2 = F.Flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
104 if (IsPic && !IsPic2)
105 warn("linking abicalls code with non-abicalls file: " + F.Filename);
106 if (!IsPic && IsPic2)
107 warn("linking non-abicalls code with abicalls file: " + F.Filename);
108 }
109
110 // Compute the result PIC/non-PIC flag.
111 uint32_t Ret = Files[0].Flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
112 for (const FileFlags &F : Files.slice(1))
113 Ret &= F.Flags & (EF_MIPS_PIC | EF_MIPS_CPIC);
114
115 // PIC code is inherently CPIC and may not set CPIC flag explicitly.
116 if (Ret & EF_MIPS_PIC)
117 Ret |= EF_MIPS_CPIC;
118 return Ret;
119}
120
121static ArchTreeEdge ArchTree[] = {
122 // MIPS32R6 and MIPS64R6 are not compatible with other extensions
123 // MIPS64R2 extensions.
124 {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON3, EF_MIPS_ARCH_64R2},
125 {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON2, EF_MIPS_ARCH_64R2},
126 {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_OCTEON, EF_MIPS_ARCH_64R2},
127 {EF_MIPS_ARCH_64R2 | EF_MIPS_MACH_LS3A, EF_MIPS_ARCH_64R2},
128 // MIPS64 extensions.
129 {EF_MIPS_ARCH_64 | EF_MIPS_MACH_SB1, EF_MIPS_ARCH_64},
130 {EF_MIPS_ARCH_64 | EF_MIPS_MACH_XLR, EF_MIPS_ARCH_64},
131 {EF_MIPS_ARCH_64R2, EF_MIPS_ARCH_64},
132 // MIPS V extensions.
133 {EF_MIPS_ARCH_64, EF_MIPS_ARCH_5},
134 // R5000 extensions.
135 {EF_MIPS_ARCH_4 | EF_MIPS_MACH_5500, EF_MIPS_ARCH_4 | EF_MIPS_MACH_5400},
136 // MIPS IV extensions.
137 {EF_MIPS_ARCH_4 | EF_MIPS_MACH_5400, EF_MIPS_ARCH_4},
138 {EF_MIPS_ARCH_4 | EF_MIPS_MACH_9000, EF_MIPS_ARCH_4},
139 {EF_MIPS_ARCH_5, EF_MIPS_ARCH_4},
140 // VR4100 extensions.
141 {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4111, EF_MIPS_ARCH_3 | EF_MIPS_MACH_4100},
142 {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4120, EF_MIPS_ARCH_3 | EF_MIPS_MACH_4100},
143 // MIPS III extensions.
144 {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4010, EF_MIPS_ARCH_3},
145 {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4100, EF_MIPS_ARCH_3},
146 {EF_MIPS_ARCH_3 | EF_MIPS_MACH_4650, EF_MIPS_ARCH_3},
147 {EF_MIPS_ARCH_3 | EF_MIPS_MACH_5900, EF_MIPS_ARCH_3},
148 {EF_MIPS_ARCH_3 | EF_MIPS_MACH_LS2E, EF_MIPS_ARCH_3},
149 {EF_MIPS_ARCH_3 | EF_MIPS_MACH_LS2F, EF_MIPS_ARCH_3},
150 {EF_MIPS_ARCH_4, EF_MIPS_ARCH_3},
151 // MIPS32 extensions.
152 {EF_MIPS_ARCH_32R2, EF_MIPS_ARCH_32},
153 // MIPS II extensions.
154 {EF_MIPS_ARCH_3, EF_MIPS_ARCH_2},
155 {EF_MIPS_ARCH_32, EF_MIPS_ARCH_2},
156 // MIPS I extensions.
157 {EF_MIPS_ARCH_1 | EF_MIPS_MACH_3900, EF_MIPS_ARCH_1},
158 {EF_MIPS_ARCH_2, EF_MIPS_ARCH_1},
159};
160
161static bool isArchMatched(uint32_t New, uint32_t Res) {
162 if (New == Res)
163 return true;
164 if (New == EF_MIPS_ARCH_32 && isArchMatched(EF_MIPS_ARCH_64, Res))
165 return true;
166 if (New == EF_MIPS_ARCH_32R2 && isArchMatched(EF_MIPS_ARCH_64R2, Res))
167 return true;
168 for (const auto &Edge : ArchTree) {
169 if (Res == Edge.Child) {
170 Res = Edge.Parent;
171 if (Res == New)
172 return true;
173 }
174 }
175 return false;
176}
177
178static StringRef getMachName(uint32_t Flags) {
179 switch (Flags & EF_MIPS_MACH) {
180 case EF_MIPS_MACH_NONE:
181 return "";
182 case EF_MIPS_MACH_3900:
183 return "r3900";
184 case EF_MIPS_MACH_4010:
185 return "r4010";
186 case EF_MIPS_MACH_4100:
187 return "r4100";
188 case EF_MIPS_MACH_4650:
189 return "r4650";
190 case EF_MIPS_MACH_4120:
191 return "r4120";
192 case EF_MIPS_MACH_4111:
193 return "r4111";
194 case EF_MIPS_MACH_5400:
195 return "vr5400";
196 case EF_MIPS_MACH_5900:
197 return "vr5900";
198 case EF_MIPS_MACH_5500:
199 return "vr5500";
200 case EF_MIPS_MACH_9000:
201 return "rm9000";
202 case EF_MIPS_MACH_LS2E:
203 return "loongson2e";
204 case EF_MIPS_MACH_LS2F:
205 return "loongson2f";
206 case EF_MIPS_MACH_LS3A:
207 return "loongson3a";
208 case EF_MIPS_MACH_OCTEON:
209 return "octeon";
210 case EF_MIPS_MACH_OCTEON2:
211 return "octeon2";
212 case EF_MIPS_MACH_OCTEON3:
213 return "octeon3";
214 case EF_MIPS_MACH_SB1:
215 return "sb1";
216 case EF_MIPS_MACH_XLR:
217 return "xlr";
218 default:
219 return "unknown machine";
220 }
221}
222
223static StringRef getArchName(uint32_t Flags) {
224 StringRef S = getMachName(Flags);
225 if (!S.empty())
226 return S;
227
228 switch (Flags & EF_MIPS_ARCH) {
229 case EF_MIPS_ARCH_1:
230 return "mips1";
231 case EF_MIPS_ARCH_2:
232 return "mips2";
233 case EF_MIPS_ARCH_3:
234 return "mips3";
235 case EF_MIPS_ARCH_4:
236 return "mips4";
237 case EF_MIPS_ARCH_5:
238 return "mips5";
239 case EF_MIPS_ARCH_32:
240 return "mips32";
241 case EF_MIPS_ARCH_64:
242 return "mips64";
243 case EF_MIPS_ARCH_32R2:
244 return "mips32r2";
245 case EF_MIPS_ARCH_64R2:
246 return "mips64r2";
247 case EF_MIPS_ARCH_32R6:
248 return "mips32r6";
249 case EF_MIPS_ARCH_64R6:
250 return "mips64r6";
251 default:
252 return "unknown arch";
253 }
254}
255
256// There are (arguably too) many MIPS ISAs out there. Their relationships
257// can be represented as a forest. If all input files have ISAs which
258// reachable by repeated proceeding from the single child to the parent,
259// these input files are compatible. In that case we need to return "highest"
260// ISA. If there are incompatible input files, we show an error.
261// For example, mips1 is a "parent" of mips2 and such files are compatible.
262// Output file gets EF_MIPS_ARCH_2 flag. From the other side mips3 and mips32
263// are incompatible because nor mips3 is a parent for misp32, nor mips32
264// is a parent for mips3.
265static uint32_t getArchFlags(ArrayRef<FileFlags> Files) {
266 uint32_t Ret = Files[0].Flags & (EF_MIPS_ARCH | EF_MIPS_MACH);
267
268 for (const FileFlags &F : Files.slice(1)) {
269 uint32_t New = F.Flags & (EF_MIPS_ARCH | EF_MIPS_MACH);
270
271 // Check ISA compatibility.
272 if (isArchMatched(New, Ret))
273 continue;
274 if (!isArchMatched(Ret, New)) {
275 error("target ISA '" + getArchName(Ret) + "' is incompatible with '" +
276 getArchName(New) + "': " + F.Filename);
277 return 0;
278 }
279 Ret = New;
280 }
281 return Ret;
282}
283
284template <class ELFT> uint32_t elf::getMipsEFlags() {
285 std::vector<FileFlags> V;
286 for (elf::ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles())
287 V.push_back({F->getName(), F->getObj().getHeader()->e_flags});
288 if (V.empty())
289 return 0;
290 checkFlags(V);
291 return getMiscFlags(V) | getPicFlags(V) | getArchFlags(V);
292}
293
294static int compareMipsFpAbi(uint8_t FpA, uint8_t FpB) {
295 if (FpA == FpB)
296 return 0;
297 if (FpB == Mips::Val_GNU_MIPS_ABI_FP_ANY)
298 return 1;
299 if (FpB == Mips::Val_GNU_MIPS_ABI_FP_64A &&
300 FpA == Mips::Val_GNU_MIPS_ABI_FP_64)
301 return 1;
302 if (FpB != Mips::Val_GNU_MIPS_ABI_FP_XX)
303 return -1;
304 if (FpA == Mips::Val_GNU_MIPS_ABI_FP_DOUBLE ||
305 FpA == Mips::Val_GNU_MIPS_ABI_FP_64 ||
306 FpA == Mips::Val_GNU_MIPS_ABI_FP_64A)
307 return 1;
308 return -1;
309}
310
311static StringRef getMipsFpAbiName(uint8_t FpAbi) {
312 switch (FpAbi) {
313 case Mips::Val_GNU_MIPS_ABI_FP_ANY:
314 return "any";
315 case Mips::Val_GNU_MIPS_ABI_FP_DOUBLE:
316 return "-mdouble-float";
317 case Mips::Val_GNU_MIPS_ABI_FP_SINGLE:
318 return "-msingle-float";
319 case Mips::Val_GNU_MIPS_ABI_FP_SOFT:
320 return "-msoft-float";
321 case Mips::Val_GNU_MIPS_ABI_FP_OLD_64:
322 return "-mips32r2 -mfp64 (old)";
323 case Mips::Val_GNU_MIPS_ABI_FP_XX:
324 return "-mfpxx";
325 case Mips::Val_GNU_MIPS_ABI_FP_64:
326 return "-mgp32 -mfp64";
327 case Mips::Val_GNU_MIPS_ABI_FP_64A:
328 return "-mgp32 -mfp64 -mno-odd-spreg";
329 default:
330 return "unknown";
331 }
332}
333
334uint8_t elf::getMipsFpAbiFlag(uint8_t OldFlag, uint8_t NewFlag,
335 StringRef FileName) {
336 if (compareMipsFpAbi(NewFlag, OldFlag) >= 0)
337 return NewFlag;
338 if (compareMipsFpAbi(OldFlag, NewFlag) < 0)
339 error("target floating point ABI '" + getMipsFpAbiName(OldFlag) +
340 "' is incompatible with '" + getMipsFpAbiName(NewFlag) +
341 "': " + FileName);
342 return OldFlag;
343}
344
345template <class ELFT> static bool isN32Abi(const InputFile *F) {
346 if (auto *EF = dyn_cast<ELFFileBase<ELFT>>(F))
347 return EF->getObj().getHeader()->e_flags & EF_MIPS_ABI2;
348 return false;
349}
350
351bool elf::isMipsN32Abi(const InputFile *F) {
352 switch (Config->EKind) {
353 case ELF32LEKind:
354 return isN32Abi<ELF32LE>(F);
355 case ELF32BEKind:
356 return isN32Abi<ELF32BE>(F);
357 case ELF64LEKind:
358 return isN32Abi<ELF64LE>(F);
359 case ELF64BEKind:
360 return isN32Abi<ELF64BE>(F);
361 default:
362 llvm_unreachable("unknown Config->EKind");
363 }
364}
365
366template uint32_t elf::getMipsEFlags<ELF32LE>();
367template uint32_t elf::getMipsEFlags<ELF32BE>();
368template uint32_t elf::getMipsEFlags<ELF64LE>();
369template uint32_t elf::getMipsEFlags<ELF64BE>();
deps/lld/ELF/Arch/PPC.cpp created+65
......@@ -0,0 +1,65 @@
1//===- PPC.cpp ------------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "Error.h"
11#include "Symbols.h"
12#include "Target.h"
13#include "llvm/Support/Endian.h"
14
15using namespace llvm;
16using namespace llvm::support::endian;
17using namespace llvm::ELF;
18using namespace lld;
19using namespace lld::elf;
20
21namespace {
22class PPC final : public TargetInfo {
23public:
24 PPC() { GotBaseSymOff = 0x8000; }
25 void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
26 RelExpr getRelExpr(uint32_t Type, const SymbolBody &S,
27 const uint8_t *Loc) const override;
28};
29} // namespace
30
31void PPC::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const {
32 switch (Type) {
33 case R_PPC_ADDR16_HA:
34 write16be(Loc, (Val + 0x8000) >> 16);
35 break;
36 case R_PPC_ADDR16_LO:
37 write16be(Loc, Val);
38 break;
39 case R_PPC_ADDR32:
40 case R_PPC_REL32:
41 write32be(Loc, Val);
42 break;
43 case R_PPC_REL24:
44 write32be(Loc, read32be(Loc) | (Val & 0x3FFFFFC));
45 break;
46 default:
47 error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type));
48 }
49}
50
51RelExpr PPC::getRelExpr(uint32_t Type, const SymbolBody &S,
52 const uint8_t *Loc) const {
53 switch (Type) {
54 case R_PPC_REL24:
55 case R_PPC_REL32:
56 return R_PC;
57 default:
58 return R_ABS;
59 }
60}
61
62TargetInfo *elf::getPPCTargetInfo() {
63 static PPC Target;
64 return &Target;
65}
deps/lld/ELF/Arch/PPC64.cpp created+217
......@@ -0,0 +1,217 @@
1//===- PPC64.cpp ----------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "Error.h"
11#include "Symbols.h"
12#include "SyntheticSections.h"
13#include "Target.h"
14#include "llvm/Support/Endian.h"
15
16using namespace llvm;
17using namespace llvm::support::endian;
18using namespace llvm::ELF;
19using namespace lld;
20using namespace lld::elf;
21
22static uint64_t PPC64TocOffset = 0x8000;
23
24uint64_t elf::getPPC64TocBase() {
25 // The TOC consists of sections .got, .toc, .tocbss, .plt in that order. The
26 // TOC starts where the first of these sections starts. We always create a
27 // .got when we see a relocation that uses it, so for us the start is always
28 // the .got.
29 uint64_t TocVA = InX::Got->getVA();
30
31 // Per the ppc64-elf-linux ABI, The TOC base is TOC value plus 0x8000
32 // thus permitting a full 64 Kbytes segment. Note that the glibc startup
33 // code (crt1.o) assumes that you can get from the TOC base to the
34 // start of the .toc section with only a single (signed) 16-bit relocation.
35 return TocVA + PPC64TocOffset;
36}
37
38namespace {
39class PPC64 final : public TargetInfo {
40public:
41 PPC64();
42 RelExpr getRelExpr(uint32_t Type, const SymbolBody &S,
43 const uint8_t *Loc) const override;
44 void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
45 int32_t Index, unsigned RelOff) const override;
46 void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
47};
48} // namespace
49
50// Relocation masks following the #lo(value), #hi(value), #ha(value),
51// #higher(value), #highera(value), #highest(value), and #highesta(value)
52// macros defined in section 4.5.1. Relocation Types of the PPC-elf64abi
53// document.
54static uint16_t applyPPCLo(uint64_t V) { return V; }
55static uint16_t applyPPCHi(uint64_t V) { return V >> 16; }
56static uint16_t applyPPCHa(uint64_t V) { return (V + 0x8000) >> 16; }
57static uint16_t applyPPCHigher(uint64_t V) { return V >> 32; }
58static uint16_t applyPPCHighera(uint64_t V) { return (V + 0x8000) >> 32; }
59static uint16_t applyPPCHighest(uint64_t V) { return V >> 48; }
60static uint16_t applyPPCHighesta(uint64_t V) { return (V + 0x8000) >> 48; }
61
62PPC64::PPC64() {
63 PltRel = GotRel = R_PPC64_GLOB_DAT;
64 RelativeRel = R_PPC64_RELATIVE;
65 GotEntrySize = 8;
66 GotPltEntrySize = 8;
67 PltEntrySize = 32;
68 PltHeaderSize = 0;
69
70 // We need 64K pages (at least under glibc/Linux, the loader won't
71 // set different permissions on a finer granularity than that).
72 DefaultMaxPageSize = 65536;
73
74 // The PPC64 ELF ABI v1 spec, says:
75 //
76 // It is normally desirable to put segments with different characteristics
77 // in separate 256 Mbyte portions of the address space, to give the
78 // operating system full paging flexibility in the 64-bit address space.
79 //
80 // And because the lowest non-zero 256M boundary is 0x10000000, PPC64 linkers
81 // use 0x10000000 as the starting address.
82 DefaultImageBase = 0x10000000;
83}
84
85RelExpr PPC64::getRelExpr(uint32_t Type, const SymbolBody &S,
86 const uint8_t *Loc) const {
87 switch (Type) {
88 default:
89 return R_ABS;
90 case R_PPC64_TOC16:
91 case R_PPC64_TOC16_DS:
92 case R_PPC64_TOC16_HA:
93 case R_PPC64_TOC16_HI:
94 case R_PPC64_TOC16_LO:
95 case R_PPC64_TOC16_LO_DS:
96 return R_GOTREL;
97 case R_PPC64_TOC:
98 return R_PPC_TOC;
99 case R_PPC64_REL24:
100 return R_PPC_PLT_OPD;
101 }
102}
103
104void PPC64::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
105 uint64_t PltEntryAddr, int32_t Index,
106 unsigned RelOff) const {
107 uint64_t Off = GotPltEntryAddr - getPPC64TocBase();
108
109 // FIXME: What we should do, in theory, is get the offset of the function
110 // descriptor in the .opd section, and use that as the offset from %r2 (the
111 // TOC-base pointer). Instead, we have the GOT-entry offset, and that will
112 // be a pointer to the function descriptor in the .opd section. Using
113 // this scheme is simpler, but requires an extra indirection per PLT dispatch.
114
115 write32be(Buf, 0xf8410028); // std %r2, 40(%r1)
116 write32be(Buf + 4, 0x3d620000 | applyPPCHa(Off)); // addis %r11, %r2, X@ha
117 write32be(Buf + 8, 0xe98b0000 | applyPPCLo(Off)); // ld %r12, X@l(%r11)
118 write32be(Buf + 12, 0xe96c0000); // ld %r11,0(%r12)
119 write32be(Buf + 16, 0x7d6903a6); // mtctr %r11
120 write32be(Buf + 20, 0xe84c0008); // ld %r2,8(%r12)
121 write32be(Buf + 24, 0xe96c0010); // ld %r11,16(%r12)
122 write32be(Buf + 28, 0x4e800420); // bctr
123}
124
125static std::pair<uint32_t, uint64_t> toAddr16Rel(uint32_t Type, uint64_t Val) {
126 uint64_t V = Val - PPC64TocOffset;
127 switch (Type) {
128 case R_PPC64_TOC16:
129 return {R_PPC64_ADDR16, V};
130 case R_PPC64_TOC16_DS:
131 return {R_PPC64_ADDR16_DS, V};
132 case R_PPC64_TOC16_HA:
133 return {R_PPC64_ADDR16_HA, V};
134 case R_PPC64_TOC16_HI:
135 return {R_PPC64_ADDR16_HI, V};
136 case R_PPC64_TOC16_LO:
137 return {R_PPC64_ADDR16_LO, V};
138 case R_PPC64_TOC16_LO_DS:
139 return {R_PPC64_ADDR16_LO_DS, V};
140 default:
141 return {Type, Val};
142 }
143}
144
145void PPC64::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const {
146 // For a TOC-relative relocation, proceed in terms of the corresponding
147 // ADDR16 relocation type.
148 std::tie(Type, Val) = toAddr16Rel(Type, Val);
149
150 switch (Type) {
151 case R_PPC64_ADDR14: {
152 checkAlignment<4>(Loc, Val, Type);
153 // Preserve the AA/LK bits in the branch instruction
154 uint8_t AALK = Loc[3];
155 write16be(Loc + 2, (AALK & 3) | (Val & 0xfffc));
156 break;
157 }
158 case R_PPC64_ADDR16:
159 checkInt<16>(Loc, Val, Type);
160 write16be(Loc, Val);
161 break;
162 case R_PPC64_ADDR16_DS:
163 checkInt<16>(Loc, Val, Type);
164 write16be(Loc, (read16be(Loc) & 3) | (Val & ~3));
165 break;
166 case R_PPC64_ADDR16_HA:
167 case R_PPC64_REL16_HA:
168 write16be(Loc, applyPPCHa(Val));
169 break;
170 case R_PPC64_ADDR16_HI:
171 case R_PPC64_REL16_HI:
172 write16be(Loc, applyPPCHi(Val));
173 break;
174 case R_PPC64_ADDR16_HIGHER:
175 write16be(Loc, applyPPCHigher(Val));
176 break;
177 case R_PPC64_ADDR16_HIGHERA:
178 write16be(Loc, applyPPCHighera(Val));
179 break;
180 case R_PPC64_ADDR16_HIGHEST:
181 write16be(Loc, applyPPCHighest(Val));
182 break;
183 case R_PPC64_ADDR16_HIGHESTA:
184 write16be(Loc, applyPPCHighesta(Val));
185 break;
186 case R_PPC64_ADDR16_LO:
187 write16be(Loc, applyPPCLo(Val));
188 break;
189 case R_PPC64_ADDR16_LO_DS:
190 case R_PPC64_REL16_LO:
191 write16be(Loc, (read16be(Loc) & 3) | (applyPPCLo(Val) & ~3));
192 break;
193 case R_PPC64_ADDR32:
194 case R_PPC64_REL32:
195 checkInt<32>(Loc, Val, Type);
196 write32be(Loc, Val);
197 break;
198 case R_PPC64_ADDR64:
199 case R_PPC64_REL64:
200 case R_PPC64_TOC:
201 write64be(Loc, Val);
202 break;
203 case R_PPC64_REL24: {
204 uint32_t Mask = 0x03FFFFFC;
205 checkInt<24>(Loc, Val, Type);
206 write32be(Loc, (read32be(Loc) & ~Mask) | (Val & Mask));
207 break;
208 }
209 default:
210 error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type));
211 }
212}
213
214TargetInfo *elf::getPPC64TargetInfo() {
215 static PPC64 Target;
216 return &Target;
217}
deps/lld/ELF/Arch/SPARCV9.cpp created+149
......@@ -0,0 +1,149 @@
1//===- SPARCV9.cpp --------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "Error.h"
11#include "InputFiles.h"
12#include "Symbols.h"
13#include "SyntheticSections.h"
14#include "Target.h"
15#include "llvm/Support/Endian.h"
16
17using namespace llvm;
18using namespace llvm::support::endian;
19using namespace llvm::ELF;
20using namespace lld;
21using namespace lld::elf;
22
23namespace {
24class SPARCV9 final : public TargetInfo {
25public:
26 SPARCV9();
27 RelExpr getRelExpr(uint32_t Type, const SymbolBody &S,
28 const uint8_t *Loc) const override;
29 void writePlt(uint8_t *Buf, uint64_t GotEntryAddr, uint64_t PltEntryAddr,
30 int32_t Index, unsigned RelOff) const override;
31 void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
32};
33} // namespace
34
35SPARCV9::SPARCV9() {
36 CopyRel = R_SPARC_COPY;
37 GotRel = R_SPARC_GLOB_DAT;
38 PltRel = R_SPARC_JMP_SLOT;
39 RelativeRel = R_SPARC_RELATIVE;
40 GotEntrySize = 8;
41 PltEntrySize = 32;
42 PltHeaderSize = 4 * PltEntrySize;
43
44 PageSize = 8192;
45 DefaultMaxPageSize = 0x100000;
46 DefaultImageBase = 0x100000;
47}
48
49RelExpr SPARCV9::getRelExpr(uint32_t Type, const SymbolBody &S,
50 const uint8_t *Loc) const {
51 switch (Type) {
52 case R_SPARC_32:
53 case R_SPARC_UA32:
54 case R_SPARC_64:
55 case R_SPARC_UA64:
56 return R_ABS;
57 case R_SPARC_PC10:
58 case R_SPARC_PC22:
59 case R_SPARC_DISP32:
60 case R_SPARC_WDISP30:
61 return R_PC;
62 case R_SPARC_GOT10:
63 return R_GOT_OFF;
64 case R_SPARC_GOT22:
65 return R_GOT_OFF;
66 case R_SPARC_WPLT30:
67 return R_PLT_PC;
68 case R_SPARC_NONE:
69 return R_NONE;
70 default:
71 error(toString(S.File) + ": unknown relocation type: " + toString(Type));
72 return R_HINT;
73 }
74}
75
76void SPARCV9::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const {
77 switch (Type) {
78 case R_SPARC_32:
79 case R_SPARC_UA32:
80 // V-word32
81 checkUInt<32>(Loc, Val, Type);
82 write32be(Loc, Val);
83 break;
84 case R_SPARC_DISP32:
85 // V-disp32
86 checkInt<32>(Loc, Val, Type);
87 write32be(Loc, Val);
88 break;
89 case R_SPARC_WDISP30:
90 case R_SPARC_WPLT30:
91 // V-disp30
92 checkInt<32>(Loc, Val, Type);
93 write32be(Loc, (read32be(Loc) & ~0x3fffffff) | ((Val >> 2) & 0x3fffffff));
94 break;
95 case R_SPARC_22:
96 // V-imm22
97 checkUInt<22>(Loc, Val, Type);
98 write32be(Loc, (read32be(Loc) & ~0x003fffff) | (Val & 0x003fffff));
99 break;
100 case R_SPARC_GOT22:
101 case R_SPARC_PC22:
102 // T-imm22
103 write32be(Loc, (read32be(Loc) & ~0x003fffff) | ((Val >> 10) & 0x003fffff));
104 break;
105 case R_SPARC_WDISP19:
106 // V-disp19
107 checkInt<21>(Loc, Val, Type);
108 write32be(Loc, (read32be(Loc) & ~0x0007ffff) | ((Val >> 2) & 0x0007ffff));
109 break;
110 case R_SPARC_GOT10:
111 case R_SPARC_PC10:
112 // T-simm10
113 write32be(Loc, (read32be(Loc) & ~0x000003ff) | (Val & 0x000003ff));
114 break;
115 case R_SPARC_64:
116 case R_SPARC_UA64:
117 case R_SPARC_GLOB_DAT:
118 // V-xword64
119 write64be(Loc, Val);
120 break;
121 default:
122 error(getErrorLocation(Loc) + "unrecognized reloc " + Twine(Type));
123 }
124}
125
126void SPARCV9::writePlt(uint8_t *Buf, uint64_t GotEntryAddr,
127 uint64_t PltEntryAddr, int32_t Index,
128 unsigned RelOff) const {
129 const uint8_t PltData[] = {
130 0x03, 0x00, 0x00, 0x00, // sethi (. - .PLT0), %g1
131 0x30, 0x68, 0x00, 0x00, // ba,a %xcc, .PLT1
132 0x01, 0x00, 0x00, 0x00, // nop
133 0x01, 0x00, 0x00, 0x00, // nop
134 0x01, 0x00, 0x00, 0x00, // nop
135 0x01, 0x00, 0x00, 0x00, // nop
136 0x01, 0x00, 0x00, 0x00, // nop
137 0x01, 0x00, 0x00, 0x00 // nop
138 };
139 memcpy(Buf, PltData, sizeof(PltData));
140
141 uint64_t Off = PltHeaderSize + Index * PltEntrySize;
142 relocateOne(Buf, R_SPARC_22, Off);
143 relocateOne(Buf + 4, R_SPARC_WDISP19, -(Off + 4 - PltEntrySize));
144}
145
146TargetInfo *elf::getSPARCV9TargetInfo() {
147 static SPARCV9 Target;
148 return &Target;
149}
deps/lld/ELF/Arch/X86.cpp created+364
......@@ -0,0 +1,364 @@
1//===- X86.cpp ------------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "Error.h"
11#include "InputFiles.h"
12#include "Symbols.h"
13#include "SyntheticSections.h"
14#include "Target.h"
15#include "llvm/Support/Endian.h"
16
17using namespace llvm;
18using namespace llvm::support::endian;
19using namespace llvm::ELF;
20using namespace lld;
21using namespace lld::elf;
22
23namespace {
24class X86 final : public TargetInfo {
25public:
26 X86();
27 RelExpr getRelExpr(uint32_t Type, const SymbolBody &S,
28 const uint8_t *Loc) const override;
29 int64_t getImplicitAddend(const uint8_t *Buf, uint32_t Type) const override;
30 void writeGotPltHeader(uint8_t *Buf) const override;
31 uint32_t getDynRel(uint32_t Type) const override;
32 void writeGotPlt(uint8_t *Buf, const SymbolBody &S) const override;
33 void writeIgotPlt(uint8_t *Buf, const SymbolBody &S) const override;
34 void writePltHeader(uint8_t *Buf) const override;
35 void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
36 int32_t Index, unsigned RelOff) const override;
37 void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
38
39 RelExpr adjustRelaxExpr(uint32_t Type, const uint8_t *Data,
40 RelExpr Expr) const override;
41 void relaxTlsGdToIe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
42 void relaxTlsGdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
43 void relaxTlsIeToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
44 void relaxTlsLdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
45};
46} // namespace
47
48X86::X86() {
49 GotBaseSymOff = -1;
50 CopyRel = R_386_COPY;
51 GotRel = R_386_GLOB_DAT;
52 PltRel = R_386_JUMP_SLOT;
53 IRelativeRel = R_386_IRELATIVE;
54 RelativeRel = R_386_RELATIVE;
55 TlsGotRel = R_386_TLS_TPOFF;
56 TlsModuleIndexRel = R_386_TLS_DTPMOD32;
57 TlsOffsetRel = R_386_TLS_DTPOFF32;
58 GotEntrySize = 4;
59 GotPltEntrySize = 4;
60 PltEntrySize = 16;
61 PltHeaderSize = 16;
62 TlsGdRelaxSkip = 2;
63 TrapInstr = 0xcccccccc; // 0xcc = INT3
64}
65
66RelExpr X86::getRelExpr(uint32_t Type, const SymbolBody &S,
67 const uint8_t *Loc) const {
68 switch (Type) {
69 case R_386_8:
70 case R_386_16:
71 case R_386_32:
72 case R_386_TLS_LDO_32:
73 return R_ABS;
74 case R_386_TLS_GD:
75 return R_TLSGD;
76 case R_386_TLS_LDM:
77 return R_TLSLD;
78 case R_386_PLT32:
79 return R_PLT_PC;
80 case R_386_PC8:
81 case R_386_PC16:
82 case R_386_PC32:
83 return R_PC;
84 case R_386_GOTPC:
85 return R_GOTONLY_PC_FROM_END;
86 case R_386_TLS_IE:
87 return R_GOT;
88 case R_386_GOT32:
89 case R_386_GOT32X:
90 // These relocations can be calculated in two different ways.
91 // Usual calculation is G + A - GOT what means an offset in GOT table
92 // (R_GOT_FROM_END). When instruction pointed by relocation has no base
93 // register, then relocations can be used when PIC code is disabled. In that
94 // case calculation is G + A, it resolves to an address of entry in GOT
95 // (R_GOT) and not an offset.
96 //
97 // To check that instruction has no base register we scan ModR/M byte.
98 // See "Table 2-2. 32-Bit Addressing Forms with the ModR/M Byte"
99 // (http://www.intel.com/content/dam/www/public/us/en/documents/manuals/
100 // 64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf)
101 if ((Loc[-1] & 0xc7) != 0x5)
102 return R_GOT_FROM_END;
103 if (Config->Pic)
104 error(toString(S.File) + ": relocation " + toString(Type) + " against '" +
105 S.getName() +
106 "' without base register can not be used when PIC enabled");
107 return R_GOT;
108 case R_386_TLS_GOTIE:
109 return R_GOT_FROM_END;
110 case R_386_GOTOFF:
111 return R_GOTREL_FROM_END;
112 case R_386_TLS_LE:
113 return R_TLS;
114 case R_386_TLS_LE_32:
115 return R_NEG_TLS;
116 case R_386_NONE:
117 return R_NONE;
118 default:
119 error(toString(S.File) + ": unknown relocation type: " + toString(Type));
120 return R_HINT;
121 }
122}
123
124RelExpr X86::adjustRelaxExpr(uint32_t Type, const uint8_t *Data,
125 RelExpr Expr) const {
126 switch (Expr) {
127 default:
128 return Expr;
129 case R_RELAX_TLS_GD_TO_IE:
130 return R_RELAX_TLS_GD_TO_IE_END;
131 case R_RELAX_TLS_GD_TO_LE:
132 return R_RELAX_TLS_GD_TO_LE_NEG;
133 }
134}
135
136void X86::writeGotPltHeader(uint8_t *Buf) const {
137 write32le(Buf, InX::Dynamic->getVA());
138}
139
140void X86::writeGotPlt(uint8_t *Buf, const SymbolBody &S) const {
141 // Entries in .got.plt initially points back to the corresponding
142 // PLT entries with a fixed offset to skip the first instruction.
143 write32le(Buf, S.getPltVA() + 6);
144}
145
146void X86::writeIgotPlt(uint8_t *Buf, const SymbolBody &S) const {
147 // An x86 entry is the address of the ifunc resolver function.
148 write32le(Buf, S.getVA());
149}
150
151uint32_t X86::getDynRel(uint32_t Type) const {
152 if (Type == R_386_TLS_LE)
153 return R_386_TLS_TPOFF;
154 if (Type == R_386_TLS_LE_32)
155 return R_386_TLS_TPOFF32;
156 return Type;
157}
158
159void X86::writePltHeader(uint8_t *Buf) const {
160 if (Config->Pic) {
161 const uint8_t V[] = {
162 0xff, 0xb3, 0x04, 0x00, 0x00, 0x00, // pushl GOTPLT+4(%ebx)
163 0xff, 0xa3, 0x08, 0x00, 0x00, 0x00, // jmp *GOTPLT+8(%ebx)
164 0x90, 0x90, 0x90, 0x90 // nop
165 };
166 memcpy(Buf, V, sizeof(V));
167
168 uint32_t Ebx = InX::Got->getVA() + InX::Got->getSize();
169 uint32_t GotPlt = InX::GotPlt->getVA() - Ebx;
170 write32le(Buf + 2, GotPlt + 4);
171 write32le(Buf + 8, GotPlt + 8);
172 return;
173 }
174
175 const uint8_t PltData[] = {
176 0xff, 0x35, 0x00, 0x00, 0x00, 0x00, // pushl (GOTPLT+4)
177 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp *(GOTPLT+8)
178 0x90, 0x90, 0x90, 0x90 // nop
179 };
180 memcpy(Buf, PltData, sizeof(PltData));
181 uint32_t GotPlt = InX::GotPlt->getVA();
182 write32le(Buf + 2, GotPlt + 4);
183 write32le(Buf + 8, GotPlt + 8);
184}
185
186void X86::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
187 uint64_t PltEntryAddr, int32_t Index,
188 unsigned RelOff) const {
189 const uint8_t Inst[] = {
190 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, // jmp *foo_in_GOT|*foo@GOT(%ebx)
191 0x68, 0x00, 0x00, 0x00, 0x00, // pushl $reloc_offset
192 0xe9, 0x00, 0x00, 0x00, 0x00 // jmp .PLT0@PC
193 };
194 memcpy(Buf, Inst, sizeof(Inst));
195
196 if (Config->Pic) {
197 // jmp *foo@GOT(%ebx)
198 uint32_t Ebx = InX::Got->getVA() + InX::Got->getSize();
199 Buf[1] = 0xa3;
200 write32le(Buf + 2, GotPltEntryAddr - Ebx);
201 } else {
202 // jmp *foo_in_GOT
203 Buf[1] = 0x25;
204 write32le(Buf + 2, GotPltEntryAddr);
205 }
206
207 write32le(Buf + 7, RelOff);
208 write32le(Buf + 12, -Index * PltEntrySize - PltHeaderSize - 16);
209}
210
211int64_t X86::getImplicitAddend(const uint8_t *Buf, uint32_t Type) const {
212 switch (Type) {
213 default:
214 return 0;
215 case R_386_8:
216 case R_386_PC8:
217 return SignExtend64<8>(*Buf);
218 case R_386_16:
219 case R_386_PC16:
220 return SignExtend64<16>(read16le(Buf));
221 case R_386_32:
222 case R_386_GOT32:
223 case R_386_GOT32X:
224 case R_386_GOTOFF:
225 case R_386_GOTPC:
226 case R_386_PC32:
227 case R_386_PLT32:
228 case R_386_TLS_LDO_32:
229 case R_386_TLS_LE:
230 return SignExtend64<32>(read32le(Buf));
231 }
232}
233
234void X86::relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const {
235 // R_386_{PC,}{8,16} are not part of the i386 psABI, but they are
236 // being used for some 16-bit programs such as boot loaders, so
237 // we want to support them.
238 switch (Type) {
239 case R_386_8:
240 checkUInt<8>(Loc, Val, Type);
241 *Loc = Val;
242 break;
243 case R_386_PC8:
244 checkInt<8>(Loc, Val, Type);
245 *Loc = Val;
246 break;
247 case R_386_16:
248 checkUInt<16>(Loc, Val, Type);
249 write16le(Loc, Val);
250 break;
251 case R_386_PC16:
252 // R_386_PC16 is normally used with 16 bit code. In that situation
253 // the PC is 16 bits, just like the addend. This means that it can
254 // point from any 16 bit address to any other if the possibility
255 // of wrapping is included.
256 // The only restriction we have to check then is that the destination
257 // address fits in 16 bits. That is impossible to do here. The problem is
258 // that we are passed the final value, which already had the
259 // current location subtracted from it.
260 // We just check that Val fits in 17 bits. This misses some cases, but
261 // should have no false positives.
262 checkInt<17>(Loc, Val, Type);
263 write16le(Loc, Val);
264 break;
265 default:
266 checkInt<32>(Loc, Val, Type);
267 write32le(Loc, Val);
268 }
269}
270
271void X86::relaxTlsGdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const {
272 // Convert
273 // leal x@tlsgd(, %ebx, 1),
274 // call __tls_get_addr@plt
275 // to
276 // movl %gs:0,%eax
277 // subl $x@ntpoff,%eax
278 const uint8_t Inst[] = {
279 0x65, 0xa1, 0x00, 0x00, 0x00, 0x00, // movl %gs:0, %eax
280 0x81, 0xe8, 0x00, 0x00, 0x00, 0x00 // subl 0(%ebx), %eax
281 };
282 memcpy(Loc - 3, Inst, sizeof(Inst));
283 write32le(Loc + 5, Val);
284}
285
286void X86::relaxTlsGdToIe(uint8_t *Loc, uint32_t Type, uint64_t Val) const {
287 // Convert
288 // leal x@tlsgd(, %ebx, 1),
289 // call __tls_get_addr@plt
290 // to
291 // movl %gs:0, %eax
292 // addl x@gotntpoff(%ebx), %eax
293 const uint8_t Inst[] = {
294 0x65, 0xa1, 0x00, 0x00, 0x00, 0x00, // movl %gs:0, %eax
295 0x03, 0x83, 0x00, 0x00, 0x00, 0x00 // addl 0(%ebx), %eax
296 };
297 memcpy(Loc - 3, Inst, sizeof(Inst));
298 write32le(Loc + 5, Val);
299}
300
301// In some conditions, relocations can be optimized to avoid using GOT.
302// This function does that for Initial Exec to Local Exec case.
303void X86::relaxTlsIeToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const {
304 // Ulrich's document section 6.2 says that @gotntpoff can
305 // be used with MOVL or ADDL instructions.
306 // @indntpoff is similar to @gotntpoff, but for use in
307 // position dependent code.
308 uint8_t Reg = (Loc[-1] >> 3) & 7;
309
310 if (Type == R_386_TLS_IE) {
311 if (Loc[-1] == 0xa1) {
312 // "movl foo@indntpoff,%eax" -> "movl $foo,%eax"
313 // This case is different from the generic case below because
314 // this is a 5 byte instruction while below is 6 bytes.
315 Loc[-1] = 0xb8;
316 } else if (Loc[-2] == 0x8b) {
317 // "movl foo@indntpoff,%reg" -> "movl $foo,%reg"
318 Loc[-2] = 0xc7;
319 Loc[-1] = 0xc0 | Reg;
320 } else {
321 // "addl foo@indntpoff,%reg" -> "addl $foo,%reg"
322 Loc[-2] = 0x81;
323 Loc[-1] = 0xc0 | Reg;
324 }
325 } else {
326 assert(Type == R_386_TLS_GOTIE);
327 if (Loc[-2] == 0x8b) {
328 // "movl foo@gottpoff(%rip),%reg" -> "movl $foo,%reg"
329 Loc[-2] = 0xc7;
330 Loc[-1] = 0xc0 | Reg;
331 } else {
332 // "addl foo@gotntpoff(%rip),%reg" -> "leal foo(%reg),%reg"
333 Loc[-2] = 0x8d;
334 Loc[-1] = 0x80 | (Reg << 3) | Reg;
335 }
336 }
337 write32le(Loc, Val);
338}
339
340void X86::relaxTlsLdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const {
341 if (Type == R_386_TLS_LDO_32) {
342 write32le(Loc, Val);
343 return;
344 }
345
346 // Convert
347 // leal foo(%reg),%eax
348 // call ___tls_get_addr
349 // to
350 // movl %gs:0,%eax
351 // nop
352 // leal 0(%esi,1),%esi
353 const uint8_t Inst[] = {
354 0x65, 0xa1, 0x00, 0x00, 0x00, 0x00, // movl %gs:0,%eax
355 0x90, // nop
356 0x8d, 0x74, 0x26, 0x00 // leal 0(%esi,1),%esi
357 };
358 memcpy(Loc - 2, Inst, sizeof(Inst));
359}
360
361TargetInfo *elf::getX86TargetInfo() {
362 static X86 Target;
363 return &Target;
364}
deps/lld/ELF/Arch/X86_64.cpp created+473
......@@ -0,0 +1,473 @@
1//===- X86_64.cpp ---------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "Error.h"
11#include "InputFiles.h"
12#include "Symbols.h"
13#include "SyntheticSections.h"
14#include "Target.h"
15#include "llvm/Object/ELF.h"
16#include "llvm/Support/Endian.h"
17
18using namespace llvm;
19using namespace llvm::object;
20using namespace llvm::support::endian;
21using namespace llvm::ELF;
22using namespace lld;
23using namespace lld::elf;
24
25namespace {
26template <class ELFT> class X86_64 final : public TargetInfo {
27public:
28 X86_64();
29 RelExpr getRelExpr(uint32_t Type, const SymbolBody &S,
30 const uint8_t *Loc) const override;
31 bool isPicRel(uint32_t Type) const override;
32 void writeGotPltHeader(uint8_t *Buf) const override;
33 void writeGotPlt(uint8_t *Buf, const SymbolBody &S) const override;
34 void writePltHeader(uint8_t *Buf) const override;
35 void writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr, uint64_t PltEntryAddr,
36 int32_t Index, unsigned RelOff) const override;
37 void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
38
39 RelExpr adjustRelaxExpr(uint32_t Type, const uint8_t *Data,
40 RelExpr Expr) const override;
41 void relaxGot(uint8_t *Loc, uint64_t Val) const override;
42 void relaxTlsGdToIe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
43 void relaxTlsGdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
44 void relaxTlsIeToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
45 void relaxTlsLdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const override;
46
47private:
48 void relaxGotNoPic(uint8_t *Loc, uint64_t Val, uint8_t Op,
49 uint8_t ModRm) const;
50};
51} // namespace
52
53template <class ELFT> X86_64<ELFT>::X86_64() {
54 GotBaseSymOff = -1;
55 CopyRel = R_X86_64_COPY;
56 GotRel = R_X86_64_GLOB_DAT;
57 PltRel = R_X86_64_JUMP_SLOT;
58 RelativeRel = R_X86_64_RELATIVE;
59 IRelativeRel = R_X86_64_IRELATIVE;
60 TlsGotRel = R_X86_64_TPOFF64;
61 TlsModuleIndexRel = R_X86_64_DTPMOD64;
62 TlsOffsetRel = R_X86_64_DTPOFF64;
63 GotEntrySize = 8;
64 GotPltEntrySize = 8;
65 PltEntrySize = 16;
66 PltHeaderSize = 16;
67 TlsGdRelaxSkip = 2;
68 TrapInstr = 0xcccccccc; // 0xcc = INT3
69
70 // Align to the large page size (known as a superpage or huge page).
71 // FreeBSD automatically promotes large, superpage-aligned allocations.
72 DefaultImageBase = 0x200000;
73}
74
75template <class ELFT>
76RelExpr X86_64<ELFT>::getRelExpr(uint32_t Type, const SymbolBody &S,
77 const uint8_t *Loc) const {
78 switch (Type) {
79 case R_X86_64_8:
80 case R_X86_64_16:
81 case R_X86_64_32:
82 case R_X86_64_32S:
83 case R_X86_64_64:
84 case R_X86_64_DTPOFF32:
85 case R_X86_64_DTPOFF64:
86 return R_ABS;
87 case R_X86_64_TPOFF32:
88 return R_TLS;
89 case R_X86_64_TLSLD:
90 return R_TLSLD_PC;
91 case R_X86_64_TLSGD:
92 return R_TLSGD_PC;
93 case R_X86_64_SIZE32:
94 case R_X86_64_SIZE64:
95 return R_SIZE;
96 case R_X86_64_PLT32:
97 return R_PLT_PC;
98 case R_X86_64_PC32:
99 case R_X86_64_PC64:
100 return R_PC;
101 case R_X86_64_GOT32:
102 case R_X86_64_GOT64:
103 return R_GOT_FROM_END;
104 case R_X86_64_GOTPCREL:
105 case R_X86_64_GOTPCRELX:
106 case R_X86_64_REX_GOTPCRELX:
107 case R_X86_64_GOTTPOFF:
108 return R_GOT_PC;
109 case R_X86_64_NONE:
110 return R_NONE;
111 default:
112 error(toString(S.File) + ": unknown relocation type: " + toString(Type));
113 return R_HINT;
114 }
115}
116
117template <class ELFT> void X86_64<ELFT>::writeGotPltHeader(uint8_t *Buf) const {
118 // The first entry holds the value of _DYNAMIC. It is not clear why that is
119 // required, but it is documented in the psabi and the glibc dynamic linker
120 // seems to use it (note that this is relevant for linking ld.so, not any
121 // other program).
122 write64le(Buf, InX::Dynamic->getVA());
123}
124
125template <class ELFT>
126void X86_64<ELFT>::writeGotPlt(uint8_t *Buf, const SymbolBody &S) const {
127 // See comments in X86TargetInfo::writeGotPlt.
128 write32le(Buf, S.getPltVA() + 6);
129}
130
131template <class ELFT> void X86_64<ELFT>::writePltHeader(uint8_t *Buf) const {
132 const uint8_t PltData[] = {
133 0xff, 0x35, 0x00, 0x00, 0x00, 0x00, // pushq GOTPLT+8(%rip)
134 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp *GOTPLT+16(%rip)
135 0x0f, 0x1f, 0x40, 0x00 // nop
136 };
137 memcpy(Buf, PltData, sizeof(PltData));
138 uint64_t GotPlt = InX::GotPlt->getVA();
139 uint64_t Plt = InX::Plt->getVA();
140 write32le(Buf + 2, GotPlt - Plt + 2); // GOTPLT+8
141 write32le(Buf + 8, GotPlt - Plt + 4); // GOTPLT+16
142}
143
144template <class ELFT>
145void X86_64<ELFT>::writePlt(uint8_t *Buf, uint64_t GotPltEntryAddr,
146 uint64_t PltEntryAddr, int32_t Index,
147 unsigned RelOff) const {
148 const uint8_t Inst[] = {
149 0xff, 0x25, 0x00, 0x00, 0x00, 0x00, // jmpq *got(%rip)
150 0x68, 0x00, 0x00, 0x00, 0x00, // pushq <relocation index>
151 0xe9, 0x00, 0x00, 0x00, 0x00 // jmpq plt[0]
152 };
153 memcpy(Buf, Inst, sizeof(Inst));
154
155 write32le(Buf + 2, GotPltEntryAddr - PltEntryAddr - 6);
156 write32le(Buf + 7, Index);
157 write32le(Buf + 12, -Index * PltEntrySize - PltHeaderSize - 16);
158}
159
160template <class ELFT> bool X86_64<ELFT>::isPicRel(uint32_t Type) const {
161 return Type != R_X86_64_PC32 && Type != R_X86_64_32 &&
162 Type != R_X86_64_TPOFF32;
163}
164
165template <class ELFT>
166void X86_64<ELFT>::relaxTlsGdToLe(uint8_t *Loc, uint32_t Type,
167 uint64_t Val) const {
168 // Convert
169 // .byte 0x66
170 // leaq x@tlsgd(%rip), %rdi
171 // .word 0x6666
172 // rex64
173 // call __tls_get_addr@plt
174 // to
175 // mov %fs:0x0,%rax
176 // lea x@tpoff,%rax
177 const uint8_t Inst[] = {
178 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00, // mov %fs:0x0,%rax
179 0x48, 0x8d, 0x80, 0x00, 0x00, 0x00, 0x00 // lea x@tpoff,%rax
180 };
181 memcpy(Loc - 4, Inst, sizeof(Inst));
182
183 // The original code used a pc relative relocation and so we have to
184 // compensate for the -4 in had in the addend.
185 write32le(Loc + 8, Val + 4);
186}
187
188template <class ELFT>
189void X86_64<ELFT>::relaxTlsGdToIe(uint8_t *Loc, uint32_t Type,
190 uint64_t Val) const {
191 // Convert
192 // .byte 0x66
193 // leaq x@tlsgd(%rip), %rdi
194 // .word 0x6666
195 // rex64
196 // call __tls_get_addr@plt
197 // to
198 // mov %fs:0x0,%rax
199 // addq x@tpoff,%rax
200 const uint8_t Inst[] = {
201 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00, // mov %fs:0x0,%rax
202 0x48, 0x03, 0x05, 0x00, 0x00, 0x00, 0x00 // addq x@tpoff,%rax
203 };
204 memcpy(Loc - 4, Inst, sizeof(Inst));
205
206 // Both code sequences are PC relatives, but since we are moving the constant
207 // forward by 8 bytes we have to subtract the value by 8.
208 write32le(Loc + 8, Val - 8);
209}
210
211// In some conditions, R_X86_64_GOTTPOFF relocation can be optimized to
212// R_X86_64_TPOFF32 so that it does not use GOT.
213template <class ELFT>
214void X86_64<ELFT>::relaxTlsIeToLe(uint8_t *Loc, uint32_t Type,
215 uint64_t Val) const {
216 uint8_t *Inst = Loc - 3;
217 uint8_t Reg = Loc[-1] >> 3;
218 uint8_t *RegSlot = Loc - 1;
219
220 // Note that ADD with RSP or R12 is converted to ADD instead of LEA
221 // because LEA with these registers needs 4 bytes to encode and thus
222 // wouldn't fit the space.
223
224 if (memcmp(Inst, "\x48\x03\x25", 3) == 0) {
225 // "addq foo@gottpoff(%rip),%rsp" -> "addq $foo,%rsp"
226 memcpy(Inst, "\x48\x81\xc4", 3);
227 } else if (memcmp(Inst, "\x4c\x03\x25", 3) == 0) {
228 // "addq foo@gottpoff(%rip),%r12" -> "addq $foo,%r12"
229 memcpy(Inst, "\x49\x81\xc4", 3);
230 } else if (memcmp(Inst, "\x4c\x03", 2) == 0) {
231 // "addq foo@gottpoff(%rip),%r[8-15]" -> "leaq foo(%r[8-15]),%r[8-15]"
232 memcpy(Inst, "\x4d\x8d", 2);
233 *RegSlot = 0x80 | (Reg << 3) | Reg;
234 } else if (memcmp(Inst, "\x48\x03", 2) == 0) {
235 // "addq foo@gottpoff(%rip),%reg -> "leaq foo(%reg),%reg"
236 memcpy(Inst, "\x48\x8d", 2);
237 *RegSlot = 0x80 | (Reg << 3) | Reg;
238 } else if (memcmp(Inst, "\x4c\x8b", 2) == 0) {
239 // "movq foo@gottpoff(%rip),%r[8-15]" -> "movq $foo,%r[8-15]"
240 memcpy(Inst, "\x49\xc7", 2);
241 *RegSlot = 0xc0 | Reg;
242 } else if (memcmp(Inst, "\x48\x8b", 2) == 0) {
243 // "movq foo@gottpoff(%rip),%reg" -> "movq $foo,%reg"
244 memcpy(Inst, "\x48\xc7", 2);
245 *RegSlot = 0xc0 | Reg;
246 } else {
247 error(getErrorLocation(Loc - 3) +
248 "R_X86_64_GOTTPOFF must be used in MOVQ or ADDQ instructions only");
249 }
250
251 // The original code used a PC relative relocation.
252 // Need to compensate for the -4 it had in the addend.
253 write32le(Loc, Val + 4);
254}
255
256template <class ELFT>
257void X86_64<ELFT>::relaxTlsLdToLe(uint8_t *Loc, uint32_t Type,
258 uint64_t Val) const {
259 // Convert
260 // leaq bar@tlsld(%rip), %rdi
261 // callq __tls_get_addr@PLT
262 // leaq bar@dtpoff(%rax), %rcx
263 // to
264 // .word 0x6666
265 // .byte 0x66
266 // mov %fs:0,%rax
267 // leaq bar@tpoff(%rax), %rcx
268 if (Type == R_X86_64_DTPOFF64) {
269 write64le(Loc, Val);
270 return;
271 }
272 if (Type == R_X86_64_DTPOFF32) {
273 write32le(Loc, Val);
274 return;
275 }
276
277 const uint8_t Inst[] = {
278 0x66, 0x66, // .word 0x6666
279 0x66, // .byte 0x66
280 0x64, 0x48, 0x8b, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00 // mov %fs:0,%rax
281 };
282 memcpy(Loc - 3, Inst, sizeof(Inst));
283}
284
285template <class ELFT>
286void X86_64<ELFT>::relocateOne(uint8_t *Loc, uint32_t Type,
287 uint64_t Val) const {
288 switch (Type) {
289 case R_X86_64_8:
290 checkUInt<8>(Loc, Val, Type);
291 *Loc = Val;
292 break;
293 case R_X86_64_16:
294 checkUInt<16>(Loc, Val, Type);
295 write16le(Loc, Val);
296 break;
297 case R_X86_64_32:
298 checkUInt<32>(Loc, Val, Type);
299 write32le(Loc, Val);
300 break;
301 case R_X86_64_32S:
302 case R_X86_64_TPOFF32:
303 case R_X86_64_GOT32:
304 case R_X86_64_GOTPCREL:
305 case R_X86_64_GOTPCRELX:
306 case R_X86_64_REX_GOTPCRELX:
307 case R_X86_64_PC32:
308 case R_X86_64_GOTTPOFF:
309 case R_X86_64_PLT32:
310 case R_X86_64_TLSGD:
311 case R_X86_64_TLSLD:
312 case R_X86_64_DTPOFF32:
313 case R_X86_64_SIZE32:
314 checkInt<32>(Loc, Val, Type);
315 write32le(Loc, Val);
316 break;
317 case R_X86_64_64:
318 case R_X86_64_DTPOFF64:
319 case R_X86_64_GLOB_DAT:
320 case R_X86_64_PC64:
321 case R_X86_64_SIZE64:
322 case R_X86_64_GOT64:
323 write64le(Loc, Val);
324 break;
325 default:
326 llvm_unreachable("unexpected relocation");
327 }
328}
329
330template <class ELFT>
331RelExpr X86_64<ELFT>::adjustRelaxExpr(uint32_t Type, const uint8_t *Data,
332 RelExpr RelExpr) const {
333 if (Type != R_X86_64_GOTPCRELX && Type != R_X86_64_REX_GOTPCRELX)
334 return RelExpr;
335 const uint8_t Op = Data[-2];
336 const uint8_t ModRm = Data[-1];
337
338 // FIXME: When PIC is disabled and foo is defined locally in the
339 // lower 32 bit address space, memory operand in mov can be converted into
340 // immediate operand. Otherwise, mov must be changed to lea. We support only
341 // latter relaxation at this moment.
342 if (Op == 0x8b)
343 return R_RELAX_GOT_PC;
344
345 // Relax call and jmp.
346 if (Op == 0xff && (ModRm == 0x15 || ModRm == 0x25))
347 return R_RELAX_GOT_PC;
348
349 // Relaxation of test, adc, add, and, cmp, or, sbb, sub, xor.
350 // If PIC then no relaxation is available.
351 // We also don't relax test/binop instructions without REX byte,
352 // they are 32bit operations and not common to have.
353 assert(Type == R_X86_64_REX_GOTPCRELX);
354 return Config->Pic ? RelExpr : R_RELAX_GOT_PC_NOPIC;
355}
356
357// A subset of relaxations can only be applied for no-PIC. This method
358// handles such relaxations. Instructions encoding information was taken from:
359// "Intel 64 and IA-32 Architectures Software Developer's Manual V2"
360// (http://www.intel.com/content/dam/www/public/us/en/documents/manuals/
361// 64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf)
362template <class ELFT>
363void X86_64<ELFT>::relaxGotNoPic(uint8_t *Loc, uint64_t Val, uint8_t Op,
364 uint8_t ModRm) const {
365 const uint8_t Rex = Loc[-3];
366 // Convert "test %reg, foo@GOTPCREL(%rip)" to "test $foo, %reg".
367 if (Op == 0x85) {
368 // See "TEST-Logical Compare" (4-428 Vol. 2B),
369 // TEST r/m64, r64 uses "full" ModR / M byte (no opcode extension).
370
371 // ModR/M byte has form XX YYY ZZZ, where
372 // YYY is MODRM.reg(register 2), ZZZ is MODRM.rm(register 1).
373 // XX has different meanings:
374 // 00: The operand's memory address is in reg1.
375 // 01: The operand's memory address is reg1 + a byte-sized displacement.
376 // 10: The operand's memory address is reg1 + a word-sized displacement.
377 // 11: The operand is reg1 itself.
378 // If an instruction requires only one operand, the unused reg2 field
379 // holds extra opcode bits rather than a register code
380 // 0xC0 == 11 000 000 binary.
381 // 0x38 == 00 111 000 binary.
382 // We transfer reg2 to reg1 here as operand.
383 // See "2.1.3 ModR/M and SIB Bytes" (Vol. 2A 2-3).
384 Loc[-1] = 0xc0 | (ModRm & 0x38) >> 3; // ModR/M byte.
385
386 // Change opcode from TEST r/m64, r64 to TEST r/m64, imm32
387 // See "TEST-Logical Compare" (4-428 Vol. 2B).
388 Loc[-2] = 0xf7;
389
390 // Move R bit to the B bit in REX byte.
391 // REX byte is encoded as 0100WRXB, where
392 // 0100 is 4bit fixed pattern.
393 // REX.W When 1, a 64-bit operand size is used. Otherwise, when 0, the
394 // default operand size is used (which is 32-bit for most but not all
395 // instructions).
396 // REX.R This 1-bit value is an extension to the MODRM.reg field.
397 // REX.X This 1-bit value is an extension to the SIB.index field.
398 // REX.B This 1-bit value is an extension to the MODRM.rm field or the
399 // SIB.base field.
400 // See "2.2.1.2 More on REX Prefix Fields " (2-8 Vol. 2A).
401 Loc[-3] = (Rex & ~0x4) | (Rex & 0x4) >> 2;
402 write32le(Loc, Val);
403 return;
404 }
405
406 // If we are here then we need to relax the adc, add, and, cmp, or, sbb, sub
407 // or xor operations.
408
409 // Convert "binop foo@GOTPCREL(%rip), %reg" to "binop $foo, %reg".
410 // Logic is close to one for test instruction above, but we also
411 // write opcode extension here, see below for details.
412 Loc[-1] = 0xc0 | (ModRm & 0x38) >> 3 | (Op & 0x3c); // ModR/M byte.
413
414 // Primary opcode is 0x81, opcode extension is one of:
415 // 000b = ADD, 001b is OR, 010b is ADC, 011b is SBB,
416 // 100b is AND, 101b is SUB, 110b is XOR, 111b is CMP.
417 // This value was wrote to MODRM.reg in a line above.
418 // See "3.2 INSTRUCTIONS (A-M)" (Vol. 2A 3-15),
419 // "INSTRUCTION SET REFERENCE, N-Z" (Vol. 2B 4-1) for
420 // descriptions about each operation.
421 Loc[-2] = 0x81;
422 Loc[-3] = (Rex & ~0x4) | (Rex & 0x4) >> 2;
423 write32le(Loc, Val);
424}
425
426template <class ELFT>
427void X86_64<ELFT>::relaxGot(uint8_t *Loc, uint64_t Val) const {
428 const uint8_t Op = Loc[-2];
429 const uint8_t ModRm = Loc[-1];
430
431 // Convert "mov foo@GOTPCREL(%rip),%reg" to "lea foo(%rip),%reg".
432 if (Op == 0x8b) {
433 Loc[-2] = 0x8d;
434 write32le(Loc, Val);
435 return;
436 }
437
438 if (Op != 0xff) {
439 // We are relaxing a rip relative to an absolute, so compensate
440 // for the old -4 addend.
441 assert(!Config->Pic);
442 relaxGotNoPic(Loc, Val + 4, Op, ModRm);
443 return;
444 }
445
446 // Convert call/jmp instructions.
447 if (ModRm == 0x15) {
448 // ABI says we can convert "call *foo@GOTPCREL(%rip)" to "nop; call foo".
449 // Instead we convert to "addr32 call foo" where addr32 is an instruction
450 // prefix. That makes result expression to be a single instruction.
451 Loc[-2] = 0x67; // addr32 prefix
452 Loc[-1] = 0xe8; // call
453 write32le(Loc, Val);
454 return;
455 }
456
457 // Convert "jmp *foo@GOTPCREL(%rip)" to "jmp foo; nop".
458 // jmp doesn't return, so it is fine to use nop here, it is just a stub.
459 assert(ModRm == 0x25);
460 Loc[-2] = 0xe9; // jmp
461 Loc[3] = 0x90; // nop
462 write32le(Loc - 1, Val + 1);
463}
464
465TargetInfo *elf::getX32TargetInfo() {
466 static X86_64<ELF32LE> Target;
467 return &Target;
468}
469
470TargetInfo *elf::getX86_64TargetInfo() {
471 static X86_64<ELF64LE> Target;
472 return &Target;
473}
deps/lld/ELF/CMakeLists.txt created+75
......@@ -0,0 +1,75 @@
1set(LLVM_TARGET_DEFINITIONS Options.td)
2tablegen(LLVM Options.inc -gen-opt-parser-defs)
3add_public_tablegen_target(ELFOptionsTableGen)
4
5if(NOT LLD_BUILT_STANDALONE)
6 set(tablegen_deps intrinsics_gen)
7endif()
8
9add_lld_library(lldELF
10 Arch/AArch64.cpp
11 Arch/AMDGPU.cpp
12 Arch/ARM.cpp
13 Arch/AVR.cpp
14 Arch/Mips.cpp
15 Arch/MipsArchTree.cpp
16 Arch/PPC.cpp
17 Arch/PPC64.cpp
18 Arch/SPARCV9.cpp
19 Arch/X86.cpp
20 Arch/X86_64.cpp
21 Driver.cpp
22 DriverUtils.cpp
23 EhFrame.cpp
24 Error.cpp
25 Filesystem.cpp
26 GdbIndex.cpp
27 ICF.cpp
28 InputFiles.cpp
29 InputSection.cpp
30 LTO.cpp
31 LinkerScript.cpp
32 MapFile.cpp
33 MarkLive.cpp
34 OutputSections.cpp
35 Relocations.cpp
36 ScriptLexer.cpp
37 ScriptParser.cpp
38 Strings.cpp
39 SymbolTable.cpp
40 Symbols.cpp
41 SyntheticSections.cpp
42 Target.cpp
43 Thunks.cpp
44 Writer.cpp
45
46 LINK_COMPONENTS
47 ${LLVM_TARGETS_TO_BUILD}
48 Analysis
49 BinaryFormat
50 BitReader
51 BitWriter
52 Codegen
53 Core
54 DebugInfoDWARF
55 Demangle
56 IPO
57 Linker
58 LTO
59 Object
60 Option
61 Passes
62 MC
63 Support
64 Target
65 TransformUtils
66
67 LINK_LIBS
68 lldConfig
69 lldCore
70 ${LLVM_PTHREAD_LIB}
71
72 DEPENDS
73 ELFOptionsTableGen
74 ${tablegen_deps}
75 )
deps/lld/ELF/Config.h created+238
......@@ -0,0 +1,238 @@
1//===- Config.h -------------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_ELF_CONFIG_H
11#define LLD_ELF_CONFIG_H
12
13#include "llvm/ADT/MapVector.h"
14#include "llvm/ADT/StringRef.h"
15#include "llvm/ADT/StringSet.h"
16#include "llvm/BinaryFormat/ELF.h"
17#include "llvm/Support/CachePruning.h"
18#include "llvm/Support/CodeGen.h"
19#include "llvm/Support/Endian.h"
20
21#include <vector>
22
23namespace lld {
24namespace elf {
25
26class InputFile;
27struct Symbol;
28
29enum ELFKind {
30 ELFNoneKind,
31 ELF32LEKind,
32 ELF32BEKind,
33 ELF64LEKind,
34 ELF64BEKind
35};
36
37// For --build-id.
38enum class BuildIdKind { None, Fast, Md5, Sha1, Hexstring, Uuid };
39
40// For --discard-{all,locals,none}.
41enum class DiscardPolicy { Default, All, Locals, None };
42
43// For --strip-{all,debug}.
44enum class StripPolicy { None, All, Debug };
45
46// For --unresolved-symbols.
47enum class UnresolvedPolicy { ReportError, Warn, WarnAll, Ignore, IgnoreAll };
48
49// For --sort-section and linkerscript sorting rules.
50enum class SortSectionPolicy { Default, None, Alignment, Name, Priority };
51
52// For --target2
53enum class Target2Policy { Abs, Rel, GotRel };
54
55struct SymbolVersion {
56 llvm::StringRef Name;
57 bool IsExternCpp;
58 bool HasWildcard;
59};
60
61// This struct contains symbols version definition that
62// can be found in version script if it is used for link.
63struct VersionDefinition {
64 llvm::StringRef Name;
65 uint16_t Id = 0;
66 std::vector<SymbolVersion> Globals;
67 size_t NameOff = 0; // Offset in the string table
68};
69
70// Structure for mapping renamed symbols
71struct RenamedSymbol {
72 Symbol *Target;
73 uint8_t OriginalBinding;
74};
75
76// This struct contains the global configuration for the linker.
77// Most fields are direct mapping from the command line options
78// and such fields have the same name as the corresponding options.
79// Most fields are initialized by the driver.
80struct Configuration {
81 InputFile *FirstElf = nullptr;
82 uint8_t OSABI = 0;
83 llvm::CachePruningPolicy ThinLTOCachePolicy;
84 llvm::StringMap<uint64_t> SectionStartMap;
85 llvm::StringRef DynamicLinker;
86 llvm::StringRef Entry;
87 llvm::StringRef Emulation;
88 llvm::StringRef Fini;
89 llvm::StringRef Init;
90 llvm::StringRef LTOAAPipeline;
91 llvm::StringRef LTONewPmPasses;
92 llvm::StringRef MapFile;
93 llvm::StringRef OutputFile;
94 llvm::StringRef OptRemarksFilename;
95 llvm::StringRef SoName;
96 llvm::StringRef Sysroot;
97 llvm::StringRef ThinLTOCacheDir;
98 std::string Rpath;
99 std::vector<VersionDefinition> VersionDefinitions;
100 std::vector<llvm::StringRef> Argv;
101 std::vector<llvm::StringRef> AuxiliaryList;
102 std::vector<llvm::StringRef> FilterList;
103 std::vector<llvm::StringRef> SearchPaths;
104 std::vector<llvm::StringRef> SymbolOrderingFile;
105 std::vector<llvm::StringRef> Undefined;
106 std::vector<SymbolVersion> VersionScriptGlobals;
107 std::vector<SymbolVersion> VersionScriptLocals;
108 std::vector<uint8_t> BuildIdVector;
109 llvm::MapVector<Symbol *, RenamedSymbol> RenamedSymbols;
110 bool AllowMultipleDefinition;
111 bool AsNeeded = false;
112 bool Bsymbolic;
113 bool BsymbolicFunctions;
114 bool ColorDiagnostics = false;
115 bool CompressDebugSections;
116 bool DefineCommon;
117 bool Demangle = true;
118 bool DisableVerify;
119 bool EhFrameHdr;
120 bool EmitRelocs;
121 bool EnableNewDtags;
122 bool ExportDynamic;
123 bool FatalWarnings;
124 bool GcSections;
125 bool GdbIndex;
126 bool GnuHash;
127 bool ICF;
128 bool MipsN32Abi = false;
129 bool NoGnuUnique;
130 bool NoUndefinedVersion;
131 bool Nostdlib;
132 bool OFormatBinary;
133 bool Omagic;
134 bool OptRemarksWithHotness;
135 bool Pie;
136 bool PrintGcSections;
137 bool Relocatable;
138 bool SaveTemps;
139 bool SingleRoRx;
140 bool Shared;
141 bool Static = false;
142 bool SysvHash;
143 bool Target1Rel;
144 bool Threads;
145 bool Trace;
146 bool Verbose;
147 bool WarnCommon;
148 bool WarnMissingEntry;
149 bool ZCombreloc;
150 bool ZExecstack;
151 bool ZNocopyreloc;
152 bool ZNodelete;
153 bool ZNodlopen;
154 bool ZNow;
155 bool ZOrigin;
156 bool ZRelro;
157 bool ZRodynamic;
158 bool ZText;
159 bool ExitEarly;
160 bool ZWxneeded;
161 DiscardPolicy Discard;
162 SortSectionPolicy SortSection;
163 StripPolicy Strip;
164 UnresolvedPolicy UnresolvedSymbols;
165 Target2Policy Target2;
166 BuildIdKind BuildId = BuildIdKind::None;
167 ELFKind EKind = ELFNoneKind;
168 uint16_t DefaultSymbolVersion = llvm::ELF::VER_NDX_GLOBAL;
169 uint16_t EMachine = llvm::ELF::EM_NONE;
170 uint64_t ErrorLimit = 20;
171 uint64_t ImageBase;
172 uint64_t MaxPageSize;
173 uint64_t ZStackSize;
174 unsigned LTOPartitions;
175 unsigned LTOO;
176 unsigned Optimize;
177 unsigned ThinLTOJobs;
178
179 // The following config options do not directly correspond to any
180 // particualr command line options.
181
182 // True if we need to pass through relocations in input files to the
183 // output file. Usually false because we consume relocations.
184 bool CopyRelocs;
185
186 // True if the target is ELF64. False if ELF32.
187 bool Is64;
188
189 // True if the target is little-endian. False if big-endian.
190 bool IsLE;
191
192 // endianness::little if IsLE is true. endianness::big otherwise.
193 llvm::support::endianness Endianness;
194
195 // True if the target is the little-endian MIPS64.
196 //
197 // The reason why we have this variable only for the MIPS is because
198 // we use this often. Some ELF headers for MIPS64EL are in a
199 // mixed-endian (which is horrible and I'd say that's a serious spec
200 // bug), and we need to know whether we are reading MIPS ELF files or
201 // not in various places.
202 //
203 // (Note that MIPS64EL is not a typo for MIPS64LE. This is the official
204 // name whatever that means. A fun hypothesis is that "EL" is short for
205 // little-endian written in the little-endian order, but I don't know
206 // if that's true.)
207 bool IsMips64EL;
208
209 // The ELF spec defines two types of relocation table entries, RELA and
210 // REL. RELA is a triplet of (offset, info, addend) while REL is a
211 // tuple of (offset, info). Addends for REL are implicit and read from
212 // the location where the relocations are applied. So, REL is more
213 // compact than RELA but requires a bit of more work to process.
214 //
215 // (From the linker writer's view, this distinction is not necessary.
216 // If the ELF had chosen whichever and sticked with it, it would have
217 // been easier to write code to process relocations, but it's too late
218 // to change the spec.)
219 //
220 // Each ABI defines its relocation type. IsRela is true if target
221 // uses RELA. As far as we know, all 64-bit ABIs are using RELA. A
222 // few 32-bit ABIs are using RELA too.
223 bool IsRela;
224
225 // True if we are creating position-independent code.
226 bool Pic;
227
228 // 4 for ELF32, 8 for ELF64.
229 int Wordsize;
230};
231
232// The only instance of Configuration struct.
233extern Configuration *Config;
234
235} // namespace elf
236} // namespace lld
237
238#endif
deps/lld/ELF/Driver.cpp created+1061
......@@ -0,0 +1,1061 @@
1//===- Driver.cpp ---------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// The driver drives the entire linking process. It is responsible for
11// parsing command line options and doing whatever it is instructed to do.
12//
13// One notable thing in the LLD's driver when compared to other linkers is
14// that the LLD's driver is agnostic on the host operating system.
15// Other linkers usually have implicit default values (such as a dynamic
16// linker path or library paths) for each host OS.
17//
18// I don't think implicit default values are useful because they are
19// usually explicitly specified by the compiler driver. They can even
20// be harmful when you are doing cross-linking. Therefore, in LLD, we
21// simply trust the compiler driver to pass all required options and
22// don't try to make effort on our side.
23//
24//===----------------------------------------------------------------------===//
25
26#include "Driver.h"
27#include "Config.h"
28#include "Error.h"
29#include "Filesystem.h"
30#include "ICF.h"
31#include "InputFiles.h"
32#include "InputSection.h"
33#include "LinkerScript.h"
34#include "Memory.h"
35#include "OutputSections.h"
36#include "ScriptParser.h"
37#include "Strings.h"
38#include "SymbolTable.h"
39#include "SyntheticSections.h"
40#include "Target.h"
41#include "Threads.h"
42#include "Writer.h"
43#include "lld/Config/Version.h"
44#include "lld/Driver/Driver.h"
45#include "llvm/ADT/StringExtras.h"
46#include "llvm/ADT/StringSwitch.h"
47#include "llvm/Support/CommandLine.h"
48#include "llvm/Support/Compression.h"
49#include "llvm/Support/Path.h"
50#include "llvm/Support/TarWriter.h"
51#include "llvm/Support/TargetSelect.h"
52#include "llvm/Support/raw_ostream.h"
53#include <cstdlib>
54#include <utility>
55
56using namespace llvm;
57using namespace llvm::ELF;
58using namespace llvm::object;
59using namespace llvm::sys;
60
61using namespace lld;
62using namespace lld::elf;
63
64Configuration *elf::Config;
65LinkerDriver *elf::Driver;
66
67BumpPtrAllocator elf::BAlloc;
68StringSaver elf::Saver{BAlloc};
69std::vector<SpecificAllocBase *> elf::SpecificAllocBase::Instances;
70
71static void setConfigs();
72
73bool elf::link(ArrayRef<const char *> Args, bool CanExitEarly,
74 raw_ostream &Error) {
75 ErrorCount = 0;
76 ErrorOS = &Error;
77 InputSections.clear();
78 Tar = nullptr;
79
80 Config = make<Configuration>();
81 Driver = make<LinkerDriver>();
82 Script = make<LinkerScript>();
83 Config->Argv = {Args.begin(), Args.end()};
84
85 Driver->main(Args, CanExitEarly);
86 freeArena();
87 return !ErrorCount;
88}
89
90// Parses a linker -m option.
91static std::tuple<ELFKind, uint16_t, uint8_t> parseEmulation(StringRef Emul) {
92 uint8_t OSABI = 0;
93 StringRef S = Emul;
94 if (S.endswith("_fbsd")) {
95 S = S.drop_back(5);
96 OSABI = ELFOSABI_FREEBSD;
97 }
98
99 std::pair<ELFKind, uint16_t> Ret =
100 StringSwitch<std::pair<ELFKind, uint16_t>>(S)
101 .Cases("aarch64elf", "aarch64linux", {ELF64LEKind, EM_AARCH64})
102 .Cases("armelf", "armelf_linux_eabi", {ELF32LEKind, EM_ARM})
103 .Case("elf32_x86_64", {ELF32LEKind, EM_X86_64})
104 .Cases("elf32btsmip", "elf32btsmipn32", {ELF32BEKind, EM_MIPS})
105 .Cases("elf32ltsmip", "elf32ltsmipn32", {ELF32LEKind, EM_MIPS})
106 .Case("elf32ppc", {ELF32BEKind, EM_PPC})
107 .Case("elf64btsmip", {ELF64BEKind, EM_MIPS})
108 .Case("elf64ltsmip", {ELF64LEKind, EM_MIPS})
109 .Case("elf64ppc", {ELF64BEKind, EM_PPC64})
110 .Cases("elf_amd64", "elf_x86_64", {ELF64LEKind, EM_X86_64})
111 .Case("elf_i386", {ELF32LEKind, EM_386})
112 .Case("elf_iamcu", {ELF32LEKind, EM_IAMCU})
113 .Default({ELFNoneKind, EM_NONE});
114
115 if (Ret.first == ELFNoneKind) {
116 if (S == "i386pe" || S == "i386pep" || S == "thumb2pe")
117 error("Windows targets are not supported on the ELF frontend: " + Emul);
118 else
119 error("unknown emulation: " + Emul);
120 }
121 return std::make_tuple(Ret.first, Ret.second, OSABI);
122}
123
124// Returns slices of MB by parsing MB as an archive file.
125// Each slice consists of a member file in the archive.
126std::vector<std::pair<MemoryBufferRef, uint64_t>> static getArchiveMembers(
127 MemoryBufferRef MB) {
128 std::unique_ptr<Archive> File =
129 check(Archive::create(MB),
130 MB.getBufferIdentifier() + ": failed to parse archive");
131
132 std::vector<std::pair<MemoryBufferRef, uint64_t>> V;
133 Error Err = Error::success();
134 for (const ErrorOr<Archive::Child> &COrErr : File->children(Err)) {
135 Archive::Child C =
136 check(COrErr, MB.getBufferIdentifier() +
137 ": could not get the child of the archive");
138 MemoryBufferRef MBRef =
139 check(C.getMemoryBufferRef(),
140 MB.getBufferIdentifier() +
141 ": could not get the buffer for a child of the archive");
142 V.push_back(std::make_pair(MBRef, C.getChildOffset()));
143 }
144 if (Err)
145 fatal(MB.getBufferIdentifier() + ": Archive::children failed: " +
146 toString(std::move(Err)));
147
148 // Take ownership of memory buffers created for members of thin archives.
149 for (std::unique_ptr<MemoryBuffer> &MB : File->takeThinBuffers())
150 make<std::unique_ptr<MemoryBuffer>>(std::move(MB));
151
152 return V;
153}
154
155// Opens a file and create a file object. Path has to be resolved already.
156void LinkerDriver::addFile(StringRef Path, bool WithLOption) {
157 using namespace sys::fs;
158
159 Optional<MemoryBufferRef> Buffer = readFile(Path);
160 if (!Buffer.hasValue())
161 return;
162 MemoryBufferRef MBRef = *Buffer;
163
164 if (InBinary) {
165 Files.push_back(make<BinaryFile>(MBRef));
166 return;
167 }
168
169 switch (identify_magic(MBRef.getBuffer())) {
170 case file_magic::unknown:
171 readLinkerScript(MBRef);
172 return;
173 case file_magic::archive: {
174 // Handle -whole-archive.
175 if (InWholeArchive) {
176 for (const auto &P : getArchiveMembers(MBRef))
177 Files.push_back(createObjectFile(P.first, Path, P.second));
178 return;
179 }
180
181 std::unique_ptr<Archive> File =
182 check(Archive::create(MBRef), Path + ": failed to parse archive");
183
184 // If an archive file has no symbol table, it is likely that a user
185 // is attempting LTO and using a default ar command that doesn't
186 // understand the LLVM bitcode file. It is a pretty common error, so
187 // we'll handle it as if it had a symbol table.
188 if (!File->isEmpty() && !File->hasSymbolTable()) {
189 for (const auto &P : getArchiveMembers(MBRef))
190 Files.push_back(make<LazyObjectFile>(P.first, Path, P.second));
191 return;
192 }
193
194 // Handle the regular case.
195 Files.push_back(make<ArchiveFile>(std::move(File)));
196 return;
197 }
198 case file_magic::elf_shared_object:
199 if (Config->Relocatable) {
200 error("attempted static link of dynamic object " + Path);
201 return;
202 }
203
204 // DSOs usually have DT_SONAME tags in their ELF headers, and the
205 // sonames are used to identify DSOs. But if they are missing,
206 // they are identified by filenames. We don't know whether the new
207 // file has a DT_SONAME or not because we haven't parsed it yet.
208 // Here, we set the default soname for the file because we might
209 // need it later.
210 //
211 // If a file was specified by -lfoo, the directory part is not
212 // significant, as a user did not specify it. This behavior is
213 // compatible with GNU.
214 Files.push_back(
215 createSharedFile(MBRef, WithLOption ? path::filename(Path) : Path));
216 return;
217 default:
218 if (InLib)
219 Files.push_back(make<LazyObjectFile>(MBRef, "", 0));
220 else
221 Files.push_back(createObjectFile(MBRef));
222 }
223}
224
225// Add a given library by searching it from input search paths.
226void LinkerDriver::addLibrary(StringRef Name) {
227 if (Optional<std::string> Path = searchLibrary(Name))
228 addFile(*Path, /*WithLOption=*/true);
229 else
230 error("unable to find library -l" + Name);
231}
232
233// This function is called on startup. We need this for LTO since
234// LTO calls LLVM functions to compile bitcode files to native code.
235// Technically this can be delayed until we read bitcode files, but
236// we don't bother to do lazily because the initialization is fast.
237static void initLLVM(opt::InputArgList &Args) {
238 InitializeAllTargets();
239 InitializeAllTargetMCs();
240 InitializeAllAsmPrinters();
241 InitializeAllAsmParsers();
242
243 // Parse and evaluate -mllvm options.
244 std::vector<const char *> V;
245 V.push_back("lld (LLVM option parsing)");
246 for (auto *Arg : Args.filtered(OPT_mllvm))
247 V.push_back(Arg->getValue());
248 cl::ParseCommandLineOptions(V.size(), V.data());
249}
250
251// Some command line options or some combinations of them are not allowed.
252// This function checks for such errors.
253static void checkOptions(opt::InputArgList &Args) {
254 // The MIPS ABI as of 2016 does not support the GNU-style symbol lookup
255 // table which is a relatively new feature.
256 if (Config->EMachine == EM_MIPS && Config->GnuHash)
257 error("the .gnu.hash section is not compatible with the MIPS target.");
258
259 if (Config->Pie && Config->Shared)
260 error("-shared and -pie may not be used together");
261
262 if (!Config->Shared && !Config->FilterList.empty())
263 error("-F may not be used without -shared");
264
265 if (!Config->Shared && !Config->AuxiliaryList.empty())
266 error("-f may not be used without -shared");
267
268 if (Config->Relocatable) {
269 if (Config->Shared)
270 error("-r and -shared may not be used together");
271 if (Config->GcSections)
272 error("-r and --gc-sections may not be used together");
273 if (Config->ICF)
274 error("-r and --icf may not be used together");
275 if (Config->Pie)
276 error("-r and -pie may not be used together");
277 }
278}
279
280static int getInteger(opt::InputArgList &Args, unsigned Key, int Default) {
281 int V = Default;
282 if (auto *Arg = Args.getLastArg(Key)) {
283 StringRef S = Arg->getValue();
284 if (!to_integer(S, V, 10))
285 error(Arg->getSpelling() + ": number expected, but got " + S);
286 }
287 return V;
288}
289
290static const char *getReproduceOption(opt::InputArgList &Args) {
291 if (auto *Arg = Args.getLastArg(OPT_reproduce))
292 return Arg->getValue();
293 return getenv("LLD_REPRODUCE");
294}
295
296static bool hasZOption(opt::InputArgList &Args, StringRef Key) {
297 for (auto *Arg : Args.filtered(OPT_z))
298 if (Key == Arg->getValue())
299 return true;
300 return false;
301}
302
303static uint64_t getZOptionValue(opt::InputArgList &Args, StringRef Key,
304 uint64_t Default) {
305 for (auto *Arg : Args.filtered(OPT_z)) {
306 std::pair<StringRef, StringRef> KV = StringRef(Arg->getValue()).split('=');
307 if (KV.first == Key) {
308 uint64_t Result = Default;
309 if (!to_integer(KV.second, Result))
310 error("invalid " + Key + ": " + KV.second);
311 return Result;
312 }
313 }
314 return Default;
315}
316
317void LinkerDriver::main(ArrayRef<const char *> ArgsArr, bool CanExitEarly) {
318 ELFOptTable Parser;
319 opt::InputArgList Args = Parser.parse(ArgsArr.slice(1));
320
321 // Interpret this flag early because error() depends on them.
322 Config->ErrorLimit = getInteger(Args, OPT_error_limit, 20);
323
324 // Handle -help
325 if (Args.hasArg(OPT_help)) {
326 printHelp(ArgsArr[0]);
327 return;
328 }
329
330 // Handle -v or -version.
331 //
332 // A note about "compatible with GNU linkers" message: this is a hack for
333 // scripts generated by GNU Libtool 2.4.6 (released in February 2014 and
334 // still the newest version in March 2017) or earlier to recognize LLD as
335 // a GNU compatible linker. As long as an output for the -v option
336 // contains "GNU" or "with BFD", they recognize us as GNU-compatible.
337 //
338 // This is somewhat ugly hack, but in reality, we had no choice other
339 // than doing this. Considering the very long release cycle of Libtool,
340 // it is not easy to improve it to recognize LLD as a GNU compatible
341 // linker in a timely manner. Even if we can make it, there are still a
342 // lot of "configure" scripts out there that are generated by old version
343 // of Libtool. We cannot convince every software developer to migrate to
344 // the latest version and re-generate scripts. So we have this hack.
345 if (Args.hasArg(OPT_v) || Args.hasArg(OPT_version))
346 message(getLLDVersion() + " (compatible with GNU linkers)");
347
348 // ld.bfd always exits after printing out the version string.
349 // ld.gold proceeds if a given option is -v. Because gold's behavior
350 // is more permissive than ld.bfd, we chose what gold does here.
351 if (Args.hasArg(OPT_version))
352 return;
353
354 Config->ExitEarly = CanExitEarly && !Args.hasArg(OPT_full_shutdown);
355
356 if (const char *Path = getReproduceOption(Args)) {
357 // Note that --reproduce is a debug option so you can ignore it
358 // if you are trying to understand the whole picture of the code.
359 Expected<std::unique_ptr<TarWriter>> ErrOrWriter =
360 TarWriter::create(Path, path::stem(Path));
361 if (ErrOrWriter) {
362 Tar = ErrOrWriter->get();
363 Tar->append("response.txt", createResponseFile(Args));
364 Tar->append("version.txt", getLLDVersion() + "\n");
365 make<std::unique_ptr<TarWriter>>(std::move(*ErrOrWriter));
366 } else {
367 error(Twine("--reproduce: failed to open ") + Path + ": " +
368 toString(ErrOrWriter.takeError()));
369 }
370 }
371
372 readConfigs(Args);
373 initLLVM(Args);
374 createFiles(Args);
375 inferMachineType();
376 setConfigs();
377 checkOptions(Args);
378 if (ErrorCount)
379 return;
380
381 switch (Config->EKind) {
382 case ELF32LEKind:
383 link<ELF32LE>(Args);
384 return;
385 case ELF32BEKind:
386 link<ELF32BE>(Args);
387 return;
388 case ELF64LEKind:
389 link<ELF64LE>(Args);
390 return;
391 case ELF64BEKind:
392 link<ELF64BE>(Args);
393 return;
394 default:
395 llvm_unreachable("unknown Config->EKind");
396 }
397}
398
399static bool getArg(opt::InputArgList &Args, unsigned K1, unsigned K2,
400 bool Default) {
401 if (auto *Arg = Args.getLastArg(K1, K2))
402 return Arg->getOption().getID() == K1;
403 return Default;
404}
405
406static std::vector<StringRef> getArgs(opt::InputArgList &Args, int Id) {
407 std::vector<StringRef> V;
408 for (auto *Arg : Args.filtered(Id))
409 V.push_back(Arg->getValue());
410 return V;
411}
412
413static std::string getRpath(opt::InputArgList &Args) {
414 std::vector<StringRef> V = getArgs(Args, OPT_rpath);
415 return llvm::join(V.begin(), V.end(), ":");
416}
417
418// Determines what we should do if there are remaining unresolved
419// symbols after the name resolution.
420static UnresolvedPolicy getUnresolvedSymbolPolicy(opt::InputArgList &Args) {
421 // -noinhibit-exec or -r imply some default values.
422 if (Args.hasArg(OPT_noinhibit_exec))
423 return UnresolvedPolicy::WarnAll;
424 if (Args.hasArg(OPT_relocatable))
425 return UnresolvedPolicy::IgnoreAll;
426
427 UnresolvedPolicy ErrorOrWarn = getArg(Args, OPT_error_unresolved_symbols,
428 OPT_warn_unresolved_symbols, true)
429 ? UnresolvedPolicy::ReportError
430 : UnresolvedPolicy::Warn;
431
432 // Process the last of -unresolved-symbols, -no-undefined or -z defs.
433 for (auto *Arg : llvm::reverse(Args)) {
434 switch (Arg->getOption().getID()) {
435 case OPT_unresolved_symbols: {
436 StringRef S = Arg->getValue();
437 if (S == "ignore-all" || S == "ignore-in-object-files")
438 return UnresolvedPolicy::Ignore;
439 if (S == "ignore-in-shared-libs" || S == "report-all")
440 return ErrorOrWarn;
441 error("unknown --unresolved-symbols value: " + S);
442 continue;
443 }
444 case OPT_no_undefined:
445 return ErrorOrWarn;
446 case OPT_z:
447 if (StringRef(Arg->getValue()) == "defs")
448 return ErrorOrWarn;
449 continue;
450 }
451 }
452
453 // -shared implies -unresolved-symbols=ignore-all because missing
454 // symbols are likely to be resolved at runtime using other DSOs.
455 if (Config->Shared)
456 return UnresolvedPolicy::Ignore;
457 return ErrorOrWarn;
458}
459
460static Target2Policy getTarget2(opt::InputArgList &Args) {
461 StringRef S = Args.getLastArgValue(OPT_target2, "got-rel");
462 if (S == "rel")
463 return Target2Policy::Rel;
464 if (S == "abs")
465 return Target2Policy::Abs;
466 if (S == "got-rel")
467 return Target2Policy::GotRel;
468 error("unknown --target2 option: " + S);
469 return Target2Policy::GotRel;
470}
471
472static bool isOutputFormatBinary(opt::InputArgList &Args) {
473 if (auto *Arg = Args.getLastArg(OPT_oformat)) {
474 StringRef S = Arg->getValue();
475 if (S == "binary")
476 return true;
477 error("unknown --oformat value: " + S);
478 }
479 return false;
480}
481
482static DiscardPolicy getDiscard(opt::InputArgList &Args) {
483 if (Args.hasArg(OPT_relocatable))
484 return DiscardPolicy::None;
485
486 auto *Arg =
487 Args.getLastArg(OPT_discard_all, OPT_discard_locals, OPT_discard_none);
488 if (!Arg)
489 return DiscardPolicy::Default;
490 if (Arg->getOption().getID() == OPT_discard_all)
491 return DiscardPolicy::All;
492 if (Arg->getOption().getID() == OPT_discard_locals)
493 return DiscardPolicy::Locals;
494 return DiscardPolicy::None;
495}
496
497static StringRef getDynamicLinker(opt::InputArgList &Args) {
498 auto *Arg = Args.getLastArg(OPT_dynamic_linker, OPT_no_dynamic_linker);
499 if (!Arg || Arg->getOption().getID() == OPT_no_dynamic_linker)
500 return "";
501 return Arg->getValue();
502}
503
504static StripPolicy getStrip(opt::InputArgList &Args) {
505 if (Args.hasArg(OPT_relocatable))
506 return StripPolicy::None;
507
508 auto *Arg = Args.getLastArg(OPT_strip_all, OPT_strip_debug);
509 if (!Arg)
510 return StripPolicy::None;
511 if (Arg->getOption().getID() == OPT_strip_all)
512 return StripPolicy::All;
513 return StripPolicy::Debug;
514}
515
516static uint64_t parseSectionAddress(StringRef S, opt::Arg *Arg) {
517 uint64_t VA = 0;
518 if (S.startswith("0x"))
519 S = S.drop_front(2);
520 if (!to_integer(S, VA, 16))
521 error("invalid argument: " + toString(Arg));
522 return VA;
523}
524
525static StringMap<uint64_t> getSectionStartMap(opt::InputArgList &Args) {
526 StringMap<uint64_t> Ret;
527 for (auto *Arg : Args.filtered(OPT_section_start)) {
528 StringRef Name;
529 StringRef Addr;
530 std::tie(Name, Addr) = StringRef(Arg->getValue()).split('=');
531 Ret[Name] = parseSectionAddress(Addr, Arg);
532 }
533
534 if (auto *Arg = Args.getLastArg(OPT_Ttext))
535 Ret[".text"] = parseSectionAddress(Arg->getValue(), Arg);
536 if (auto *Arg = Args.getLastArg(OPT_Tdata))
537 Ret[".data"] = parseSectionAddress(Arg->getValue(), Arg);
538 if (auto *Arg = Args.getLastArg(OPT_Tbss))
539 Ret[".bss"] = parseSectionAddress(Arg->getValue(), Arg);
540 return Ret;
541}
542
543static SortSectionPolicy getSortSection(opt::InputArgList &Args) {
544 StringRef S = Args.getLastArgValue(OPT_sort_section);
545 if (S == "alignment")
546 return SortSectionPolicy::Alignment;
547 if (S == "name")
548 return SortSectionPolicy::Name;
549 if (!S.empty())
550 error("unknown --sort-section rule: " + S);
551 return SortSectionPolicy::Default;
552}
553
554static std::pair<bool, bool> getHashStyle(opt::InputArgList &Args) {
555 StringRef S = Args.getLastArgValue(OPT_hash_style, "sysv");
556 if (S == "sysv")
557 return {true, false};
558 if (S == "gnu")
559 return {false, true};
560 if (S != "both")
561 error("unknown -hash-style: " + S);
562 return {true, true};
563}
564
565// Parse --build-id or --build-id=<style>. We handle "tree" as a
566// synonym for "sha1" because all our hash functions including
567// -build-id=sha1 are actually tree hashes for performance reasons.
568static std::pair<BuildIdKind, std::vector<uint8_t>>
569getBuildId(opt::InputArgList &Args) {
570 auto *Arg = Args.getLastArg(OPT_build_id, OPT_build_id_eq);
571 if (!Arg)
572 return {BuildIdKind::None, {}};
573
574 if (Arg->getOption().getID() == OPT_build_id)
575 return {BuildIdKind::Fast, {}};
576
577 StringRef S = Arg->getValue();
578 if (S == "md5")
579 return {BuildIdKind::Md5, {}};
580 if (S == "sha1" || S == "tree")
581 return {BuildIdKind::Sha1, {}};
582 if (S == "uuid")
583 return {BuildIdKind::Uuid, {}};
584 if (S.startswith("0x"))
585 return {BuildIdKind::Hexstring, parseHex(S.substr(2))};
586
587 if (S != "none")
588 error("unknown --build-id style: " + S);
589 return {BuildIdKind::None, {}};
590}
591
592static std::vector<StringRef> getLines(MemoryBufferRef MB) {
593 SmallVector<StringRef, 0> Arr;
594 MB.getBuffer().split(Arr, '\n');
595
596 std::vector<StringRef> Ret;
597 for (StringRef S : Arr) {
598 S = S.trim();
599 if (!S.empty())
600 Ret.push_back(S);
601 }
602 return Ret;
603}
604
605static bool getCompressDebugSections(opt::InputArgList &Args) {
606 StringRef S = Args.getLastArgValue(OPT_compress_debug_sections, "none");
607 if (S == "none")
608 return false;
609 if (S != "zlib")
610 error("unknown --compress-debug-sections value: " + S);
611 if (!zlib::isAvailable())
612 error("--compress-debug-sections: zlib is not available");
613 return true;
614}
615
616// Initializes Config members by the command line options.
617void LinkerDriver::readConfigs(opt::InputArgList &Args) {
618 Config->AllowMultipleDefinition = Args.hasArg(OPT_allow_multiple_definition);
619 Config->AuxiliaryList = getArgs(Args, OPT_auxiliary);
620 Config->Bsymbolic = Args.hasArg(OPT_Bsymbolic);
621 Config->BsymbolicFunctions = Args.hasArg(OPT_Bsymbolic_functions);
622 Config->CompressDebugSections = getCompressDebugSections(Args);
623 Config->DefineCommon = getArg(Args, OPT_define_common, OPT_no_define_common,
624 !Args.hasArg(OPT_relocatable));
625 Config->Demangle = getArg(Args, OPT_demangle, OPT_no_demangle, true);
626 Config->DisableVerify = Args.hasArg(OPT_disable_verify);
627 Config->Discard = getDiscard(Args);
628 Config->DynamicLinker = getDynamicLinker(Args);
629 Config->EhFrameHdr = Args.hasArg(OPT_eh_frame_hdr);
630 Config->EmitRelocs = Args.hasArg(OPT_emit_relocs);
631 Config->EnableNewDtags = !Args.hasArg(OPT_disable_new_dtags);
632 Config->Entry = Args.getLastArgValue(OPT_entry);
633 Config->ExportDynamic =
634 getArg(Args, OPT_export_dynamic, OPT_no_export_dynamic, false);
635 Config->FatalWarnings =
636 getArg(Args, OPT_fatal_warnings, OPT_no_fatal_warnings, false);
637 Config->FilterList = getArgs(Args, OPT_filter);
638 Config->Fini = Args.getLastArgValue(OPT_fini, "_fini");
639 Config->GcSections = getArg(Args, OPT_gc_sections, OPT_no_gc_sections, false);
640 Config->GdbIndex = Args.hasArg(OPT_gdb_index);
641 Config->ICF = getArg(Args, OPT_icf_all, OPT_icf_none, false);
642 Config->Init = Args.getLastArgValue(OPT_init, "_init");
643 Config->LTOAAPipeline = Args.getLastArgValue(OPT_lto_aa_pipeline);
644 Config->LTONewPmPasses = Args.getLastArgValue(OPT_lto_newpm_passes);
645 Config->LTOO = getInteger(Args, OPT_lto_O, 2);
646 Config->LTOPartitions = getInteger(Args, OPT_lto_partitions, 1);
647 Config->MapFile = Args.getLastArgValue(OPT_Map);
648 Config->NoGnuUnique = Args.hasArg(OPT_no_gnu_unique);
649 Config->NoUndefinedVersion = Args.hasArg(OPT_no_undefined_version);
650 Config->Nostdlib = Args.hasArg(OPT_nostdlib);
651 Config->OFormatBinary = isOutputFormatBinary(Args);
652 Config->Omagic = Args.hasArg(OPT_omagic);
653 Config->OptRemarksFilename = Args.getLastArgValue(OPT_opt_remarks_filename);
654 Config->OptRemarksWithHotness = Args.hasArg(OPT_opt_remarks_with_hotness);
655 Config->Optimize = getInteger(Args, OPT_O, 1);
656 Config->OutputFile = Args.getLastArgValue(OPT_o);
657 Config->Pie = getArg(Args, OPT_pie, OPT_nopie, false);
658 Config->PrintGcSections = Args.hasArg(OPT_print_gc_sections);
659 Config->Rpath = getRpath(Args);
660 Config->Relocatable = Args.hasArg(OPT_relocatable);
661 Config->SaveTemps = Args.hasArg(OPT_save_temps);
662 Config->SearchPaths = getArgs(Args, OPT_L);
663 Config->SectionStartMap = getSectionStartMap(Args);
664 Config->Shared = Args.hasArg(OPT_shared);
665 Config->SingleRoRx = Args.hasArg(OPT_no_rosegment);
666 Config->SoName = Args.getLastArgValue(OPT_soname);
667 Config->SortSection = getSortSection(Args);
668 Config->Strip = getStrip(Args);
669 Config->Sysroot = Args.getLastArgValue(OPT_sysroot);
670 Config->Target1Rel = getArg(Args, OPT_target1_rel, OPT_target1_abs, false);
671 Config->Target2 = getTarget2(Args);
672 Config->ThinLTOCacheDir = Args.getLastArgValue(OPT_thinlto_cache_dir);
673 Config->ThinLTOCachePolicy = check(
674 parseCachePruningPolicy(Args.getLastArgValue(OPT_thinlto_cache_policy)),
675 "--thinlto-cache-policy: invalid cache policy");
676 Config->ThinLTOJobs = getInteger(Args, OPT_thinlto_jobs, -1u);
677 Config->Threads = getArg(Args, OPT_threads, OPT_no_threads, true);
678 Config->Trace = Args.hasArg(OPT_trace);
679 Config->Undefined = getArgs(Args, OPT_undefined);
680 Config->UnresolvedSymbols = getUnresolvedSymbolPolicy(Args);
681 Config->Verbose = Args.hasArg(OPT_verbose);
682 Config->WarnCommon = Args.hasArg(OPT_warn_common);
683 Config->ZCombreloc = !hasZOption(Args, "nocombreloc");
684 Config->ZExecstack = hasZOption(Args, "execstack");
685 Config->ZNocopyreloc = hasZOption(Args, "nocopyreloc");
686 Config->ZNodelete = hasZOption(Args, "nodelete");
687 Config->ZNodlopen = hasZOption(Args, "nodlopen");
688 Config->ZNow = hasZOption(Args, "now");
689 Config->ZOrigin = hasZOption(Args, "origin");
690 Config->ZRelro = !hasZOption(Args, "norelro");
691 Config->ZRodynamic = hasZOption(Args, "rodynamic");
692 Config->ZStackSize = getZOptionValue(Args, "stack-size", 0);
693 Config->ZText = !hasZOption(Args, "notext");
694 Config->ZWxneeded = hasZOption(Args, "wxneeded");
695
696 if (Config->LTOO > 3)
697 error("invalid optimization level for LTO: " +
698 Args.getLastArgValue(OPT_lto_O));
699 if (Config->LTOPartitions == 0)
700 error("--lto-partitions: number of threads must be > 0");
701 if (Config->ThinLTOJobs == 0)
702 error("--thinlto-jobs: number of threads must be > 0");
703
704 if (auto *Arg = Args.getLastArg(OPT_m)) {
705 // Parse ELF{32,64}{LE,BE} and CPU type.
706 StringRef S = Arg->getValue();
707 std::tie(Config->EKind, Config->EMachine, Config->OSABI) =
708 parseEmulation(S);
709 Config->MipsN32Abi = (S == "elf32btsmipn32" || S == "elf32ltsmipn32");
710 Config->Emulation = S;
711 }
712
713 if (Args.hasArg(OPT_print_map))
714 Config->MapFile = "-";
715
716 // --omagic is an option to create old-fashioned executables in which
717 // .text segments are writable. Today, the option is still in use to
718 // create special-purpose programs such as boot loaders. It doesn't
719 // make sense to create PT_GNU_RELRO for such executables.
720 if (Config->Omagic)
721 Config->ZRelro = false;
722
723 std::tie(Config->SysvHash, Config->GnuHash) = getHashStyle(Args);
724 std::tie(Config->BuildId, Config->BuildIdVector) = getBuildId(Args);
725
726 if (auto *Arg = Args.getLastArg(OPT_symbol_ordering_file))
727 if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue()))
728 Config->SymbolOrderingFile = getLines(*Buffer);
729
730 // If --retain-symbol-file is used, we'll keep only the symbols listed in
731 // the file and discard all others.
732 if (auto *Arg = Args.getLastArg(OPT_retain_symbols_file)) {
733 Config->DefaultSymbolVersion = VER_NDX_LOCAL;
734 if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue()))
735 for (StringRef S : getLines(*Buffer))
736 Config->VersionScriptGlobals.push_back(
737 {S, /*IsExternCpp*/ false, /*HasWildcard*/ false});
738 }
739
740 bool HasExportDynamic =
741 getArg(Args, OPT_export_dynamic, OPT_no_export_dynamic, false);
742
743 // Parses -dynamic-list and -export-dynamic-symbol. They make some
744 // symbols private. Note that -export-dynamic takes precedence over them
745 // as it says all symbols should be exported.
746 if (!HasExportDynamic) {
747 for (auto *Arg : Args.filtered(OPT_dynamic_list))
748 if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue()))
749 readDynamicList(*Buffer);
750
751 for (auto *Arg : Args.filtered(OPT_export_dynamic_symbol))
752 Config->VersionScriptGlobals.push_back(
753 {Arg->getValue(), /*IsExternCpp*/ false, /*HasWildcard*/ false});
754
755 // Dynamic lists are a simplified linker script that doesn't need the
756 // "global:" and implicitly ends with a "local:*". Set the variables
757 // needed to simulate that.
758 if (Args.hasArg(OPT_dynamic_list) ||
759 Args.hasArg(OPT_export_dynamic_symbol)) {
760 Config->ExportDynamic = true;
761 if (!Config->Shared)
762 Config->DefaultSymbolVersion = VER_NDX_LOCAL;
763 }
764 }
765
766 if (auto *Arg = Args.getLastArg(OPT_version_script))
767 if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue()))
768 readVersionScript(*Buffer);
769}
770
771// Some Config members do not directly correspond to any particular
772// command line options, but computed based on other Config values.
773// This function initialize such members. See Config.h for the details
774// of these values.
775static void setConfigs() {
776 ELFKind Kind = Config->EKind;
777 uint16_t Machine = Config->EMachine;
778
779 // There is an ILP32 ABI for x86-64, although it's not very popular.
780 // It is called the x32 ABI.
781 bool IsX32 = (Kind == ELF32LEKind && Machine == EM_X86_64);
782
783 Config->CopyRelocs = (Config->Relocatable || Config->EmitRelocs);
784 Config->Is64 = (Kind == ELF64LEKind || Kind == ELF64BEKind);
785 Config->IsLE = (Kind == ELF32LEKind || Kind == ELF64LEKind);
786 Config->Endianness =
787 Config->IsLE ? support::endianness::little : support::endianness::big;
788 Config->IsMips64EL = (Kind == ELF64LEKind && Machine == EM_MIPS);
789 Config->IsRela = Config->Is64 || IsX32 || Config->MipsN32Abi;
790 Config->Pic = Config->Pie || Config->Shared;
791 Config->Wordsize = Config->Is64 ? 8 : 4;
792}
793
794// Returns a value of "-format" option.
795static bool getBinaryOption(StringRef S) {
796 if (S == "binary")
797 return true;
798 if (S == "elf" || S == "default")
799 return false;
800 error("unknown -format value: " + S +
801 " (supported formats: elf, default, binary)");
802 return false;
803}
804
805void LinkerDriver::createFiles(opt::InputArgList &Args) {
806 for (auto *Arg : Args) {
807 switch (Arg->getOption().getID()) {
808 case OPT_l:
809 addLibrary(Arg->getValue());
810 break;
811 case OPT_INPUT:
812 addFile(Arg->getValue(), /*WithLOption=*/false);
813 break;
814 case OPT_alias_script_T:
815 case OPT_script:
816 if (Optional<MemoryBufferRef> MB = readFile(Arg->getValue()))
817 readLinkerScript(*MB);
818 break;
819 case OPT_as_needed:
820 Config->AsNeeded = true;
821 break;
822 case OPT_format:
823 InBinary = getBinaryOption(Arg->getValue());
824 break;
825 case OPT_no_as_needed:
826 Config->AsNeeded = false;
827 break;
828 case OPT_Bstatic:
829 Config->Static = true;
830 break;
831 case OPT_Bdynamic:
832 Config->Static = false;
833 break;
834 case OPT_whole_archive:
835 InWholeArchive = true;
836 break;
837 case OPT_no_whole_archive:
838 InWholeArchive = false;
839 break;
840 case OPT_start_lib:
841 InLib = true;
842 break;
843 case OPT_end_lib:
844 InLib = false;
845 break;
846 }
847 }
848
849 if (Files.empty() && ErrorCount == 0)
850 error("no input files");
851}
852
853// If -m <machine_type> was not given, infer it from object files.
854void LinkerDriver::inferMachineType() {
855 if (Config->EKind != ELFNoneKind)
856 return;
857
858 for (InputFile *F : Files) {
859 if (F->EKind == ELFNoneKind)
860 continue;
861 Config->EKind = F->EKind;
862 Config->EMachine = F->EMachine;
863 Config->OSABI = F->OSABI;
864 Config->MipsN32Abi = Config->EMachine == EM_MIPS && isMipsN32Abi(F);
865 return;
866 }
867 error("target emulation unknown: -m or at least one .o file required");
868}
869
870// Parse -z max-page-size=<value>. The default value is defined by
871// each target.
872static uint64_t getMaxPageSize(opt::InputArgList &Args) {
873 uint64_t Val =
874 getZOptionValue(Args, "max-page-size", Target->DefaultMaxPageSize);
875 if (!isPowerOf2_64(Val))
876 error("max-page-size: value isn't a power of 2");
877 return Val;
878}
879
880// Parses -image-base option.
881static uint64_t getImageBase(opt::InputArgList &Args) {
882 // Use default if no -image-base option is given.
883 // Because we are using "Target" here, this function
884 // has to be called after the variable is initialized.
885 auto *Arg = Args.getLastArg(OPT_image_base);
886 if (!Arg)
887 return Config->Pic ? 0 : Target->DefaultImageBase;
888
889 StringRef S = Arg->getValue();
890 uint64_t V;
891 if (!to_integer(S, V)) {
892 error("-image-base: number expected, but got " + S);
893 return 0;
894 }
895 if ((V % Config->MaxPageSize) != 0)
896 warn("-image-base: address isn't multiple of page size: " + S);
897 return V;
898}
899
900// Parses --defsym=alias option.
901static std::vector<std::pair<StringRef, StringRef>>
902getDefsym(opt::InputArgList &Args) {
903 std::vector<std::pair<StringRef, StringRef>> Ret;
904 for (auto *Arg : Args.filtered(OPT_defsym)) {
905 StringRef From;
906 StringRef To;
907 std::tie(From, To) = StringRef(Arg->getValue()).split('=');
908 if (!isValidCIdentifier(To))
909 error("--defsym: symbol name expected, but got " + To);
910 Ret.push_back({From, To});
911 }
912 return Ret;
913}
914
915// Parses `--exclude-libs=lib,lib,...`.
916// The library names may be delimited by commas or colons.
917static DenseSet<StringRef> getExcludeLibs(opt::InputArgList &Args) {
918 DenseSet<StringRef> Ret;
919 for (auto *Arg : Args.filtered(OPT_exclude_libs)) {
920 StringRef S = Arg->getValue();
921 for (;;) {
922 size_t Pos = S.find_first_of(",:");
923 if (Pos == StringRef::npos)
924 break;
925 Ret.insert(S.substr(0, Pos));
926 S = S.substr(Pos + 1);
927 }
928 Ret.insert(S);
929 }
930 return Ret;
931}
932
933// Handles the -exclude-libs option. If a static library file is specified
934// by the -exclude-libs option, all public symbols from the archive become
935// private unless otherwise specified by version scripts or something.
936// A special library name "ALL" means all archive files.
937//
938// This is not a popular option, but some programs such as bionic libc use it.
939static void excludeLibs(opt::InputArgList &Args, ArrayRef<InputFile *> Files) {
940 DenseSet<StringRef> Libs = getExcludeLibs(Args);
941 bool All = Libs.count("ALL");
942
943 for (InputFile *File : Files)
944 if (auto *F = dyn_cast<ArchiveFile>(File))
945 if (All || Libs.count(path::filename(F->getName())))
946 for (Symbol *Sym : F->getSymbols())
947 Sym->VersionId = VER_NDX_LOCAL;
948}
949
950// Do actual linking. Note that when this function is called,
951// all linker scripts have already been parsed.
952template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
953 SymbolTable<ELFT> Symtab;
954 elf::Symtab<ELFT>::X = &Symtab;
955 Target = getTarget();
956
957 Config->MaxPageSize = getMaxPageSize(Args);
958 Config->ImageBase = getImageBase(Args);
959
960 // Default output filename is "a.out" by the Unix tradition.
961 if (Config->OutputFile.empty())
962 Config->OutputFile = "a.out";
963
964 // Fail early if the output file or map file is not writable. If a user has a
965 // long link, e.g. due to a large LTO link, they do not wish to run it and
966 // find that it failed because there was a mistake in their command-line.
967 if (auto E = tryCreateFile(Config->OutputFile))
968 error("cannot open output file " + Config->OutputFile + ": " + E.message());
969 if (auto E = tryCreateFile(Config->MapFile))
970 error("cannot open map file " + Config->MapFile + ": " + E.message());
971 if (ErrorCount)
972 return;
973
974 // Use default entry point name if no name was given via the command
975 // line nor linker scripts. For some reason, MIPS entry point name is
976 // different from others.
977 Config->WarnMissingEntry =
978 (!Config->Entry.empty() || (!Config->Shared && !Config->Relocatable));
979 if (Config->Entry.empty() && !Config->Relocatable)
980 Config->Entry = (Config->EMachine == EM_MIPS) ? "__start" : "_start";
981
982 // Handle --trace-symbol.
983 for (auto *Arg : Args.filtered(OPT_trace_symbol))
984 Symtab.trace(Arg->getValue());
985
986 // Add all files to the symbol table. This will add almost all
987 // symbols that we need to the symbol table.
988 for (InputFile *F : Files)
989 Symtab.addFile(F);
990
991 // If an entry symbol is in a static archive, pull out that file now
992 // to complete the symbol table. After this, no new names except a
993 // few linker-synthesized ones will be added to the symbol table.
994 if (Symtab.find(Config->Entry))
995 Symtab.addUndefined(Config->Entry);
996
997 // Return if there were name resolution errors.
998 if (ErrorCount)
999 return;
1000
1001 // Handle the `--undefined <sym>` options.
1002 Symtab.scanUndefinedFlags();
1003
1004 // Handle undefined symbols in DSOs.
1005 Symtab.scanShlibUndefined();
1006
1007 // Handle the -exclude-libs option.
1008 if (Args.hasArg(OPT_exclude_libs))
1009 excludeLibs(Args, Files);
1010
1011 // Apply version scripts.
1012 Symtab.scanVersionScript();
1013
1014 // Create wrapped symbols for -wrap option.
1015 for (auto *Arg : Args.filtered(OPT_wrap))
1016 Symtab.addSymbolWrap(Arg->getValue());
1017
1018 // Create alias symbols for -defsym option.
1019 for (std::pair<StringRef, StringRef> &Def : getDefsym(Args))
1020 Symtab.addSymbolAlias(Def.first, Def.second);
1021
1022 Symtab.addCombinedLTOObject();
1023 if (ErrorCount)
1024 return;
1025
1026 // Some symbols (such as __ehdr_start) are defined lazily only when there
1027 // are undefined symbols for them, so we add these to trigger that logic.
1028 for (StringRef Sym : Script->Opt.ReferencedSymbols)
1029 Symtab.addUndefined(Sym);
1030
1031 // Apply symbol renames for -wrap and -defsym
1032 Symtab.applySymbolRenames();
1033
1034 // Now that we have a complete list of input files.
1035 // Beyond this point, no new files are added.
1036 // Aggregate all input sections into one place.
1037 for (elf::ObjectFile<ELFT> *F : Symtab.getObjectFiles())
1038 for (InputSectionBase *S : F->getSections())
1039 if (S && S != &InputSection::Discarded)
1040 InputSections.push_back(S);
1041 for (BinaryFile *F : Symtab.getBinaryFiles())
1042 for (InputSectionBase *S : F->getSections())
1043 InputSections.push_back(cast<InputSection>(S));
1044
1045 // This adds a .comment section containing a version string. We have to add it
1046 // before decompressAndMergeSections because the .comment section is a
1047 // mergeable section.
1048 if (!Config->Relocatable)
1049 InputSections.push_back(createCommentSection<ELFT>());
1050
1051 // Do size optimizations: garbage collection, merging of SHF_MERGE sections
1052 // and identical code folding.
1053 if (Config->GcSections)
1054 markLive<ELFT>();
1055 decompressAndMergeSections();
1056 if (Config->ICF)
1057 doIcf<ELFT>();
1058
1059 // Write the result to the file.
1060 writeResult<ELFT>();
1061}
deps/lld/ELF/Driver.h created+75
......@@ -0,0 +1,75 @@
1//===- Driver.h -------------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_ELF_DRIVER_H
11#define LLD_ELF_DRIVER_H
12
13#include "SymbolTable.h"
14#include "lld/Core/LLVM.h"
15#include "lld/Core/Reproduce.h"
16#include "llvm/ADT/Optional.h"
17#include "llvm/ADT/StringRef.h"
18#include "llvm/ADT/StringSet.h"
19#include "llvm/Option/ArgList.h"
20#include "llvm/Support/raw_ostream.h"
21
22namespace lld {
23namespace elf {
24
25extern class LinkerDriver *Driver;
26
27class LinkerDriver {
28public:
29 void main(ArrayRef<const char *> Args, bool CanExitEarly);
30 void addFile(StringRef Path, bool WithLOption);
31 void addLibrary(StringRef Name);
32
33private:
34 void readConfigs(llvm::opt::InputArgList &Args);
35 void createFiles(llvm::opt::InputArgList &Args);
36 void inferMachineType();
37 template <class ELFT> void link(llvm::opt::InputArgList &Args);
38
39 // True if we are in --whole-archive and --no-whole-archive.
40 bool InWholeArchive = false;
41
42 // True if we are in --start-lib and --end-lib.
43 bool InLib = false;
44
45 // True if we are in -format=binary and -format=elf.
46 bool InBinary = false;
47
48 std::vector<InputFile *> Files;
49};
50
51// Parses command line options.
52class ELFOptTable : public llvm::opt::OptTable {
53public:
54 ELFOptTable();
55 llvm::opt::InputArgList parse(ArrayRef<const char *> Argv);
56};
57
58// Create enum with OPT_xxx values for each option in Options.td
59enum {
60 OPT_INVALID = 0,
61#define OPTION(_1, _2, ID, _4, _5, _6, _7, _8, _9, _10, _11, _12) OPT_##ID,
62#include "Options.inc"
63#undef OPTION
64};
65
66void printHelp(const char *Argv0);
67std::string createResponseFile(const llvm::opt::InputArgList &Args);
68
69llvm::Optional<std::string> findFromSearchPaths(StringRef Path);
70llvm::Optional<std::string> searchLibrary(StringRef Path);
71
72} // namespace elf
73} // namespace lld
74
75#endif
deps/lld/ELF/DriverUtils.cpp created+208
......@@ -0,0 +1,208 @@
1//===- DriverUtils.cpp ----------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains utility functions for the driver. Because there
11// are so many small functions, we created this separate file to make
12// Driver.cpp less cluttered.
13//
14//===----------------------------------------------------------------------===//
15
16#include "Driver.h"
17#include "Error.h"
18#include "Memory.h"
19#include "lld/Config/Version.h"
20#include "lld/Core/Reproduce.h"
21#include "llvm/ADT/Optional.h"
22#include "llvm/ADT/STLExtras.h"
23#include "llvm/ADT/Triple.h"
24#include "llvm/Option/Option.h"
25#include "llvm/Support/CommandLine.h"
26#include "llvm/Support/FileSystem.h"
27#include "llvm/Support/Path.h"
28#include "llvm/Support/Process.h"
29
30using namespace llvm;
31using namespace llvm::sys;
32
33using namespace lld;
34using namespace lld::elf;
35
36// Create OptTable
37
38// Create prefix string literals used in Options.td
39#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
40#include "Options.inc"
41#undef PREFIX
42
43// Create table mapping all options defined in Options.td
44static const opt::OptTable::Info OptInfo[] = {
45#define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \
46 {X1, X2, X10, X11, OPT_##ID, opt::Option::KIND##Class, \
47 X9, X8, OPT_##GROUP, OPT_##ALIAS, X7, X12},
48#include "Options.inc"
49#undef OPTION
50};
51
52ELFOptTable::ELFOptTable() : OptTable(OptInfo) {}
53
54// Parse -color-diagnostics={auto,always,never} or -no-color-diagnostics.
55static bool getColorDiagnostics(opt::InputArgList &Args) {
56 auto *Arg = Args.getLastArg(OPT_color_diagnostics, OPT_color_diagnostics_eq,
57 OPT_no_color_diagnostics);
58 if (!Arg)
59 return ErrorOS->has_colors();
60 if (Arg->getOption().getID() == OPT_color_diagnostics)
61 return true;
62 if (Arg->getOption().getID() == OPT_no_color_diagnostics)
63 return false;
64
65 StringRef S = Arg->getValue();
66 if (S == "auto")
67 return ErrorOS->has_colors();
68 if (S == "always")
69 return true;
70 if (S != "never")
71 error("unknown option: -color-diagnostics=" + S);
72 return false;
73}
74
75static cl::TokenizerCallback getQuotingStyle(opt::InputArgList &Args) {
76 if (auto *Arg = Args.getLastArg(OPT_rsp_quoting)) {
77 StringRef S = Arg->getValue();
78 if (S != "windows" && S != "posix")
79 error("invalid response file quoting: " + S);
80 if (S == "windows")
81 return cl::TokenizeWindowsCommandLine;
82 return cl::TokenizeGNUCommandLine;
83 }
84 if (Triple(sys::getProcessTriple()).getOS() == Triple::Win32)
85 return cl::TokenizeWindowsCommandLine;
86 return cl::TokenizeGNUCommandLine;
87}
88
89// Parses a given list of options.
90opt::InputArgList ELFOptTable::parse(ArrayRef<const char *> Argv) {
91 // Make InputArgList from string vectors.
92 unsigned MissingIndex;
93 unsigned MissingCount;
94 SmallVector<const char *, 256> Vec(Argv.data(), Argv.data() + Argv.size());
95
96 // We need to get the quoting style for response files before parsing all
97 // options so we parse here before and ignore all the options but
98 // --rsp-quoting.
99 opt::InputArgList Args = this->ParseArgs(Vec, MissingIndex, MissingCount);
100
101 // Expand response files (arguments in the form of @<filename>)
102 // and then parse the argument again.
103 cl::ExpandResponseFiles(Saver, getQuotingStyle(Args), Vec);
104 Args = this->ParseArgs(Vec, MissingIndex, MissingCount);
105
106 // Interpret -color-diagnostics early so that error messages
107 // for unknown flags are colored.
108 Config->ColorDiagnostics = getColorDiagnostics(Args);
109 if (MissingCount)
110 error(Twine(Args.getArgString(MissingIndex)) + ": missing argument");
111
112 for (auto *Arg : Args.filtered(OPT_UNKNOWN))
113 error("unknown argument: " + Arg->getSpelling());
114 return Args;
115}
116
117void elf::printHelp(const char *Argv0) {
118 ELFOptTable Table;
119 Table.PrintHelp(outs(), Argv0, "lld", false);
120 outs() << "\n";
121
122 // Scripts generated by Libtool versions up to at least 2.4.6 (the most
123 // recent version as of March 2017) expect /: supported targets:.* elf/
124 // in a message for the -help option. If it doesn't match, the scripts
125 // assume that the linker doesn't support very basic features such as
126 // shared libraries. Therefore, we need to print out at least "elf".
127 // Here, we print out all the targets that we support.
128 outs() << Argv0 << ": supported targets: "
129 << "elf32-i386 elf32-iamcu elf32-littlearm elf32-ntradbigmips "
130 << "elf32-ntradlittlemips elf32-powerpc elf32-tradbigmips "
131 << "elf32-tradlittlemips elf32-x86-64 "
132 << "elf64-amdgpu elf64-littleaarch64 elf64-powerpc elf64-tradbigmips "
133 << "elf64-tradlittlemips elf64-x86-64\n";
134}
135
136// Reconstructs command line arguments so that so that you can re-run
137// the same command with the same inputs. This is for --reproduce.
138std::string elf::createResponseFile(const opt::InputArgList &Args) {
139 SmallString<0> Data;
140 raw_svector_ostream OS(Data);
141
142 // Copy the command line to the output while rewriting paths.
143 for (auto *Arg : Args) {
144 switch (Arg->getOption().getID()) {
145 case OPT_reproduce:
146 break;
147 case OPT_INPUT:
148 OS << quote(rewritePath(Arg->getValue())) << "\n";
149 break;
150 case OPT_o:
151 // If -o path contains directories, "lld @response.txt" will likely
152 // fail because the archive we are creating doesn't contain empty
153 // directories for the output path (-o doesn't create directories).
154 // Strip directories to prevent the issue.
155 OS << "-o " << quote(sys::path::filename(Arg->getValue())) << "\n";
156 break;
157 case OPT_L:
158 case OPT_dynamic_list:
159 case OPT_rpath:
160 case OPT_alias_script_T:
161 case OPT_script:
162 case OPT_version_script:
163 OS << Arg->getSpelling() << " " << quote(rewritePath(Arg->getValue()))
164 << "\n";
165 break;
166 default:
167 OS << toString(Arg) << "\n";
168 }
169 }
170 return Data.str();
171}
172
173// Find a file by concatenating given paths. If a resulting path
174// starts with "=", the character is replaced with a --sysroot value.
175static Optional<std::string> findFile(StringRef Path1, const Twine &Path2) {
176 SmallString<128> S;
177 if (Path1.startswith("="))
178 path::append(S, Config->Sysroot, Path1.substr(1), Path2);
179 else
180 path::append(S, Path1, Path2);
181
182 if (fs::exists(S))
183 return S.str().str();
184 return None;
185}
186
187Optional<std::string> elf::findFromSearchPaths(StringRef Path) {
188 for (StringRef Dir : Config->SearchPaths)
189 if (Optional<std::string> S = findFile(Dir, Path))
190 return S;
191 return None;
192}
193
194// This is for -lfoo. We'll look for libfoo.so or libfoo.a from
195// search paths.
196Optional<std::string> elf::searchLibrary(StringRef Name) {
197 if (Name.startswith(":"))
198 return findFromSearchPaths(Name.substr(1));
199
200 for (StringRef Dir : Config->SearchPaths) {
201 if (!Config->Static)
202 if (Optional<std::string> S = findFile(Dir, "lib" + Name + ".so"))
203 return S;
204 if (Optional<std::string> S = findFile(Dir, "lib" + Name + ".a"))
205 return S;
206 }
207 return None;
208}
deps/lld/ELF/EhFrame.cpp created+212
......@@ -0,0 +1,212 @@
1//===- EhFrame.cpp -------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// .eh_frame section contains information on how to unwind the stack when
11// an exception is thrown. The section consists of sequence of CIE and FDE
12// records. The linker needs to merge CIEs and associate FDEs to CIEs.
13// That means the linker has to understand the format of the section.
14//
15// This file contains a few utility functions to read .eh_frame contents.
16//
17//===----------------------------------------------------------------------===//
18
19#include "EhFrame.h"
20#include "Error.h"
21#include "InputSection.h"
22#include "Relocations.h"
23#include "Strings.h"
24
25#include "llvm/BinaryFormat/Dwarf.h"
26#include "llvm/Object/ELF.h"
27#include "llvm/Support/Endian.h"
28
29using namespace llvm;
30using namespace llvm::ELF;
31using namespace llvm::dwarf;
32using namespace llvm::object;
33using namespace llvm::support::endian;
34
35using namespace lld;
36using namespace lld::elf;
37
38namespace {
39template <class ELFT> class EhReader {
40public:
41 EhReader(InputSectionBase *S, ArrayRef<uint8_t> D) : IS(S), D(D) {}
42 size_t readEhRecordSize();
43 uint8_t getFdeEncoding();
44
45private:
46 template <class P> void failOn(const P *Loc, const Twine &Msg) {
47 fatal("corrupted .eh_frame: " + Msg + "\n>>> defined in " +
48 IS->getObjMsg<ELFT>((const uint8_t *)Loc - IS->Data.data()));
49 }
50
51 uint8_t readByte();
52 void skipBytes(size_t Count);
53 StringRef readString();
54 void skipLeb128();
55 void skipAugP();
56
57 InputSectionBase *IS;
58 ArrayRef<uint8_t> D;
59};
60}
61
62template <class ELFT>
63size_t elf::readEhRecordSize(InputSectionBase *S, size_t Off) {
64 return EhReader<ELFT>(S, S->Data.slice(Off)).readEhRecordSize();
65}
66
67// .eh_frame section is a sequence of records. Each record starts with
68// a 4 byte length field. This function reads the length.
69template <class ELFT> size_t EhReader<ELFT>::readEhRecordSize() {
70 const endianness E = ELFT::TargetEndianness;
71 if (D.size() < 4)
72 failOn(D.data(), "CIE/FDE too small");
73
74 // First 4 bytes of CIE/FDE is the size of the record.
75 // If it is 0xFFFFFFFF, the next 8 bytes contain the size instead,
76 // but we do not support that format yet.
77 uint64_t V = read32<E>(D.data());
78 if (V == UINT32_MAX)
79 failOn(D.data(), "CIE/FDE too large");
80 uint64_t Size = V + 4;
81 if (Size > D.size())
82 failOn(D.data(), "CIE/FDE ends past the end of the section");
83 return Size;
84}
85
86// Read a byte and advance D by one byte.
87template <class ELFT> uint8_t EhReader<ELFT>::readByte() {
88 if (D.empty())
89 failOn(D.data(), "unexpected end of CIE");
90 uint8_t B = D.front();
91 D = D.slice(1);
92 return B;
93}
94
95template <class ELFT> void EhReader<ELFT>::skipBytes(size_t Count) {
96 if (D.size() < Count)
97 failOn(D.data(), "CIE is too small");
98 D = D.slice(Count);
99}
100
101// Read a null-terminated string.
102template <class ELFT> StringRef EhReader<ELFT>::readString() {
103 const uint8_t *End = std::find(D.begin(), D.end(), '\0');
104 if (End == D.end())
105 failOn(D.data(), "corrupted CIE (failed to read string)");
106 StringRef S = toStringRef(D.slice(0, End - D.begin()));
107 D = D.slice(S.size() + 1);
108 return S;
109}
110
111// Skip an integer encoded in the LEB128 format.
112// Actual number is not of interest because only the runtime needs it.
113// But we need to be at least able to skip it so that we can read
114// the field that follows a LEB128 number.
115template <class ELFT> void EhReader<ELFT>::skipLeb128() {
116 const uint8_t *ErrPos = D.data();
117 while (!D.empty()) {
118 uint8_t Val = D.front();
119 D = D.slice(1);
120 if ((Val & 0x80) == 0)
121 return;
122 }
123 failOn(ErrPos, "corrupted CIE (failed to read LEB128)");
124}
125
126static size_t getAugPSize(unsigned Enc) {
127 switch (Enc & 0x0f) {
128 case DW_EH_PE_absptr:
129 case DW_EH_PE_signed:
130 return Config->Wordsize;
131 case DW_EH_PE_udata2:
132 case DW_EH_PE_sdata2:
133 return 2;
134 case DW_EH_PE_udata4:
135 case DW_EH_PE_sdata4:
136 return 4;
137 case DW_EH_PE_udata8:
138 case DW_EH_PE_sdata8:
139 return 8;
140 }
141 return 0;
142}
143
144template <class ELFT> void EhReader<ELFT>::skipAugP() {
145 uint8_t Enc = readByte();
146 if ((Enc & 0xf0) == DW_EH_PE_aligned)
147 failOn(D.data() - 1, "DW_EH_PE_aligned encoding is not supported");
148 size_t Size = getAugPSize(Enc);
149 if (Size == 0)
150 failOn(D.data() - 1, "unknown FDE encoding");
151 if (Size >= D.size())
152 failOn(D.data() - 1, "corrupted CIE");
153 D = D.slice(Size);
154}
155
156template <class ELFT> uint8_t elf::getFdeEncoding(EhSectionPiece *P) {
157 auto *IS = static_cast<InputSectionBase *>(P->ID);
158 return EhReader<ELFT>(IS, P->data()).getFdeEncoding();
159}
160
161template <class ELFT> uint8_t EhReader<ELFT>::getFdeEncoding() {
162 skipBytes(8);
163 int Version = readByte();
164 if (Version != 1 && Version != 3)
165 failOn(D.data() - 1,
166 "FDE version 1 or 3 expected, but got " + Twine(Version));
167
168 StringRef Aug = readString();
169
170 // Skip code and data alignment factors.
171 skipLeb128();
172 skipLeb128();
173
174 // Skip the return address register. In CIE version 1 this is a single
175 // byte. In CIE version 3 this is an unsigned LEB128.
176 if (Version == 1)
177 readByte();
178 else
179 skipLeb128();
180
181 // We only care about an 'R' value, but other records may precede an 'R'
182 // record. Unfortunately records are not in TLV (type-length-value) format,
183 // so we need to teach the linker how to skip records for each type.
184 for (char C : Aug) {
185 if (C == 'R')
186 return readByte();
187 if (C == 'z') {
188 skipLeb128();
189 continue;
190 }
191 if (C == 'P') {
192 skipAugP();
193 continue;
194 }
195 if (C == 'L') {
196 readByte();
197 continue;
198 }
199 failOn(Aug.data(), "unknown .eh_frame augmentation string: " + Aug);
200 }
201 return DW_EH_PE_absptr;
202}
203
204template size_t elf::readEhRecordSize<ELF32LE>(InputSectionBase *S, size_t Off);
205template size_t elf::readEhRecordSize<ELF32BE>(InputSectionBase *S, size_t Off);
206template size_t elf::readEhRecordSize<ELF64LE>(InputSectionBase *S, size_t Off);
207template size_t elf::readEhRecordSize<ELF64BE>(InputSectionBase *S, size_t Off);
208
209template uint8_t elf::getFdeEncoding<ELF32LE>(EhSectionPiece *P);
210template uint8_t elf::getFdeEncoding<ELF32BE>(EhSectionPiece *P);
211template uint8_t elf::getFdeEncoding<ELF64LE>(EhSectionPiece *P);
212template uint8_t elf::getFdeEncoding<ELF64BE>(EhSectionPiece *P);
deps/lld/ELF/EhFrame.h created+25
......@@ -0,0 +1,25 @@
1//===- EhFrame.h ------------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_ELF_EHFRAME_H
11#define LLD_ELF_EHFRAME_H
12
13#include "lld/Core/LLVM.h"
14
15namespace lld {
16namespace elf {
17class InputSectionBase;
18struct EhSectionPiece;
19
20template <class ELFT> size_t readEhRecordSize(InputSectionBase *S, size_t Off);
21template <class ELFT> uint8_t getFdeEncoding(EhSectionPiece *P);
22} // namespace elf
23} // namespace lld
24
25#endif
deps/lld/ELF/Error.cpp created+116
......@@ -0,0 +1,116 @@
1//===- Error.cpp ----------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "Error.h"
11#include "Config.h"
12
13#include "llvm/ADT/Twine.h"
14#include "llvm/Support/Error.h"
15#include "llvm/Support/ManagedStatic.h"
16#include "llvm/Support/raw_ostream.h"
17#include <mutex>
18
19#if !defined(_MSC_VER) && !defined(__MINGW32__)
20#include <unistd.h>
21#endif
22
23using namespace llvm;
24
25using namespace lld;
26using namespace lld::elf;
27
28uint64_t elf::ErrorCount;
29raw_ostream *elf::ErrorOS;
30
31// The functions defined in this file can be called from multiple threads,
32// but outs() or errs() are not thread-safe. We protect them using a mutex.
33static std::mutex Mu;
34
35// Prints "\n" or does nothing, depending on Msg contents of
36// the previous call of this function.
37static void newline(const Twine &Msg) {
38 // True if the previous error message contained "\n".
39 // We want to separate multi-line error messages with a newline.
40 static bool Flag;
41
42 if (Flag)
43 *ErrorOS << "\n";
44 Flag = (StringRef(Msg.str()).find('\n') != StringRef::npos);
45}
46
47static void print(StringRef S, raw_ostream::Colors C) {
48 *ErrorOS << Config->Argv[0] << ": ";
49 if (Config->ColorDiagnostics) {
50 ErrorOS->changeColor(C, true);
51 *ErrorOS << S;
52 ErrorOS->resetColor();
53 } else {
54 *ErrorOS << S;
55 }
56}
57
58void elf::log(const Twine &Msg) {
59 if (Config->Verbose) {
60 std::lock_guard<std::mutex> Lock(Mu);
61 outs() << Config->Argv[0] << ": " << Msg << "\n";
62 outs().flush();
63 }
64}
65
66void elf::message(const Twine &Msg) {
67 std::lock_guard<std::mutex> Lock(Mu);
68 outs() << Msg << "\n";
69 outs().flush();
70}
71
72void elf::warn(const Twine &Msg) {
73 if (Config->FatalWarnings) {
74 error(Msg);
75 return;
76 }
77
78 std::lock_guard<std::mutex> Lock(Mu);
79 newline(Msg);
80 print("warning: ", raw_ostream::MAGENTA);
81 *ErrorOS << Msg << "\n";
82}
83
84void elf::error(const Twine &Msg) {
85 std::lock_guard<std::mutex> Lock(Mu);
86 newline(Msg);
87
88 if (Config->ErrorLimit == 0 || ErrorCount < Config->ErrorLimit) {
89 print("error: ", raw_ostream::RED);
90 *ErrorOS << Msg << "\n";
91 } else if (ErrorCount == Config->ErrorLimit) {
92 print("error: ", raw_ostream::RED);
93 *ErrorOS << "too many errors emitted, stopping now"
94 << " (use -error-limit=0 to see all errors)\n";
95 if (Config->ExitEarly)
96 exitLld(1);
97 }
98
99 ++ErrorCount;
100}
101
102void elf::exitLld(int Val) {
103 // Dealloc/destroy ManagedStatic variables before calling
104 // _exit(). In a non-LTO build, this is a nop. In an LTO
105 // build allows us to get the output of -time-passes.
106 llvm_shutdown();
107
108 outs().flush();
109 errs().flush();
110 _exit(Val);
111}
112
113void elf::fatal(const Twine &Msg) {
114 error(Msg);
115 exitLld(1);
116}
deps/lld/ELF/Error.h created+78
......@@ -0,0 +1,78 @@
1//===- Error.h --------------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// In LLD, we have three levels of errors: fatal, error or warn.
11//
12// Fatal makes the program exit immediately with an error message.
13// You shouldn't use it except for reporting a corrupted input file.
14//
15// Error prints out an error message and increment a global variable
16// ErrorCount to record the fact that we met an error condition. It does
17// not exit, so it is safe for a lld-as-a-library use case. It is generally
18// useful because it can report more than one error in a single run.
19//
20// Warn doesn't do anything but printing out a given message.
21//
22// It is not recommended to use llvm::outs() or llvm::errs() directly
23// in LLD because they are not thread-safe. The functions declared in
24// this file are mutually excluded, so you want to use them instead.
25//
26//===----------------------------------------------------------------------===//
27
28#ifndef LLD_ELF_ERROR_H
29#define LLD_ELF_ERROR_H
30
31#include "lld/Core/LLVM.h"
32
33#include "llvm/Support/Error.h"
34
35namespace lld {
36namespace elf {
37
38extern uint64_t ErrorCount;
39extern llvm::raw_ostream *ErrorOS;
40
41void log(const Twine &Msg);
42void message(const Twine &Msg);
43void warn(const Twine &Msg);
44void error(const Twine &Msg);
45LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg);
46
47LLVM_ATTRIBUTE_NORETURN void exitLld(int Val);
48
49// check() functions are convenient functions to strip errors
50// from error-or-value objects.
51template <class T> T check(ErrorOr<T> E) {
52 if (auto EC = E.getError())
53 fatal(EC.message());
54 return std::move(*E);
55}
56
57template <class T> T check(Expected<T> E) {
58 if (!E)
59 fatal(llvm::toString(E.takeError()));
60 return std::move(*E);
61}
62
63template <class T> T check(ErrorOr<T> E, const Twine &Prefix) {
64 if (auto EC = E.getError())
65 fatal(Prefix + ": " + EC.message());
66 return std::move(*E);
67}
68
69template <class T> T check(Expected<T> E, const Twine &Prefix) {
70 if (!E)
71 fatal(Prefix + ": " + toString(E.takeError()));
72 return std::move(*E);
73}
74
75} // namespace elf
76} // namespace lld
77
78#endif
deps/lld/ELF/Filesystem.cpp created+77
......@@ -0,0 +1,77 @@
1//===- Filesystem.cpp -----------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains a few utility functions to handle files.
11//
12//===----------------------------------------------------------------------===//
13
14#include "Filesystem.h"
15#include "Config.h"
16#include "llvm/Support/FileSystem.h"
17#include "llvm/Support/FileOutputBuffer.h"
18#include <thread>
19
20using namespace llvm;
21
22using namespace lld;
23using namespace lld::elf;
24
25// Removes a given file asynchronously. This is a performance hack,
26// so remove this when operating systems are improved.
27//
28// On Linux (and probably on other Unix-like systems), unlink(2) is a
29// noticeably slow system call. As of 2016, unlink takes 250
30// milliseconds to remove a 1 GB file on ext4 filesystem on my machine.
31//
32// To create a new result file, we first remove existing file. So, if
33// you repeatedly link a 1 GB program in a regular compile-link-debug
34// cycle, every cycle wastes 250 milliseconds only to remove a file.
35// Since LLD can link a 1 GB binary in about 5 seconds, that waste
36// actually counts.
37//
38// This function spawns a background thread to call unlink.
39// The calling thread returns almost immediately.
40void elf::unlinkAsync(StringRef Path) {
41 if (!Config->Threads || !sys::fs::exists(Config->OutputFile) ||
42 !sys::fs::is_regular_file(Config->OutputFile))
43 return;
44
45 // First, rename Path to avoid race condition. We cannot remove
46 // Path from a different thread because we are now going to create
47 // Path as a new file. If we do that in a different thread, the new
48 // thread can remove the new file.
49 SmallString<128> TempPath;
50 if (sys::fs::createUniqueFile(Path + "tmp%%%%%%%%", TempPath))
51 return;
52 if (sys::fs::rename(Path, TempPath)) {
53 sys::fs::remove(TempPath);
54 return;
55 }
56
57 // Remove TempPath in background.
58 std::thread([=] { ::remove(TempPath.str().str().c_str()); }).detach();
59}
60
61// Simulate file creation to see if Path is writable.
62//
63// Determining whether a file is writable or not is amazingly hard,
64// and after all the only reliable way of doing that is to actually
65// create a file. But we don't want to do that in this function
66// because LLD shouldn't update any file if it will end in a failure.
67// We also don't want to reimplement heuristics to determine if a
68// file is writable. So we'll let FileOutputBuffer do the work.
69//
70// FileOutputBuffer doesn't touch a desitnation file until commit()
71// is called. We use that class without calling commit() to predict
72// if the given file is writable.
73std::error_code elf::tryCreateFile(StringRef Path) {
74 if (Path.empty())
75 return std::error_code();
76 return FileOutputBuffer::create(Path, 1).getError();
77}
deps/lld/ELF/Filesystem.h created+22
......@@ -0,0 +1,22 @@
1//===- Filesystem.h ---------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_ELF_FILESYSTEM_H
11#define LLD_ELF_FILESYSTEM_H
12
13#include "lld/Core/LLVM.h"
14
15namespace lld {
16namespace elf {
17void unlinkAsync(StringRef Path);
18std::error_code tryCreateFile(StringRef Path);
19} // namespace elf
20} // namespace lld
21
22#endif
deps/lld/ELF/GdbIndex.cpp created+49
......@@ -0,0 +1,49 @@
1//===- GdbIndex.cpp -------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// The -gdb-index option instructs the linker to emit a .gdb_index section.
11// The section contains information to make gdb startup faster.
12// The format of the section is described at
13// https://sourceware.org/gdb/onlinedocs/gdb/Index-Section-Format.html.
14//
15//===----------------------------------------------------------------------===//
16
17#include "GdbIndex.h"
18#include "Memory.h"
19#include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
20#include "llvm/Object/ELFObjectFile.h"
21
22using namespace llvm;
23using namespace llvm::object;
24using namespace lld;
25using namespace lld::elf;
26
27std::pair<bool, GdbSymbol *> GdbHashTab::add(uint32_t Hash, size_t Offset) {
28 GdbSymbol *&Sym = Map[Offset];
29 if (Sym)
30 return {false, Sym};
31 Sym = make<GdbSymbol>(Hash, Offset);
32 return {true, Sym};
33}
34
35void GdbHashTab::finalizeContents() {
36 uint32_t Size = std::max<uint32_t>(1024, NextPowerOf2(Map.size() * 4 / 3));
37 uint32_t Mask = Size - 1;
38 Table.resize(Size);
39
40 for (auto &P : Map) {
41 GdbSymbol *Sym = P.second;
42 uint32_t I = Sym->NameHash & Mask;
43 uint32_t Step = ((Sym->NameHash * 17) & Mask) | 1;
44
45 while (Table[I])
46 I = (I + Step) & Mask;
47 Table[I] = Sym;
48 }
49}
deps/lld/ELF/GdbIndex.h created+82
......@@ -0,0 +1,82 @@
1//===- GdbIndex.h --------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===-------------------------------------------------------------------===//
9
10#ifndef LLD_ELF_GDB_INDEX_H
11#define LLD_ELF_GDB_INDEX_H
12
13#include "InputFiles.h"
14#include "llvm/DebugInfo/DWARF/DWARFContext.h"
15#include "llvm/Object/ELF.h"
16
17namespace lld {
18namespace elf {
19
20class InputSection;
21
22// Struct represents single entry of address area of gdb index.
23struct AddressEntry {
24 InputSection *Section;
25 uint64_t LowAddress;
26 uint64_t HighAddress;
27 uint32_t CuIndex;
28};
29
30// Struct represents single entry of compilation units list area of gdb index.
31// It consist of CU offset in .debug_info section and it's size.
32struct CompilationUnitEntry {
33 uint64_t CuOffset;
34 uint64_t CuLength;
35};
36
37// Represents data about symbol and type names which are used
38// to build symbol table and constant pool area of gdb index.
39struct NameTypeEntry {
40 StringRef Name;
41 uint8_t Type;
42};
43
44// We fill one GdbIndexDataChunk for each object where scan of
45// debug information performed. That information futher used
46// for filling gdb index section areas.
47struct GdbIndexChunk {
48 InputSection *DebugInfoSec;
49 std::vector<AddressEntry> AddressArea;
50 std::vector<CompilationUnitEntry> CompilationUnits;
51 std::vector<NameTypeEntry> NamesAndTypes;
52};
53
54// Element of GdbHashTab hash table.
55struct GdbSymbol {
56 GdbSymbol(uint32_t Hash, size_t Offset)
57 : NameHash(Hash), NameOffset(Offset) {}
58 uint32_t NameHash;
59 size_t NameOffset;
60 size_t CuVectorIndex;
61};
62
63// This class manages the hashed symbol table for the .gdb_index section.
64// The hash value for a table entry is computed by applying an iterative hash
65// function to the symbol's name.
66class GdbHashTab final {
67public:
68 std::pair<bool, GdbSymbol *> add(uint32_t Hash, size_t Offset);
69
70 void finalizeContents();
71 size_t getCapacity() { return Table.size(); }
72 GdbSymbol *getSymbol(size_t I) { return Table[I]; }
73
74private:
75 llvm::DenseMap<size_t, GdbSymbol *> Map;
76 std::vector<GdbSymbol *> Table;
77};
78
79} // namespace elf
80} // namespace lld
81
82#endif
deps/lld/ELF/ICF.cpp created+435
......@@ -0,0 +1,435 @@
1//===- ICF.cpp ------------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// ICF is short for Identical Code Folding. This is a size optimization to
11// identify and merge two or more read-only sections (typically functions)
12// that happened to have the same contents. It usually reduces output size
13// by a few percent.
14//
15// In ICF, two sections are considered identical if they have the same
16// section flags, section data, and relocations. Relocations are tricky,
17// because two relocations are considered the same if they have the same
18// relocation types, values, and if they point to the same sections *in
19// terms of ICF*.
20//
21// Here is an example. If foo and bar defined below are compiled to the
22// same machine instructions, ICF can and should merge the two, although
23// their relocations point to each other.
24//
25// void foo() { bar(); }
26// void bar() { foo(); }
27//
28// If you merge the two, their relocations point to the same section and
29// thus you know they are mergeable, but how do you know they are
30// mergeable in the first place? This is not an easy problem to solve.
31//
32// What we are doing in LLD is to partition sections into equivalence
33// classes. Sections in the same equivalence class when the algorithm
34// terminates are considered identical. Here are details:
35//
36// 1. First, we partition sections using their hash values as keys. Hash
37// values contain section types, section contents and numbers of
38// relocations. During this step, relocation targets are not taken into
39// account. We just put sections that apparently differ into different
40// equivalence classes.
41//
42// 2. Next, for each equivalence class, we visit sections to compare
43// relocation targets. Relocation targets are considered equivalent if
44// their targets are in the same equivalence class. Sections with
45// different relocation targets are put into different equivalence
46// clases.
47//
48// 3. If we split an equivalence class in step 2, two relocations
49// previously target the same equivalence class may now target
50// different equivalence classes. Therefore, we repeat step 2 until a
51// convergence is obtained.
52//
53// 4. For each equivalence class C, pick an arbitrary section in C, and
54// merge all the other sections in C with it.
55//
56// For small programs, this algorithm needs 3-5 iterations. For large
57// programs such as Chromium, it takes more than 20 iterations.
58//
59// This algorithm was mentioned as an "optimistic algorithm" in [1],
60// though gold implements a different algorithm than this.
61//
62// We parallelize each step so that multiple threads can work on different
63// equivalence classes concurrently. That gave us a large performance
64// boost when applying ICF on large programs. For example, MSVC link.exe
65// or GNU gold takes 10-20 seconds to apply ICF on Chromium, whose output
66// size is about 1.5 GB, but LLD can finish it in less than 2 seconds on a
67// 2.8 GHz 40 core machine. Even without threading, LLD's ICF is still
68// faster than MSVC or gold though.
69//
70// [1] Safe ICF: Pointer Safe and Unwinding aware Identical Code Folding
71// in the Gold Linker
72// http://static.googleusercontent.com/media/research.google.com/en//pubs/archive/36912.pdf
73//
74//===----------------------------------------------------------------------===//
75
76#include "ICF.h"
77#include "Config.h"
78#include "SymbolTable.h"
79#include "Threads.h"
80#include "llvm/ADT/Hashing.h"
81#include "llvm/BinaryFormat/ELF.h"
82#include "llvm/Object/ELF.h"
83#include <algorithm>
84#include <atomic>
85
86using namespace lld;
87using namespace lld::elf;
88using namespace llvm;
89using namespace llvm::ELF;
90using namespace llvm::object;
91
92namespace {
93template <class ELFT> class ICF {
94public:
95 void run();
96
97private:
98 void segregate(size_t Begin, size_t End, bool Constant);
99
100 template <class RelTy>
101 bool constantEq(const InputSection *A, ArrayRef<RelTy> RelsA,
102 const InputSection *B, ArrayRef<RelTy> RelsB);
103
104 template <class RelTy>
105 bool variableEq(const InputSection *A, ArrayRef<RelTy> RelsA,
106 const InputSection *B, ArrayRef<RelTy> RelsB);
107
108 bool equalsConstant(const InputSection *A, const InputSection *B);
109 bool equalsVariable(const InputSection *A, const InputSection *B);
110
111 size_t findBoundary(size_t Begin, size_t End);
112
113 void forEachClassRange(size_t Begin, size_t End,
114 std::function<void(size_t, size_t)> Fn);
115
116 void forEachClass(std::function<void(size_t, size_t)> Fn);
117
118 std::vector<InputSection *> Sections;
119
120 // We repeat the main loop while `Repeat` is true.
121 std::atomic<bool> Repeat;
122
123 // The main loop counter.
124 int Cnt = 0;
125
126 // We have two locations for equivalence classes. On the first iteration
127 // of the main loop, Class[0] has a valid value, and Class[1] contains
128 // garbage. We read equivalence classes from slot 0 and write to slot 1.
129 // So, Class[0] represents the current class, and Class[1] represents
130 // the next class. On each iteration, we switch their roles and use them
131 // alternately.
132 //
133 // Why are we doing this? Recall that other threads may be working on
134 // other equivalence classes in parallel. They may read sections that we
135 // are updating. We cannot update equivalence classes in place because
136 // it breaks the invariance that all possibly-identical sections must be
137 // in the same equivalence class at any moment. In other words, the for
138 // loop to update equivalence classes is not atomic, and that is
139 // observable from other threads. By writing new classes to other
140 // places, we can keep the invariance.
141 //
142 // Below, `Current` has the index of the current class, and `Next` has
143 // the index of the next class. If threading is enabled, they are either
144 // (0, 1) or (1, 0).
145 //
146 // Note on single-thread: if that's the case, they are always (0, 0)
147 // because we can safely read the next class without worrying about race
148 // conditions. Using the same location makes this algorithm converge
149 // faster because it uses results of the same iteration earlier.
150 int Current = 0;
151 int Next = 0;
152};
153}
154
155// Returns a hash value for S. Note that the information about
156// relocation targets is not included in the hash value.
157template <class ELFT> static uint32_t getHash(InputSection *S) {
158 return hash_combine(S->Flags, S->getSize(), S->NumRelocations);
159}
160
161// Returns true if section S is subject of ICF.
162static bool isEligible(InputSection *S) {
163 // .init and .fini contains instructions that must be executed to
164 // initialize and finalize the process. They cannot and should not
165 // be merged.
166 return S->Live && (S->Flags & SHF_ALLOC) && (S->Flags & SHF_EXECINSTR) &&
167 !(S->Flags & SHF_WRITE) && S->Name != ".init" && S->Name != ".fini";
168}
169
170// Split an equivalence class into smaller classes.
171template <class ELFT>
172void ICF<ELFT>::segregate(size_t Begin, size_t End, bool Constant) {
173 // This loop rearranges sections in [Begin, End) so that all sections
174 // that are equal in terms of equals{Constant,Variable} are contiguous
175 // in [Begin, End).
176 //
177 // The algorithm is quadratic in the worst case, but that is not an
178 // issue in practice because the number of the distinct sections in
179 // each range is usually very small.
180
181 while (Begin < End) {
182 // Divide [Begin, End) into two. Let Mid be the start index of the
183 // second group.
184 auto Bound =
185 std::stable_partition(Sections.begin() + Begin + 1,
186 Sections.begin() + End, [&](InputSection *S) {
187 if (Constant)
188 return equalsConstant(Sections[Begin], S);
189 return equalsVariable(Sections[Begin], S);
190 });
191 size_t Mid = Bound - Sections.begin();
192
193 // Now we split [Begin, End) into [Begin, Mid) and [Mid, End) by
194 // updating the sections in [Begin, Mid). We use Mid as an equivalence
195 // class ID because every group ends with a unique index.
196 for (size_t I = Begin; I < Mid; ++I)
197 Sections[I]->Class[Next] = Mid;
198
199 // If we created a group, we need to iterate the main loop again.
200 if (Mid != End)
201 Repeat = true;
202
203 Begin = Mid;
204 }
205}
206
207// Compare two lists of relocations.
208template <class ELFT>
209template <class RelTy>
210bool ICF<ELFT>::constantEq(const InputSection *A, ArrayRef<RelTy> RelsA,
211 const InputSection *B, ArrayRef<RelTy> RelsB) {
212 auto Eq = [&](const RelTy &RA, const RelTy &RB) {
213 if (RA.r_offset != RB.r_offset ||
214 RA.getType(Config->IsMips64EL) != RB.getType(Config->IsMips64EL))
215 return false;
216 uint64_t AddA = getAddend<ELFT>(RA);
217 uint64_t AddB = getAddend<ELFT>(RB);
218
219 SymbolBody &SA = A->template getFile<ELFT>()->getRelocTargetSym(RA);
220 SymbolBody &SB = B->template getFile<ELFT>()->getRelocTargetSym(RB);
221 if (&SA == &SB)
222 return AddA == AddB;
223
224 auto *DA = dyn_cast<DefinedRegular>(&SA);
225 auto *DB = dyn_cast<DefinedRegular>(&SB);
226 if (!DA || !DB)
227 return false;
228
229 // Relocations referring to absolute symbols are constant-equal if their
230 // values are equal.
231 if (!DA->Section || !DB->Section)
232 return !DA->Section && !DB->Section &&
233 DA->Value + AddA == DB->Value + AddB;
234
235 if (DA->Section->kind() != DB->Section->kind())
236 return false;
237
238 // Relocations referring to InputSections are constant-equal if their
239 // section offsets are equal.
240 if (isa<InputSection>(DA->Section))
241 return DA->Value + AddA == DB->Value + AddB;
242
243 // Relocations referring to MergeInputSections are constant-equal if their
244 // offsets in the output section are equal.
245 auto *X = dyn_cast<MergeInputSection>(DA->Section);
246 if (!X)
247 return false;
248 auto *Y = cast<MergeInputSection>(DB->Section);
249 if (X->getParent() != Y->getParent())
250 return false;
251
252 uint64_t OffsetA =
253 SA.isSection() ? X->getOffset(AddA) : X->getOffset(DA->Value) + AddA;
254 uint64_t OffsetB =
255 SB.isSection() ? Y->getOffset(AddB) : Y->getOffset(DB->Value) + AddB;
256 return OffsetA == OffsetB;
257 };
258
259 return RelsA.size() == RelsB.size() &&
260 std::equal(RelsA.begin(), RelsA.end(), RelsB.begin(), Eq);
261}
262
263// Compare "non-moving" part of two InputSections, namely everything
264// except relocation targets.
265template <class ELFT>
266bool ICF<ELFT>::equalsConstant(const InputSection *A, const InputSection *B) {
267 if (A->NumRelocations != B->NumRelocations || A->Flags != B->Flags ||
268 A->getSize() != B->getSize() || A->Data != B->Data)
269 return false;
270
271 if (A->AreRelocsRela)
272 return constantEq(A, A->template relas<ELFT>(), B,
273 B->template relas<ELFT>());
274 return constantEq(A, A->template rels<ELFT>(), B, B->template rels<ELFT>());
275}
276
277// Compare two lists of relocations. Returns true if all pairs of
278// relocations point to the same section in terms of ICF.
279template <class ELFT>
280template <class RelTy>
281bool ICF<ELFT>::variableEq(const InputSection *A, ArrayRef<RelTy> RelsA,
282 const InputSection *B, ArrayRef<RelTy> RelsB) {
283 auto Eq = [&](const RelTy &RA, const RelTy &RB) {
284 // The two sections must be identical.
285 SymbolBody &SA = A->template getFile<ELFT>()->getRelocTargetSym(RA);
286 SymbolBody &SB = B->template getFile<ELFT>()->getRelocTargetSym(RB);
287 if (&SA == &SB)
288 return true;
289
290 auto *DA = cast<DefinedRegular>(&SA);
291 auto *DB = cast<DefinedRegular>(&SB);
292
293 // We already dealt with absolute and non-InputSection symbols in
294 // constantEq, and for InputSections we have already checked everything
295 // except the equivalence class.
296 if (!DA->Section)
297 return true;
298 auto *X = dyn_cast<InputSection>(DA->Section);
299 if (!X)
300 return true;
301 auto *Y = cast<InputSection>(DB->Section);
302
303 // Ineligible sections are in the special equivalence class 0.
304 // They can never be the same in terms of the equivalence class.
305 if (X->Class[Current] == 0)
306 return false;
307
308 return X->Class[Current] == Y->Class[Current];
309 };
310
311 return std::equal(RelsA.begin(), RelsA.end(), RelsB.begin(), Eq);
312}
313
314// Compare "moving" part of two InputSections, namely relocation targets.
315template <class ELFT>
316bool ICF<ELFT>::equalsVariable(const InputSection *A, const InputSection *B) {
317 if (A->AreRelocsRela)
318 return variableEq(A, A->template relas<ELFT>(), B,
319 B->template relas<ELFT>());
320 return variableEq(A, A->template rels<ELFT>(), B, B->template rels<ELFT>());
321}
322
323template <class ELFT> size_t ICF<ELFT>::findBoundary(size_t Begin, size_t End) {
324 uint32_t Class = Sections[Begin]->Class[Current];
325 for (size_t I = Begin + 1; I < End; ++I)
326 if (Class != Sections[I]->Class[Current])
327 return I;
328 return End;
329}
330
331// Sections in the same equivalence class are contiguous in Sections
332// vector. Therefore, Sections vector can be considered as contiguous
333// groups of sections, grouped by the class.
334//
335// This function calls Fn on every group that starts within [Begin, End).
336// Note that a group must start in that range but doesn't necessarily
337// have to end before End.
338template <class ELFT>
339void ICF<ELFT>::forEachClassRange(size_t Begin, size_t End,
340 std::function<void(size_t, size_t)> Fn) {
341 if (Begin > 0)
342 Begin = findBoundary(Begin - 1, End);
343
344 while (Begin < End) {
345 size_t Mid = findBoundary(Begin, Sections.size());
346 Fn(Begin, Mid);
347 Begin = Mid;
348 }
349}
350
351// Call Fn on each equivalence class.
352template <class ELFT>
353void ICF<ELFT>::forEachClass(std::function<void(size_t, size_t)> Fn) {
354 // If threading is disabled or the number of sections are
355 // too small to use threading, call Fn sequentially.
356 if (!Config->Threads || Sections.size() < 1024) {
357 forEachClassRange(0, Sections.size(), Fn);
358 ++Cnt;
359 return;
360 }
361
362 Current = Cnt % 2;
363 Next = (Cnt + 1) % 2;
364
365 // Split sections into 256 shards and call Fn in parallel.
366 size_t NumShards = 256;
367 size_t Step = Sections.size() / NumShards;
368 parallelForEachN(0, NumShards, [&](size_t I) {
369 size_t End = (I == NumShards - 1) ? Sections.size() : (I + 1) * Step;
370 forEachClassRange(I * Step, End, Fn);
371 });
372 ++Cnt;
373}
374
375// The main function of ICF.
376template <class ELFT> void ICF<ELFT>::run() {
377 // Collect sections to merge.
378 for (InputSectionBase *Sec : InputSections)
379 if (auto *S = dyn_cast<InputSection>(Sec))
380 if (isEligible(S))
381 Sections.push_back(S);
382
383 // Initially, we use hash values to partition sections.
384 for (InputSection *S : Sections)
385 // Set MSB to 1 to avoid collisions with non-hash IDs.
386 S->Class[0] = getHash<ELFT>(S) | (1 << 31);
387
388 // From now on, sections in Sections vector are ordered so that sections
389 // in the same equivalence class are consecutive in the vector.
390 std::stable_sort(Sections.begin(), Sections.end(),
391 [](InputSection *A, InputSection *B) {
392 return A->Class[0] < B->Class[0];
393 });
394
395 // Compare static contents and assign unique IDs for each static content.
396 forEachClass([&](size_t Begin, size_t End) { segregate(Begin, End, true); });
397
398 // Split groups by comparing relocations until convergence is obtained.
399 do {
400 Repeat = false;
401 forEachClass(
402 [&](size_t Begin, size_t End) { segregate(Begin, End, false); });
403 } while (Repeat);
404
405 log("ICF needed " + Twine(Cnt) + " iterations");
406
407 // Merge sections by the equivalence class.
408 forEachClass([&](size_t Begin, size_t End) {
409 if (End - Begin == 1)
410 return;
411
412 log("selected " + Sections[Begin]->Name);
413 for (size_t I = Begin + 1; I < End; ++I) {
414 log(" removed " + Sections[I]->Name);
415 Sections[Begin]->replace(Sections[I]);
416 }
417 });
418
419 // Mark ARM Exception Index table sections that refer to folded code
420 // sections as not live. These sections have an implict dependency
421 // via the link order dependency.
422 if (Config->EMachine == EM_ARM)
423 for (InputSectionBase *Sec : InputSections)
424 if (auto *S = dyn_cast<InputSection>(Sec))
425 if (S->Flags & SHF_LINK_ORDER)
426 S->Live = S->getLinkOrderDep()->Live;
427}
428
429// ICF entry point function.
430template <class ELFT> void elf::doIcf() { ICF<ELFT>().run(); }
431
432template void elf::doIcf<ELF32LE>();
433template void elf::doIcf<ELF32BE>();
434template void elf::doIcf<ELF64LE>();
435template void elf::doIcf<ELF64BE>();
deps/lld/ELF/ICF.h created+19
......@@ -0,0 +1,19 @@
1//===- ICF.h --------------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_ELF_ICF_H
11#define LLD_ELF_ICF_H
12
13namespace lld {
14namespace elf {
15template <class ELFT> void doIcf();
16}
17} // namespace lld
18
19#endif
deps/lld/ELF/InputFiles.cpp created+1109
......@@ -0,0 +1,1109 @@
1//===- InputFiles.cpp -----------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "InputFiles.h"
11#include "Error.h"
12#include "InputSection.h"
13#include "LinkerScript.h"
14#include "Memory.h"
15#include "SymbolTable.h"
16#include "Symbols.h"
17#include "SyntheticSections.h"
18#include "llvm/ADT/STLExtras.h"
19#include "llvm/CodeGen/Analysis.h"
20#include "llvm/DebugInfo/DWARF/DWARFContext.h"
21#include "llvm/IR/LLVMContext.h"
22#include "llvm/IR/Module.h"
23#include "llvm/LTO/LTO.h"
24#include "llvm/MC/StringTableBuilder.h"
25#include "llvm/Object/ELFObjectFile.h"
26#include "llvm/Support/Path.h"
27#include "llvm/Support/TarWriter.h"
28#include "llvm/Support/raw_ostream.h"
29
30using namespace llvm;
31using namespace llvm::ELF;
32using namespace llvm::object;
33using namespace llvm::sys::fs;
34
35using namespace lld;
36using namespace lld::elf;
37
38TarWriter *elf::Tar;
39
40InputFile::InputFile(Kind K, MemoryBufferRef M) : MB(M), FileKind(K) {}
41
42namespace {
43// In ELF object file all section addresses are zero. If we have multiple
44// .text sections (when using -ffunction-section or comdat group) then
45// LLVM DWARF parser will not be able to parse .debug_line correctly, unless
46// we assign each section some unique address. This callback method assigns
47// each section an address equal to its offset in ELF object file.
48class ObjectInfo : public LoadedObjectInfoHelper<ObjectInfo> {
49public:
50 uint64_t getSectionLoadAddress(const object::SectionRef &Sec) const override {
51 return static_cast<const ELFSectionRef &>(Sec).getOffset();
52 }
53};
54}
55
56Optional<MemoryBufferRef> elf::readFile(StringRef Path) {
57 log(Path);
58 auto MBOrErr = MemoryBuffer::getFile(Path);
59 if (auto EC = MBOrErr.getError()) {
60 error("cannot open " + Path + ": " + EC.message());
61 return None;
62 }
63
64 std::unique_ptr<MemoryBuffer> &MB = *MBOrErr;
65 MemoryBufferRef MBRef = MB->getMemBufferRef();
66 make<std::unique_ptr<MemoryBuffer>>(std::move(MB)); // take MB ownership
67
68 if (Tar)
69 Tar->append(relativeToRoot(Path), MBRef.getBuffer());
70 return MBRef;
71}
72
73template <class ELFT> void elf::ObjectFile<ELFT>::initializeDwarfLine() {
74 std::unique_ptr<object::ObjectFile> Obj =
75 check(object::ObjectFile::createObjectFile(this->MB), toString(this));
76
77 ObjectInfo ObjInfo;
78 DWARFContextInMemory Dwarf(*Obj, &ObjInfo);
79 DwarfLine.reset(new DWARFDebugLine);
80 DWARFDataExtractor LineData(Dwarf.getLineSection(), Config->IsLE,
81 Config->Wordsize);
82
83 // The second parameter is offset in .debug_line section
84 // for compilation unit (CU) of interest. We have only one
85 // CU (object file), so offset is always 0.
86 DwarfLine->getOrParseLineTable(LineData, 0);
87}
88
89// Returns source line information for a given offset
90// using DWARF debug info.
91template <class ELFT>
92Optional<DILineInfo> elf::ObjectFile<ELFT>::getDILineInfo(InputSectionBase *S,
93 uint64_t Offset) {
94 llvm::call_once(InitDwarfLine, [this]() { initializeDwarfLine(); });
95
96 // The offset to CU is 0.
97 const DWARFDebugLine::LineTable *Tbl = DwarfLine->getLineTable(0);
98 if (!Tbl)
99 return None;
100
101 // Use fake address calcuated by adding section file offset and offset in
102 // section. See comments for ObjectInfo class.
103 DILineInfo Info;
104 Tbl->getFileLineInfoForAddress(
105 S->getOffsetInFile() + Offset, nullptr,
106 DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath, Info);
107 if (Info.Line == 0)
108 return None;
109 return Info;
110}
111
112// Returns source line information for a given offset
113// using DWARF debug info.
114template <class ELFT>
115std::string elf::ObjectFile<ELFT>::getLineInfo(InputSectionBase *S,
116 uint64_t Offset) {
117 if (Optional<DILineInfo> Info = getDILineInfo(S, Offset))
118 return Info->FileName + ":" + std::to_string(Info->Line);
119 return "";
120}
121
122// Returns "<internal>", "foo.a(bar.o)" or "baz.o".
123std::string lld::toString(const InputFile *F) {
124 if (!F)
125 return "<internal>";
126
127 if (F->ToStringCache.empty()) {
128 if (F->ArchiveName.empty())
129 F->ToStringCache = F->getName();
130 else
131 F->ToStringCache = (F->ArchiveName + "(" + F->getName() + ")").str();
132 }
133 return F->ToStringCache;
134}
135
136template <class ELFT>
137ELFFileBase<ELFT>::ELFFileBase(Kind K, MemoryBufferRef MB) : InputFile(K, MB) {
138 if (ELFT::TargetEndianness == support::little)
139 EKind = ELFT::Is64Bits ? ELF64LEKind : ELF32LEKind;
140 else
141 EKind = ELFT::Is64Bits ? ELF64BEKind : ELF32BEKind;
142
143 EMachine = getObj().getHeader()->e_machine;
144 OSABI = getObj().getHeader()->e_ident[llvm::ELF::EI_OSABI];
145}
146
147template <class ELFT>
148typename ELFT::SymRange ELFFileBase<ELFT>::getGlobalSymbols() {
149 return makeArrayRef(Symbols.begin() + FirstNonLocal, Symbols.end());
150}
151
152template <class ELFT>
153uint32_t ELFFileBase<ELFT>::getSectionIndex(const Elf_Sym &Sym) const {
154 return check(getObj().getSectionIndex(&Sym, Symbols, SymtabSHNDX),
155 toString(this));
156}
157
158template <class ELFT>
159void ELFFileBase<ELFT>::initSymtab(ArrayRef<Elf_Shdr> Sections,
160 const Elf_Shdr *Symtab) {
161 FirstNonLocal = Symtab->sh_info;
162 Symbols = check(getObj().symbols(Symtab), toString(this));
163 if (FirstNonLocal == 0 || FirstNonLocal > Symbols.size())
164 fatal(toString(this) + ": invalid sh_info in symbol table");
165
166 StringTable = check(getObj().getStringTableForSymtab(*Symtab, Sections),
167 toString(this));
168}
169
170template <class ELFT>
171elf::ObjectFile<ELFT>::ObjectFile(MemoryBufferRef M, StringRef ArchiveName)
172 : ELFFileBase<ELFT>(Base::ObjectKind, M) {
173 this->ArchiveName = ArchiveName;
174}
175
176template <class ELFT>
177ArrayRef<SymbolBody *> elf::ObjectFile<ELFT>::getLocalSymbols() {
178 if (this->SymbolBodies.empty())
179 return this->SymbolBodies;
180 return makeArrayRef(this->SymbolBodies).slice(1, this->FirstNonLocal - 1);
181}
182
183template <class ELFT>
184ArrayRef<SymbolBody *> elf::ObjectFile<ELFT>::getSymbols() {
185 if (this->SymbolBodies.empty())
186 return this->SymbolBodies;
187 return makeArrayRef(this->SymbolBodies).slice(1);
188}
189
190template <class ELFT>
191void elf::ObjectFile<ELFT>::parse(DenseSet<CachedHashStringRef> &ComdatGroups) {
192 // Read section and symbol tables.
193 initializeSections(ComdatGroups);
194 initializeSymbols();
195}
196
197// Sections with SHT_GROUP and comdat bits define comdat section groups.
198// They are identified and deduplicated by group name. This function
199// returns a group name.
200template <class ELFT>
201StringRef
202elf::ObjectFile<ELFT>::getShtGroupSignature(ArrayRef<Elf_Shdr> Sections,
203 const Elf_Shdr &Sec) {
204 // Group signatures are stored as symbol names in object files.
205 // sh_info contains a symbol index, so we fetch a symbol and read its name.
206 if (this->Symbols.empty())
207 this->initSymtab(
208 Sections,
209 check(object::getSection<ELFT>(Sections, Sec.sh_link), toString(this)));
210
211 const Elf_Sym *Sym = check(
212 object::getSymbol<ELFT>(this->Symbols, Sec.sh_info), toString(this));
213 StringRef Signature = check(Sym->getName(this->StringTable), toString(this));
214
215 // As a special case, if a symbol is a section symbol and has no name,
216 // we use a section name as a signature.
217 //
218 // Such SHT_GROUP sections are invalid from the perspective of the ELF
219 // standard, but GNU gold 1.14 (the neweset version as of July 2017) or
220 // older produce such sections as outputs for the -r option, so we need
221 // a bug-compatibility.
222 if (Signature.empty() && Sym->getType() == STT_SECTION)
223 return getSectionName(Sec);
224 return Signature;
225}
226
227template <class ELFT>
228ArrayRef<typename elf::ObjectFile<ELFT>::Elf_Word>
229elf::ObjectFile<ELFT>::getShtGroupEntries(const Elf_Shdr &Sec) {
230 const ELFFile<ELFT> &Obj = this->getObj();
231 ArrayRef<Elf_Word> Entries = check(
232 Obj.template getSectionContentsAsArray<Elf_Word>(&Sec), toString(this));
233 if (Entries.empty() || Entries[0] != GRP_COMDAT)
234 fatal(toString(this) + ": unsupported SHT_GROUP format");
235 return Entries.slice(1);
236}
237
238template <class ELFT>
239bool elf::ObjectFile<ELFT>::shouldMerge(const Elf_Shdr &Sec) {
240 // We don't merge sections if -O0 (default is -O1). This makes sometimes
241 // the linker significantly faster, although the output will be bigger.
242 if (Config->Optimize == 0)
243 return false;
244
245 // Do not merge sections if generating a relocatable object. It makes
246 // the code simpler because we do not need to update relocation addends
247 // to reflect changes introduced by merging. Instead of that we write
248 // such "merge" sections into separate OutputSections and keep SHF_MERGE
249 // / SHF_STRINGS flags and sh_entsize value to be able to perform merging
250 // later during a final linking.
251 if (Config->Relocatable)
252 return false;
253
254 // A mergeable section with size 0 is useless because they don't have
255 // any data to merge. A mergeable string section with size 0 can be
256 // argued as invalid because it doesn't end with a null character.
257 // We'll avoid a mess by handling them as if they were non-mergeable.
258 if (Sec.sh_size == 0)
259 return false;
260
261 // Check for sh_entsize. The ELF spec is not clear about the zero
262 // sh_entsize. It says that "the member [sh_entsize] contains 0 if
263 // the section does not hold a table of fixed-size entries". We know
264 // that Rust 1.13 produces a string mergeable section with a zero
265 // sh_entsize. Here we just accept it rather than being picky about it.
266 uint64_t EntSize = Sec.sh_entsize;
267 if (EntSize == 0)
268 return false;
269 if (Sec.sh_size % EntSize)
270 fatal(toString(this) +
271 ": SHF_MERGE section size must be a multiple of sh_entsize");
272
273 uint64_t Flags = Sec.sh_flags;
274 if (!(Flags & SHF_MERGE))
275 return false;
276 if (Flags & SHF_WRITE)
277 fatal(toString(this) + ": writable SHF_MERGE section is not supported");
278
279 // Don't try to merge if the alignment is larger than the sh_entsize and this
280 // is not SHF_STRINGS.
281 //
282 // Since this is not a SHF_STRINGS, we would need to pad after every entity.
283 // It would be equivalent for the producer of the .o to just set a larger
284 // sh_entsize.
285 if (Flags & SHF_STRINGS)
286 return true;
287
288 return Sec.sh_addralign <= EntSize;
289}
290
291template <class ELFT>
292void elf::ObjectFile<ELFT>::initializeSections(
293 DenseSet<CachedHashStringRef> &ComdatGroups) {
294 const ELFFile<ELFT> &Obj = this->getObj();
295
296 ArrayRef<Elf_Shdr> ObjSections =
297 check(this->getObj().sections(), toString(this));
298 uint64_t Size = ObjSections.size();
299 this->Sections.resize(Size);
300 this->SectionStringTable =
301 check(Obj.getSectionStringTable(ObjSections), toString(this));
302
303 for (size_t I = 0, E = ObjSections.size(); I < E; I++) {
304 if (this->Sections[I] == &InputSection::Discarded)
305 continue;
306 const Elf_Shdr &Sec = ObjSections[I];
307
308 // SHF_EXCLUDE'ed sections are discarded by the linker. However,
309 // if -r is given, we'll let the final link discard such sections.
310 // This is compatible with GNU.
311 if ((Sec.sh_flags & SHF_EXCLUDE) && !Config->Relocatable) {
312 this->Sections[I] = &InputSection::Discarded;
313 continue;
314 }
315
316 switch (Sec.sh_type) {
317 case SHT_GROUP: {
318 // De-duplicate section groups by their signatures.
319 StringRef Signature = getShtGroupSignature(ObjSections, Sec);
320 bool IsNew = ComdatGroups.insert(CachedHashStringRef(Signature)).second;
321 this->Sections[I] = &InputSection::Discarded;
322
323 // If it is a new section group, we want to keep group members.
324 // Group leader sections, which contain indices of group members, are
325 // discarded because they are useless beyond this point. The only
326 // exception is the -r option because in order to produce re-linkable
327 // object files, we want to pass through basically everything.
328 if (IsNew) {
329 if (Config->Relocatable)
330 this->Sections[I] = createInputSection(Sec);
331 continue;
332 }
333
334 // Otherwise, discard group members.
335 for (uint32_t SecIndex : getShtGroupEntries(Sec)) {
336 if (SecIndex >= Size)
337 fatal(toString(this) +
338 ": invalid section index in group: " + Twine(SecIndex));
339 this->Sections[SecIndex] = &InputSection::Discarded;
340 }
341 break;
342 }
343 case SHT_SYMTAB:
344 this->initSymtab(ObjSections, &Sec);
345 break;
346 case SHT_SYMTAB_SHNDX:
347 this->SymtabSHNDX =
348 check(Obj.getSHNDXTable(Sec, ObjSections), toString(this));
349 break;
350 case SHT_STRTAB:
351 case SHT_NULL:
352 break;
353 default:
354 this->Sections[I] = createInputSection(Sec);
355 }
356
357 // .ARM.exidx sections have a reverse dependency on the InputSection they
358 // have a SHF_LINK_ORDER dependency, this is identified by the sh_link.
359 if (Sec.sh_flags & SHF_LINK_ORDER) {
360 if (Sec.sh_link >= this->Sections.size())
361 fatal(toString(this) + ": invalid sh_link index: " +
362 Twine(Sec.sh_link));
363 this->Sections[Sec.sh_link]->DependentSections.push_back(
364 this->Sections[I]);
365 }
366 }
367}
368
369template <class ELFT>
370InputSectionBase *elf::ObjectFile<ELFT>::getRelocTarget(const Elf_Shdr &Sec) {
371 uint32_t Idx = Sec.sh_info;
372 if (Idx >= this->Sections.size())
373 fatal(toString(this) + ": invalid relocated section index: " + Twine(Idx));
374 InputSectionBase *Target = this->Sections[Idx];
375
376 // Strictly speaking, a relocation section must be included in the
377 // group of the section it relocates. However, LLVM 3.3 and earlier
378 // would fail to do so, so we gracefully handle that case.
379 if (Target == &InputSection::Discarded)
380 return nullptr;
381
382 if (!Target)
383 fatal(toString(this) + ": unsupported relocation reference");
384 return Target;
385}
386
387// Create a regular InputSection class that has the same contents
388// as a given section.
389InputSectionBase *toRegularSection(MergeInputSection *Sec) {
390 auto *Ret = make<InputSection>(Sec->Flags, Sec->Type, Sec->Alignment,
391 Sec->Data, Sec->Name);
392 Ret->File = Sec->File;
393 return Ret;
394}
395
396template <class ELFT>
397InputSectionBase *
398elf::ObjectFile<ELFT>::createInputSection(const Elf_Shdr &Sec) {
399 StringRef Name = getSectionName(Sec);
400
401 switch (Sec.sh_type) {
402 case SHT_ARM_ATTRIBUTES:
403 // FIXME: ARM meta-data section. Retain the first attribute section
404 // we see. The eglibc ARM dynamic loaders require the presence of an
405 // attribute section for dlopen to work.
406 // In a full implementation we would merge all attribute sections.
407 if (InX::ARMAttributes == nullptr) {
408 InX::ARMAttributes = make<InputSection>(this, &Sec, Name);
409 return InX::ARMAttributes;
410 }
411 return &InputSection::Discarded;
412 case SHT_RELA:
413 case SHT_REL: {
414 // Find the relocation target section and associate this
415 // section with it. Target can be discarded, for example
416 // if it is a duplicated member of SHT_GROUP section, we
417 // do not create or proccess relocatable sections then.
418 InputSectionBase *Target = getRelocTarget(Sec);
419 if (!Target)
420 return nullptr;
421
422 // This section contains relocation information.
423 // If -r is given, we do not interpret or apply relocation
424 // but just copy relocation sections to output.
425 if (Config->Relocatable)
426 return make<InputSection>(this, &Sec, Name);
427
428 if (Target->FirstRelocation)
429 fatal(toString(this) +
430 ": multiple relocation sections to one section are not supported");
431
432 // Mergeable sections with relocations are tricky because relocations
433 // need to be taken into account when comparing section contents for
434 // merging. It's not worth supporting such mergeable sections because
435 // they are rare and it'd complicates the internal design (we usually
436 // have to determine if two sections are mergeable early in the link
437 // process much before applying relocations). We simply handle mergeable
438 // sections with relocations as non-mergeable.
439 if (auto *MS = dyn_cast<MergeInputSection>(Target)) {
440 Target = toRegularSection(MS);
441 this->Sections[Sec.sh_info] = Target;
442 }
443
444 size_t NumRelocations;
445 if (Sec.sh_type == SHT_RELA) {
446 ArrayRef<Elf_Rela> Rels =
447 check(this->getObj().relas(&Sec), toString(this));
448 Target->FirstRelocation = Rels.begin();
449 NumRelocations = Rels.size();
450 Target->AreRelocsRela = true;
451 } else {
452 ArrayRef<Elf_Rel> Rels = check(this->getObj().rels(&Sec), toString(this));
453 Target->FirstRelocation = Rels.begin();
454 NumRelocations = Rels.size();
455 Target->AreRelocsRela = false;
456 }
457 assert(isUInt<31>(NumRelocations));
458 Target->NumRelocations = NumRelocations;
459
460 // Relocation sections processed by the linker are usually removed
461 // from the output, so returning `nullptr` for the normal case.
462 // However, if -emit-relocs is given, we need to leave them in the output.
463 // (Some post link analysis tools need this information.)
464 if (Config->EmitRelocs) {
465 InputSection *RelocSec = make<InputSection>(this, &Sec, Name);
466 // We will not emit relocation section if target was discarded.
467 Target->DependentSections.push_back(RelocSec);
468 return RelocSec;
469 }
470 return nullptr;
471 }
472 }
473
474 // The GNU linker uses .note.GNU-stack section as a marker indicating
475 // that the code in the object file does not expect that the stack is
476 // executable (in terms of NX bit). If all input files have the marker,
477 // the GNU linker adds a PT_GNU_STACK segment to tells the loader to
478 // make the stack non-executable. Most object files have this section as
479 // of 2017.
480 //
481 // But making the stack non-executable is a norm today for security
482 // reasons. Failure to do so may result in a serious security issue.
483 // Therefore, we make LLD always add PT_GNU_STACK unless it is
484 // explicitly told to do otherwise (by -z execstack). Because the stack
485 // executable-ness is controlled solely by command line options,
486 // .note.GNU-stack sections are simply ignored.
487 if (Name == ".note.GNU-stack")
488 return &InputSection::Discarded;
489
490 // Split stacks is a feature to support a discontiguous stack. At least
491 // as of 2017, it seems that the feature is not being used widely.
492 // Only GNU gold supports that. We don't. For the details about that,
493 // see https://gcc.gnu.org/wiki/SplitStacks
494 if (Name == ".note.GNU-split-stack") {
495 error(toString(this) +
496 ": object file compiled with -fsplit-stack is not supported");
497 return &InputSection::Discarded;
498 }
499
500 if (Config->Strip != StripPolicy::None && Name.startswith(".debug"))
501 return &InputSection::Discarded;
502
503 // If -gdb-index is given, LLD creates .gdb_index section, and that
504 // section serves the same purpose as .debug_gnu_pub{names,types} sections.
505 // If that's the case, we want to eliminate .debug_gnu_pub{names,types}
506 // because they are redundant and can waste large amount of disk space
507 // (for example, they are about 400 MiB in total for a clang debug build.)
508 if (Config->GdbIndex &&
509 (Name == ".debug_gnu_pubnames" || Name == ".debug_gnu_pubtypes"))
510 return &InputSection::Discarded;
511
512 // The linkonce feature is a sort of proto-comdat. Some glibc i386 object
513 // files contain definitions of symbol "__x86.get_pc_thunk.bx" in linkonce
514 // sections. Drop those sections to avoid duplicate symbol errors.
515 // FIXME: This is glibc PR20543, we should remove this hack once that has been
516 // fixed for a while.
517 if (Name.startswith(".gnu.linkonce."))
518 return &InputSection::Discarded;
519
520 // The linker merges EH (exception handling) frames and creates a
521 // .eh_frame_hdr section for runtime. So we handle them with a special
522 // class. For relocatable outputs, they are just passed through.
523 if (Name == ".eh_frame" && !Config->Relocatable)
524 return make<EhInputSection>(this, &Sec, Name);
525
526 if (shouldMerge(Sec))
527 return make<MergeInputSection>(this, &Sec, Name);
528 return make<InputSection>(this, &Sec, Name);
529}
530
531template <class ELFT>
532StringRef elf::ObjectFile<ELFT>::getSectionName(const Elf_Shdr &Sec) {
533 return check(this->getObj().getSectionName(&Sec, SectionStringTable),
534 toString(this));
535}
536
537template <class ELFT> void elf::ObjectFile<ELFT>::initializeSymbols() {
538 SymbolBodies.reserve(this->Symbols.size());
539 for (const Elf_Sym &Sym : this->Symbols)
540 SymbolBodies.push_back(createSymbolBody(&Sym));
541}
542
543template <class ELFT>
544InputSectionBase *elf::ObjectFile<ELFT>::getSection(const Elf_Sym &Sym) const {
545 uint32_t Index = this->getSectionIndex(Sym);
546 if (Index >= this->Sections.size())
547 fatal(toString(this) + ": invalid section index: " + Twine(Index));
548 InputSectionBase *S = this->Sections[Index];
549
550 // We found that GNU assembler 2.17.50 [FreeBSD] 2007-07-03 could
551 // generate broken objects. STT_SECTION/STT_NOTYPE symbols can be
552 // associated with SHT_REL[A]/SHT_SYMTAB/SHT_STRTAB sections.
553 // In this case it is fine for section to be null here as we do not
554 // allocate sections of these types.
555 if (!S) {
556 if (Index == 0 || Sym.getType() == STT_SECTION ||
557 Sym.getType() == STT_NOTYPE)
558 return nullptr;
559 fatal(toString(this) + ": invalid section index: " + Twine(Index));
560 }
561
562 if (S == &InputSection::Discarded)
563 return S;
564 return S->Repl;
565}
566
567template <class ELFT>
568SymbolBody *elf::ObjectFile<ELFT>::createSymbolBody(const Elf_Sym *Sym) {
569 int Binding = Sym->getBinding();
570 InputSectionBase *Sec = getSection(*Sym);
571
572 uint8_t StOther = Sym->st_other;
573 uint8_t Type = Sym->getType();
574 uint64_t Value = Sym->st_value;
575 uint64_t Size = Sym->st_size;
576
577 if (Binding == STB_LOCAL) {
578 if (Sym->getType() == STT_FILE)
579 SourceFile = check(Sym->getName(this->StringTable), toString(this));
580
581 if (this->StringTable.size() <= Sym->st_name)
582 fatal(toString(this) + ": invalid symbol name offset");
583
584 StringRefZ Name = this->StringTable.data() + Sym->st_name;
585 if (Sym->st_shndx == SHN_UNDEF)
586 return make<Undefined>(Name, /*IsLocal=*/true, StOther, Type, this);
587
588 return make<DefinedRegular>(Name, /*IsLocal=*/true, StOther, Type, Value,
589 Size, Sec, this);
590 }
591
592 StringRef Name = check(Sym->getName(this->StringTable), toString(this));
593
594 switch (Sym->st_shndx) {
595 case SHN_UNDEF:
596 return elf::Symtab<ELFT>::X
597 ->addUndefined(Name, /*IsLocal=*/false, Binding, StOther, Type,
598 /*CanOmitFromDynSym=*/false, this)
599 ->body();
600 case SHN_COMMON:
601 if (Value == 0 || Value >= UINT32_MAX)
602 fatal(toString(this) + ": common symbol '" + Name +
603 "' has invalid alignment: " + Twine(Value));
604 return elf::Symtab<ELFT>::X
605 ->addCommon(Name, Size, Value, Binding, StOther, Type, this)
606 ->body();
607 }
608
609 switch (Binding) {
610 default:
611 fatal(toString(this) + ": unexpected binding: " + Twine(Binding));
612 case STB_GLOBAL:
613 case STB_WEAK:
614 case STB_GNU_UNIQUE:
615 if (Sec == &InputSection::Discarded)
616 return elf::Symtab<ELFT>::X
617 ->addUndefined(Name, /*IsLocal=*/false, Binding, StOther, Type,
618 /*CanOmitFromDynSym=*/false, this)
619 ->body();
620 return elf::Symtab<ELFT>::X
621 ->addRegular(Name, StOther, Type, Value, Size, Binding, Sec, this)
622 ->body();
623 }
624}
625
626ArchiveFile::ArchiveFile(std::unique_ptr<Archive> &&File)
627 : InputFile(ArchiveKind, File->getMemoryBufferRef()),
628 File(std::move(File)) {}
629
630template <class ELFT> void ArchiveFile::parse() {
631 Symbols.reserve(File->getNumberOfSymbols());
632 for (const Archive::Symbol &Sym : File->symbols())
633 Symbols.push_back(Symtab<ELFT>::X->addLazyArchive(this, Sym));
634}
635
636// Returns a buffer pointing to a member file containing a given symbol.
637std::pair<MemoryBufferRef, uint64_t>
638ArchiveFile::getMember(const Archive::Symbol *Sym) {
639 Archive::Child C =
640 check(Sym->getMember(), toString(this) +
641 ": could not get the member for symbol " +
642 Sym->getName());
643
644 if (!Seen.insert(C.getChildOffset()).second)
645 return {MemoryBufferRef(), 0};
646
647 MemoryBufferRef Ret =
648 check(C.getMemoryBufferRef(),
649 toString(this) +
650 ": could not get the buffer for the member defining symbol " +
651 Sym->getName());
652
653 if (C.getParent()->isThin() && Tar)
654 Tar->append(relativeToRoot(check(C.getFullName(), toString(this))),
655 Ret.getBuffer());
656 if (C.getParent()->isThin())
657 return {Ret, 0};
658 return {Ret, C.getChildOffset()};
659}
660
661template <class ELFT>
662SharedFile<ELFT>::SharedFile(MemoryBufferRef M, StringRef DefaultSoName)
663 : ELFFileBase<ELFT>(Base::SharedKind, M), SoName(DefaultSoName),
664 AsNeeded(Config->AsNeeded) {}
665
666template <class ELFT>
667const typename ELFT::Shdr *
668SharedFile<ELFT>::getSection(const Elf_Sym &Sym) const {
669 return check(
670 this->getObj().getSection(&Sym, this->Symbols, this->SymtabSHNDX),
671 toString(this));
672}
673
674// Partially parse the shared object file so that we can call
675// getSoName on this object.
676template <class ELFT> void SharedFile<ELFT>::parseSoName() {
677 const Elf_Shdr *DynamicSec = nullptr;
678 const ELFFile<ELFT> Obj = this->getObj();
679 ArrayRef<Elf_Shdr> Sections = check(Obj.sections(), toString(this));
680
681 // Search for .dynsym, .dynamic, .symtab, .gnu.version and .gnu.version_d.
682 for (const Elf_Shdr &Sec : Sections) {
683 switch (Sec.sh_type) {
684 default:
685 continue;
686 case SHT_DYNSYM:
687 this->initSymtab(Sections, &Sec);
688 break;
689 case SHT_DYNAMIC:
690 DynamicSec = &Sec;
691 break;
692 case SHT_SYMTAB_SHNDX:
693 this->SymtabSHNDX =
694 check(Obj.getSHNDXTable(Sec, Sections), toString(this));
695 break;
696 case SHT_GNU_versym:
697 this->VersymSec = &Sec;
698 break;
699 case SHT_GNU_verdef:
700 this->VerdefSec = &Sec;
701 break;
702 }
703 }
704
705 if (this->VersymSec && this->Symbols.empty())
706 error("SHT_GNU_versym should be associated with symbol table");
707
708 // Search for a DT_SONAME tag to initialize this->SoName.
709 if (!DynamicSec)
710 return;
711 ArrayRef<Elf_Dyn> Arr =
712 check(Obj.template getSectionContentsAsArray<Elf_Dyn>(DynamicSec),
713 toString(this));
714 for (const Elf_Dyn &Dyn : Arr) {
715 if (Dyn.d_tag == DT_SONAME) {
716 uint64_t Val = Dyn.getVal();
717 if (Val >= this->StringTable.size())
718 fatal(toString(this) + ": invalid DT_SONAME entry");
719 SoName = this->StringTable.data() + Val;
720 return;
721 }
722 }
723}
724
725// Parse the version definitions in the object file if present. Returns a vector
726// whose nth element contains a pointer to the Elf_Verdef for version identifier
727// n. Version identifiers that are not definitions map to nullptr. The array
728// always has at least length 1.
729template <class ELFT>
730std::vector<const typename ELFT::Verdef *>
731SharedFile<ELFT>::parseVerdefs(const Elf_Versym *&Versym) {
732 std::vector<const Elf_Verdef *> Verdefs(1);
733 // We only need to process symbol versions for this DSO if it has both a
734 // versym and a verdef section, which indicates that the DSO contains symbol
735 // version definitions.
736 if (!VersymSec || !VerdefSec)
737 return Verdefs;
738
739 // The location of the first global versym entry.
740 const char *Base = this->MB.getBuffer().data();
741 Versym = reinterpret_cast<const Elf_Versym *>(Base + VersymSec->sh_offset) +
742 this->FirstNonLocal;
743
744 // We cannot determine the largest verdef identifier without inspecting
745 // every Elf_Verdef, but both bfd and gold assign verdef identifiers
746 // sequentially starting from 1, so we predict that the largest identifier
747 // will be VerdefCount.
748 unsigned VerdefCount = VerdefSec->sh_info;
749 Verdefs.resize(VerdefCount + 1);
750
751 // Build the Verdefs array by following the chain of Elf_Verdef objects
752 // from the start of the .gnu.version_d section.
753 const char *Verdef = Base + VerdefSec->sh_offset;
754 for (unsigned I = 0; I != VerdefCount; ++I) {
755 auto *CurVerdef = reinterpret_cast<const Elf_Verdef *>(Verdef);
756 Verdef += CurVerdef->vd_next;
757 unsigned VerdefIndex = CurVerdef->vd_ndx;
758 if (Verdefs.size() <= VerdefIndex)
759 Verdefs.resize(VerdefIndex + 1);
760 Verdefs[VerdefIndex] = CurVerdef;
761 }
762
763 return Verdefs;
764}
765
766// Fully parse the shared object file. This must be called after parseSoName().
767template <class ELFT> void SharedFile<ELFT>::parseRest() {
768 // Create mapping from version identifiers to Elf_Verdef entries.
769 const Elf_Versym *Versym = nullptr;
770 std::vector<const Elf_Verdef *> Verdefs = parseVerdefs(Versym);
771
772 Elf_Sym_Range Syms = this->getGlobalSymbols();
773 for (const Elf_Sym &Sym : Syms) {
774 unsigned VersymIndex = 0;
775 if (Versym) {
776 VersymIndex = Versym->vs_index;
777 ++Versym;
778 }
779 bool Hidden = VersymIndex & VERSYM_HIDDEN;
780 VersymIndex = VersymIndex & ~VERSYM_HIDDEN;
781
782 StringRef Name = check(Sym.getName(this->StringTable), toString(this));
783 if (Sym.isUndefined()) {
784 Undefs.push_back(Name);
785 continue;
786 }
787
788 // Ignore local symbols.
789 if (Versym && VersymIndex == VER_NDX_LOCAL)
790 continue;
791
792 const Elf_Verdef *V =
793 VersymIndex == VER_NDX_GLOBAL ? nullptr : Verdefs[VersymIndex];
794
795 if (!Hidden)
796 elf::Symtab<ELFT>::X->addShared(this, Name, Sym, V);
797
798 // Also add the symbol with the versioned name to handle undefined symbols
799 // with explicit versions.
800 if (V) {
801 StringRef VerName = this->StringTable.data() + V->getAux()->vda_name;
802 Name = Saver.save(Name + "@" + VerName);
803 elf::Symtab<ELFT>::X->addShared(this, Name, Sym, V);
804 }
805 }
806}
807
808static ELFKind getBitcodeELFKind(const Triple &T) {
809 if (T.isLittleEndian())
810 return T.isArch64Bit() ? ELF64LEKind : ELF32LEKind;
811 return T.isArch64Bit() ? ELF64BEKind : ELF32BEKind;
812}
813
814static uint8_t getBitcodeMachineKind(StringRef Path, const Triple &T) {
815 switch (T.getArch()) {
816 case Triple::aarch64:
817 return EM_AARCH64;
818 case Triple::arm:
819 case Triple::thumb:
820 return EM_ARM;
821 case Triple::avr:
822 return EM_AVR;
823 case Triple::mips:
824 case Triple::mipsel:
825 case Triple::mips64:
826 case Triple::mips64el:
827 return EM_MIPS;
828 case Triple::ppc:
829 return EM_PPC;
830 case Triple::ppc64:
831 return EM_PPC64;
832 case Triple::x86:
833 return T.isOSIAMCU() ? EM_IAMCU : EM_386;
834 case Triple::x86_64:
835 return EM_X86_64;
836 default:
837 fatal(Path + ": could not infer e_machine from bitcode target triple " +
838 T.str());
839 }
840}
841
842BitcodeFile::BitcodeFile(MemoryBufferRef MB, StringRef ArchiveName,
843 uint64_t OffsetInArchive)
844 : InputFile(BitcodeKind, MB) {
845 this->ArchiveName = ArchiveName;
846
847 // Here we pass a new MemoryBufferRef which is identified by ArchiveName
848 // (the fully resolved path of the archive) + member name + offset of the
849 // member in the archive.
850 // ThinLTO uses the MemoryBufferRef identifier to access its internal
851 // data structures and if two archives define two members with the same name,
852 // this causes a collision which result in only one of the objects being
853 // taken into consideration at LTO time (which very likely causes undefined
854 // symbols later in the link stage).
855 MemoryBufferRef MBRef(MB.getBuffer(),
856 Saver.save(ArchiveName + MB.getBufferIdentifier() +
857 utostr(OffsetInArchive)));
858 Obj = check(lto::InputFile::create(MBRef), toString(this));
859
860 Triple T(Obj->getTargetTriple());
861 EKind = getBitcodeELFKind(T);
862 EMachine = getBitcodeMachineKind(MB.getBufferIdentifier(), T);
863}
864
865static uint8_t mapVisibility(GlobalValue::VisibilityTypes GvVisibility) {
866 switch (GvVisibility) {
867 case GlobalValue::DefaultVisibility:
868 return STV_DEFAULT;
869 case GlobalValue::HiddenVisibility:
870 return STV_HIDDEN;
871 case GlobalValue::ProtectedVisibility:
872 return STV_PROTECTED;
873 }
874 llvm_unreachable("unknown visibility");
875}
876
877template <class ELFT>
878static Symbol *createBitcodeSymbol(const std::vector<bool> &KeptComdats,
879 const lto::InputFile::Symbol &ObjSym,
880 BitcodeFile *F) {
881 StringRef NameRef = Saver.save(ObjSym.getName());
882 uint32_t Binding = ObjSym.isWeak() ? STB_WEAK : STB_GLOBAL;
883
884 uint8_t Type = ObjSym.isTLS() ? STT_TLS : STT_NOTYPE;
885 uint8_t Visibility = mapVisibility(ObjSym.getVisibility());
886 bool CanOmitFromDynSym = ObjSym.canBeOmittedFromSymbolTable();
887
888 int C = ObjSym.getComdatIndex();
889 if (C != -1 && !KeptComdats[C])
890 return Symtab<ELFT>::X->addUndefined(NameRef, /*IsLocal=*/false, Binding,
891 Visibility, Type, CanOmitFromDynSym,
892 F);
893
894 if (ObjSym.isUndefined())
895 return Symtab<ELFT>::X->addUndefined(NameRef, /*IsLocal=*/false, Binding,
896 Visibility, Type, CanOmitFromDynSym,
897 F);
898
899 if (ObjSym.isCommon())
900 return Symtab<ELFT>::X->addCommon(NameRef, ObjSym.getCommonSize(),
901 ObjSym.getCommonAlignment(), Binding,
902 Visibility, STT_OBJECT, F);
903
904 return Symtab<ELFT>::X->addBitcode(NameRef, Binding, Visibility, Type,
905 CanOmitFromDynSym, F);
906}
907
908template <class ELFT>
909void BitcodeFile::parse(DenseSet<CachedHashStringRef> &ComdatGroups) {
910 std::vector<bool> KeptComdats;
911 for (StringRef S : Obj->getComdatTable())
912 KeptComdats.push_back(ComdatGroups.insert(CachedHashStringRef(S)).second);
913
914 for (const lto::InputFile::Symbol &ObjSym : Obj->symbols())
915 Symbols.push_back(createBitcodeSymbol<ELFT>(KeptComdats, ObjSym, this));
916}
917
918static ELFKind getELFKind(MemoryBufferRef MB) {
919 unsigned char Size;
920 unsigned char Endian;
921 std::tie(Size, Endian) = getElfArchType(MB.getBuffer());
922
923 if (Endian != ELFDATA2LSB && Endian != ELFDATA2MSB)
924 fatal(MB.getBufferIdentifier() + ": invalid data encoding");
925 if (Size != ELFCLASS32 && Size != ELFCLASS64)
926 fatal(MB.getBufferIdentifier() + ": invalid file class");
927
928 size_t BufSize = MB.getBuffer().size();
929 if ((Size == ELFCLASS32 && BufSize < sizeof(Elf32_Ehdr)) ||
930 (Size == ELFCLASS64 && BufSize < sizeof(Elf64_Ehdr)))
931 fatal(MB.getBufferIdentifier() + ": file is too short");
932
933 if (Size == ELFCLASS32)
934 return (Endian == ELFDATA2LSB) ? ELF32LEKind : ELF32BEKind;
935 return (Endian == ELFDATA2LSB) ? ELF64LEKind : ELF64BEKind;
936}
937
938template <class ELFT> void BinaryFile::parse() {
939 ArrayRef<uint8_t> Data = toArrayRef(MB.getBuffer());
940 auto *Section =
941 make<InputSection>(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, 8, Data, ".data");
942 Sections.push_back(Section);
943
944 // For each input file foo that is embedded to a result as a binary
945 // blob, we define _binary_foo_{start,end,size} symbols, so that
946 // user programs can access blobs by name. Non-alphanumeric
947 // characters in a filename are replaced with underscore.
948 std::string S = "_binary_" + MB.getBufferIdentifier().str();
949 for (size_t I = 0; I < S.size(); ++I)
950 if (!isalnum(S[I]))
951 S[I] = '_';
952
953 elf::Symtab<ELFT>::X->addRegular(Saver.save(S + "_start"), STV_DEFAULT,
954 STT_OBJECT, 0, 0, STB_GLOBAL, Section,
955 nullptr);
956 elf::Symtab<ELFT>::X->addRegular(Saver.save(S + "_end"), STV_DEFAULT,
957 STT_OBJECT, Data.size(), 0, STB_GLOBAL,
958 Section, nullptr);
959 elf::Symtab<ELFT>::X->addRegular(Saver.save(S + "_size"), STV_DEFAULT,
960 STT_OBJECT, Data.size(), 0, STB_GLOBAL,
961 nullptr, nullptr);
962}
963
964static bool isBitcode(MemoryBufferRef MB) {
965 using namespace sys::fs;
966 return identify_magic(MB.getBuffer()) == file_magic::bitcode;
967}
968
969InputFile *elf::createObjectFile(MemoryBufferRef MB, StringRef ArchiveName,
970 uint64_t OffsetInArchive) {
971 if (isBitcode(MB))
972 return make<BitcodeFile>(MB, ArchiveName, OffsetInArchive);
973
974 switch (getELFKind(MB)) {
975 case ELF32LEKind:
976 return make<ObjectFile<ELF32LE>>(MB, ArchiveName);
977 case ELF32BEKind:
978 return make<ObjectFile<ELF32BE>>(MB, ArchiveName);
979 case ELF64LEKind:
980 return make<ObjectFile<ELF64LE>>(MB, ArchiveName);
981 case ELF64BEKind:
982 return make<ObjectFile<ELF64BE>>(MB, ArchiveName);
983 default:
984 llvm_unreachable("getELFKind");
985 }
986}
987
988InputFile *elf::createSharedFile(MemoryBufferRef MB, StringRef DefaultSoName) {
989 switch (getELFKind(MB)) {
990 case ELF32LEKind:
991 return make<SharedFile<ELF32LE>>(MB, DefaultSoName);
992 case ELF32BEKind:
993 return make<SharedFile<ELF32BE>>(MB, DefaultSoName);
994 case ELF64LEKind:
995 return make<SharedFile<ELF64LE>>(MB, DefaultSoName);
996 case ELF64BEKind:
997 return make<SharedFile<ELF64BE>>(MB, DefaultSoName);
998 default:
999 llvm_unreachable("getELFKind");
1000 }
1001}
1002
1003MemoryBufferRef LazyObjectFile::getBuffer() {
1004 if (Seen)
1005 return MemoryBufferRef();
1006 Seen = true;
1007 return MB;
1008}
1009
1010InputFile *LazyObjectFile::fetch() {
1011 MemoryBufferRef MBRef = getBuffer();
1012 if (MBRef.getBuffer().empty())
1013 return nullptr;
1014 return createObjectFile(MBRef, ArchiveName, OffsetInArchive);
1015}
1016
1017template <class ELFT> void LazyObjectFile::parse() {
1018 for (StringRef Sym : getSymbols())
1019 Symtab<ELFT>::X->addLazyObject(Sym, *this);
1020}
1021
1022template <class ELFT> std::vector<StringRef> LazyObjectFile::getElfSymbols() {
1023 typedef typename ELFT::Shdr Elf_Shdr;
1024 typedef typename ELFT::Sym Elf_Sym;
1025 typedef typename ELFT::SymRange Elf_Sym_Range;
1026
1027 const ELFFile<ELFT> Obj(this->MB.getBuffer());
1028 ArrayRef<Elf_Shdr> Sections = check(Obj.sections(), toString(this));
1029 for (const Elf_Shdr &Sec : Sections) {
1030 if (Sec.sh_type != SHT_SYMTAB)
1031 continue;
1032
1033 Elf_Sym_Range Syms = check(Obj.symbols(&Sec), toString(this));
1034 uint32_t FirstNonLocal = Sec.sh_info;
1035 StringRef StringTable =
1036 check(Obj.getStringTableForSymtab(Sec, Sections), toString(this));
1037 std::vector<StringRef> V;
1038
1039 for (const Elf_Sym &Sym : Syms.slice(FirstNonLocal))
1040 if (Sym.st_shndx != SHN_UNDEF)
1041 V.push_back(check(Sym.getName(StringTable), toString(this)));
1042 return V;
1043 }
1044 return {};
1045}
1046
1047std::vector<StringRef> LazyObjectFile::getBitcodeSymbols() {
1048 std::unique_ptr<lto::InputFile> Obj =
1049 check(lto::InputFile::create(this->MB), toString(this));
1050 std::vector<StringRef> V;
1051 for (const lto::InputFile::Symbol &Sym : Obj->symbols())
1052 if (!Sym.isUndefined())
1053 V.push_back(Saver.save(Sym.getName()));
1054 return V;
1055}
1056
1057// Returns a vector of globally-visible defined symbol names.
1058std::vector<StringRef> LazyObjectFile::getSymbols() {
1059 if (isBitcode(this->MB))
1060 return getBitcodeSymbols();
1061
1062 switch (getELFKind(this->MB)) {
1063 case ELF32LEKind:
1064 return getElfSymbols<ELF32LE>();
1065 case ELF32BEKind:
1066 return getElfSymbols<ELF32BE>();
1067 case ELF64LEKind:
1068 return getElfSymbols<ELF64LE>();
1069 case ELF64BEKind:
1070 return getElfSymbols<ELF64BE>();
1071 default:
1072 llvm_unreachable("getELFKind");
1073 }
1074}
1075
1076template void ArchiveFile::parse<ELF32LE>();
1077template void ArchiveFile::parse<ELF32BE>();
1078template void ArchiveFile::parse<ELF64LE>();
1079template void ArchiveFile::parse<ELF64BE>();
1080
1081template void BitcodeFile::parse<ELF32LE>(DenseSet<CachedHashStringRef> &);
1082template void BitcodeFile::parse<ELF32BE>(DenseSet<CachedHashStringRef> &);
1083template void BitcodeFile::parse<ELF64LE>(DenseSet<CachedHashStringRef> &);
1084template void BitcodeFile::parse<ELF64BE>(DenseSet<CachedHashStringRef> &);
1085
1086template void LazyObjectFile::parse<ELF32LE>();
1087template void LazyObjectFile::parse<ELF32BE>();
1088template void LazyObjectFile::parse<ELF64LE>();
1089template void LazyObjectFile::parse<ELF64BE>();
1090
1091template class elf::ELFFileBase<ELF32LE>;
1092template class elf::ELFFileBase<ELF32BE>;
1093template class elf::ELFFileBase<ELF64LE>;
1094template class elf::ELFFileBase<ELF64BE>;
1095
1096template class elf::ObjectFile<ELF32LE>;
1097template class elf::ObjectFile<ELF32BE>;
1098template class elf::ObjectFile<ELF64LE>;
1099template class elf::ObjectFile<ELF64BE>;
1100
1101template class elf::SharedFile<ELF32LE>;
1102template class elf::SharedFile<ELF32BE>;
1103template class elf::SharedFile<ELF64LE>;
1104template class elf::SharedFile<ELF64BE>;
1105
1106template void BinaryFile::parse<ELF32LE>();
1107template void BinaryFile::parse<ELF32BE>();
1108template void BinaryFile::parse<ELF64LE>();
1109template void BinaryFile::parse<ELF64BE>();
deps/lld/ELF/InputFiles.h created+346
......@@ -0,0 +1,346 @@
1//===- InputFiles.h ---------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_ELF_INPUT_FILES_H
11#define LLD_ELF_INPUT_FILES_H
12
13#include "Config.h"
14#include "Error.h"
15#include "InputSection.h"
16#include "Symbols.h"
17
18#include "lld/Core/LLVM.h"
19#include "lld/Core/Reproduce.h"
20#include "llvm/ADT/CachedHashString.h"
21#include "llvm/ADT/DenseSet.h"
22#include "llvm/ADT/STLExtras.h"
23#include "llvm/IR/Comdat.h"
24#include "llvm/Object/Archive.h"
25#include "llvm/Object/ELF.h"
26#include "llvm/Object/IRObjectFile.h"
27#include "llvm/Support/Threading.h"
28
29#include <map>
30
31namespace llvm {
32class DWARFDebugLine;
33class TarWriter;
34struct DILineInfo;
35namespace lto {
36class InputFile;
37}
38} // namespace llvm
39
40namespace lld {
41namespace elf {
42class InputFile;
43}
44
45// Returns "(internal)", "foo.a(bar.o)" or "baz.o".
46std::string toString(const elf::InputFile *F);
47
48namespace elf {
49
50using llvm::object::Archive;
51
52class Lazy;
53class SymbolBody;
54
55// If -reproduce option is given, all input files are written
56// to this tar archive.
57extern llvm::TarWriter *Tar;
58
59// Opens a given file.
60llvm::Optional<MemoryBufferRef> readFile(StringRef Path);
61
62// The root class of input files.
63class InputFile {
64public:
65 enum Kind {
66 ObjectKind,
67 SharedKind,
68 LazyObjectKind,
69 ArchiveKind,
70 BitcodeKind,
71 BinaryKind,
72 };
73
74 Kind kind() const { return FileKind; }
75
76 StringRef getName() const { return MB.getBufferIdentifier(); }
77 MemoryBufferRef MB;
78
79 // Returns sections. It is a runtime error to call this function
80 // on files that don't have the notion of sections.
81 ArrayRef<InputSectionBase *> getSections() const {
82 assert(FileKind == ObjectKind || FileKind == BinaryKind);
83 return Sections;
84 }
85
86 // Filename of .a which contained this file. If this file was
87 // not in an archive file, it is the empty string. We use this
88 // string for creating error messages.
89 StringRef ArchiveName;
90
91 // If this is an architecture-specific file, the following members
92 // have ELF type (i.e. ELF{32,64}{LE,BE}) and target machine type.
93 ELFKind EKind = ELFNoneKind;
94 uint16_t EMachine = llvm::ELF::EM_NONE;
95 uint8_t OSABI = 0;
96
97 // Cache for toString(). Only toString() should use this member.
98 mutable std::string ToStringCache;
99
100protected:
101 InputFile(Kind K, MemoryBufferRef M);
102 std::vector<InputSectionBase *> Sections;
103
104private:
105 const Kind FileKind;
106};
107
108template <typename ELFT> class ELFFileBase : public InputFile {
109public:
110 typedef typename ELFT::Shdr Elf_Shdr;
111 typedef typename ELFT::Sym Elf_Sym;
112 typedef typename ELFT::Word Elf_Word;
113 typedef typename ELFT::SymRange Elf_Sym_Range;
114
115 ELFFileBase(Kind K, MemoryBufferRef M);
116 static bool classof(const InputFile *F) {
117 Kind K = F->kind();
118 return K == ObjectKind || K == SharedKind;
119 }
120
121 llvm::object::ELFFile<ELFT> getObj() const {
122 return llvm::object::ELFFile<ELFT>(MB.getBuffer());
123 }
124
125 StringRef getStringTable() const { return StringTable; }
126
127 uint32_t getSectionIndex(const Elf_Sym &Sym) const;
128
129 Elf_Sym_Range getGlobalSymbols();
130
131protected:
132 ArrayRef<Elf_Sym> Symbols;
133 uint32_t FirstNonLocal = 0;
134 ArrayRef<Elf_Word> SymtabSHNDX;
135 StringRef StringTable;
136 void initSymtab(ArrayRef<Elf_Shdr> Sections, const Elf_Shdr *Symtab);
137};
138
139// .o file.
140template <class ELFT> class ObjectFile : public ELFFileBase<ELFT> {
141 typedef ELFFileBase<ELFT> Base;
142 typedef typename ELFT::Rel Elf_Rel;
143 typedef typename ELFT::Rela Elf_Rela;
144 typedef typename ELFT::Sym Elf_Sym;
145 typedef typename ELFT::Shdr Elf_Shdr;
146 typedef typename ELFT::Word Elf_Word;
147
148 StringRef getShtGroupSignature(ArrayRef<Elf_Shdr> Sections,
149 const Elf_Shdr &Sec);
150 ArrayRef<Elf_Word> getShtGroupEntries(const Elf_Shdr &Sec);
151
152public:
153 static bool classof(const InputFile *F) {
154 return F->kind() == Base::ObjectKind;
155 }
156
157 ArrayRef<SymbolBody *> getSymbols();
158 ArrayRef<SymbolBody *> getLocalSymbols();
159
160 ObjectFile(MemoryBufferRef M, StringRef ArchiveName);
161 void parse(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);
162
163 InputSectionBase *getSection(const Elf_Sym &Sym) const;
164
165 SymbolBody &getSymbolBody(uint32_t SymbolIndex) const {
166 if (SymbolIndex >= SymbolBodies.size())
167 fatal(toString(this) + ": invalid symbol index");
168 return *SymbolBodies[SymbolIndex];
169 }
170
171 template <typename RelT>
172 SymbolBody &getRelocTargetSym(const RelT &Rel) const {
173 uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
174 return getSymbolBody(SymIndex);
175 }
176
177 // Returns source line information for a given offset.
178 // If no information is available, returns "".
179 std::string getLineInfo(InputSectionBase *S, uint64_t Offset);
180 llvm::Optional<llvm::DILineInfo> getDILineInfo(InputSectionBase *, uint64_t);
181
182 // MIPS GP0 value defined by this file. This value represents the gp value
183 // used to create the relocatable object and required to support
184 // R_MIPS_GPREL16 / R_MIPS_GPREL32 relocations.
185 uint32_t MipsGp0 = 0;
186
187 // Name of source file obtained from STT_FILE symbol value,
188 // or empty string if there is no such symbol in object file
189 // symbol table.
190 StringRef SourceFile;
191
192private:
193 void
194 initializeSections(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);
195 void initializeSymbols();
196 void initializeDwarfLine();
197 InputSectionBase *getRelocTarget(const Elf_Shdr &Sec);
198 InputSectionBase *createInputSection(const Elf_Shdr &Sec);
199 StringRef getSectionName(const Elf_Shdr &Sec);
200
201 bool shouldMerge(const Elf_Shdr &Sec);
202 SymbolBody *createSymbolBody(const Elf_Sym *Sym);
203
204 // List of all symbols referenced or defined by this file.
205 std::vector<SymbolBody *> SymbolBodies;
206
207 // .shstrtab contents.
208 StringRef SectionStringTable;
209
210 // Debugging information to retrieve source file and line for error
211 // reporting. Linker may find reasonable number of errors in a
212 // single object file, so we cache debugging information in order to
213 // parse it only once for each object file we link.
214 std::unique_ptr<llvm::DWARFDebugLine> DwarfLine;
215 llvm::once_flag InitDwarfLine;
216};
217
218// LazyObjectFile is analogous to ArchiveFile in the sense that
219// the file contains lazy symbols. The difference is that
220// LazyObjectFile wraps a single file instead of multiple files.
221//
222// This class is used for --start-lib and --end-lib options which
223// instruct the linker to link object files between them with the
224// archive file semantics.
225class LazyObjectFile : public InputFile {
226public:
227 LazyObjectFile(MemoryBufferRef M, StringRef ArchiveName,
228 uint64_t OffsetInArchive)
229 : InputFile(LazyObjectKind, M), OffsetInArchive(OffsetInArchive) {
230 this->ArchiveName = ArchiveName;
231 }
232
233 static bool classof(const InputFile *F) {
234 return F->kind() == LazyObjectKind;
235 }
236
237 template <class ELFT> void parse();
238 MemoryBufferRef getBuffer();
239 InputFile *fetch();
240
241private:
242 std::vector<StringRef> getSymbols();
243 template <class ELFT> std::vector<StringRef> getElfSymbols();
244 std::vector<StringRef> getBitcodeSymbols();
245
246 bool Seen = false;
247 uint64_t OffsetInArchive;
248};
249
250// An ArchiveFile object represents a .a file.
251class ArchiveFile : public InputFile {
252public:
253 explicit ArchiveFile(std::unique_ptr<Archive> &&File);
254 static bool classof(const InputFile *F) { return F->kind() == ArchiveKind; }
255 template <class ELFT> void parse();
256 ArrayRef<Symbol *> getSymbols() { return Symbols; }
257
258 // Returns a memory buffer for a given symbol and the offset in the archive
259 // for the member. An empty memory buffer and an offset of zero
260 // is returned if we have already returned the same memory buffer.
261 // (So that we don't instantiate same members more than once.)
262 std::pair<MemoryBufferRef, uint64_t> getMember(const Archive::Symbol *Sym);
263
264private:
265 std::unique_ptr<Archive> File;
266 llvm::DenseSet<uint64_t> Seen;
267 std::vector<Symbol *> Symbols;
268};
269
270class BitcodeFile : public InputFile {
271public:
272 BitcodeFile(MemoryBufferRef M, StringRef ArchiveName,
273 uint64_t OffsetInArchive);
274 static bool classof(const InputFile *F) { return F->kind() == BitcodeKind; }
275 template <class ELFT>
276 void parse(llvm::DenseSet<llvm::CachedHashStringRef> &ComdatGroups);
277 ArrayRef<Symbol *> getSymbols() { return Symbols; }
278 std::unique_ptr<llvm::lto::InputFile> Obj;
279
280private:
281 std::vector<Symbol *> Symbols;
282};
283
284// .so file.
285template <class ELFT> class SharedFile : public ELFFileBase<ELFT> {
286 typedef ELFFileBase<ELFT> Base;
287 typedef typename ELFT::Dyn Elf_Dyn;
288 typedef typename ELFT::Shdr Elf_Shdr;
289 typedef typename ELFT::Sym Elf_Sym;
290 typedef typename ELFT::SymRange Elf_Sym_Range;
291 typedef typename ELFT::Verdef Elf_Verdef;
292 typedef typename ELFT::Versym Elf_Versym;
293
294 std::vector<StringRef> Undefs;
295 const Elf_Shdr *VersymSec = nullptr;
296 const Elf_Shdr *VerdefSec = nullptr;
297
298public:
299 std::string SoName;
300
301 const Elf_Shdr *getSection(const Elf_Sym &Sym) const;
302 llvm::ArrayRef<StringRef> getUndefinedSymbols() { return Undefs; }
303
304 static bool classof(const InputFile *F) {
305 return F->kind() == Base::SharedKind;
306 }
307
308 SharedFile(MemoryBufferRef M, StringRef DefaultSoName);
309
310 void parseSoName();
311 void parseRest();
312 std::vector<const Elf_Verdef *> parseVerdefs(const Elf_Versym *&Versym);
313
314 struct NeededVer {
315 // The string table offset of the version name in the output file.
316 size_t StrTab;
317
318 // The version identifier for this version name.
319 uint16_t Index;
320 };
321
322 // Mapping from Elf_Verdef data structures to information about Elf_Vernaux
323 // data structures in the output file.
324 std::map<const Elf_Verdef *, NeededVer> VerdefMap;
325
326 // Used for --as-needed
327 bool AsNeeded = false;
328 bool IsUsed = false;
329 bool isNeeded() const { return !AsNeeded || IsUsed; }
330};
331
332class BinaryFile : public InputFile {
333public:
334 explicit BinaryFile(MemoryBufferRef M) : InputFile(BinaryKind, M) {}
335 static bool classof(const InputFile *F) { return F->kind() == BinaryKind; }
336 template <class ELFT> void parse();
337};
338
339InputFile *createObjectFile(MemoryBufferRef MB, StringRef ArchiveName = "",
340 uint64_t OffsetInArchive = 0);
341InputFile *createSharedFile(MemoryBufferRef MB, StringRef DefaultSoName);
342
343} // namespace elf
344} // namespace lld
345
346#endif
deps/lld/ELF/InputSection.cpp created+1040
......@@ -0,0 +1,1040 @@
1//===- InputSection.cpp ---------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "InputSection.h"
11#include "Config.h"
12#include "EhFrame.h"
13#include "Error.h"
14#include "InputFiles.h"
15#include "LinkerScript.h"
16#include "Memory.h"
17#include "OutputSections.h"
18#include "Relocations.h"
19#include "SyntheticSections.h"
20#include "Target.h"
21#include "Thunks.h"
22#include "llvm/Object/Decompressor.h"
23#include "llvm/Support/Compiler.h"
24#include "llvm/Support/Compression.h"
25#include "llvm/Support/Endian.h"
26#include "llvm/Support/Path.h"
27#include "llvm/Support/Threading.h"
28#include <mutex>
29
30using namespace llvm;
31using namespace llvm::ELF;
32using namespace llvm::object;
33using namespace llvm::support;
34using namespace llvm::support::endian;
35using namespace llvm::sys;
36
37using namespace lld;
38using namespace lld::elf;
39
40std::vector<InputSectionBase *> elf::InputSections;
41
42// Returns a string to construct an error message.
43std::string lld::toString(const InputSectionBase *Sec) {
44 return (toString(Sec->File) + ":(" + Sec->Name + ")").str();
45}
46
47template <class ELFT>
48static ArrayRef<uint8_t> getSectionContents(elf::ObjectFile<ELFT> *File,
49 const typename ELFT::Shdr *Hdr) {
50 if (!File || Hdr->sh_type == SHT_NOBITS)
51 return makeArrayRef<uint8_t>(nullptr, Hdr->sh_size);
52 return check(File->getObj().getSectionContents(Hdr));
53}
54
55InputSectionBase::InputSectionBase(InputFile *File, uint64_t Flags,
56 uint32_t Type, uint64_t Entsize,
57 uint32_t Link, uint32_t Info,
58 uint32_t Alignment, ArrayRef<uint8_t> Data,
59 StringRef Name, Kind SectionKind)
60 : SectionBase(SectionKind, Name, Flags, Entsize, Alignment, Type, Info,
61 Link),
62 File(File), Data(Data), Repl(this) {
63 Live = !Config->GcSections || !(Flags & SHF_ALLOC);
64 Assigned = false;
65 NumRelocations = 0;
66 AreRelocsRela = false;
67
68 // The ELF spec states that a value of 0 means the section has
69 // no alignment constraits.
70 uint32_t V = std::max<uint64_t>(Alignment, 1);
71 if (!isPowerOf2_64(V))
72 fatal(toString(File) + ": section sh_addralign is not a power of 2");
73 this->Alignment = V;
74}
75
76// Drop SHF_GROUP bit unless we are producing a re-linkable object file.
77// SHF_GROUP is a marker that a section belongs to some comdat group.
78// That flag doesn't make sense in an executable.
79static uint64_t getFlags(uint64_t Flags) {
80 Flags &= ~(uint64_t)SHF_INFO_LINK;
81 if (!Config->Relocatable)
82 Flags &= ~(uint64_t)SHF_GROUP;
83 return Flags;
84}
85
86// GNU assembler 2.24 and LLVM 4.0.0's MC (the newest release as of
87// March 2017) fail to infer section types for sections starting with
88// ".init_array." or ".fini_array.". They set SHT_PROGBITS instead of
89// SHF_INIT_ARRAY. As a result, the following assembler directive
90// creates ".init_array.100" with SHT_PROGBITS, for example.
91//
92// .section .init_array.100, "aw"
93//
94// This function forces SHT_{INIT,FINI}_ARRAY so that we can handle
95// incorrect inputs as if they were correct from the beginning.
96static uint64_t getType(uint64_t Type, StringRef Name) {
97 if (Type == SHT_PROGBITS && Name.startswith(".init_array."))
98 return SHT_INIT_ARRAY;
99 if (Type == SHT_PROGBITS && Name.startswith(".fini_array."))
100 return SHT_FINI_ARRAY;
101 return Type;
102}
103
104template <class ELFT>
105InputSectionBase::InputSectionBase(elf::ObjectFile<ELFT> *File,
106 const typename ELFT::Shdr *Hdr,
107 StringRef Name, Kind SectionKind)
108 : InputSectionBase(File, getFlags(Hdr->sh_flags),
109 getType(Hdr->sh_type, Name), Hdr->sh_entsize,
110 Hdr->sh_link, Hdr->sh_info, Hdr->sh_addralign,
111 getSectionContents(File, Hdr), Name, SectionKind) {
112 // We reject object files having insanely large alignments even though
113 // they are allowed by the spec. I think 4GB is a reasonable limitation.
114 // We might want to relax this in the future.
115 if (Hdr->sh_addralign > UINT32_MAX)
116 fatal(toString(File) + ": section sh_addralign is too large");
117}
118
119size_t InputSectionBase::getSize() const {
120 if (auto *S = dyn_cast<SyntheticSection>(this))
121 return S->getSize();
122
123 return Data.size();
124}
125
126uint64_t InputSectionBase::getOffsetInFile() const {
127 const uint8_t *FileStart = (const uint8_t *)File->MB.getBufferStart();
128 const uint8_t *SecStart = Data.begin();
129 return SecStart - FileStart;
130}
131
132uint64_t SectionBase::getOffset(uint64_t Offset) const {
133 switch (kind()) {
134 case Output: {
135 auto *OS = cast<OutputSection>(this);
136 // For output sections we treat offset -1 as the end of the section.
137 return Offset == uint64_t(-1) ? OS->Size : Offset;
138 }
139 case Regular:
140 return cast<InputSection>(this)->OutSecOff + Offset;
141 case Synthetic: {
142 auto *IS = cast<InputSection>(this);
143 // For synthetic sections we treat offset -1 as the end of the section.
144 return IS->OutSecOff + (Offset == uint64_t(-1) ? IS->getSize() : Offset);
145 }
146 case EHFrame:
147 // The file crtbeginT.o has relocations pointing to the start of an empty
148 // .eh_frame that is known to be the first in the link. It does that to
149 // identify the start of the output .eh_frame.
150 return Offset;
151 case Merge:
152 const MergeInputSection *MS = cast<MergeInputSection>(this);
153 if (InputSection *IS = MS->getParent())
154 return IS->OutSecOff + MS->getOffset(Offset);
155 return MS->getOffset(Offset);
156 }
157 llvm_unreachable("invalid section kind");
158}
159
160OutputSection *SectionBase::getOutputSection() {
161 InputSection *Sec;
162 if (auto *IS = dyn_cast<InputSection>(this))
163 Sec = IS;
164 else if (auto *MS = dyn_cast<MergeInputSection>(this))
165 Sec = MS->getParent();
166 else if (auto *EH = dyn_cast<EhInputSection>(this))
167 Sec = EH->getParent();
168 else
169 return cast<OutputSection>(this);
170 return Sec ? Sec->getParent() : nullptr;
171}
172
173// Uncompress section contents. Note that this function is called
174// from parallel_for_each, so it must be thread-safe.
175void InputSectionBase::uncompress() {
176 Decompressor Dec = check(Decompressor::create(Name, toStringRef(Data),
177 Config->IsLE, Config->Is64));
178
179 size_t Size = Dec.getDecompressedSize();
180 char *OutputBuf;
181 {
182 static std::mutex Mu;
183 std::lock_guard<std::mutex> Lock(Mu);
184 OutputBuf = BAlloc.Allocate<char>(Size);
185 }
186
187 if (Error E = Dec.decompress({OutputBuf, Size}))
188 fatal(toString(this) +
189 ": decompress failed: " + llvm::toString(std::move(E)));
190 this->Data = ArrayRef<uint8_t>((uint8_t *)OutputBuf, Size);
191 this->Flags &= ~(uint64_t)SHF_COMPRESSED;
192}
193
194uint64_t SectionBase::getOffset(const DefinedRegular &Sym) const {
195 return getOffset(Sym.Value);
196}
197
198InputSection *InputSectionBase::getLinkOrderDep() const {
199 if ((Flags & SHF_LINK_ORDER) && Link != 0) {
200 InputSectionBase *L = File->getSections()[Link];
201 if (auto *IS = dyn_cast<InputSection>(L))
202 return IS;
203 error(
204 "Merge and .eh_frame sections are not supported with SHF_LINK_ORDER " +
205 toString(L));
206 }
207 return nullptr;
208}
209
210// Returns a source location string. Used to construct an error message.
211template <class ELFT>
212std::string InputSectionBase::getLocation(uint64_t Offset) {
213 // We don't have file for synthetic sections.
214 if (getFile<ELFT>() == nullptr)
215 return (Config->OutputFile + ":(" + Name + "+0x" + utohexstr(Offset) + ")")
216 .str();
217
218 // First check if we can get desired values from debugging information.
219 std::string LineInfo = getFile<ELFT>()->getLineInfo(this, Offset);
220 if (!LineInfo.empty())
221 return LineInfo;
222
223 // File->SourceFile contains STT_FILE symbol that contains a
224 // source file name. If it's missing, we use an object file name.
225 std::string SrcFile = getFile<ELFT>()->SourceFile;
226 if (SrcFile.empty())
227 SrcFile = toString(File);
228
229 // Find a function symbol that encloses a given location.
230 for (SymbolBody *B : getFile<ELFT>()->getSymbols())
231 if (auto *D = dyn_cast<DefinedRegular>(B))
232 if (D->Section == this && D->Type == STT_FUNC)
233 if (D->Value <= Offset && Offset < D->Value + D->Size)
234 return SrcFile + ":(function " + toString(*D) + ")";
235
236 // If there's no symbol, print out the offset in the section.
237 return (SrcFile + ":(" + Name + "+0x" + utohexstr(Offset) + ")").str();
238}
239
240// Returns a source location string. This function is intended to be
241// used for constructing an error message. The returned message looks
242// like this:
243//
244// foo.c:42 (/home/alice/possibly/very/long/path/foo.c:42)
245//
246// Returns an empty string if there's no way to get line info.
247template <class ELFT> std::string InputSectionBase::getSrcMsg(uint64_t Offset) {
248 // Synthetic sections don't have input files.
249 elf::ObjectFile<ELFT> *File = getFile<ELFT>();
250 if (!File)
251 return "";
252
253 Optional<DILineInfo> Info = File->getDILineInfo(this, Offset);
254
255 // File->SourceFile contains STT_FILE symbol, and that is a last resort.
256 if (!Info)
257 return File->SourceFile;
258
259 std::string Path = Info->FileName;
260 std::string Filename = path::filename(Path);
261 std::string Lineno = ":" + std::to_string(Info->Line);
262 if (Filename == Path)
263 return Filename + Lineno;
264 return Filename + Lineno + " (" + Path + Lineno + ")";
265}
266
267// Returns a filename string along with an optional section name. This
268// function is intended to be used for constructing an error
269// message. The returned message looks like this:
270//
271// path/to/foo.o:(function bar)
272//
273// or
274//
275// path/to/foo.o:(function bar) in archive path/to/bar.a
276template <class ELFT> std::string InputSectionBase::getObjMsg(uint64_t Off) {
277 // Synthetic sections don't have input files.
278 elf::ObjectFile<ELFT> *File = getFile<ELFT>();
279 if (!File)
280 return ("(internal):(" + Name + "+0x" + utohexstr(Off) + ")").str();
281 std::string Filename = File->getName();
282
283 std::string Archive;
284 if (!File->ArchiveName.empty())
285 Archive = (" in archive " + File->ArchiveName).str();
286
287 // Find a symbol that encloses a given location.
288 for (SymbolBody *B : getFile<ELFT>()->getSymbols())
289 if (auto *D = dyn_cast<DefinedRegular>(B))
290 if (D->Section == this && D->Value <= Off && Off < D->Value + D->Size)
291 return Filename + ":(" + toString(*D) + ")" + Archive;
292
293 // If there's no symbol, print out the offset in the section.
294 return (Filename + ":(" + Name + "+0x" + utohexstr(Off) + ")" + Archive)
295 .str();
296}
297
298InputSectionBase InputSectionBase::Discarded;
299
300InputSection::InputSection(uint64_t Flags, uint32_t Type, uint32_t Alignment,
301 ArrayRef<uint8_t> Data, StringRef Name, Kind K)
302 : InputSectionBase(nullptr, Flags, Type,
303 /*Entsize*/ 0, /*Link*/ 0, /*Info*/ 0, Alignment, Data,
304 Name, K) {}
305
306template <class ELFT>
307InputSection::InputSection(elf::ObjectFile<ELFT> *F,
308 const typename ELFT::Shdr *Header, StringRef Name)
309 : InputSectionBase(F, Header, Name, InputSectionBase::Regular) {}
310
311bool InputSection::classof(const SectionBase *S) {
312 return S->kind() == SectionBase::Regular ||
313 S->kind() == SectionBase::Synthetic;
314}
315
316bool InputSectionBase::classof(const SectionBase *S) {
317 return S->kind() != Output;
318}
319
320OutputSection *InputSection::getParent() const {
321 return cast_or_null<OutputSection>(Parent);
322}
323
324// Copy SHT_GROUP section contents. Used only for the -r option.
325template <class ELFT> void InputSection::copyShtGroup(uint8_t *Buf) {
326 // ELFT::Word is the 32-bit integral type in the target endianness.
327 typedef typename ELFT::Word u32;
328 ArrayRef<u32> From = getDataAs<u32>();
329 auto *To = reinterpret_cast<u32 *>(Buf);
330
331 // The first entry is not a section number but a flag.
332 *To++ = From[0];
333
334 // Adjust section numbers because section numbers in an input object
335 // files are different in the output.
336 ArrayRef<InputSectionBase *> Sections = this->File->getSections();
337 for (uint32_t Idx : From.slice(1))
338 *To++ = Sections[Idx]->getOutputSection()->SectionIndex;
339}
340
341InputSectionBase *InputSection::getRelocatedSection() {
342 assert(this->Type == SHT_RELA || this->Type == SHT_REL);
343 ArrayRef<InputSectionBase *> Sections = this->File->getSections();
344 return Sections[this->Info];
345}
346
347// This is used for -r and --emit-relocs. We can't use memcpy to copy
348// relocations because we need to update symbol table offset and section index
349// for each relocation. So we copy relocations one by one.
350template <class ELFT, class RelTy>
351void InputSection::copyRelocations(uint8_t *Buf, ArrayRef<RelTy> Rels) {
352 InputSectionBase *RelocatedSection = getRelocatedSection();
353
354 // Loop is slow and have complexity O(N*M), where N - amount of
355 // relocations and M - amount of symbols in symbol table.
356 // That happens because getSymbolIndex(...) call below performs
357 // simple linear search.
358 for (const RelTy &Rel : Rels) {
359 uint32_t Type = Rel.getType(Config->IsMips64EL);
360 SymbolBody &Body = this->getFile<ELFT>()->getRelocTargetSym(Rel);
361
362 auto *P = reinterpret_cast<typename ELFT::Rela *>(Buf);
363 Buf += sizeof(RelTy);
364
365 if (Config->IsRela)
366 P->r_addend = getAddend<ELFT>(Rel);
367
368 // Output section VA is zero for -r, so r_offset is an offset within the
369 // section, but for --emit-relocs it is an virtual address.
370 P->r_offset = RelocatedSection->getOutputSection()->Addr +
371 RelocatedSection->getOffset(Rel.r_offset);
372 P->setSymbolAndType(InX::SymTab->getSymbolIndex(&Body), Type,
373 Config->IsMips64EL);
374
375 if (Body.Type == STT_SECTION) {
376 // We combine multiple section symbols into only one per
377 // section. This means we have to update the addend. That is
378 // trivial for Elf_Rela, but for Elf_Rel we have to write to the
379 // section data. We do that by adding to the Relocation vector.
380
381 // .eh_frame is horribly special and can reference discarded sections. To
382 // avoid having to parse and recreate .eh_frame, we just replace any
383 // relocation in it pointing to discarded sections with R_*_NONE, which
384 // hopefully creates a frame that is ignored at runtime.
385 SectionBase *Section = cast<DefinedRegular>(Body).Section;
386 if (Section == &InputSection::Discarded) {
387 P->setSymbolAndType(0, 0, false);
388 continue;
389 }
390
391 if (Config->IsRela) {
392 P->r_addend += Body.getVA() - Section->getOutputSection()->Addr;
393 } else if (Config->Relocatable) {
394 const uint8_t *BufLoc = RelocatedSection->Data.begin() + Rel.r_offset;
395 RelocatedSection->Relocations.push_back(
396 {R_ABS, Type, Rel.r_offset, Target->getImplicitAddend(BufLoc, Type),
397 &Body});
398 }
399 }
400
401 }
402}
403
404// The ARM and AArch64 ABI handle pc-relative relocations to undefined weak
405// references specially. The general rule is that the value of the symbol in
406// this context is the address of the place P. A further special case is that
407// branch relocations to an undefined weak reference resolve to the next
408// instruction.
409static uint32_t getARMUndefinedRelativeWeakVA(uint32_t Type, uint32_t A,
410 uint32_t P) {
411 switch (Type) {
412 // Unresolved branch relocations to weak references resolve to next
413 // instruction, this will be either 2 or 4 bytes on from P.
414 case R_ARM_THM_JUMP11:
415 return P + 2 + A;
416 case R_ARM_CALL:
417 case R_ARM_JUMP24:
418 case R_ARM_PC24:
419 case R_ARM_PLT32:
420 case R_ARM_PREL31:
421 case R_ARM_THM_JUMP19:
422 case R_ARM_THM_JUMP24:
423 return P + 4 + A;
424 case R_ARM_THM_CALL:
425 // We don't want an interworking BLX to ARM
426 return P + 5 + A;
427 // Unresolved non branch pc-relative relocations
428 // R_ARM_TARGET2 which can be resolved relatively is not present as it never
429 // targets a weak-reference.
430 case R_ARM_MOVW_PREL_NC:
431 case R_ARM_MOVT_PREL:
432 case R_ARM_REL32:
433 case R_ARM_THM_MOVW_PREL_NC:
434 case R_ARM_THM_MOVT_PREL:
435 return P + A;
436 }
437 llvm_unreachable("ARM pc-relative relocation expected\n");
438}
439
440// The comment above getARMUndefinedRelativeWeakVA applies to this function.
441static uint64_t getAArch64UndefinedRelativeWeakVA(uint64_t Type, uint64_t A,
442 uint64_t P) {
443 switch (Type) {
444 // Unresolved branch relocations to weak references resolve to next
445 // instruction, this is 4 bytes on from P.
446 case R_AARCH64_CALL26:
447 case R_AARCH64_CONDBR19:
448 case R_AARCH64_JUMP26:
449 case R_AARCH64_TSTBR14:
450 return P + 4 + A;
451 // Unresolved non branch pc-relative relocations
452 case R_AARCH64_PREL16:
453 case R_AARCH64_PREL32:
454 case R_AARCH64_PREL64:
455 case R_AARCH64_ADR_PREL_LO21:
456 return P + A;
457 }
458 llvm_unreachable("AArch64 pc-relative relocation expected\n");
459}
460
461// ARM SBREL relocations are of the form S + A - B where B is the static base
462// The ARM ABI defines base to be "addressing origin of the output segment
463// defining the symbol S". We defined the "addressing origin"/static base to be
464// the base of the PT_LOAD segment containing the Body.
465// The procedure call standard only defines a Read Write Position Independent
466// RWPI variant so in practice we should expect the static base to be the base
467// of the RW segment.
468static uint64_t getARMStaticBase(const SymbolBody &Body) {
469 OutputSection *OS = Body.getOutputSection();
470 if (!OS || !OS->FirstInPtLoad)
471 fatal("SBREL relocation to " + Body.getName() + " without static base");
472 return OS->FirstInPtLoad->Addr;
473}
474
475static uint64_t getRelocTargetVA(uint32_t Type, int64_t A, uint64_t P,
476 const SymbolBody &Body, RelExpr Expr) {
477 switch (Expr) {
478 case R_ABS:
479 case R_RELAX_GOT_PC_NOPIC:
480 return Body.getVA(A);
481 case R_ARM_SBREL:
482 return Body.getVA(A) - getARMStaticBase(Body);
483 case R_GOT:
484 case R_RELAX_TLS_GD_TO_IE_ABS:
485 return Body.getGotVA() + A;
486 case R_GOTONLY_PC:
487 return InX::Got->getVA() + A - P;
488 case R_GOTONLY_PC_FROM_END:
489 return InX::Got->getVA() + A - P + InX::Got->getSize();
490 case R_GOTREL:
491 return Body.getVA(A) - InX::Got->getVA();
492 case R_GOTREL_FROM_END:
493 return Body.getVA(A) - InX::Got->getVA() - InX::Got->getSize();
494 case R_GOT_FROM_END:
495 case R_RELAX_TLS_GD_TO_IE_END:
496 return Body.getGotOffset() + A - InX::Got->getSize();
497 case R_GOT_OFF:
498 return Body.getGotOffset() + A;
499 case R_GOT_PAGE_PC:
500 case R_RELAX_TLS_GD_TO_IE_PAGE_PC:
501 return getAArch64Page(Body.getGotVA() + A) - getAArch64Page(P);
502 case R_GOT_PC:
503 case R_RELAX_TLS_GD_TO_IE:
504 return Body.getGotVA() + A - P;
505 case R_HINT:
506 case R_NONE:
507 case R_TLSDESC_CALL:
508 llvm_unreachable("cannot relocate hint relocs");
509 case R_MIPS_GOTREL:
510 return Body.getVA(A) - InX::MipsGot->getGp();
511 case R_MIPS_GOT_GP:
512 return InX::MipsGot->getGp() + A;
513 case R_MIPS_GOT_GP_PC: {
514 // R_MIPS_LO16 expression has R_MIPS_GOT_GP_PC type iif the target
515 // is _gp_disp symbol. In that case we should use the following
516 // formula for calculation "AHL + GP - P + 4". For details see p. 4-19 at
517 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
518 uint64_t V = InX::MipsGot->getGp() + A - P;
519 if (Type == R_MIPS_LO16)
520 V += 4;
521 return V;
522 }
523 case R_MIPS_GOT_LOCAL_PAGE:
524 // If relocation against MIPS local symbol requires GOT entry, this entry
525 // should be initialized by 'page address'. This address is high 16-bits
526 // of sum the symbol's value and the addend.
527 return InX::MipsGot->getVA() + InX::MipsGot->getPageEntryOffset(Body, A) -
528 InX::MipsGot->getGp();
529 case R_MIPS_GOT_OFF:
530 case R_MIPS_GOT_OFF32:
531 // In case of MIPS if a GOT relocation has non-zero addend this addend
532 // should be applied to the GOT entry content not to the GOT entry offset.
533 // That is why we use separate expression type.
534 return InX::MipsGot->getVA() + InX::MipsGot->getBodyEntryOffset(Body, A) -
535 InX::MipsGot->getGp();
536 case R_MIPS_TLSGD:
537 return InX::MipsGot->getVA() + InX::MipsGot->getTlsOffset() +
538 InX::MipsGot->getGlobalDynOffset(Body) - InX::MipsGot->getGp();
539 case R_MIPS_TLSLD:
540 return InX::MipsGot->getVA() + InX::MipsGot->getTlsOffset() +
541 InX::MipsGot->getTlsIndexOff() - InX::MipsGot->getGp();
542 case R_PAGE_PC:
543 case R_PLT_PAGE_PC: {
544 uint64_t Dest;
545 if (Body.isUndefined() && !Body.isLocal() && Body.symbol()->isWeak())
546 Dest = getAArch64Page(A);
547 else
548 Dest = getAArch64Page(Body.getVA(A));
549 return Dest - getAArch64Page(P);
550 }
551 case R_PC: {
552 uint64_t Dest;
553 if (Body.isUndefined() && !Body.isLocal() && Body.symbol()->isWeak()) {
554 // On ARM and AArch64 a branch to an undefined weak resolves to the
555 // next instruction, otherwise the place.
556 if (Config->EMachine == EM_ARM)
557 Dest = getARMUndefinedRelativeWeakVA(Type, A, P);
558 else if (Config->EMachine == EM_AARCH64)
559 Dest = getAArch64UndefinedRelativeWeakVA(Type, A, P);
560 else
561 Dest = Body.getVA(A);
562 } else {
563 Dest = Body.getVA(A);
564 }
565 return Dest - P;
566 }
567 case R_PLT:
568 return Body.getPltVA() + A;
569 case R_PLT_PC:
570 case R_PPC_PLT_OPD:
571 return Body.getPltVA() + A - P;
572 case R_PPC_OPD: {
573 uint64_t SymVA = Body.getVA(A);
574 // If we have an undefined weak symbol, we might get here with a symbol
575 // address of zero. That could overflow, but the code must be unreachable,
576 // so don't bother doing anything at all.
577 if (!SymVA)
578 return 0;
579 if (Out::Opd) {
580 // If this is a local call, and we currently have the address of a
581 // function-descriptor, get the underlying code address instead.
582 uint64_t OpdStart = Out::Opd->Addr;
583 uint64_t OpdEnd = OpdStart + Out::Opd->Size;
584 bool InOpd = OpdStart <= SymVA && SymVA < OpdEnd;
585 if (InOpd)
586 SymVA = read64be(&Out::OpdBuf[SymVA - OpdStart]);
587 }
588 return SymVA - P;
589 }
590 case R_PPC_TOC:
591 return getPPC64TocBase() + A;
592 case R_RELAX_GOT_PC:
593 return Body.getVA(A) - P;
594 case R_RELAX_TLS_GD_TO_LE:
595 case R_RELAX_TLS_IE_TO_LE:
596 case R_RELAX_TLS_LD_TO_LE:
597 case R_TLS:
598 // A weak undefined TLS symbol resolves to the base of the TLS
599 // block, i.e. gets a value of zero. If we pass --gc-sections to
600 // lld and .tbss is not referenced, it gets reclaimed and we don't
601 // create a TLS program header. Therefore, we resolve this
602 // statically to zero.
603 if (Body.isTls() && (Body.isLazy() || Body.isUndefined()) &&
604 Body.symbol()->isWeak())
605 return 0;
606 if (Target->TcbSize)
607 return Body.getVA(A) + alignTo(Target->TcbSize, Out::TlsPhdr->p_align);
608 return Body.getVA(A) - Out::TlsPhdr->p_memsz;
609 case R_RELAX_TLS_GD_TO_LE_NEG:
610 case R_NEG_TLS:
611 return Out::TlsPhdr->p_memsz - Body.getVA(A);
612 case R_SIZE:
613 return A; // Body.getSize was already folded into the addend.
614 case R_TLSDESC:
615 return InX::Got->getGlobalDynAddr(Body) + A;
616 case R_TLSDESC_PAGE:
617 return getAArch64Page(InX::Got->getGlobalDynAddr(Body) + A) -
618 getAArch64Page(P);
619 case R_TLSGD:
620 return InX::Got->getGlobalDynOffset(Body) + A - InX::Got->getSize();
621 case R_TLSGD_PC:
622 return InX::Got->getGlobalDynAddr(Body) + A - P;
623 case R_TLSLD:
624 return InX::Got->getTlsIndexOff() + A - InX::Got->getSize();
625 case R_TLSLD_PC:
626 return InX::Got->getTlsIndexVA() + A - P;
627 }
628 llvm_unreachable("Invalid expression");
629}
630
631// This function applies relocations to sections without SHF_ALLOC bit.
632// Such sections are never mapped to memory at runtime. Debug sections are
633// an example. Relocations in non-alloc sections are much easier to
634// handle than in allocated sections because it will never need complex
635// treatement such as GOT or PLT (because at runtime no one refers them).
636// So, we handle relocations for non-alloc sections directly in this
637// function as a performance optimization.
638template <class ELFT, class RelTy>
639void InputSection::relocateNonAlloc(uint8_t *Buf, ArrayRef<RelTy> Rels) {
640 for (const RelTy &Rel : Rels) {
641 uint32_t Type = Rel.getType(Config->IsMips64EL);
642 uint64_t Offset = getOffset(Rel.r_offset);
643 uint8_t *BufLoc = Buf + Offset;
644 int64_t Addend = getAddend<ELFT>(Rel);
645 if (!RelTy::IsRela)
646 Addend += Target->getImplicitAddend(BufLoc, Type);
647
648 SymbolBody &Sym = this->getFile<ELFT>()->getRelocTargetSym(Rel);
649 RelExpr Expr = Target->getRelExpr(Type, Sym, BufLoc);
650 if (Expr == R_NONE)
651 continue;
652 if (Expr != R_ABS) {
653 error(this->getLocation<ELFT>(Offset) + ": has non-ABS reloc");
654 return;
655 }
656
657 uint64_t AddrLoc = getParent()->Addr + Offset;
658 uint64_t SymVA = 0;
659 if (!Sym.isTls() || Out::TlsPhdr)
660 SymVA = SignExtend64<sizeof(typename ELFT::uint) * 8>(
661 getRelocTargetVA(Type, Addend, AddrLoc, Sym, R_ABS));
662 Target->relocateOne(BufLoc, Type, SymVA);
663 }
664}
665
666template <class ELFT> elf::ObjectFile<ELFT> *InputSectionBase::getFile() const {
667 return cast_or_null<elf::ObjectFile<ELFT>>(File);
668}
669
670template <class ELFT>
671void InputSectionBase::relocate(uint8_t *Buf, uint8_t *BufEnd) {
672 if (Flags & SHF_ALLOC)
673 relocateAlloc(Buf, BufEnd);
674 else
675 relocateNonAlloc<ELFT>(Buf, BufEnd);
676}
677
678template <class ELFT>
679void InputSectionBase::relocateNonAlloc(uint8_t *Buf, uint8_t *BufEnd) {
680 // scanReloc function in Writer.cpp constructs Relocations
681 // vector only for SHF_ALLOC'ed sections. For other sections,
682 // we handle relocations directly here.
683 auto *IS = cast<InputSection>(this);
684 assert(!(IS->Flags & SHF_ALLOC));
685 if (IS->AreRelocsRela)
686 IS->relocateNonAlloc<ELFT>(Buf, IS->template relas<ELFT>());
687 else
688 IS->relocateNonAlloc<ELFT>(Buf, IS->template rels<ELFT>());
689}
690
691void InputSectionBase::relocateAlloc(uint8_t *Buf, uint8_t *BufEnd) {
692 assert(Flags & SHF_ALLOC);
693 const unsigned Bits = Config->Wordsize * 8;
694 for (const Relocation &Rel : Relocations) {
695 uint64_t Offset = getOffset(Rel.Offset);
696 uint8_t *BufLoc = Buf + Offset;
697 uint32_t Type = Rel.Type;
698
699 uint64_t AddrLoc = getOutputSection()->Addr + Offset;
700 RelExpr Expr = Rel.Expr;
701 uint64_t TargetVA = SignExtend64(
702 getRelocTargetVA(Type, Rel.Addend, AddrLoc, *Rel.Sym, Expr), Bits);
703
704 switch (Expr) {
705 case R_RELAX_GOT_PC:
706 case R_RELAX_GOT_PC_NOPIC:
707 Target->relaxGot(BufLoc, TargetVA);
708 break;
709 case R_RELAX_TLS_IE_TO_LE:
710 Target->relaxTlsIeToLe(BufLoc, Type, TargetVA);
711 break;
712 case R_RELAX_TLS_LD_TO_LE:
713 Target->relaxTlsLdToLe(BufLoc, Type, TargetVA);
714 break;
715 case R_RELAX_TLS_GD_TO_LE:
716 case R_RELAX_TLS_GD_TO_LE_NEG:
717 Target->relaxTlsGdToLe(BufLoc, Type, TargetVA);
718 break;
719 case R_RELAX_TLS_GD_TO_IE:
720 case R_RELAX_TLS_GD_TO_IE_ABS:
721 case R_RELAX_TLS_GD_TO_IE_PAGE_PC:
722 case R_RELAX_TLS_GD_TO_IE_END:
723 Target->relaxTlsGdToIe(BufLoc, Type, TargetVA);
724 break;
725 case R_PPC_PLT_OPD:
726 // Patch a nop (0x60000000) to a ld.
727 if (BufLoc + 8 <= BufEnd && read32be(BufLoc + 4) == 0x60000000)
728 write32be(BufLoc + 4, 0xe8410028); // ld %r2, 40(%r1)
729 LLVM_FALLTHROUGH;
730 default:
731 Target->relocateOne(BufLoc, Type, TargetVA);
732 break;
733 }
734 }
735}
736
737template <class ELFT> void InputSection::writeTo(uint8_t *Buf) {
738 if (this->Type == SHT_NOBITS)
739 return;
740
741 if (auto *S = dyn_cast<SyntheticSection>(this)) {
742 S->writeTo(Buf + OutSecOff);
743 return;
744 }
745
746 // If -r or --emit-relocs is given, then an InputSection
747 // may be a relocation section.
748 if (this->Type == SHT_RELA) {
749 copyRelocations<ELFT>(Buf + OutSecOff,
750 this->template getDataAs<typename ELFT::Rela>());
751 return;
752 }
753 if (this->Type == SHT_REL) {
754 copyRelocations<ELFT>(Buf + OutSecOff,
755 this->template getDataAs<typename ELFT::Rel>());
756 return;
757 }
758
759 // If -r is given, we may have a SHT_GROUP section.
760 if (this->Type == SHT_GROUP) {
761 copyShtGroup<ELFT>(Buf + OutSecOff);
762 return;
763 }
764
765 // Copy section contents from source object file to output file
766 // and then apply relocations.
767 memcpy(Buf + OutSecOff, Data.data(), Data.size());
768 uint8_t *BufEnd = Buf + OutSecOff + Data.size();
769 this->relocate<ELFT>(Buf, BufEnd);
770}
771
772void InputSection::replace(InputSection *Other) {
773 this->Alignment = std::max(this->Alignment, Other->Alignment);
774 Other->Repl = this->Repl;
775 Other->Live = false;
776}
777
778template <class ELFT>
779EhInputSection::EhInputSection(elf::ObjectFile<ELFT> *F,
780 const typename ELFT::Shdr *Header,
781 StringRef Name)
782 : InputSectionBase(F, Header, Name, InputSectionBase::EHFrame) {
783 // Mark .eh_frame sections as live by default because there are
784 // usually no relocations that point to .eh_frames. Otherwise,
785 // the garbage collector would drop all .eh_frame sections.
786 this->Live = true;
787}
788
789SyntheticSection *EhInputSection::getParent() const {
790 return cast_or_null<SyntheticSection>(Parent);
791}
792
793bool EhInputSection::classof(const SectionBase *S) {
794 return S->kind() == InputSectionBase::EHFrame;
795}
796
797// Returns the index of the first relocation that points to a region between
798// Begin and Begin+Size.
799template <class IntTy, class RelTy>
800static unsigned getReloc(IntTy Begin, IntTy Size, const ArrayRef<RelTy> &Rels,
801 unsigned &RelocI) {
802 // Start search from RelocI for fast access. That works because the
803 // relocations are sorted in .eh_frame.
804 for (unsigned N = Rels.size(); RelocI < N; ++RelocI) {
805 const RelTy &Rel = Rels[RelocI];
806 if (Rel.r_offset < Begin)
807 continue;
808
809 if (Rel.r_offset < Begin + Size)
810 return RelocI;
811 return -1;
812 }
813 return -1;
814}
815
816// .eh_frame is a sequence of CIE or FDE records.
817// This function splits an input section into records and returns them.
818template <class ELFT> void EhInputSection::split() {
819 // Early exit if already split.
820 if (!this->Pieces.empty())
821 return;
822
823 if (this->NumRelocations) {
824 if (this->AreRelocsRela)
825 split<ELFT>(this->relas<ELFT>());
826 else
827 split<ELFT>(this->rels<ELFT>());
828 return;
829 }
830 split<ELFT>(makeArrayRef<typename ELFT::Rela>(nullptr, nullptr));
831}
832
833template <class ELFT, class RelTy>
834void EhInputSection::split(ArrayRef<RelTy> Rels) {
835 ArrayRef<uint8_t> Data = this->Data;
836 unsigned RelI = 0;
837 for (size_t Off = 0, End = Data.size(); Off != End;) {
838 size_t Size = readEhRecordSize<ELFT>(this, Off);
839 this->Pieces.emplace_back(Off, this, Size, getReloc(Off, Size, Rels, RelI));
840 // The empty record is the end marker.
841 if (Size == 4)
842 break;
843 Off += Size;
844 }
845}
846
847static size_t findNull(ArrayRef<uint8_t> A, size_t EntSize) {
848 // Optimize the common case.
849 StringRef S((const char *)A.data(), A.size());
850 if (EntSize == 1)
851 return S.find(0);
852
853 for (unsigned I = 0, N = S.size(); I != N; I += EntSize) {
854 const char *B = S.begin() + I;
855 if (std::all_of(B, B + EntSize, [](char C) { return C == 0; }))
856 return I;
857 }
858 return StringRef::npos;
859}
860
861SyntheticSection *MergeInputSection::getParent() const {
862 return cast_or_null<SyntheticSection>(Parent);
863}
864
865// Split SHF_STRINGS section. Such section is a sequence of
866// null-terminated strings.
867void MergeInputSection::splitStrings(ArrayRef<uint8_t> Data, size_t EntSize) {
868 size_t Off = 0;
869 bool IsAlloc = this->Flags & SHF_ALLOC;
870 while (!Data.empty()) {
871 size_t End = findNull(Data, EntSize);
872 if (End == StringRef::npos)
873 fatal(toString(this) + ": string is not null terminated");
874 size_t Size = End + EntSize;
875 Pieces.emplace_back(Off, !IsAlloc);
876 Hashes.push_back(hash_value(toStringRef(Data.slice(0, Size))));
877 Data = Data.slice(Size);
878 Off += Size;
879 }
880}
881
882// Split non-SHF_STRINGS section. Such section is a sequence of
883// fixed size records.
884void MergeInputSection::splitNonStrings(ArrayRef<uint8_t> Data,
885 size_t EntSize) {
886 size_t Size = Data.size();
887 assert((Size % EntSize) == 0);
888 bool IsAlloc = this->Flags & SHF_ALLOC;
889 for (unsigned I = 0, N = Size; I != N; I += EntSize) {
890 Hashes.push_back(hash_value(toStringRef(Data.slice(I, EntSize))));
891 Pieces.emplace_back(I, !IsAlloc);
892 }
893}
894
895template <class ELFT>
896MergeInputSection::MergeInputSection(elf::ObjectFile<ELFT> *F,
897 const typename ELFT::Shdr *Header,
898 StringRef Name)
899 : InputSectionBase(F, Header, Name, InputSectionBase::Merge) {}
900
901// This function is called after we obtain a complete list of input sections
902// that need to be linked. This is responsible to split section contents
903// into small chunks for further processing.
904//
905// Note that this function is called from parallel_for_each. This must be
906// thread-safe (i.e. no memory allocation from the pools).
907void MergeInputSection::splitIntoPieces() {
908 ArrayRef<uint8_t> Data = this->Data;
909 uint64_t EntSize = this->Entsize;
910 if (this->Flags & SHF_STRINGS)
911 splitStrings(Data, EntSize);
912 else
913 splitNonStrings(Data, EntSize);
914
915 if (Config->GcSections && (this->Flags & SHF_ALLOC))
916 for (uint64_t Off : LiveOffsets)
917 this->getSectionPiece(Off)->Live = true;
918}
919
920bool MergeInputSection::classof(const SectionBase *S) {
921 return S->kind() == InputSectionBase::Merge;
922}
923
924// Do binary search to get a section piece at a given input offset.
925SectionPiece *MergeInputSection::getSectionPiece(uint64_t Offset) {
926 auto *This = static_cast<const MergeInputSection *>(this);
927 return const_cast<SectionPiece *>(This->getSectionPiece(Offset));
928}
929
930template <class It, class T, class Compare>
931static It fastUpperBound(It First, It Last, const T &Value, Compare Comp) {
932 size_t Size = std::distance(First, Last);
933 assert(Size != 0);
934 while (Size != 1) {
935 size_t H = Size / 2;
936 const It MI = First + H;
937 Size -= H;
938 First = Comp(Value, *MI) ? First : First + H;
939 }
940 return Comp(Value, *First) ? First : First + 1;
941}
942
943const SectionPiece *MergeInputSection::getSectionPiece(uint64_t Offset) const {
944 uint64_t Size = this->Data.size();
945 if (Offset >= Size)
946 fatal(toString(this) + ": entry is past the end of the section");
947
948 // Find the element this offset points to.
949 auto I = fastUpperBound(
950 Pieces.begin(), Pieces.end(), Offset,
951 [](const uint64_t &A, const SectionPiece &B) { return A < B.InputOff; });
952 --I;
953 return &*I;
954}
955
956// Returns the offset in an output section for a given input offset.
957// Because contents of a mergeable section is not contiguous in output,
958// it is not just an addition to a base output offset.
959uint64_t MergeInputSection::getOffset(uint64_t Offset) const {
960 // Initialize OffsetMap lazily.
961 llvm::call_once(InitOffsetMap, [&] {
962 OffsetMap.reserve(Pieces.size());
963 for (const SectionPiece &Piece : Pieces)
964 OffsetMap[Piece.InputOff] = Piece.OutputOff;
965 });
966
967 // Find a string starting at a given offset.
968 auto It = OffsetMap.find(Offset);
969 if (It != OffsetMap.end())
970 return It->second;
971
972 if (!this->Live)
973 return 0;
974
975 // If Offset is not at beginning of a section piece, it is not in the map.
976 // In that case we need to search from the original section piece vector.
977 const SectionPiece &Piece = *this->getSectionPiece(Offset);
978 if (!Piece.Live)
979 return 0;
980
981 uint64_t Addend = Offset - Piece.InputOff;
982 return Piece.OutputOff + Addend;
983}
984
985template InputSection::InputSection(elf::ObjectFile<ELF32LE> *,
986 const ELF32LE::Shdr *, StringRef);
987template InputSection::InputSection(elf::ObjectFile<ELF32BE> *,
988 const ELF32BE::Shdr *, StringRef);
989template InputSection::InputSection(elf::ObjectFile<ELF64LE> *,
990 const ELF64LE::Shdr *, StringRef);
991template InputSection::InputSection(elf::ObjectFile<ELF64BE> *,
992 const ELF64BE::Shdr *, StringRef);
993
994template std::string InputSectionBase::getLocation<ELF32LE>(uint64_t);
995template std::string InputSectionBase::getLocation<ELF32BE>(uint64_t);
996template std::string InputSectionBase::getLocation<ELF64LE>(uint64_t);
997template std::string InputSectionBase::getLocation<ELF64BE>(uint64_t);
998
999template std::string InputSectionBase::getSrcMsg<ELF32LE>(uint64_t);
1000template std::string InputSectionBase::getSrcMsg<ELF32BE>(uint64_t);
1001template std::string InputSectionBase::getSrcMsg<ELF64LE>(uint64_t);
1002template std::string InputSectionBase::getSrcMsg<ELF64BE>(uint64_t);
1003
1004template std::string InputSectionBase::getObjMsg<ELF32LE>(uint64_t);
1005template std::string InputSectionBase::getObjMsg<ELF32BE>(uint64_t);
1006template std::string InputSectionBase::getObjMsg<ELF64LE>(uint64_t);
1007template std::string InputSectionBase::getObjMsg<ELF64BE>(uint64_t);
1008
1009template void InputSection::writeTo<ELF32LE>(uint8_t *);
1010template void InputSection::writeTo<ELF32BE>(uint8_t *);
1011template void InputSection::writeTo<ELF64LE>(uint8_t *);
1012template void InputSection::writeTo<ELF64BE>(uint8_t *);
1013
1014template elf::ObjectFile<ELF32LE> *InputSectionBase::getFile<ELF32LE>() const;
1015template elf::ObjectFile<ELF32BE> *InputSectionBase::getFile<ELF32BE>() const;
1016template elf::ObjectFile<ELF64LE> *InputSectionBase::getFile<ELF64LE>() const;
1017template elf::ObjectFile<ELF64BE> *InputSectionBase::getFile<ELF64BE>() const;
1018
1019template MergeInputSection::MergeInputSection(elf::ObjectFile<ELF32LE> *,
1020 const ELF32LE::Shdr *, StringRef);
1021template MergeInputSection::MergeInputSection(elf::ObjectFile<ELF32BE> *,
1022 const ELF32BE::Shdr *, StringRef);
1023template MergeInputSection::MergeInputSection(elf::ObjectFile<ELF64LE> *,
1024 const ELF64LE::Shdr *, StringRef);
1025template MergeInputSection::MergeInputSection(elf::ObjectFile<ELF64BE> *,
1026 const ELF64BE::Shdr *, StringRef);
1027
1028template EhInputSection::EhInputSection(elf::ObjectFile<ELF32LE> *,
1029 const ELF32LE::Shdr *, StringRef);
1030template EhInputSection::EhInputSection(elf::ObjectFile<ELF32BE> *,
1031 const ELF32BE::Shdr *, StringRef);
1032template EhInputSection::EhInputSection(elf::ObjectFile<ELF64LE> *,
1033 const ELF64LE::Shdr *, StringRef);
1034template EhInputSection::EhInputSection(elf::ObjectFile<ELF64BE> *,
1035 const ELF64BE::Shdr *, StringRef);
1036
1037template void EhInputSection::split<ELF32LE>();
1038template void EhInputSection::split<ELF32BE>();
1039template void EhInputSection::split<ELF64LE>();
1040template void EhInputSection::split<ELF64BE>();
deps/lld/ELF/InputSection.h created+339
......@@ -0,0 +1,339 @@
1//===- InputSection.h -------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_ELF_INPUT_SECTION_H
11#define LLD_ELF_INPUT_SECTION_H
12
13#include "Config.h"
14#include "Relocations.h"
15#include "Thunks.h"
16#include "lld/Core/LLVM.h"
17#include "llvm/ADT/CachedHashString.h"
18#include "llvm/ADT/DenseSet.h"
19#include "llvm/ADT/TinyPtrVector.h"
20#include "llvm/Object/ELF.h"
21#include "llvm/Support/Threading.h"
22#include <mutex>
23
24namespace lld {
25namespace elf {
26
27class DefinedCommon;
28class SymbolBody;
29struct SectionPiece;
30
31class DefinedRegular;
32class SyntheticSection;
33template <class ELFT> class EhFrameSection;
34class MergeSyntheticSection;
35template <class ELFT> class ObjectFile;
36class OutputSection;
37
38// This is the base class of all sections that lld handles. Some are sections in
39// input files, some are sections in the produced output file and some exist
40// just as a convenience for implementing special ways of combining some
41// sections.
42class SectionBase {
43public:
44 enum Kind { Regular, EHFrame, Merge, Synthetic, Output };
45
46 Kind kind() const { return (Kind)SectionKind; }
47
48 StringRef Name;
49
50 unsigned SectionKind : 3;
51
52 // The next two bit fields are only used by InputSectionBase, but we
53 // put them here so the struct packs better.
54
55 // The garbage collector sets sections' Live bits.
56 // If GC is disabled, all sections are considered live by default.
57 unsigned Live : 1; // for garbage collection
58 unsigned Assigned : 1; // for linker script
59
60 uint32_t Alignment;
61
62 // These corresponds to the fields in Elf_Shdr.
63 uint64_t Flags;
64 uint64_t Entsize;
65 uint32_t Type;
66 uint32_t Link;
67 uint32_t Info;
68
69 OutputSection *getOutputSection();
70 const OutputSection *getOutputSection() const {
71 return const_cast<SectionBase *>(this)->getOutputSection();
72 }
73
74 // Translate an offset in the input section to an offset in the output
75 // section.
76 uint64_t getOffset(uint64_t Offset) const;
77
78 uint64_t getOffset(const DefinedRegular &Sym) const;
79
80protected:
81 SectionBase(Kind SectionKind, StringRef Name, uint64_t Flags,
82 uint64_t Entsize, uint64_t Alignment, uint32_t Type,
83 uint32_t Info, uint32_t Link)
84 : Name(Name), SectionKind(SectionKind), Alignment(Alignment),
85 Flags(Flags), Entsize(Entsize), Type(Type), Link(Link), Info(Info) {
86 Live = false;
87 Assigned = false;
88 }
89};
90
91// This corresponds to a section of an input file.
92class InputSectionBase : public SectionBase {
93public:
94 static bool classof(const SectionBase *S);
95
96 // The file this section is from.
97 InputFile *File;
98
99 ArrayRef<uint8_t> Data;
100 uint64_t getOffsetInFile() const;
101
102 static InputSectionBase Discarded;
103
104 InputSectionBase()
105 : SectionBase(Regular, "", /*Flags*/ 0, /*Entsize*/ 0, /*Alignment*/ 0,
106 /*Type*/ 0,
107 /*Info*/ 0, /*Link*/ 0),
108 Repl(this) {
109 Live = false;
110 Assigned = false;
111 NumRelocations = 0;
112 AreRelocsRela = false;
113 }
114
115 template <class ELFT>
116 InputSectionBase(ObjectFile<ELFT> *File, const typename ELFT::Shdr *Header,
117 StringRef Name, Kind SectionKind);
118
119 InputSectionBase(InputFile *File, uint64_t Flags, uint32_t Type,
120 uint64_t Entsize, uint32_t Link, uint32_t Info,
121 uint32_t Alignment, ArrayRef<uint8_t> Data, StringRef Name,
122 Kind SectionKind);
123
124 // Input sections are part of an output section. Special sections
125 // like .eh_frame and merge sections are first combined into a
126 // synthetic section that is then added to an output section. In all
127 // cases this points one level up.
128 SectionBase *Parent = nullptr;
129
130 // Relocations that refer to this section.
131 const void *FirstRelocation = nullptr;
132 unsigned NumRelocations : 31;
133 unsigned AreRelocsRela : 1;
134 template <class ELFT> ArrayRef<typename ELFT::Rel> rels() const {
135 assert(!AreRelocsRela);
136 return llvm::makeArrayRef(
137 static_cast<const typename ELFT::Rel *>(FirstRelocation),
138 NumRelocations);
139 }
140 template <class ELFT> ArrayRef<typename ELFT::Rela> relas() const {
141 assert(AreRelocsRela);
142 return llvm::makeArrayRef(
143 static_cast<const typename ELFT::Rela *>(FirstRelocation),
144 NumRelocations);
145 }
146
147 // This pointer points to the "real" instance of this instance.
148 // Usually Repl == this. However, if ICF merges two sections,
149 // Repl pointer of one section points to another section. So,
150 // if you need to get a pointer to this instance, do not use
151 // this but instead this->Repl.
152 InputSectionBase *Repl;
153
154 // InputSections that are dependent on us (reverse dependency for GC)
155 llvm::TinyPtrVector<InputSectionBase *> DependentSections;
156
157 // Returns the size of this section (even if this is a common or BSS.)
158 size_t getSize() const;
159
160 template <class ELFT> ObjectFile<ELFT> *getFile() const;
161
162 template <class ELFT> llvm::object::ELFFile<ELFT> getObj() const {
163 return getFile<ELFT>()->getObj();
164 }
165
166 InputSection *getLinkOrderDep() const;
167
168 void uncompress();
169
170 // Returns a source location string. Used to construct an error message.
171 template <class ELFT> std::string getLocation(uint64_t Offset);
172 template <class ELFT> std::string getSrcMsg(uint64_t Offset);
173 template <class ELFT> std::string getObjMsg(uint64_t Offset);
174
175 template <class ELFT> void relocate(uint8_t *Buf, uint8_t *BufEnd);
176 void relocateAlloc(uint8_t *Buf, uint8_t *BufEnd);
177 template <class ELFT> void relocateNonAlloc(uint8_t *Buf, uint8_t *BufEnd);
178
179 std::vector<Relocation> Relocations;
180
181 template <typename T> llvm::ArrayRef<T> getDataAs() const {
182 size_t S = Data.size();
183 assert(S % sizeof(T) == 0);
184 return llvm::makeArrayRef<T>((const T *)Data.data(), S / sizeof(T));
185 }
186};
187
188// SectionPiece represents a piece of splittable section contents.
189// We allocate a lot of these and binary search on them. This means that they
190// have to be as compact as possible, which is why we don't store the size (can
191// be found by looking at the next one) and put the hash in a side table.
192struct SectionPiece {
193 SectionPiece(size_t Off, bool Live = false)
194 : InputOff(Off), OutputOff(-1), Live(Live || !Config->GcSections) {}
195
196 size_t InputOff;
197 ssize_t OutputOff : 8 * sizeof(ssize_t) - 1;
198 size_t Live : 1;
199};
200static_assert(sizeof(SectionPiece) == 2 * sizeof(size_t),
201 "SectionPiece is too big");
202
203// This corresponds to a SHF_MERGE section of an input file.
204class MergeInputSection : public InputSectionBase {
205public:
206 template <class ELFT>
207 MergeInputSection(ObjectFile<ELFT> *F, const typename ELFT::Shdr *Header,
208 StringRef Name);
209 static bool classof(const SectionBase *S);
210 void splitIntoPieces();
211
212 // Mark the piece at a given offset live. Used by GC.
213 void markLiveAt(uint64_t Offset) {
214 assert(this->Flags & llvm::ELF::SHF_ALLOC);
215 LiveOffsets.insert(Offset);
216 }
217
218 // Translate an offset in the input section to an offset
219 // in the output section.
220 uint64_t getOffset(uint64_t Offset) const;
221
222 // Splittable sections are handled as a sequence of data
223 // rather than a single large blob of data.
224 std::vector<SectionPiece> Pieces;
225
226 // Returns I'th piece's data. This function is very hot when
227 // string merging is enabled, so we want to inline.
228 LLVM_ATTRIBUTE_ALWAYS_INLINE
229 llvm::CachedHashStringRef getData(size_t I) const {
230 size_t Begin = Pieces[I].InputOff;
231 size_t End;
232 if (Pieces.size() - 1 == I)
233 End = this->Data.size();
234 else
235 End = Pieces[I + 1].InputOff;
236
237 StringRef S = {(const char *)(this->Data.data() + Begin), End - Begin};
238 return {S, Hashes[I]};
239 }
240
241 // Returns the SectionPiece at a given input section offset.
242 SectionPiece *getSectionPiece(uint64_t Offset);
243 const SectionPiece *getSectionPiece(uint64_t Offset) const;
244
245 SyntheticSection *getParent() const;
246
247private:
248 void splitStrings(ArrayRef<uint8_t> A, size_t Size);
249 void splitNonStrings(ArrayRef<uint8_t> A, size_t Size);
250
251 std::vector<uint32_t> Hashes;
252
253 mutable llvm::DenseMap<uint64_t, uint64_t> OffsetMap;
254 mutable llvm::once_flag InitOffsetMap;
255
256 llvm::DenseSet<uint64_t> LiveOffsets;
257};
258
259struct EhSectionPiece : public SectionPiece {
260 EhSectionPiece(size_t Off, InputSectionBase *ID, uint32_t Size,
261 unsigned FirstRelocation)
262 : SectionPiece(Off, false), ID(ID), Size(Size),
263 FirstRelocation(FirstRelocation) {}
264 InputSectionBase *ID;
265 uint32_t Size;
266 uint32_t size() const { return Size; }
267
268 ArrayRef<uint8_t> data() { return {ID->Data.data() + this->InputOff, Size}; }
269 unsigned FirstRelocation;
270};
271
272// This corresponds to a .eh_frame section of an input file.
273class EhInputSection : public InputSectionBase {
274public:
275 template <class ELFT>
276 EhInputSection(ObjectFile<ELFT> *F, const typename ELFT::Shdr *Header,
277 StringRef Name);
278 static bool classof(const SectionBase *S);
279 template <class ELFT> void split();
280 template <class ELFT, class RelTy> void split(ArrayRef<RelTy> Rels);
281
282 // Splittable sections are handled as a sequence of data
283 // rather than a single large blob of data.
284 std::vector<EhSectionPiece> Pieces;
285
286 SyntheticSection *getParent() const;
287};
288
289// This is a section that is added directly to an output section
290// instead of needing special combination via a synthetic section. This
291// includes all input sections with the exceptions of SHF_MERGE and
292// .eh_frame. It also includes the synthetic sections themselves.
293class InputSection : public InputSectionBase {
294public:
295 InputSection(uint64_t Flags, uint32_t Type, uint32_t Alignment,
296 ArrayRef<uint8_t> Data, StringRef Name, Kind K = Regular);
297 template <class ELFT>
298 InputSection(ObjectFile<ELFT> *F, const typename ELFT::Shdr *Header,
299 StringRef Name);
300
301 // Write this section to a mmap'ed file, assuming Buf is pointing to
302 // beginning of the output section.
303 template <class ELFT> void writeTo(uint8_t *Buf);
304
305 OutputSection *getParent() const;
306
307 // The offset from beginning of the output sections this section was assigned
308 // to. The writer sets a value.
309 uint64_t OutSecOff = 0;
310
311 static bool classof(const SectionBase *S);
312
313 InputSectionBase *getRelocatedSection();
314
315 template <class ELFT, class RelTy>
316 void relocateNonAlloc(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);
317
318 // Used by ICF.
319 uint32_t Class[2] = {0, 0};
320
321 // Called by ICF to merge two input sections.
322 void replace(InputSection *Other);
323
324private:
325 template <class ELFT, class RelTy>
326 void copyRelocations(uint8_t *Buf, llvm::ArrayRef<RelTy> Rels);
327
328 template <class ELFT> void copyShtGroup(uint8_t *Buf);
329};
330
331// The list of all input sections.
332extern std::vector<InputSectionBase *> InputSections;
333
334} // namespace elf
335
336std::string toString(const elf::InputSectionBase *);
337} // namespace lld
338
339#endif
deps/lld/ELF/LTO.cpp created+191
......@@ -0,0 +1,191 @@
1//===- LTO.cpp ------------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "LTO.h"
11#include "Config.h"
12#include "Error.h"
13#include "InputFiles.h"
14#include "Symbols.h"
15#include "lld/Core/TargetOptionsCommandFlags.h"
16#include "llvm/ADT/STLExtras.h"
17#include "llvm/ADT/SmallString.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/ADT/Twine.h"
20#include "llvm/BinaryFormat/ELF.h"
21#include "llvm/IR/DiagnosticPrinter.h"
22#include "llvm/LTO/Caching.h"
23#include "llvm/LTO/Config.h"
24#include "llvm/LTO/LTO.h"
25#include "llvm/Object/SymbolicFile.h"
26#include "llvm/Support/CodeGen.h"
27#include "llvm/Support/Error.h"
28#include "llvm/Support/FileSystem.h"
29#include "llvm/Support/MemoryBuffer.h"
30#include "llvm/Support/raw_ostream.h"
31#include <algorithm>
32#include <cstddef>
33#include <memory>
34#include <string>
35#include <system_error>
36#include <vector>
37
38using namespace llvm;
39using namespace llvm::object;
40using namespace llvm::ELF;
41
42using namespace lld;
43using namespace lld::elf;
44
45// This is for use when debugging LTO.
46static void saveBuffer(StringRef Buffer, const Twine &Path) {
47 std::error_code EC;
48 raw_fd_ostream OS(Path.str(), EC, sys::fs::OpenFlags::F_None);
49 if (EC)
50 error("cannot create " + Path + ": " + EC.message());
51 OS << Buffer;
52}
53
54static void diagnosticHandler(const DiagnosticInfo &DI) {
55 SmallString<128> ErrStorage;
56 raw_svector_ostream OS(ErrStorage);
57 DiagnosticPrinterRawOStream DP(OS);
58 DI.print(DP);
59 warn(ErrStorage);
60}
61
62static void checkError(Error E) {
63 handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) -> Error {
64 error(EIB.message());
65 return Error::success();
66 });
67}
68
69static std::unique_ptr<lto::LTO> createLTO() {
70 lto::Config Conf;
71
72 // LLD supports the new relocations.
73 Conf.Options = InitTargetOptionsFromCodeGenFlags();
74 Conf.Options.RelaxELFRelocations = true;
75
76 if (Config->Relocatable)
77 Conf.RelocModel = None;
78 else if (Config->Pic)
79 Conf.RelocModel = Reloc::PIC_;
80 else
81 Conf.RelocModel = Reloc::Static;
82 Conf.CodeModel = GetCodeModelFromCMModel();
83 Conf.DisableVerify = Config->DisableVerify;
84 Conf.DiagHandler = diagnosticHandler;
85 Conf.OptLevel = Config->LTOO;
86
87 // Set up a custom pipeline if we've been asked to.
88 Conf.OptPipeline = Config->LTONewPmPasses;
89 Conf.AAPipeline = Config->LTOAAPipeline;
90
91 // Set up optimization remarks if we've been asked to.
92 Conf.RemarksFilename = Config->OptRemarksFilename;
93 Conf.RemarksWithHotness = Config->OptRemarksWithHotness;
94
95 if (Config->SaveTemps)
96 checkError(Conf.addSaveTemps(std::string(Config->OutputFile) + ".",
97 /*UseInputModulePath*/ true));
98
99 lto::ThinBackend Backend;
100 if (Config->ThinLTOJobs != -1u)
101 Backend = lto::createInProcessThinBackend(Config->ThinLTOJobs);
102 return llvm::make_unique<lto::LTO>(std::move(Conf), Backend,
103 Config->LTOPartitions);
104}
105
106BitcodeCompiler::BitcodeCompiler() : LTOObj(createLTO()) {}
107
108BitcodeCompiler::~BitcodeCompiler() = default;
109
110static void undefine(Symbol *S) {
111 replaceBody<Undefined>(S, S->body()->getName(), /*IsLocal=*/false,
112 STV_DEFAULT, S->body()->Type, nullptr);
113}
114
115void BitcodeCompiler::add(BitcodeFile &F) {
116 lto::InputFile &Obj = *F.Obj;
117 unsigned SymNum = 0;
118 std::vector<Symbol *> Syms = F.getSymbols();
119 std::vector<lto::SymbolResolution> Resols(Syms.size());
120
121 // Provide a resolution to the LTO API for each symbol.
122 for (const lto::InputFile::Symbol &ObjSym : Obj.symbols()) {
123 Symbol *Sym = Syms[SymNum];
124 lto::SymbolResolution &R = Resols[SymNum];
125 ++SymNum;
126 SymbolBody *B = Sym->body();
127
128 // Ideally we shouldn't check for SF_Undefined but currently IRObjectFile
129 // reports two symbols for module ASM defined. Without this check, lld
130 // flags an undefined in IR with a definition in ASM as prevailing.
131 // Once IRObjectFile is fixed to report only one symbol this hack can
132 // be removed.
133 R.Prevailing = !ObjSym.isUndefined() && B->File == &F;
134
135 R.VisibleToRegularObj =
136 Sym->IsUsedInRegularObj || (R.Prevailing && Sym->includeInDynsym());
137 if (R.Prevailing)
138 undefine(Sym);
139 R.LinkerRedefined = Config->RenamedSymbols.count(Sym);
140 }
141 checkError(LTOObj->add(std::move(F.Obj), Resols));
142}
143
144// Merge all the bitcode files we have seen, codegen the result
145// and return the resulting ObjectFile(s).
146std::vector<InputFile *> BitcodeCompiler::compile() {
147 std::vector<InputFile *> Ret;
148 unsigned MaxTasks = LTOObj->getMaxTasks();
149 Buff.resize(MaxTasks);
150 Files.resize(MaxTasks);
151
152 // The --thinlto-cache-dir option specifies the path to a directory in which
153 // to cache native object files for ThinLTO incremental builds. If a path was
154 // specified, configure LTO to use it as the cache directory.
155 lto::NativeObjectCache Cache;
156 if (!Config->ThinLTOCacheDir.empty())
157 Cache = check(
158 lto::localCache(Config->ThinLTOCacheDir,
159 [&](size_t Task, std::unique_ptr<MemoryBuffer> MB) {
160 Files[Task] = std::move(MB);
161 }));
162
163 checkError(LTOObj->run(
164 [&](size_t Task) {
165 return llvm::make_unique<lto::NativeObjectStream>(
166 llvm::make_unique<raw_svector_ostream>(Buff[Task]));
167 },
168 Cache));
169
170 if (!Config->ThinLTOCacheDir.empty())
171 pruneCache(Config->ThinLTOCacheDir, Config->ThinLTOCachePolicy);
172
173 for (unsigned I = 0; I != MaxTasks; ++I) {
174 if (Buff[I].empty())
175 continue;
176 if (Config->SaveTemps) {
177 if (I == 0)
178 saveBuffer(Buff[I], Config->OutputFile + ".lto.o");
179 else
180 saveBuffer(Buff[I], Config->OutputFile + Twine(I) + ".lto.o");
181 }
182 InputFile *Obj = createObjectFile(MemoryBufferRef(Buff[I], "lto.tmp"));
183 Ret.push_back(Obj);
184 }
185
186 for (std::unique_ptr<MemoryBuffer> &File : Files)
187 if (File)
188 Ret.push_back(createObjectFile(*File));
189
190 return Ret;
191}
deps/lld/ELF/LTO.h created+57
......@@ -0,0 +1,57 @@
1//===- LTO.h ----------------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file provides a way to combine bitcode files into one ELF
11// file by compiling them using LLVM.
12//
13// If LTO is in use, your input files are not in regular ELF files
14// but instead LLVM bitcode files. In that case, the linker has to
15// convert bitcode files into the native format so that we can create
16// an ELF file that contains native code. This file provides that
17// functionality.
18//
19//===----------------------------------------------------------------------===//
20
21#ifndef LLD_ELF_LTO_H
22#define LLD_ELF_LTO_H
23
24#include "lld/Core/LLVM.h"
25#include "llvm/ADT/SmallString.h"
26#include <memory>
27#include <vector>
28
29namespace llvm {
30namespace lto {
31class LTO;
32}
33} // namespace llvm
34
35namespace lld {
36namespace elf {
37
38class BitcodeFile;
39class InputFile;
40
41class BitcodeCompiler {
42public:
43 BitcodeCompiler();
44 ~BitcodeCompiler();
45
46 void add(BitcodeFile &F);
47 std::vector<InputFile *> compile();
48
49private:
50 std::unique_ptr<llvm::lto::LTO> LTOObj;
51 std::vector<SmallString<0>> Buff;
52 std::vector<std::unique_ptr<MemoryBuffer>> Files;
53};
54} // namespace elf
55} // namespace lld
56
57#endif
deps/lld/ELF/LinkerScript.cpp created+1255
......@@ -0,0 +1,1255 @@
1//===- LinkerScript.cpp ---------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains the parser/evaluator of the linker script.
11//
12//===----------------------------------------------------------------------===//
13
14#include "LinkerScript.h"
15#include "Config.h"
16#include "InputSection.h"
17#include "Memory.h"
18#include "OutputSections.h"
19#include "Strings.h"
20#include "SymbolTable.h"
21#include "Symbols.h"
22#include "SyntheticSections.h"
23#include "Target.h"
24#include "Threads.h"
25#include "Writer.h"
26#include "llvm/ADT/STLExtras.h"
27#include "llvm/ADT/StringRef.h"
28#include "llvm/BinaryFormat/ELF.h"
29#include "llvm/Support/Casting.h"
30#include "llvm/Support/Compression.h"
31#include "llvm/Support/Endian.h"
32#include "llvm/Support/ErrorHandling.h"
33#include "llvm/Support/FileSystem.h"
34#include "llvm/Support/Path.h"
35#include <algorithm>
36#include <cassert>
37#include <cstddef>
38#include <cstdint>
39#include <iterator>
40#include <limits>
41#include <string>
42#include <vector>
43
44using namespace llvm;
45using namespace llvm::ELF;
46using namespace llvm::object;
47using namespace llvm::support::endian;
48using namespace lld;
49using namespace lld::elf;
50
51LinkerScript *elf::Script;
52
53uint64_t ExprValue::getValue() const {
54 if (Sec) {
55 if (OutputSection *OS = Sec->getOutputSection())
56 return alignTo(Sec->getOffset(Val) + OS->Addr, Alignment);
57 error(Loc + ": unable to evaluate expression: input section " + Sec->Name +
58 " has no output section assigned");
59 }
60 return alignTo(Val, Alignment);
61}
62
63uint64_t ExprValue::getSecAddr() const {
64 if (Sec)
65 return Sec->getOffset(0) + Sec->getOutputSection()->Addr;
66 return 0;
67}
68
69template <class ELFT> static SymbolBody *addRegular(SymbolAssignment *Cmd) {
70 Symbol *Sym;
71 uint8_t Visibility = Cmd->Hidden ? STV_HIDDEN : STV_DEFAULT;
72 std::tie(Sym, std::ignore) = Symtab<ELFT>::X->insert(
73 Cmd->Name, /*Type*/ 0, Visibility, /*CanOmitFromDynSym*/ false,
74 /*File*/ nullptr);
75 Sym->Binding = STB_GLOBAL;
76 ExprValue Value = Cmd->Expression();
77 SectionBase *Sec = Value.isAbsolute() ? nullptr : Value.Sec;
78
79 // We want to set symbol values early if we can. This allows us to use symbols
80 // as variables in linker scripts. Doing so allows us to write expressions
81 // like this: `alignment = 16; . = ALIGN(., alignment)`
82 uint64_t SymValue = Value.isAbsolute() ? Value.getValue() : 0;
83 replaceBody<DefinedRegular>(Sym, Cmd->Name, /*IsLocal=*/false, Visibility,
84 STT_NOTYPE, SymValue, 0, Sec, nullptr);
85 return Sym->body();
86}
87
88OutputSectionCommand *
89LinkerScript::createOutputSectionCommand(StringRef Name, StringRef Location) {
90 OutputSectionCommand *&CmdRef = NameToOutputSectionCommand[Name];
91 OutputSectionCommand *Cmd;
92 if (CmdRef && CmdRef->Location.empty()) {
93 // There was a forward reference.
94 Cmd = CmdRef;
95 } else {
96 Cmd = make<OutputSectionCommand>(Name);
97 if (!CmdRef)
98 CmdRef = Cmd;
99 }
100 Cmd->Location = Location;
101 return Cmd;
102}
103
104OutputSectionCommand *
105LinkerScript::getOrCreateOutputSectionCommand(StringRef Name) {
106 OutputSectionCommand *&CmdRef = NameToOutputSectionCommand[Name];
107 if (!CmdRef)
108 CmdRef = make<OutputSectionCommand>(Name);
109 return CmdRef;
110}
111
112void LinkerScript::setDot(Expr E, const Twine &Loc, bool InSec) {
113 uint64_t Val = E().getValue();
114 if (Val < Dot && InSec)
115 error(Loc + ": unable to move location counter backward for: " +
116 CurAddressState->OutSec->Name);
117 Dot = Val;
118 // Update to location counter means update to section size.
119 if (InSec)
120 CurAddressState->OutSec->Size = Dot - CurAddressState->OutSec->Addr;
121}
122
123// Sets value of a symbol. Two kinds of symbols are processed: synthetic
124// symbols, whose value is an offset from beginning of section and regular
125// symbols whose value is absolute.
126void LinkerScript::assignSymbol(SymbolAssignment *Cmd, bool InSec) {
127 if (Cmd->Name == ".") {
128 setDot(Cmd->Expression, Cmd->Location, InSec);
129 return;
130 }
131
132 if (!Cmd->Sym)
133 return;
134
135 auto *Sym = cast<DefinedRegular>(Cmd->Sym);
136 ExprValue V = Cmd->Expression();
137 if (V.isAbsolute()) {
138 Sym->Value = V.getValue();
139 } else {
140 Sym->Section = V.Sec;
141 Sym->Value = alignTo(V.Val, V.Alignment);
142 }
143}
144
145static SymbolBody *findSymbol(StringRef S) {
146 switch (Config->EKind) {
147 case ELF32LEKind:
148 return Symtab<ELF32LE>::X->find(S);
149 case ELF32BEKind:
150 return Symtab<ELF32BE>::X->find(S);
151 case ELF64LEKind:
152 return Symtab<ELF64LE>::X->find(S);
153 case ELF64BEKind:
154 return Symtab<ELF64BE>::X->find(S);
155 default:
156 llvm_unreachable("unknown Config->EKind");
157 }
158}
159
160static SymbolBody *addRegularSymbol(SymbolAssignment *Cmd) {
161 switch (Config->EKind) {
162 case ELF32LEKind:
163 return addRegular<ELF32LE>(Cmd);
164 case ELF32BEKind:
165 return addRegular<ELF32BE>(Cmd);
166 case ELF64LEKind:
167 return addRegular<ELF64LE>(Cmd);
168 case ELF64BEKind:
169 return addRegular<ELF64BE>(Cmd);
170 default:
171 llvm_unreachable("unknown Config->EKind");
172 }
173}
174
175void LinkerScript::addSymbol(SymbolAssignment *Cmd) {
176 if (Cmd->Name == ".")
177 return;
178
179 // If a symbol was in PROVIDE(), we need to define it only when
180 // it is a referenced undefined symbol.
181 SymbolBody *B = findSymbol(Cmd->Name);
182 if (Cmd->Provide && (!B || B->isDefined()))
183 return;
184
185 Cmd->Sym = addRegularSymbol(Cmd);
186}
187
188bool SymbolAssignment::classof(const BaseCommand *C) {
189 return C->Kind == AssignmentKind;
190}
191
192bool OutputSectionCommand::classof(const BaseCommand *C) {
193 return C->Kind == OutputSectionKind;
194}
195
196// Fill [Buf, Buf + Size) with Filler.
197// This is used for linker script "=fillexp" command.
198static void fill(uint8_t *Buf, size_t Size, uint32_t Filler) {
199 size_t I = 0;
200 for (; I + 4 < Size; I += 4)
201 memcpy(Buf + I, &Filler, 4);
202 memcpy(Buf + I, &Filler, Size - I);
203}
204
205bool InputSectionDescription::classof(const BaseCommand *C) {
206 return C->Kind == InputSectionKind;
207}
208
209bool AssertCommand::classof(const BaseCommand *C) {
210 return C->Kind == AssertKind;
211}
212
213bool BytesDataCommand::classof(const BaseCommand *C) {
214 return C->Kind == BytesDataKind;
215}
216
217static StringRef basename(InputSectionBase *S) {
218 if (S->File)
219 return sys::path::filename(S->File->getName());
220 return "";
221}
222
223bool LinkerScript::shouldKeep(InputSectionBase *S) {
224 for (InputSectionDescription *ID : Opt.KeptSections)
225 if (ID->FilePat.match(basename(S)))
226 for (SectionPattern &P : ID->SectionPatterns)
227 if (P.SectionPat.match(S->Name))
228 return true;
229 return false;
230}
231
232// If an input string is in the form of "foo.N" where N is a number,
233// return N. Otherwise, returns 65536, which is one greater than the
234// lowest priority.
235static int getPriority(StringRef S) {
236 size_t Pos = S.rfind('.');
237 if (Pos == StringRef::npos)
238 return 65536;
239 int V;
240 if (!to_integer(S.substr(Pos + 1), V, 10))
241 return 65536;
242 return V;
243}
244
245// A helper function for the SORT() command.
246static std::function<bool(InputSectionBase *, InputSectionBase *)>
247getComparator(SortSectionPolicy K) {
248 switch (K) {
249 case SortSectionPolicy::Alignment:
250 return [](InputSectionBase *A, InputSectionBase *B) {
251 // ">" is not a mistake. Sections with larger alignments are placed
252 // before sections with smaller alignments in order to reduce the
253 // amount of padding necessary. This is compatible with GNU.
254 return A->Alignment > B->Alignment;
255 };
256 case SortSectionPolicy::Name:
257 return [](InputSectionBase *A, InputSectionBase *B) {
258 return A->Name < B->Name;
259 };
260 case SortSectionPolicy::Priority:
261 return [](InputSectionBase *A, InputSectionBase *B) {
262 return getPriority(A->Name) < getPriority(B->Name);
263 };
264 default:
265 llvm_unreachable("unknown sort policy");
266 }
267}
268
269// A helper function for the SORT() command.
270static bool matchConstraints(ArrayRef<InputSectionBase *> Sections,
271 ConstraintKind Kind) {
272 if (Kind == ConstraintKind::NoConstraint)
273 return true;
274
275 bool IsRW = llvm::any_of(Sections, [](InputSectionBase *Sec) {
276 return static_cast<InputSectionBase *>(Sec)->Flags & SHF_WRITE;
277 });
278
279 return (IsRW && Kind == ConstraintKind::ReadWrite) ||
280 (!IsRW && Kind == ConstraintKind::ReadOnly);
281}
282
283static void sortSections(InputSection **Begin, InputSection **End,
284 SortSectionPolicy K) {
285 if (K != SortSectionPolicy::Default && K != SortSectionPolicy::None)
286 std::stable_sort(Begin, End, getComparator(K));
287}
288
289// Compute and remember which sections the InputSectionDescription matches.
290std::vector<InputSection *>
291LinkerScript::computeInputSections(const InputSectionDescription *Cmd) {
292 std::vector<InputSection *> Ret;
293
294 // Collects all sections that satisfy constraints of Cmd.
295 for (const SectionPattern &Pat : Cmd->SectionPatterns) {
296 size_t SizeBefore = Ret.size();
297
298 for (InputSectionBase *Sec : InputSections) {
299 if (Sec->Assigned)
300 continue;
301
302 if (!Sec->Live) {
303 reportDiscarded(Sec);
304 continue;
305 }
306
307 // For -emit-relocs we have to ignore entries like
308 // .rela.dyn : { *(.rela.data) }
309 // which are common because they are in the default bfd script.
310 if (Sec->Type == SHT_REL || Sec->Type == SHT_RELA)
311 continue;
312
313 StringRef Filename = basename(Sec);
314 if (!Cmd->FilePat.match(Filename) ||
315 Pat.ExcludedFilePat.match(Filename) ||
316 !Pat.SectionPat.match(Sec->Name))
317 continue;
318
319 Ret.push_back(cast<InputSection>(Sec));
320 Sec->Assigned = true;
321 }
322
323 // Sort sections as instructed by SORT-family commands and --sort-section
324 // option. Because SORT-family commands can be nested at most two depth
325 // (e.g. SORT_BY_NAME(SORT_BY_ALIGNMENT(.text.*))) and because the command
326 // line option is respected even if a SORT command is given, the exact
327 // behavior we have here is a bit complicated. Here are the rules.
328 //
329 // 1. If two SORT commands are given, --sort-section is ignored.
330 // 2. If one SORT command is given, and if it is not SORT_NONE,
331 // --sort-section is handled as an inner SORT command.
332 // 3. If one SORT command is given, and if it is SORT_NONE, don't sort.
333 // 4. If no SORT command is given, sort according to --sort-section.
334 InputSection **Begin = Ret.data() + SizeBefore;
335 InputSection **End = Ret.data() + Ret.size();
336 if (Pat.SortOuter != SortSectionPolicy::None) {
337 if (Pat.SortInner == SortSectionPolicy::Default)
338 sortSections(Begin, End, Config->SortSection);
339 else
340 sortSections(Begin, End, Pat.SortInner);
341 sortSections(Begin, End, Pat.SortOuter);
342 }
343 }
344 return Ret;
345}
346
347void LinkerScript::discard(ArrayRef<InputSectionBase *> V) {
348 for (InputSectionBase *S : V) {
349 S->Live = false;
350 if (S == InX::ShStrTab || S == InX::Dynamic || S == InX::DynSymTab ||
351 S == InX::DynStrTab)
352 error("discarding " + S->Name + " section is not allowed");
353 discard(S->DependentSections);
354 }
355}
356
357std::vector<InputSectionBase *>
358LinkerScript::createInputSectionList(OutputSectionCommand &OutCmd) {
359 std::vector<InputSectionBase *> Ret;
360
361 for (BaseCommand *Base : OutCmd.Commands) {
362 auto *Cmd = dyn_cast<InputSectionDescription>(Base);
363 if (!Cmd)
364 continue;
365
366 Cmd->Sections = computeInputSections(Cmd);
367 Ret.insert(Ret.end(), Cmd->Sections.begin(), Cmd->Sections.end());
368 }
369
370 return Ret;
371}
372
373void LinkerScript::processCommands(OutputSectionFactory &Factory) {
374 // A symbol can be assigned before any section is mentioned in the linker
375 // script. In an DSO, the symbol values are addresses, so the only important
376 // section values are:
377 // * SHN_UNDEF
378 // * SHN_ABS
379 // * Any value meaning a regular section.
380 // To handle that, create a dummy aether section that fills the void before
381 // the linker scripts switches to another section. It has an index of one
382 // which will map to whatever the first actual section is.
383 Aether = make<OutputSection>("", 0, SHF_ALLOC);
384 Aether->SectionIndex = 1;
385 auto State = make_unique<AddressState>(Opt);
386 // CurAddressState captures the local AddressState and makes it accessible
387 // deliberately. This is needed as there are some cases where we cannot just
388 // thread the current state through to a lambda function created by the
389 // script parser.
390 CurAddressState = State.get();
391 CurAddressState->OutSec = Aether;
392 Dot = 0;
393
394 for (size_t I = 0; I < Opt.Commands.size(); ++I) {
395 // Handle symbol assignments outside of any output section.
396 if (auto *Cmd = dyn_cast<SymbolAssignment>(Opt.Commands[I])) {
397 addSymbol(Cmd);
398 continue;
399 }
400
401 if (auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I])) {
402 std::vector<InputSectionBase *> V = createInputSectionList(*Cmd);
403
404 // The output section name `/DISCARD/' is special.
405 // Any input section assigned to it is discarded.
406 if (Cmd->Name == "/DISCARD/") {
407 discard(V);
408 continue;
409 }
410
411 // This is for ONLY_IF_RO and ONLY_IF_RW. An output section directive
412 // ".foo : ONLY_IF_R[OW] { ... }" is handled only if all member input
413 // sections satisfy a given constraint. If not, a directive is handled
414 // as if it wasn't present from the beginning.
415 //
416 // Because we'll iterate over Commands many more times, the easiest
417 // way to "make it as if it wasn't present" is to just remove it.
418 if (!matchConstraints(V, Cmd->Constraint)) {
419 for (InputSectionBase *S : V)
420 S->Assigned = false;
421 Opt.Commands.erase(Opt.Commands.begin() + I);
422 --I;
423 continue;
424 }
425
426 // A directive may contain symbol definitions like this:
427 // ".foo : { ...; bar = .; }". Handle them.
428 for (BaseCommand *Base : Cmd->Commands)
429 if (auto *OutCmd = dyn_cast<SymbolAssignment>(Base))
430 addSymbol(OutCmd);
431
432 // Handle subalign (e.g. ".foo : SUBALIGN(32) { ... }"). If subalign
433 // is given, input sections are aligned to that value, whether the
434 // given value is larger or smaller than the original section alignment.
435 if (Cmd->SubalignExpr) {
436 uint32_t Subalign = Cmd->SubalignExpr().getValue();
437 for (InputSectionBase *S : V)
438 S->Alignment = Subalign;
439 }
440
441 // Add input sections to an output section.
442 for (InputSectionBase *S : V)
443 Factory.addInputSec(S, Cmd->Name, Cmd->Sec);
444 if (OutputSection *Sec = Cmd->Sec) {
445 assert(Sec->SectionIndex == INT_MAX);
446 Sec->SectionIndex = I;
447 if (Cmd->Noload)
448 Sec->Type = SHT_NOBITS;
449 SecToCommand[Sec] = Cmd;
450 }
451 }
452 }
453 CurAddressState = nullptr;
454}
455
456void LinkerScript::fabricateDefaultCommands() {
457 std::vector<BaseCommand *> Commands;
458
459 // Define start address
460 uint64_t StartAddr = -1;
461
462 // The Sections with -T<section> have been sorted in order of ascending
463 // address. We must lower StartAddr if the lowest -T<section address> as
464 // calls to setDot() must be monotonically increasing.
465 for (auto &KV : Config->SectionStartMap)
466 StartAddr = std::min(StartAddr, KV.second);
467
468 Commands.push_back(make<SymbolAssignment>(
469 ".",
470 [=] {
471 return std::min(StartAddr, Config->ImageBase + elf::getHeaderSize());
472 },
473 ""));
474
475 // For each OutputSection that needs a VA fabricate an OutputSectionCommand
476 // with an InputSectionDescription describing the InputSections
477 for (OutputSection *Sec : OutputSections) {
478 auto *OSCmd = createOutputSectionCommand(Sec->Name, "<internal>");
479 OSCmd->Sec = Sec;
480 SecToCommand[Sec] = OSCmd;
481
482 Commands.push_back(OSCmd);
483 if (Sec->Sections.size()) {
484 auto *ISD = make<InputSectionDescription>("");
485 OSCmd->Commands.push_back(ISD);
486 for (InputSection *ISec : Sec->Sections) {
487 ISD->Sections.push_back(ISec);
488 ISec->Assigned = true;
489 }
490 }
491 }
492 // SECTIONS commands run before other non SECTIONS commands
493 Commands.insert(Commands.end(), Opt.Commands.begin(), Opt.Commands.end());
494 Opt.Commands = std::move(Commands);
495}
496
497// Add sections that didn't match any sections command.
498void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) {
499 unsigned NumCommands = Opt.Commands.size();
500 for (InputSectionBase *S : InputSections) {
501 if (!S->Live || S->Parent)
502 continue;
503 StringRef Name = getOutputSectionName(S->Name);
504 auto End = Opt.Commands.begin() + NumCommands;
505 auto I = std::find_if(Opt.Commands.begin(), End, [&](BaseCommand *Base) {
506 if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
507 return Cmd->Name == Name;
508 return false;
509 });
510 OutputSectionCommand *Cmd;
511 if (I == End) {
512 Factory.addInputSec(S, Name);
513 OutputSection *Sec = S->getOutputSection();
514 assert(Sec->SectionIndex == INT_MAX);
515 OutputSectionCommand *&CmdRef = SecToCommand[Sec];
516 if (!CmdRef) {
517 CmdRef = createOutputSectionCommand(Sec->Name, "<internal>");
518 CmdRef->Sec = Sec;
519 Opt.Commands.push_back(CmdRef);
520 }
521 Cmd = CmdRef;
522 } else {
523 Cmd = cast<OutputSectionCommand>(*I);
524 Factory.addInputSec(S, Name, Cmd->Sec);
525 if (OutputSection *Sec = Cmd->Sec) {
526 SecToCommand[Sec] = Cmd;
527 unsigned Index = std::distance(Opt.Commands.begin(), I);
528 assert(Sec->SectionIndex == INT_MAX || Sec->SectionIndex == Index);
529 Sec->SectionIndex = Index;
530 }
531 }
532 auto *ISD = make<InputSectionDescription>("");
533 ISD->Sections.push_back(cast<InputSection>(S));
534 Cmd->Commands.push_back(ISD);
535 }
536}
537
538uint64_t LinkerScript::advance(uint64_t Size, unsigned Align) {
539 bool IsTbss = (CurAddressState->OutSec->Flags & SHF_TLS) &&
540 CurAddressState->OutSec->Type == SHT_NOBITS;
541 uint64_t Start = IsTbss ? Dot + CurAddressState->ThreadBssOffset : Dot;
542 Start = alignTo(Start, Align);
543 uint64_t End = Start + Size;
544
545 if (IsTbss)
546 CurAddressState->ThreadBssOffset = End - Dot;
547 else
548 Dot = End;
549 return End;
550}
551
552void LinkerScript::output(InputSection *S) {
553 uint64_t Pos = advance(S->getSize(), S->Alignment);
554 S->OutSecOff = Pos - S->getSize() - CurAddressState->OutSec->Addr;
555
556 // Update output section size after adding each section. This is so that
557 // SIZEOF works correctly in the case below:
558 // .foo { *(.aaa) a = SIZEOF(.foo); *(.bbb) }
559 CurAddressState->OutSec->Size = Pos - CurAddressState->OutSec->Addr;
560
561 // If there is a memory region associated with this input section, then
562 // place the section in that region and update the region index.
563 if (CurAddressState->MemRegion) {
564 uint64_t &CurOffset =
565 CurAddressState->MemRegionOffset[CurAddressState->MemRegion];
566 CurOffset += CurAddressState->OutSec->Size;
567 uint64_t CurSize = CurOffset - CurAddressState->MemRegion->Origin;
568 if (CurSize > CurAddressState->MemRegion->Length) {
569 uint64_t OverflowAmt = CurSize - CurAddressState->MemRegion->Length;
570 error("section '" + CurAddressState->OutSec->Name +
571 "' will not fit in region '" + CurAddressState->MemRegion->Name +
572 "': overflowed by " + Twine(OverflowAmt) + " bytes");
573 }
574 }
575}
576
577void LinkerScript::switchTo(OutputSection *Sec) {
578 if (CurAddressState->OutSec == Sec)
579 return;
580
581 CurAddressState->OutSec = Sec;
582 CurAddressState->OutSec->Addr =
583 advance(0, CurAddressState->OutSec->Alignment);
584
585 // If neither AT nor AT> is specified for an allocatable section, the linker
586 // will set the LMA such that the difference between VMA and LMA for the
587 // section is the same as the preceding output section in the same region
588 // https://sourceware.org/binutils/docs-2.20/ld/Output-Section-LMA.html
589 if (CurAddressState->LMAOffset)
590 CurAddressState->OutSec->LMAOffset = CurAddressState->LMAOffset();
591}
592
593void LinkerScript::process(BaseCommand &Base) {
594 // This handles the assignments to symbol or to the dot.
595 if (auto *Cmd = dyn_cast<SymbolAssignment>(&Base)) {
596 assignSymbol(Cmd, true);
597 return;
598 }
599
600 // Handle BYTE(), SHORT(), LONG(), or QUAD().
601 if (auto *Cmd = dyn_cast<BytesDataCommand>(&Base)) {
602 Cmd->Offset = Dot - CurAddressState->OutSec->Addr;
603 Dot += Cmd->Size;
604 CurAddressState->OutSec->Size = Dot - CurAddressState->OutSec->Addr;
605 return;
606 }
607
608 // Handle ASSERT().
609 if (auto *Cmd = dyn_cast<AssertCommand>(&Base)) {
610 Cmd->Expression();
611 return;
612 }
613
614 // Handle a single input section description command.
615 // It calculates and assigns the offsets for each section and also
616 // updates the output section size.
617 auto &Cmd = cast<InputSectionDescription>(Base);
618 for (InputSection *Sec : Cmd.Sections) {
619 // We tentatively added all synthetic sections at the beginning and removed
620 // empty ones afterwards (because there is no way to know whether they were
621 // going be empty or not other than actually running linker scripts.)
622 // We need to ignore remains of empty sections.
623 if (auto *S = dyn_cast<SyntheticSection>(Sec))
624 if (S->empty())
625 continue;
626
627 if (!Sec->Live)
628 continue;
629 assert(CurAddressState->OutSec == Sec->getParent());
630 output(Sec);
631 }
632}
633
634// This function searches for a memory region to place the given output
635// section in. If found, a pointer to the appropriate memory region is
636// returned. Otherwise, a nullptr is returned.
637MemoryRegion *LinkerScript::findMemoryRegion(OutputSectionCommand *Cmd) {
638 // If a memory region name was specified in the output section command,
639 // then try to find that region first.
640 if (!Cmd->MemoryRegionName.empty()) {
641 auto It = Opt.MemoryRegions.find(Cmd->MemoryRegionName);
642 if (It != Opt.MemoryRegions.end())
643 return &It->second;
644 error("memory region '" + Cmd->MemoryRegionName + "' not declared");
645 return nullptr;
646 }
647
648 // If at least one memory region is defined, all sections must
649 // belong to some memory region. Otherwise, we don't need to do
650 // anything for memory regions.
651 if (Opt.MemoryRegions.empty())
652 return nullptr;
653
654 OutputSection *Sec = Cmd->Sec;
655 // See if a region can be found by matching section flags.
656 for (auto &Pair : Opt.MemoryRegions) {
657 MemoryRegion &M = Pair.second;
658 if ((M.Flags & Sec->Flags) && (M.NegFlags & Sec->Flags) == 0)
659 return &M;
660 }
661
662 // Otherwise, no suitable region was found.
663 if (Sec->Flags & SHF_ALLOC)
664 error("no memory region specified for section '" + Sec->Name + "'");
665 return nullptr;
666}
667
668// This function assigns offsets to input sections and an output section
669// for a single sections command (e.g. ".text { *(.text); }").
670void LinkerScript::assignOffsets(OutputSectionCommand *Cmd) {
671 OutputSection *Sec = Cmd->Sec;
672 if (!Sec)
673 return;
674
675 if (!(Sec->Flags & SHF_ALLOC))
676 Dot = 0;
677 else if (Cmd->AddrExpr)
678 setDot(Cmd->AddrExpr, Cmd->Location, false);
679
680 if (Cmd->LMAExpr) {
681 uint64_t D = Dot;
682 CurAddressState->LMAOffset = [=] { return Cmd->LMAExpr().getValue() - D; };
683 }
684
685 CurAddressState->MemRegion = Cmd->MemRegion;
686 if (CurAddressState->MemRegion)
687 Dot = CurAddressState->MemRegionOffset[CurAddressState->MemRegion];
688 switchTo(Sec);
689
690 // We do not support custom layout for compressed debug sectons.
691 // At this point we already know their size and have compressed content.
692 if (CurAddressState->OutSec->Flags & SHF_COMPRESSED)
693 return;
694
695 for (BaseCommand *C : Cmd->Commands)
696 process(*C);
697}
698
699void LinkerScript::removeEmptyCommands() {
700 // It is common practice to use very generic linker scripts. So for any
701 // given run some of the output sections in the script will be empty.
702 // We could create corresponding empty output sections, but that would
703 // clutter the output.
704 // We instead remove trivially empty sections. The bfd linker seems even
705 // more aggressive at removing them.
706 auto Pos = std::remove_if(
707 Opt.Commands.begin(), Opt.Commands.end(), [&](BaseCommand *Base) {
708 if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
709 return Cmd->Sec == nullptr;
710 return false;
711 });
712 Opt.Commands.erase(Pos, Opt.Commands.end());
713}
714
715static bool isAllSectionDescription(const OutputSectionCommand &Cmd) {
716 for (BaseCommand *Base : Cmd.Commands)
717 if (!isa<InputSectionDescription>(*Base))
718 return false;
719 return true;
720}
721
722void LinkerScript::adjustSectionsBeforeSorting() {
723 // If the output section contains only symbol assignments, create a
724 // corresponding output section. The bfd linker seems to only create them if
725 // '.' is assigned to, but creating these section should not have any bad
726 // consequeces and gives us a section to put the symbol in.
727 uint64_t Flags = SHF_ALLOC;
728
729 for (int I = 0, E = Opt.Commands.size(); I != E; ++I) {
730 auto *Cmd = dyn_cast<OutputSectionCommand>(Opt.Commands[I]);
731 if (!Cmd)
732 continue;
733 if (OutputSection *Sec = Cmd->Sec) {
734 Flags = Sec->Flags;
735 continue;
736 }
737
738 if (isAllSectionDescription(*Cmd))
739 continue;
740
741 auto *OutSec = make<OutputSection>(Cmd->Name, SHT_PROGBITS, Flags);
742 OutSec->SectionIndex = I;
743 Cmd->Sec = OutSec;
744 SecToCommand[OutSec] = Cmd;
745 }
746}
747
748void LinkerScript::adjustSectionsAfterSorting() {
749 // Try and find an appropriate memory region to assign offsets in.
750 for (BaseCommand *Base : Opt.Commands) {
751 if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base)) {
752 Cmd->MemRegion = findMemoryRegion(Cmd);
753 // Handle align (e.g. ".foo : ALIGN(16) { ... }").
754 if (Cmd->AlignExpr)
755 Cmd->Sec->updateAlignment(Cmd->AlignExpr().getValue());
756 }
757 }
758
759 // If output section command doesn't specify any segments,
760 // and we haven't previously assigned any section to segment,
761 // then we simply assign section to the very first load segment.
762 // Below is an example of such linker script:
763 // PHDRS { seg PT_LOAD; }
764 // SECTIONS { .aaa : { *(.aaa) } }
765 std::vector<StringRef> DefPhdrs;
766 auto FirstPtLoad =
767 std::find_if(Opt.PhdrsCommands.begin(), Opt.PhdrsCommands.end(),
768 [](const PhdrsCommand &Cmd) { return Cmd.Type == PT_LOAD; });
769 if (FirstPtLoad != Opt.PhdrsCommands.end())
770 DefPhdrs.push_back(FirstPtLoad->Name);
771
772 // Walk the commands and propagate the program headers to commands that don't
773 // explicitly specify them.
774 for (BaseCommand *Base : Opt.Commands) {
775 auto *Cmd = dyn_cast<OutputSectionCommand>(Base);
776 if (!Cmd)
777 continue;
778
779 if (Cmd->Phdrs.empty()) {
780 OutputSection *Sec = Cmd->Sec;
781 // To match the bfd linker script behaviour, only propagate program
782 // headers to sections that are allocated.
783 if (Sec && (Sec->Flags & SHF_ALLOC))
784 Cmd->Phdrs = DefPhdrs;
785 } else {
786 DefPhdrs = Cmd->Phdrs;
787 }
788 }
789
790 removeEmptyCommands();
791}
792
793void LinkerScript::processNonSectionCommands() {
794 for (BaseCommand *Base : Opt.Commands) {
795 if (auto *Cmd = dyn_cast<SymbolAssignment>(Base))
796 assignSymbol(Cmd, false);
797 else if (auto *Cmd = dyn_cast<AssertCommand>(Base))
798 Cmd->Expression();
799 }
800}
801
802void LinkerScript::allocateHeaders(std::vector<PhdrEntry> &Phdrs) {
803 uint64_t Min = std::numeric_limits<uint64_t>::max();
804 for (OutputSectionCommand *Cmd : OutputSectionCommands) {
805 OutputSection *Sec = Cmd->Sec;
806 if (Sec->Flags & SHF_ALLOC)
807 Min = std::min<uint64_t>(Min, Sec->Addr);
808 }
809
810 auto FirstPTLoad = llvm::find_if(
811 Phdrs, [](const PhdrEntry &E) { return E.p_type == PT_LOAD; });
812 if (FirstPTLoad == Phdrs.end())
813 return;
814
815 uint64_t HeaderSize = getHeaderSize();
816 if (HeaderSize <= Min || Script->hasPhdrsCommands()) {
817 Min = alignDown(Min - HeaderSize, Config->MaxPageSize);
818 Out::ElfHeader->Addr = Min;
819 Out::ProgramHeaders->Addr = Min + Out::ElfHeader->Size;
820 return;
821 }
822
823 assert(FirstPTLoad->First == Out::ElfHeader);
824 OutputSection *ActualFirst = nullptr;
825 for (OutputSectionCommand *Cmd : OutputSectionCommands) {
826 OutputSection *Sec = Cmd->Sec;
827 if (Sec->FirstInPtLoad == Out::ElfHeader) {
828 ActualFirst = Sec;
829 break;
830 }
831 }
832 if (ActualFirst) {
833 for (OutputSectionCommand *Cmd : OutputSectionCommands) {
834 OutputSection *Sec = Cmd->Sec;
835 if (Sec->FirstInPtLoad == Out::ElfHeader)
836 Sec->FirstInPtLoad = ActualFirst;
837 }
838 FirstPTLoad->First = ActualFirst;
839 } else {
840 Phdrs.erase(FirstPTLoad);
841 }
842
843 auto PhdrI = llvm::find_if(
844 Phdrs, [](const PhdrEntry &E) { return E.p_type == PT_PHDR; });
845 if (PhdrI != Phdrs.end())
846 Phdrs.erase(PhdrI);
847}
848
849LinkerScript::AddressState::AddressState(const ScriptConfiguration &Opt) {
850 for (auto &MRI : Opt.MemoryRegions) {
851 const MemoryRegion *MR = &MRI.second;
852 MemRegionOffset[MR] = MR->Origin;
853 }
854}
855
856void LinkerScript::assignAddresses() {
857 // Assign addresses as instructed by linker script SECTIONS sub-commands.
858 Dot = 0;
859 auto State = make_unique<AddressState>(Opt);
860 // CurAddressState captures the local AddressState and makes it accessible
861 // deliberately. This is needed as there are some cases where we cannot just
862 // thread the current state through to a lambda function created by the
863 // script parser.
864 CurAddressState = State.get();
865 ErrorOnMissingSection = true;
866 switchTo(Aether);
867
868 for (BaseCommand *Base : Opt.Commands) {
869 if (auto *Cmd = dyn_cast<SymbolAssignment>(Base)) {
870 assignSymbol(Cmd, false);
871 continue;
872 }
873
874 if (auto *Cmd = dyn_cast<AssertCommand>(Base)) {
875 Cmd->Expression();
876 continue;
877 }
878
879 auto *Cmd = cast<OutputSectionCommand>(Base);
880 assignOffsets(Cmd);
881 }
882 CurAddressState = nullptr;
883}
884
885// Creates program headers as instructed by PHDRS linker script command.
886std::vector<PhdrEntry> LinkerScript::createPhdrs() {
887 std::vector<PhdrEntry> Ret;
888
889 // Process PHDRS and FILEHDR keywords because they are not
890 // real output sections and cannot be added in the following loop.
891 for (const PhdrsCommand &Cmd : Opt.PhdrsCommands) {
892 Ret.emplace_back(Cmd.Type, Cmd.Flags == UINT_MAX ? PF_R : Cmd.Flags);
893 PhdrEntry &Phdr = Ret.back();
894
895 if (Cmd.HasFilehdr)
896 Phdr.add(Out::ElfHeader);
897 if (Cmd.HasPhdrs)
898 Phdr.add(Out::ProgramHeaders);
899
900 if (Cmd.LMAExpr) {
901 Phdr.p_paddr = Cmd.LMAExpr().getValue();
902 Phdr.HasLMA = true;
903 }
904 }
905
906 // Add output sections to program headers.
907 for (OutputSectionCommand *Cmd : OutputSectionCommands) {
908 // Assign headers specified by linker script
909 for (size_t Id : getPhdrIndices(Cmd)) {
910 OutputSection *Sec = Cmd->Sec;
911 Ret[Id].add(Sec);
912 if (Opt.PhdrsCommands[Id].Flags == UINT_MAX)
913 Ret[Id].p_flags |= Sec->getPhdrFlags();
914 }
915 }
916 return Ret;
917}
918
919bool LinkerScript::ignoreInterpSection() {
920 // Ignore .interp section in case we have PHDRS specification
921 // and PT_INTERP isn't listed.
922 if (Opt.PhdrsCommands.empty())
923 return false;
924 for (PhdrsCommand &Cmd : Opt.PhdrsCommands)
925 if (Cmd.Type == PT_INTERP)
926 return false;
927 return true;
928}
929
930OutputSectionCommand *LinkerScript::getCmd(OutputSection *Sec) const {
931 auto I = SecToCommand.find(Sec);
932 if (I == SecToCommand.end())
933 return nullptr;
934 return I->second;
935}
936
937void OutputSectionCommand::sort(std::function<int(InputSectionBase *S)> Order) {
938 typedef std::pair<unsigned, InputSection *> Pair;
939 auto Comp = [](const Pair &A, const Pair &B) { return A.first < B.first; };
940
941 std::vector<Pair> V;
942 assert(Commands.size() == 1);
943 auto *ISD = cast<InputSectionDescription>(Commands[0]);
944 for (InputSection *S : ISD->Sections)
945 V.push_back({Order(S), S});
946 std::stable_sort(V.begin(), V.end(), Comp);
947 ISD->Sections.clear();
948 for (Pair &P : V)
949 ISD->Sections.push_back(P.second);
950}
951
952// Returns true if S matches /Filename.?\.o$/.
953static bool isCrtBeginEnd(StringRef S, StringRef Filename) {
954 if (!S.endswith(".o"))
955 return false;
956 S = S.drop_back(2);
957 if (S.endswith(Filename))
958 return true;
959 return !S.empty() && S.drop_back().endswith(Filename);
960}
961
962static bool isCrtbegin(StringRef S) { return isCrtBeginEnd(S, "crtbegin"); }
963static bool isCrtend(StringRef S) { return isCrtBeginEnd(S, "crtend"); }
964
965// .ctors and .dtors are sorted by this priority from highest to lowest.
966//
967// 1. The section was contained in crtbegin (crtbegin contains
968// some sentinel value in its .ctors and .dtors so that the runtime
969// can find the beginning of the sections.)
970//
971// 2. The section has an optional priority value in the form of ".ctors.N"
972// or ".dtors.N" where N is a number. Unlike .{init,fini}_array,
973// they are compared as string rather than number.
974//
975// 3. The section is just ".ctors" or ".dtors".
976//
977// 4. The section was contained in crtend, which contains an end marker.
978//
979// In an ideal world, we don't need this function because .init_array and
980// .ctors are duplicate features (and .init_array is newer.) However, there
981// are too many real-world use cases of .ctors, so we had no choice to
982// support that with this rather ad-hoc semantics.
983static bool compCtors(const InputSection *A, const InputSection *B) {
984 bool BeginA = isCrtbegin(A->File->getName());
985 bool BeginB = isCrtbegin(B->File->getName());
986 if (BeginA != BeginB)
987 return BeginA;
988 bool EndA = isCrtend(A->File->getName());
989 bool EndB = isCrtend(B->File->getName());
990 if (EndA != EndB)
991 return EndB;
992 StringRef X = A->Name;
993 StringRef Y = B->Name;
994 assert(X.startswith(".ctors") || X.startswith(".dtors"));
995 assert(Y.startswith(".ctors") || Y.startswith(".dtors"));
996 X = X.substr(6);
997 Y = Y.substr(6);
998 if (X.empty() && Y.empty())
999 return false;
1000 return X < Y;
1001}
1002
1003// Sorts input sections by the special rules for .ctors and .dtors.
1004// Unfortunately, the rules are different from the one for .{init,fini}_array.
1005// Read the comment above.
1006void OutputSectionCommand::sortCtorsDtors() {
1007 assert(Commands.size() == 1);
1008 auto *ISD = cast<InputSectionDescription>(Commands[0]);
1009 std::stable_sort(ISD->Sections.begin(), ISD->Sections.end(), compCtors);
1010}
1011
1012// Sorts input sections by section name suffixes, so that .foo.N comes
1013// before .foo.M if N < M. Used to sort .{init,fini}_array.N sections.
1014// We want to keep the original order if the priorities are the same
1015// because the compiler keeps the original initialization order in a
1016// translation unit and we need to respect that.
1017// For more detail, read the section of the GCC's manual about init_priority.
1018void OutputSectionCommand::sortInitFini() {
1019 // Sort sections by priority.
1020 sort([](InputSectionBase *S) { return getPriority(S->Name); });
1021}
1022
1023uint32_t OutputSectionCommand::getFiller() {
1024 if (Filler)
1025 return *Filler;
1026 if (Sec->Flags & SHF_EXECINSTR)
1027 return Target->TrapInstr;
1028 return 0;
1029}
1030
1031static void writeInt(uint8_t *Buf, uint64_t Data, uint64_t Size) {
1032 if (Size == 1)
1033 *Buf = Data;
1034 else if (Size == 2)
1035 write16(Buf, Data, Config->Endianness);
1036 else if (Size == 4)
1037 write32(Buf, Data, Config->Endianness);
1038 else if (Size == 8)
1039 write64(Buf, Data, Config->Endianness);
1040 else
1041 llvm_unreachable("unsupported Size argument");
1042}
1043
1044static bool compareByFilePosition(InputSection *A, InputSection *B) {
1045 // Synthetic doesn't have link order dependecy, stable_sort will keep it last
1046 if (A->kind() == InputSectionBase::Synthetic ||
1047 B->kind() == InputSectionBase::Synthetic)
1048 return false;
1049 InputSection *LA = A->getLinkOrderDep();
1050 InputSection *LB = B->getLinkOrderDep();
1051 OutputSection *AOut = LA->getParent();
1052 OutputSection *BOut = LB->getParent();
1053 if (AOut != BOut)
1054 return AOut->SectionIndex < BOut->SectionIndex;
1055 return LA->OutSecOff < LB->OutSecOff;
1056}
1057
1058template <class ELFT>
1059static void finalizeShtGroup(OutputSection *OS,
1060 ArrayRef<InputSection *> Sections) {
1061 assert(Config->Relocatable && Sections.size() == 1);
1062
1063 // sh_link field for SHT_GROUP sections should contain the section index of
1064 // the symbol table.
1065 OS->Link = InX::SymTab->getParent()->SectionIndex;
1066
1067 // sh_info then contain index of an entry in symbol table section which
1068 // provides signature of the section group.
1069 elf::ObjectFile<ELFT> *Obj = Sections[0]->getFile<ELFT>();
1070 ArrayRef<SymbolBody *> Symbols = Obj->getSymbols();
1071 OS->Info = InX::SymTab->getSymbolIndex(Symbols[Sections[0]->Info - 1]);
1072}
1073
1074template <class ELFT> void OutputSectionCommand::finalize() {
1075 // Link order may be distributed across several InputSectionDescriptions
1076 // but sort must consider them all at once.
1077 std::vector<InputSection **> ScriptSections;
1078 std::vector<InputSection *> Sections;
1079 for (BaseCommand *Base : Commands)
1080 if (auto *ISD = dyn_cast<InputSectionDescription>(Base))
1081 for (InputSection *&IS : ISD->Sections) {
1082 ScriptSections.push_back(&IS);
1083 Sections.push_back(IS);
1084 }
1085
1086 if ((Sec->Flags & SHF_LINK_ORDER)) {
1087 std::stable_sort(Sections.begin(), Sections.end(), compareByFilePosition);
1088 for (int I = 0, N = Sections.size(); I < N; ++I)
1089 *ScriptSections[I] = Sections[I];
1090
1091 // We must preserve the link order dependency of sections with the
1092 // SHF_LINK_ORDER flag. The dependency is indicated by the sh_link field. We
1093 // need to translate the InputSection sh_link to the OutputSection sh_link,
1094 // all InputSections in the OutputSection have the same dependency.
1095 if (auto *D = Sections.front()->getLinkOrderDep())
1096 Sec->Link = D->getParent()->SectionIndex;
1097 }
1098
1099 uint32_t Type = Sec->Type;
1100 if (Type == SHT_GROUP) {
1101 finalizeShtGroup<ELFT>(Sec, Sections);
1102 return;
1103 }
1104
1105 if (!Config->CopyRelocs || (Type != SHT_RELA && Type != SHT_REL))
1106 return;
1107
1108 InputSection *First = Sections[0];
1109 if (isa<SyntheticSection>(First))
1110 return;
1111
1112 Sec->Link = InX::SymTab->getParent()->SectionIndex;
1113 // sh_info for SHT_REL[A] sections should contain the section header index of
1114 // the section to which the relocation applies.
1115 InputSectionBase *S = First->getRelocatedSection();
1116 Sec->Info = S->getOutputSection()->SectionIndex;
1117 Sec->Flags |= SHF_INFO_LINK;
1118}
1119
1120// Compress section contents if this section contains debug info.
1121template <class ELFT> void OutputSectionCommand::maybeCompress() {
1122 typedef typename ELFT::Chdr Elf_Chdr;
1123
1124 // Compress only DWARF debug sections.
1125 if (!Config->CompressDebugSections || (Sec->Flags & SHF_ALLOC) ||
1126 !Name.startswith(".debug_"))
1127 return;
1128
1129 // Create a section header.
1130 Sec->ZDebugHeader.resize(sizeof(Elf_Chdr));
1131 auto *Hdr = reinterpret_cast<Elf_Chdr *>(Sec->ZDebugHeader.data());
1132 Hdr->ch_type = ELFCOMPRESS_ZLIB;
1133 Hdr->ch_size = Sec->Size;
1134 Hdr->ch_addralign = Sec->Alignment;
1135
1136 // Write section contents to a temporary buffer and compress it.
1137 std::vector<uint8_t> Buf(Sec->Size);
1138 writeTo<ELFT>(Buf.data());
1139 if (Error E = zlib::compress(toStringRef(Buf), Sec->CompressedData))
1140 fatal("compress failed: " + llvm::toString(std::move(E)));
1141
1142 // Update section headers.
1143 Sec->Size = sizeof(Elf_Chdr) + Sec->CompressedData.size();
1144 Sec->Flags |= SHF_COMPRESSED;
1145}
1146
1147template <class ELFT> void OutputSectionCommand::writeTo(uint8_t *Buf) {
1148 if (Sec->Type == SHT_NOBITS)
1149 return;
1150
1151 Sec->Loc = Buf;
1152
1153 // If -compress-debug-section is specified and if this is a debug seciton,
1154 // we've already compressed section contents. If that's the case,
1155 // just write it down.
1156 if (!Sec->CompressedData.empty()) {
1157 memcpy(Buf, Sec->ZDebugHeader.data(), Sec->ZDebugHeader.size());
1158 memcpy(Buf + Sec->ZDebugHeader.size(), Sec->CompressedData.data(),
1159 Sec->CompressedData.size());
1160 return;
1161 }
1162
1163 // Write leading padding.
1164 std::vector<InputSection *> Sections;
1165 for (BaseCommand *Cmd : Commands)
1166 if (auto *ISD = dyn_cast<InputSectionDescription>(Cmd))
1167 for (InputSection *IS : ISD->Sections)
1168 if (IS->Live)
1169 Sections.push_back(IS);
1170 uint32_t Filler = getFiller();
1171 if (Filler)
1172 fill(Buf, Sections.empty() ? Sec->Size : Sections[0]->OutSecOff, Filler);
1173
1174 parallelForEachN(0, Sections.size(), [=](size_t I) {
1175 InputSection *IS = Sections[I];
1176 IS->writeTo<ELFT>(Buf);
1177
1178 // Fill gaps between sections.
1179 if (Filler) {
1180 uint8_t *Start = Buf + IS->OutSecOff + IS->getSize();
1181 uint8_t *End;
1182 if (I + 1 == Sections.size())
1183 End = Buf + Sec->Size;
1184 else
1185 End = Buf + Sections[I + 1]->OutSecOff;
1186 fill(Start, End - Start, Filler);
1187 }
1188 });
1189
1190 // Linker scripts may have BYTE()-family commands with which you
1191 // can write arbitrary bytes to the output. Process them if any.
1192 for (BaseCommand *Base : Commands)
1193 if (auto *Data = dyn_cast<BytesDataCommand>(Base))
1194 writeInt(Buf + Data->Offset, Data->Expression().getValue(), Data->Size);
1195}
1196
1197ExprValue LinkerScript::getSymbolValue(const Twine &Loc, StringRef S) {
1198 if (S == ".")
1199 return {CurAddressState->OutSec, Dot - CurAddressState->OutSec->Addr, Loc};
1200 if (SymbolBody *B = findSymbol(S)) {
1201 if (auto *D = dyn_cast<DefinedRegular>(B))
1202 return {D->Section, D->Value, Loc};
1203 if (auto *C = dyn_cast<DefinedCommon>(B))
1204 return {InX::Common, C->Offset, Loc};
1205 }
1206 error(Loc + ": symbol not found: " + S);
1207 return 0;
1208}
1209
1210bool LinkerScript::isDefined(StringRef S) { return findSymbol(S) != nullptr; }
1211
1212static const size_t NoPhdr = -1;
1213
1214// Returns indices of ELF headers containing specific section. Each index is a
1215// zero based number of ELF header listed within PHDRS {} script block.
1216std::vector<size_t> LinkerScript::getPhdrIndices(OutputSectionCommand *Cmd) {
1217 std::vector<size_t> Ret;
1218 for (StringRef PhdrName : Cmd->Phdrs) {
1219 size_t Index = getPhdrIndex(Cmd->Location, PhdrName);
1220 if (Index != NoPhdr)
1221 Ret.push_back(Index);
1222 }
1223 return Ret;
1224}
1225
1226// Returns the index of the segment named PhdrName if found otherwise
1227// NoPhdr. When not found, if PhdrName is not the special case value 'NONE'
1228// (which can be used to explicitly specify that a section isn't assigned to a
1229// segment) then error.
1230size_t LinkerScript::getPhdrIndex(const Twine &Loc, StringRef PhdrName) {
1231 size_t I = 0;
1232 for (PhdrsCommand &Cmd : Opt.PhdrsCommands) {
1233 if (Cmd.Name == PhdrName)
1234 return I;
1235 ++I;
1236 }
1237 if (PhdrName != "NONE")
1238 error(Loc + ": section header '" + PhdrName + "' is not listed in PHDRS");
1239 return NoPhdr;
1240}
1241
1242template void OutputSectionCommand::writeTo<ELF32LE>(uint8_t *Buf);
1243template void OutputSectionCommand::writeTo<ELF32BE>(uint8_t *Buf);
1244template void OutputSectionCommand::writeTo<ELF64LE>(uint8_t *Buf);
1245template void OutputSectionCommand::writeTo<ELF64BE>(uint8_t *Buf);
1246
1247template void OutputSectionCommand::maybeCompress<ELF32LE>();
1248template void OutputSectionCommand::maybeCompress<ELF32BE>();
1249template void OutputSectionCommand::maybeCompress<ELF64LE>();
1250template void OutputSectionCommand::maybeCompress<ELF64BE>();
1251
1252template void OutputSectionCommand::finalize<ELF32LE>();
1253template void OutputSectionCommand::finalize<ELF32BE>();
1254template void OutputSectionCommand::finalize<ELF64LE>();
1255template void OutputSectionCommand::finalize<ELF64BE>();
deps/lld/ELF/LinkerScript.h created+306
......@@ -0,0 +1,306 @@
1//===- LinkerScript.h -------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_ELF_LINKER_SCRIPT_H
11#define LLD_ELF_LINKER_SCRIPT_H
12
13#include "Config.h"
14#include "Strings.h"
15#include "Writer.h"
16#include "lld/Core/LLVM.h"
17#include "llvm/ADT/ArrayRef.h"
18#include "llvm/ADT/DenseMap.h"
19#include "llvm/ADT/DenseSet.h"
20#include "llvm/ADT/StringRef.h"
21#include "llvm/Support/MemoryBuffer.h"
22#include <cstddef>
23#include <cstdint>
24#include <functional>
25#include <memory>
26#include <vector>
27
28namespace lld {
29namespace elf {
30
31class DefinedCommon;
32class SymbolBody;
33class InputSectionBase;
34class InputSection;
35class OutputSection;
36class OutputSectionFactory;
37class InputSectionBase;
38class SectionBase;
39
40struct ExprValue {
41 SectionBase *Sec;
42 uint64_t Val;
43 bool ForceAbsolute;
44 uint64_t Alignment = 1;
45 std::string Loc;
46
47 ExprValue(SectionBase *Sec, bool ForceAbsolute, uint64_t Val,
48 const Twine &Loc)
49 : Sec(Sec), Val(Val), ForceAbsolute(ForceAbsolute), Loc(Loc.str()) {}
50 ExprValue(SectionBase *Sec, uint64_t Val, const Twine &Loc)
51 : ExprValue(Sec, false, Val, Loc) {}
52 ExprValue(uint64_t Val) : ExprValue(nullptr, Val, "") {}
53 bool isAbsolute() const { return ForceAbsolute || Sec == nullptr; }
54 uint64_t getValue() const;
55 uint64_t getSecAddr() const;
56};
57
58// This represents an expression in the linker script.
59// ScriptParser::readExpr reads an expression and returns an Expr.
60// Later, we evaluate the expression by calling the function.
61typedef std::function<ExprValue()> Expr;
62
63// This enum is used to implement linker script SECTIONS command.
64// https://sourceware.org/binutils/docs/ld/SECTIONS.html#SECTIONS
65enum SectionsCommandKind {
66 AssignmentKind, // . = expr or <sym> = expr
67 OutputSectionKind,
68 InputSectionKind,
69 AssertKind, // ASSERT(expr)
70 BytesDataKind // BYTE(expr), SHORT(expr), LONG(expr) or QUAD(expr)
71};
72
73struct BaseCommand {
74 BaseCommand(int K) : Kind(K) {}
75 int Kind;
76};
77
78// This represents ". = <expr>" or "<symbol> = <expr>".
79struct SymbolAssignment : BaseCommand {
80 SymbolAssignment(StringRef Name, Expr E, std::string Loc)
81 : BaseCommand(AssignmentKind), Name(Name), Expression(E), Location(Loc) {}
82
83 static bool classof(const BaseCommand *C);
84
85 // The LHS of an expression. Name is either a symbol name or ".".
86 StringRef Name;
87 SymbolBody *Sym = nullptr;
88
89 // The RHS of an expression.
90 Expr Expression;
91
92 // Command attributes for PROVIDE, HIDDEN and PROVIDE_HIDDEN.
93 bool Provide = false;
94 bool Hidden = false;
95
96 // Holds file name and line number for error reporting.
97 std::string Location;
98};
99
100// Linker scripts allow additional constraints to be put on ouput sections.
101// If an output section is marked as ONLY_IF_RO, the section is created
102// only if its input sections are read-only. Likewise, an output section
103// with ONLY_IF_RW is created if all input sections are RW.
104enum class ConstraintKind { NoConstraint, ReadOnly, ReadWrite };
105
106// This struct is used to represent the location and size of regions of
107// target memory. Instances of the struct are created by parsing the
108// MEMORY command.
109struct MemoryRegion {
110 std::string Name;
111 uint64_t Origin;
112 uint64_t Length;
113 uint32_t Flags;
114 uint32_t NegFlags;
115};
116
117struct OutputSectionCommand : BaseCommand {
118 OutputSectionCommand(StringRef Name)
119 : BaseCommand(OutputSectionKind), Name(Name) {}
120
121 static bool classof(const BaseCommand *C);
122
123 OutputSection *Sec = nullptr;
124 MemoryRegion *MemRegion = nullptr;
125 StringRef Name;
126 Expr AddrExpr;
127 Expr AlignExpr;
128 Expr LMAExpr;
129 Expr SubalignExpr;
130 std::vector<BaseCommand *> Commands;
131 std::vector<StringRef> Phdrs;
132 llvm::Optional<uint32_t> Filler;
133 ConstraintKind Constraint = ConstraintKind::NoConstraint;
134 std::string Location;
135 std::string MemoryRegionName;
136 bool Noload = false;
137
138 template <class ELFT> void finalize();
139 template <class ELFT> void writeTo(uint8_t *Buf);
140 template <class ELFT> void maybeCompress();
141 uint32_t getFiller();
142
143 void sort(std::function<int(InputSectionBase *S)> Order);
144 void sortInitFini();
145 void sortCtorsDtors();
146};
147
148// This struct represents one section match pattern in SECTIONS() command.
149// It can optionally have negative match pattern for EXCLUDED_FILE command.
150// Also it may be surrounded with SORT() command, so contains sorting rules.
151struct SectionPattern {
152 SectionPattern(StringMatcher &&Pat1, StringMatcher &&Pat2)
153 : ExcludedFilePat(Pat1), SectionPat(Pat2) {}
154
155 StringMatcher ExcludedFilePat;
156 StringMatcher SectionPat;
157 SortSectionPolicy SortOuter;
158 SortSectionPolicy SortInner;
159};
160
161struct InputSectionDescription : BaseCommand {
162 InputSectionDescription(StringRef FilePattern)
163 : BaseCommand(InputSectionKind), FilePat(FilePattern) {}
164
165 static bool classof(const BaseCommand *C);
166
167 StringMatcher FilePat;
168
169 // Input sections that matches at least one of SectionPatterns
170 // will be associated with this InputSectionDescription.
171 std::vector<SectionPattern> SectionPatterns;
172
173 std::vector<InputSection *> Sections;
174};
175
176// Represents an ASSERT().
177struct AssertCommand : BaseCommand {
178 AssertCommand(Expr E) : BaseCommand(AssertKind), Expression(E) {}
179
180 static bool classof(const BaseCommand *C);
181
182 Expr Expression;
183};
184
185// Represents BYTE(), SHORT(), LONG(), or QUAD().
186struct BytesDataCommand : BaseCommand {
187 BytesDataCommand(Expr E, unsigned Size)
188 : BaseCommand(BytesDataKind), Expression(E), Size(Size) {}
189
190 static bool classof(const BaseCommand *C);
191
192 Expr Expression;
193 unsigned Offset;
194 unsigned Size;
195};
196
197struct PhdrsCommand {
198 StringRef Name;
199 unsigned Type;
200 bool HasFilehdr;
201 bool HasPhdrs;
202 unsigned Flags;
203 Expr LMAExpr;
204};
205
206// ScriptConfiguration holds linker script parse results.
207struct ScriptConfiguration {
208 // Used to assign addresses to sections.
209 std::vector<BaseCommand *> Commands;
210
211 // Used to assign sections to headers.
212 std::vector<PhdrsCommand> PhdrsCommands;
213
214 bool HasSections = false;
215
216 // List of section patterns specified with KEEP commands. They will
217 // be kept even if they are unused and --gc-sections is specified.
218 std::vector<InputSectionDescription *> KeptSections;
219
220 // A map from memory region name to a memory region descriptor.
221 llvm::DenseMap<llvm::StringRef, MemoryRegion> MemoryRegions;
222
223 // A list of symbols referenced by the script.
224 std::vector<llvm::StringRef> ReferencedSymbols;
225};
226
227class LinkerScript final {
228 // Temporary state used in processCommands() and assignAddresses()
229 // that must be reinitialized for each call to the above functions, and must
230 // not be used outside of the scope of a call to the above functions.
231 struct AddressState {
232 uint64_t ThreadBssOffset = 0;
233 OutputSection *OutSec = nullptr;
234 MemoryRegion *MemRegion = nullptr;
235 llvm::DenseMap<const MemoryRegion *, uint64_t> MemRegionOffset;
236 std::function<uint64_t()> LMAOffset;
237 AddressState(const ScriptConfiguration &Opt);
238 };
239 llvm::DenseMap<OutputSection *, OutputSectionCommand *> SecToCommand;
240 llvm::DenseMap<StringRef, OutputSectionCommand *> NameToOutputSectionCommand;
241
242 void assignSymbol(SymbolAssignment *Cmd, bool InSec);
243 void setDot(Expr E, const Twine &Loc, bool InSec);
244
245 std::vector<InputSection *>
246 computeInputSections(const InputSectionDescription *);
247
248 std::vector<InputSectionBase *>
249 createInputSectionList(OutputSectionCommand &Cmd);
250
251 std::vector<size_t> getPhdrIndices(OutputSectionCommand *Cmd);
252 size_t getPhdrIndex(const Twine &Loc, StringRef PhdrName);
253
254 MemoryRegion *findMemoryRegion(OutputSectionCommand *Cmd);
255
256 void switchTo(OutputSection *Sec);
257 uint64_t advance(uint64_t Size, unsigned Align);
258 void output(InputSection *Sec);
259 void process(BaseCommand &Base);
260
261 AddressState *CurAddressState = nullptr;
262 OutputSection *Aether;
263
264 uint64_t Dot;
265
266public:
267 bool ErrorOnMissingSection = false;
268 OutputSectionCommand *createOutputSectionCommand(StringRef Name,
269 StringRef Location);
270 OutputSectionCommand *getOrCreateOutputSectionCommand(StringRef Name);
271
272 OutputSectionCommand *getCmd(OutputSection *Sec) const;
273 bool hasPhdrsCommands() { return !Opt.PhdrsCommands.empty(); }
274 uint64_t getDot() { return Dot; }
275 void discard(ArrayRef<InputSectionBase *> V);
276
277 ExprValue getSymbolValue(const Twine &Loc, StringRef S);
278 bool isDefined(StringRef S);
279
280 void fabricateDefaultCommands();
281 void addOrphanSections(OutputSectionFactory &Factory);
282 void removeEmptyCommands();
283 void adjustSectionsBeforeSorting();
284 void adjustSectionsAfterSorting();
285
286 std::vector<PhdrEntry> createPhdrs();
287 bool ignoreInterpSection();
288
289 bool shouldKeep(InputSectionBase *S);
290 void assignOffsets(OutputSectionCommand *Cmd);
291 void processNonSectionCommands();
292 void assignAddresses();
293 void allocateHeaders(std::vector<PhdrEntry> &Phdrs);
294 void addSymbol(SymbolAssignment *Cmd);
295 void processCommands(OutputSectionFactory &Factory);
296
297 // Parsed linker script configurations are set to this struct.
298 ScriptConfiguration Opt;
299};
300
301extern LinkerScript *Script;
302
303} // end namespace elf
304} // end namespace lld
305
306#endif // LLD_ELF_LINKER_SCRIPT_H
deps/lld/ELF/MapFile.cpp created+150
......@@ -0,0 +1,150 @@
1//===- MapFile.cpp --------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the -Map option. It shows lists in order and
11// hierarchically the output sections, input sections, input files and
12// symbol:
13//
14// Address Size Align Out In Symbol
15// 00201000 00000015 4 .text
16// 00201000 0000000e 4 test.o:(.text)
17// 0020100e 00000000 0 local
18// 00201005 00000000 0 f(int)
19//
20//===----------------------------------------------------------------------===//
21
22#include "MapFile.h"
23#include "InputFiles.h"
24#include "LinkerScript.h"
25#include "OutputSections.h"
26#include "Strings.h"
27#include "SymbolTable.h"
28#include "Threads.h"
29
30#include "llvm/Support/raw_ostream.h"
31
32using namespace llvm;
33using namespace llvm::object;
34
35using namespace lld;
36using namespace lld::elf;
37
38typedef DenseMap<const SectionBase *, SmallVector<DefinedRegular *, 4>>
39 SymbolMapTy;
40
41// Print out the first three columns of a line.
42template <class ELFT>
43static void writeHeader(raw_ostream &OS, uint64_t Addr, uint64_t Size,
44 uint64_t Align) {
45 int W = ELFT::Is64Bits ? 16 : 8;
46 OS << format("%0*llx %0*llx %5lld ", W, Addr, W, Size, Align);
47}
48
49static std::string indent(int Depth) { return std::string(Depth * 8, ' '); }
50
51// Returns a list of all symbols that we want to print out.
52template <class ELFT> std::vector<DefinedRegular *> getSymbols() {
53 std::vector<DefinedRegular *> V;
54 for (elf::ObjectFile<ELFT> *File : Symtab<ELFT>::X->getObjectFiles())
55 for (SymbolBody *B : File->getSymbols())
56 if (B->File == File && !B->isSection())
57 if (auto *Sym = dyn_cast<DefinedRegular>(B))
58 if (Sym->Section && Sym->Section->Live)
59 V.push_back(Sym);
60 return V;
61}
62
63// Returns a map from sections to their symbols.
64template <class ELFT>
65SymbolMapTy getSectionSyms(ArrayRef<DefinedRegular *> Syms) {
66 SymbolMapTy Ret;
67 for (DefinedRegular *S : Syms)
68 Ret[S->Section].push_back(S);
69
70 // Sort symbols by address. We want to print out symbols in the
71 // order in the output file rather than the order they appeared
72 // in the input files.
73 for (auto &It : Ret) {
74 SmallVectorImpl<DefinedRegular *> &V = It.second;
75 std::sort(V.begin(), V.end(), [](DefinedRegular *A, DefinedRegular *B) {
76 return A->getVA() < B->getVA();
77 });
78 }
79 return Ret;
80}
81
82// Construct a map from symbols to their stringified representations.
83// Demangling symbols (which is what toString() does) is slow, so
84// we do that in batch using parallel-for.
85template <class ELFT>
86DenseMap<DefinedRegular *, std::string>
87getSymbolStrings(ArrayRef<DefinedRegular *> Syms) {
88 std::vector<std::string> Str(Syms.size());
89 parallelForEachN(0, Syms.size(), [&](size_t I) {
90 raw_string_ostream OS(Str[I]);
91 writeHeader<ELFT>(OS, Syms[I]->getVA(), Syms[I]->template getSize<ELFT>(),
92 0);
93 OS << indent(2) << toString(*Syms[I]);
94 });
95
96 DenseMap<DefinedRegular *, std::string> Ret;
97 for (size_t I = 0, E = Syms.size(); I < E; ++I)
98 Ret[Syms[I]] = std::move(Str[I]);
99 return Ret;
100}
101
102template <class ELFT>
103void elf::writeMapFile(llvm::ArrayRef<OutputSectionCommand *> Script) {
104 if (Config->MapFile.empty())
105 return;
106
107 // Open a map file for writing.
108 std::error_code EC;
109 raw_fd_ostream OS(Config->MapFile, EC, sys::fs::F_None);
110 if (EC) {
111 error("cannot open " + Config->MapFile + ": " + EC.message());
112 return;
113 }
114
115 // Collect symbol info that we want to print out.
116 std::vector<DefinedRegular *> Syms = getSymbols<ELFT>();
117 SymbolMapTy SectionSyms = getSectionSyms<ELFT>(Syms);
118 DenseMap<DefinedRegular *, std::string> SymStr = getSymbolStrings<ELFT>(Syms);
119
120 // Print out the header line.
121 int W = ELFT::Is64Bits ? 16 : 8;
122 OS << left_justify("Address", W) << ' ' << left_justify("Size", W)
123 << " Align Out In Symbol\n";
124
125 // Print out file contents.
126 for (OutputSectionCommand *Cmd : Script) {
127 OutputSection *OSec = Cmd->Sec;
128 writeHeader<ELFT>(OS, OSec->Addr, OSec->Size, OSec->Alignment);
129 OS << OSec->Name << '\n';
130
131 // Dump symbols for each input section.
132 for (BaseCommand *Base : Cmd->Commands) {
133 auto *ISD = dyn_cast<InputSectionDescription>(Base);
134 if (!ISD)
135 continue;
136 for (InputSection *IS : ISD->Sections) {
137 writeHeader<ELFT>(OS, OSec->Addr + IS->OutSecOff, IS->getSize(),
138 IS->Alignment);
139 OS << indent(1) << toString(IS) << '\n';
140 for (DefinedRegular *Sym : SectionSyms[IS])
141 OS << SymStr[Sym] << '\n';
142 }
143 }
144 }
145}
146
147template void elf::writeMapFile<ELF32LE>(ArrayRef<OutputSectionCommand *>);
148template void elf::writeMapFile<ELF32BE>(ArrayRef<OutputSectionCommand *>);
149template void elf::writeMapFile<ELF64LE>(ArrayRef<OutputSectionCommand *>);
150template void elf::writeMapFile<ELF64BE>(ArrayRef<OutputSectionCommand *>);
deps/lld/ELF/MapFile.h created+23
......@@ -0,0 +1,23 @@
1//===- MapFile.h ------------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_ELF_MAPFILE_H
11#define LLD_ELF_MAPFILE_H
12
13#include <llvm/ADT/ArrayRef.h>
14
15namespace lld {
16namespace elf {
17struct OutputSectionCommand;
18template <class ELFT>
19void writeMapFile(llvm::ArrayRef<OutputSectionCommand *> Script);
20} // namespace elf
21} // namespace lld
22
23#endif
deps/lld/ELF/MarkLive.cpp created+268
......@@ -0,0 +1,268 @@
1//===- MarkLive.cpp -------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements --gc-sections, which is a feature to remove unused
11// sections from output. Unused sections are sections that are not reachable
12// from known GC-root symbols or sections. Naturally the feature is
13// implemented as a mark-sweep garbage collector.
14//
15// Here's how it works. Each InputSectionBase has a "Live" bit. The bit is off
16// by default. Starting with GC-root symbols or sections, markLive function
17// defined in this file visits all reachable sections to set their Live
18// bits. Writer will then ignore sections whose Live bits are off, so that
19// such sections are not included into output.
20//
21//===----------------------------------------------------------------------===//
22
23#include "InputSection.h"
24#include "LinkerScript.h"
25#include "Memory.h"
26#include "OutputSections.h"
27#include "Strings.h"
28#include "SymbolTable.h"
29#include "Symbols.h"
30#include "Target.h"
31#include "Writer.h"
32#include "llvm/ADT/STLExtras.h"
33#include "llvm/Object/ELF.h"
34#include <functional>
35#include <vector>
36
37using namespace llvm;
38using namespace llvm::ELF;
39using namespace llvm::object;
40using namespace llvm::support::endian;
41
42using namespace lld;
43using namespace lld::elf;
44
45namespace {
46// A resolved relocation. The Sec and Offset fields are set if the relocation
47// was resolved to an offset within a section.
48struct ResolvedReloc {
49 InputSectionBase *Sec;
50 uint64_t Offset;
51};
52} // end anonymous namespace
53
54template <class ELFT>
55static typename ELFT::uint getAddend(InputSectionBase &Sec,
56 const typename ELFT::Rel &Rel) {
57 return Target->getImplicitAddend(Sec.Data.begin() + Rel.r_offset,
58 Rel.getType(Config->IsMips64EL));
59}
60
61template <class ELFT>
62static typename ELFT::uint getAddend(InputSectionBase &Sec,
63 const typename ELFT::Rela &Rel) {
64 return Rel.r_addend;
65}
66
67// There are normally few input sections whose names are valid C
68// identifiers, so we just store a std::vector instead of a multimap.
69static DenseMap<StringRef, std::vector<InputSectionBase *>> CNamedSections;
70
71template <class ELFT, class RelT>
72static void resolveReloc(InputSectionBase &Sec, RelT &Rel,
73 std::function<void(ResolvedReloc)> Fn) {
74 SymbolBody &B = Sec.getFile<ELFT>()->getRelocTargetSym(Rel);
75 if (auto *D = dyn_cast<DefinedRegular>(&B)) {
76 if (!D->Section)
77 return;
78 typename ELFT::uint Offset = D->Value;
79 if (D->isSection())
80 Offset += getAddend<ELFT>(Sec, Rel);
81 Fn({cast<InputSectionBase>(D->Section), Offset});
82 } else if (auto *U = dyn_cast<Undefined>(&B)) {
83 for (InputSectionBase *Sec : CNamedSections.lookup(U->getName()))
84 Fn({Sec, 0});
85 }
86}
87
88// Calls Fn for each section that Sec refers to via relocations.
89template <class ELFT>
90static void forEachSuccessor(InputSection &Sec,
91 std::function<void(ResolvedReloc)> Fn) {
92 if (Sec.AreRelocsRela) {
93 for (const typename ELFT::Rela &Rel : Sec.template relas<ELFT>())
94 resolveReloc<ELFT>(Sec, Rel, Fn);
95 } else {
96 for (const typename ELFT::Rel &Rel : Sec.template rels<ELFT>())
97 resolveReloc<ELFT>(Sec, Rel, Fn);
98 }
99 for (InputSectionBase *IS : Sec.DependentSections)
100 Fn({IS, 0});
101}
102
103// The .eh_frame section is an unfortunate special case.
104// The section is divided in CIEs and FDEs and the relocations it can have are
105// * CIEs can refer to a personality function.
106// * FDEs can refer to a LSDA
107// * FDEs refer to the function they contain information about
108// The last kind of relocation cannot keep the referred section alive, or they
109// would keep everything alive in a common object file. In fact, each FDE is
110// alive if the section it refers to is alive.
111// To keep things simple, in here we just ignore the last relocation kind. The
112// other two keep the referred section alive.
113//
114// A possible improvement would be to fully process .eh_frame in the middle of
115// the gc pass. With that we would be able to also gc some sections holding
116// LSDAs and personality functions if we found that they were unused.
117template <class ELFT, class RelTy>
118static void scanEhFrameSection(EhInputSection &EH, ArrayRef<RelTy> Rels,
119 std::function<void(ResolvedReloc)> Enqueue) {
120 const endianness E = ELFT::TargetEndianness;
121 for (unsigned I = 0, N = EH.Pieces.size(); I < N; ++I) {
122 EhSectionPiece &Piece = EH.Pieces[I];
123 unsigned FirstRelI = Piece.FirstRelocation;
124 if (FirstRelI == (unsigned)-1)
125 continue;
126 if (read32<E>(Piece.data().data() + 4) == 0) {
127 // This is a CIE, we only need to worry about the first relocation. It is
128 // known to point to the personality function.
129 resolveReloc<ELFT>(EH, Rels[FirstRelI], Enqueue);
130 continue;
131 }
132 // This is a FDE. The relocations point to the described function or to
133 // a LSDA. We only need to keep the LSDA alive, so ignore anything that
134 // points to executable sections.
135 typename ELFT::uint PieceEnd = Piece.InputOff + Piece.size();
136 for (unsigned I2 = FirstRelI, N2 = Rels.size(); I2 < N2; ++I2) {
137 const RelTy &Rel = Rels[I2];
138 if (Rel.r_offset >= PieceEnd)
139 break;
140 resolveReloc<ELFT>(EH, Rels[I2], [&](ResolvedReloc R) {
141 if (!R.Sec || R.Sec == &InputSection::Discarded)
142 return;
143 if (R.Sec->Flags & SHF_EXECINSTR)
144 return;
145 Enqueue({R.Sec, 0});
146 });
147 }
148 }
149}
150
151template <class ELFT>
152static void scanEhFrameSection(EhInputSection &EH,
153 std::function<void(ResolvedReloc)> Enqueue) {
154 if (!EH.NumRelocations)
155 return;
156
157 // Unfortunately we need to split .eh_frame early since some relocations in
158 // .eh_frame keep other section alive and some don't.
159 EH.split<ELFT>();
160
161 if (EH.AreRelocsRela)
162 scanEhFrameSection<ELFT>(EH, EH.template relas<ELFT>(), Enqueue);
163 else
164 scanEhFrameSection<ELFT>(EH, EH.template rels<ELFT>(), Enqueue);
165}
166
167// We do not garbage-collect two types of sections:
168// 1) Sections used by the loader (.init, .fini, .ctors, .dtors or .jcr)
169// 2) Non-allocatable sections which typically contain debugging information
170template <class ELFT> static bool isReserved(InputSectionBase *Sec) {
171 switch (Sec->Type) {
172 case SHT_FINI_ARRAY:
173 case SHT_INIT_ARRAY:
174 case SHT_NOTE:
175 case SHT_PREINIT_ARRAY:
176 return true;
177 default:
178 if (!(Sec->Flags & SHF_ALLOC))
179 return true;
180
181 StringRef S = Sec->Name;
182 return S.startswith(".ctors") || S.startswith(".dtors") ||
183 S.startswith(".init") || S.startswith(".fini") ||
184 S.startswith(".jcr");
185 }
186}
187
188// This is the main function of the garbage collector.
189// Starting from GC-root sections, this function visits all reachable
190// sections to set their "Live" bits.
191template <class ELFT> void elf::markLive() {
192 SmallVector<InputSection *, 256> Q;
193 CNamedSections.clear();
194
195 auto Enqueue = [&](ResolvedReloc R) {
196 // Skip over discarded sections. This in theory shouldn't happen, because
197 // the ELF spec doesn't allow a relocation to point to a deduplicated
198 // COMDAT section directly. Unfortunately this happens in practice (e.g.
199 // .eh_frame) so we need to add a check.
200 if (R.Sec == &InputSection::Discarded)
201 return;
202
203 // We don't gc non alloc sections.
204 if (!(R.Sec->Flags & SHF_ALLOC))
205 return;
206
207 // Usually, a whole section is marked as live or dead, but in mergeable
208 // (splittable) sections, each piece of data has independent liveness bit.
209 // So we explicitly tell it which offset is in use.
210 if (auto *MS = dyn_cast<MergeInputSection>(R.Sec))
211 MS->markLiveAt(R.Offset);
212
213 if (R.Sec->Live)
214 return;
215 R.Sec->Live = true;
216 // Add input section to the queue.
217 if (InputSection *S = dyn_cast<InputSection>(R.Sec))
218 Q.push_back(S);
219 };
220
221 auto MarkSymbol = [&](const SymbolBody *Sym) {
222 if (auto *D = dyn_cast_or_null<DefinedRegular>(Sym))
223 if (auto *IS = cast_or_null<InputSectionBase>(D->Section))
224 Enqueue({IS, D->Value});
225 };
226
227 // Add GC root symbols.
228 MarkSymbol(Symtab<ELFT>::X->find(Config->Entry));
229 MarkSymbol(Symtab<ELFT>::X->find(Config->Init));
230 MarkSymbol(Symtab<ELFT>::X->find(Config->Fini));
231 for (StringRef S : Config->Undefined)
232 MarkSymbol(Symtab<ELFT>::X->find(S));
233 for (StringRef S : Script->Opt.ReferencedSymbols)
234 MarkSymbol(Symtab<ELFT>::X->find(S));
235
236 // Preserve externally-visible symbols if the symbols defined by this
237 // file can interrupt other ELF file's symbols at runtime.
238 for (const Symbol *S : Symtab<ELFT>::X->getSymbols())
239 if (S->includeInDynsym())
240 MarkSymbol(S->body());
241
242 // Preserve special sections and those which are specified in linker
243 // script KEEP command.
244 for (InputSectionBase *Sec : InputSections) {
245 // .eh_frame is always marked as live now, but also it can reference to
246 // sections that contain personality. We preserve all non-text sections
247 // referred by .eh_frame here.
248 if (auto *EH = dyn_cast_or_null<EhInputSection>(Sec))
249 scanEhFrameSection<ELFT>(*EH, Enqueue);
250 if (Sec->Flags & SHF_LINK_ORDER)
251 continue;
252 if (isReserved<ELFT>(Sec) || Script->shouldKeep(Sec))
253 Enqueue({Sec, 0});
254 else if (isValidCIdentifier(Sec->Name)) {
255 CNamedSections[Saver.save("__start_" + Sec->Name)].push_back(Sec);
256 CNamedSections[Saver.save("__end_" + Sec->Name)].push_back(Sec);
257 }
258 }
259
260 // Mark all reachable sections.
261 while (!Q.empty())
262 forEachSuccessor<ELFT>(*Q.pop_back_val(), Enqueue);
263}
264
265template void elf::markLive<ELF32LE>();
266template void elf::markLive<ELF32BE>();
267template void elf::markLive<ELF64LE>();
268template void elf::markLive<ELF64BE>();
deps/lld/ELF/Memory.h created+67
......@@ -0,0 +1,67 @@
1//===- Memory.h -------------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines arena allocators.
11//
12// Almost all large objects, such as files, sections or symbols, are
13// used for the entire lifetime of the linker once they are created.
14// This usage characteristic makes arena allocator an attractive choice
15// where the entire linker is one arena. With an arena, newly created
16// objects belong to the arena and freed all at once when everything is done.
17// Arena allocators are efficient and easy to understand.
18// Most objects are allocated using the arena allocators defined by this file.
19//
20// If you edit this file, please edit COFF/Memory.h too.
21//
22//===----------------------------------------------------------------------===//
23
24#ifndef LLD_ELF_MEMORY_H
25#define LLD_ELF_MEMORY_H
26
27#include "llvm/Support/Allocator.h"
28#include "llvm/Support/StringSaver.h"
29#include <vector>
30
31namespace lld {
32namespace elf {
33
34// Use this arena if your object doesn't have a destructor.
35extern llvm::BumpPtrAllocator BAlloc;
36extern llvm::StringSaver Saver;
37
38// These two classes are hack to keep track of all
39// SpecificBumpPtrAllocator instances.
40struct SpecificAllocBase {
41 SpecificAllocBase() { Instances.push_back(this); }
42 virtual ~SpecificAllocBase() = default;
43 virtual void reset() = 0;
44 static std::vector<SpecificAllocBase *> Instances;
45};
46
47template <class T> struct SpecificAlloc : public SpecificAllocBase {
48 void reset() override { Alloc.DestroyAll(); }
49 llvm::SpecificBumpPtrAllocator<T> Alloc;
50};
51
52// Use this arena if your object has a destructor.
53// Your destructor will be invoked from freeArena().
54template <typename T, typename... U> T *make(U &&... Args) {
55 static SpecificAlloc<T> Alloc;
56 return new (Alloc.Alloc.Allocate()) T(std::forward<U>(Args)...);
57}
58
59inline void freeArena() {
60 for (SpecificAllocBase *Alloc : SpecificAllocBase::Instances)
61 Alloc->reset();
62 BAlloc.Reset();
63}
64} // namespace elf
65} // namespace lld
66
67#endif
deps/lld/ELF/Options.td created+414
......@@ -0,0 +1,414 @@
1include "llvm/Option/OptParser.td"
2
3// For options whose names are multiple letters, either one dash or
4// two can precede the option name except those that start with 'o'.
5class F<string name>: Flag<["--", "-"], name>;
6class J<string name>: Joined<["--", "-"], name>;
7class S<string name>: Separate<["--", "-"], name>;
8class JS<string name>: JoinedOrSeparate<["--", "-"], name>;
9
10def auxiliary: S<"auxiliary">, HelpText<"Set DT_AUXILIARY field to the specified name">;
11
12def Bsymbolic: F<"Bsymbolic">, HelpText<"Bind defined symbols locally">;
13
14def Bsymbolic_functions: F<"Bsymbolic-functions">,
15 HelpText<"Bind defined function symbols locally">;
16
17def Bdynamic: F<"Bdynamic">, HelpText<"Link against shared libraries">;
18
19def Bstatic: F<"Bstatic">, HelpText<"Do not link against shared libraries">;
20
21def build_id: F<"build-id">, HelpText<"Generate build ID note">;
22
23def build_id_eq: J<"build-id=">, HelpText<"Generate build ID note">;
24
25def compress_debug_sections : J<"compress-debug-sections=">,
26 HelpText<"Compress DWARF debug sections">;
27
28def defsym: J<"defsym=">, HelpText<"Define a symbol alias">;
29
30def L: JoinedOrSeparate<["-"], "L">, MetaVarName<"<dir>">,
31 HelpText<"Add a directory to the library search path">;
32
33def O: Joined<["-"], "O">, HelpText<"Optimize output file size">;
34
35def Tbss: S<"Tbss">, HelpText<"Same as --section-start with .bss as the sectionname">;
36
37def Tdata: S<"Tdata">, HelpText<"Same as --section-start with .data as the sectionname">;
38
39def Ttext: S<"Ttext">, HelpText<"Same as --section-start with .text as the sectionname">;
40
41def allow_multiple_definition: F<"allow-multiple-definition">,
42 HelpText<"Allow multiple definitions">;
43
44def as_needed: F<"as-needed">,
45 HelpText<"Only set DT_NEEDED for shared libraries if used">;
46
47def color_diagnostics: F<"color-diagnostics">,
48 HelpText<"Use colors in diagnostics">;
49
50def color_diagnostics_eq: J<"color-diagnostics=">,
51 HelpText<"Use colors in diagnostics">;
52
53def define_common: F<"define-common">,
54 HelpText<"Assign space to common symbols">;
55
56def demangle: F<"demangle">, HelpText<"Demangle symbol names">;
57
58def disable_new_dtags: F<"disable-new-dtags">,
59 HelpText<"Disable new dynamic tags">;
60
61def discard_all: F<"discard-all">, HelpText<"Delete all local symbols">;
62
63def discard_locals: F<"discard-locals">,
64 HelpText<"Delete temporary local symbols">;
65
66def discard_none: F<"discard-none">,
67 HelpText<"Keep all symbols in the symbol table">;
68
69def dynamic_linker: S<"dynamic-linker">,
70 HelpText<"Which dynamic linker to use">;
71
72def dynamic_list: S<"dynamic-list">,
73 HelpText<"Read a list of dynamic symbols">;
74
75def eh_frame_hdr: F<"eh-frame-hdr">,
76 HelpText<"Request creation of .eh_frame_hdr section and PT_GNU_EH_FRAME segment header">;
77
78def emit_relocs: F<"emit-relocs">, HelpText<"Generate relocations in output">;
79
80def enable_new_dtags: F<"enable-new-dtags">,
81 HelpText<"Enable new dynamic tags">;
82
83def end_lib: F<"end-lib">,
84 HelpText<"End a grouping of objects that should be treated as if they were together in an archive">;
85
86def entry: S<"entry">, MetaVarName<"<entry>">,
87 HelpText<"Name of entry point symbol">;
88
89def error_limit: S<"error-limit">,
90 HelpText<"Maximum number of errors to emit before stopping (0 = no limit)">;
91
92def error_unresolved_symbols: F<"error-unresolved-symbols">,
93 HelpText<"Report unresolved symbols as errors">;
94
95def exclude_libs: S<"exclude-libs">,
96 HelpText<"Exclude static libraries from automatic export">;
97
98def export_dynamic: F<"export-dynamic">,
99 HelpText<"Put symbols in the dynamic symbol table">;
100
101def export_dynamic_symbol: S<"export-dynamic-symbol">,
102 HelpText<"Put a symbol in the dynamic symbol table">;
103
104def fatal_warnings: F<"fatal-warnings">,
105 HelpText<"Treat warnings as errors">;
106
107def filter: J<"filter=">, HelpText<"Set DT_FILTER field to the specified name">;
108
109def fini: S<"fini">, MetaVarName<"<symbol>">,
110 HelpText<"Specify a finalizer function">;
111
112def full_shutdown : F<"full-shutdown">,
113 HelpText<"Perform a full shutdown instead of calling _exit">;
114
115def format: J<"format=">, MetaVarName<"<input-format>">,
116 HelpText<"Change the input format of the inputs following this option">;
117
118def gc_sections: F<"gc-sections">,
119 HelpText<"Enable garbage collection of unused sections">;
120
121def gdb_index: F<"gdb-index">,
122 HelpText<"Generate .gdb_index section">;
123
124def hash_style: S<"hash-style">,
125 HelpText<"Specify hash style (sysv, gnu or both)">;
126
127def help: F<"help">, HelpText<"Print option help">;
128
129def icf_all: F<"icf=all">, HelpText<"Enable identical code folding">;
130
131def icf_none: F<"icf=none">, HelpText<"Disable identical code folding">;
132
133def image_base : J<"image-base=">, HelpText<"Set the base address">;
134
135def init: S<"init">, MetaVarName<"<symbol>">,
136 HelpText<"Specify an initializer function">;
137
138def l: JoinedOrSeparate<["-"], "l">, MetaVarName<"<libName>">,
139 HelpText<"Root name of library to use">;
140
141def lto_O: J<"lto-O">, MetaVarName<"<opt-level>">,
142 HelpText<"Optimization level for LTO">;
143
144def m: JoinedOrSeparate<["-"], "m">, HelpText<"Set target emulation">;
145
146def Map: JS<"Map">, HelpText<"Print a link map to the specified file">;
147
148def nostdlib: F<"nostdlib">,
149 HelpText<"Only search directories specified on the command line">;
150
151def no_as_needed: F<"no-as-needed">,
152 HelpText<"Always DT_NEEDED for shared libraries">;
153
154def no_color_diagnostics: F<"no-color-diagnostics">,
155 HelpText<"Do not use colors in diagnostics">;
156
157def no_define_common: F<"no-define-common">,
158 HelpText<"Do not assign space to common symbols">;
159
160def no_demangle: F<"no-demangle">,
161 HelpText<"Do not demangle symbol names">;
162
163def no_dynamic_linker: F<"no-dynamic-linker">,
164 HelpText<"Inhibit output of .interp section">;
165
166def no_export_dynamic: F<"no-export-dynamic">;
167def no_fatal_warnings: F<"no-fatal-warnings">;
168
169def no_gc_sections: F<"no-gc-sections">,
170 HelpText<"Disable garbage collection of unused sections">;
171
172def no_gnu_unique: F<"no-gnu-unique">,
173 HelpText<"Disable STB_GNU_UNIQUE symbol binding">;
174
175def no_threads: F<"no-threads">,
176 HelpText<"Do not run the linker multi-threaded">;
177
178def no_whole_archive: F<"no-whole-archive">,
179 HelpText<"Restores the default behavior of loading archive members">;
180
181def noinhibit_exec: F<"noinhibit-exec">,
182 HelpText<"Retain the executable output file whenever it is still usable">;
183
184def nopie: F<"nopie">, HelpText<"Do not create a position independent executable">;
185
186def no_rosegment: F<"no-rosegment">, HelpText<"Do not put read-only non-executable sections in their own segment">;
187
188def no_undefined: F<"no-undefined">,
189 HelpText<"Report unresolved symbols even if the linker is creating a shared library">;
190
191def no_undefined_version: F<"no-undefined-version">,
192 HelpText<"Report version scripts that refer undefined symbols">;
193
194def o: JoinedOrSeparate<["-"], "o">, MetaVarName<"<path>">,
195 HelpText<"Path to file to write output">;
196
197def oformat: Separate<["--"], "oformat">, MetaVarName<"<format>">,
198 HelpText<"Specify the binary format for the output object file">;
199
200def omagic: Flag<["--"], "omagic">, MetaVarName<"<magic>">,
201 HelpText<"Set the text and data sections to be readable and writable">;
202
203def pie: F<"pie">, HelpText<"Create a position independent executable">;
204
205def print_gc_sections: F<"print-gc-sections">,
206 HelpText<"List removed unused sections">;
207
208def print_map: F<"print-map">,
209 HelpText<"Print a link map to the standard output">;
210
211def reproduce: S<"reproduce">,
212 HelpText<"Dump linker invocation and input files for debugging">;
213
214def rpath: S<"rpath">, HelpText<"Add a DT_RUNPATH to the output">;
215
216def relocatable: F<"relocatable">, HelpText<"Create relocatable object file">;
217
218def retain_symbols_file: J<"retain-symbols-file=">, MetaVarName<"<file>">,
219 HelpText<"Retain only the symbols listed in the file">;
220
221def script: S<"script">, HelpText<"Read linker script">;
222
223def section_start: S<"section-start">, MetaVarName<"<address>">,
224 HelpText<"Set address of section">;
225
226def shared: F<"shared">, HelpText<"Build a shared object">;
227
228def soname: J<"soname=">, HelpText<"Set DT_SONAME">;
229
230def sort_section: S<"sort-section">, HelpText<"Specifies sections sorting rule when linkerscript is used">;
231
232def start_lib: F<"start-lib">,
233 HelpText<"Start a grouping of objects that should be treated as if they were together in an archive">;
234
235def strip_all: F<"strip-all">, HelpText<"Strip all symbols">;
236
237def strip_debug: F<"strip-debug">, HelpText<"Strip debugging information">;
238
239def symbol_ordering_file: S<"symbol-ordering-file">,
240 HelpText<"Layout sections in the order specified by symbol file">;
241
242def sysroot: J<"sysroot=">, HelpText<"Set the system root">;
243
244def target1_rel: F<"target1-rel">, HelpText<"Interpret R_ARM_TARGET1 as R_ARM_REL32">;
245
246def target1_abs: F<"target1-abs">, HelpText<"Interpret R_ARM_TARGET1 as R_ARM_ABS32">;
247
248def target2: J<"target2=">, MetaVarName<"<type>">, HelpText<"Interpret R_ARM_TARGET2 as <type>, where <type> is one of rel, abs, or got-rel">;
249
250def threads: F<"threads">, HelpText<"Run the linker multi-threaded">;
251
252def trace: F<"trace">, HelpText<"Print the names of the input files">;
253
254def trace_symbol : S<"trace-symbol">, HelpText<"Trace references to symbols">;
255
256def undefined: S<"undefined">,
257 HelpText<"Force undefined symbol during linking">;
258
259def unresolved_symbols: J<"unresolved-symbols=">,
260 HelpText<"Determine how to handle unresolved symbols">;
261
262def rsp_quoting: J<"rsp-quoting=">,
263 HelpText<"Quoting style for response files. Values supported: windows|posix">;
264
265def v: Flag<["-"], "v">, HelpText<"Display the version number">;
266
267def verbose: F<"verbose">, HelpText<"Verbose mode">;
268
269def version: F<"version">, HelpText<"Display the version number and exit">;
270
271def version_script: S<"version-script">,
272 HelpText<"Read a version script">;
273
274def warn_common: F<"warn-common">,
275 HelpText<"Warn about duplicate common symbols">;
276
277def warn_unresolved_symbols: F<"warn-unresolved-symbols">,
278 HelpText<"Report unresolved symbols as warnings">;
279
280def whole_archive: F<"whole-archive">,
281 HelpText<"Force load of all members in a static library">;
282
283def wrap: S<"wrap">, MetaVarName<"<symbol>">,
284 HelpText<"Use wrapper functions for symbol">;
285
286def z: JoinedOrSeparate<["-"], "z">, MetaVarName<"<option>">,
287 HelpText<"Linker option extensions">;
288
289// Aliases
290def alias_auxiliary: Separate<["-"], "f">, Alias<auxiliary>;
291def alias_Bdynamic_call_shared: F<"call_shared">, Alias<Bdynamic>;
292def alias_Bdynamic_dy: F<"dy">, Alias<Bdynamic>;
293def alias_Bstatic_dn: F<"dn">, Alias<Bstatic>;
294def alias_Bstatic_non_shared: F<"non_shared">, Alias<Bstatic>;
295def alias_Bstatic_static: F<"static">, Alias<Bstatic>;
296def alias_L__library_path: J<"library-path=">, Alias<L>;
297def alias_define_common_d: Flag<["-"], "d">, Alias<define_common>;
298def alias_define_common_dc: F<"dc">, Alias<define_common>;
299def alias_define_common_dp: F<"dp">, Alias<define_common>;
300def alias_defsym: S<"defsym">, Alias<defsym>;
301def alias_discard_all_x: Flag<["-"], "x">, Alias<discard_all>;
302def alias_discard_locals_X: Flag<["-"], "X">, Alias<discard_locals>;
303def alias_dynamic_list: J<"dynamic-list=">, Alias<dynamic_list>;
304def alias_emit_relocs: Flag<["-"], "q">, Alias<emit_relocs>;
305def alias_entry_e: JoinedOrSeparate<["-"], "e">, Alias<entry>;
306def alias_entry_entry: J<"entry=">, Alias<entry>;
307def alias_error_limit: J<"error-limit=">, Alias<error_limit>;
308def alias_exclude_libs: J<"exclude-libs=">, Alias<exclude_libs>;
309def alias_export_dynamic_E: Flag<["-"], "E">, Alias<export_dynamic>;
310def alias_export_dynamic_symbol: J<"export-dynamic-symbol=">,
311 Alias<export_dynamic_symbol>;
312def alias_filter: Separate<["-"], "F">, Alias<filter>;
313def alias_fini_fini: J<"fini=">, Alias<fini>;
314def alias_format_b: S<"b">, Alias<format>;
315def alias_hash_style_hash_style: J<"hash-style=">, Alias<hash_style>;
316def alias_init_init: J<"init=">, Alias<init>;
317def alias_l__library: J<"library=">, Alias<l>;
318def alias_Map_eq: J<"Map=">, Alias<Map>;
319def alias_omagic: Flag<["-"], "N">, Alias<omagic>;
320def alias_o_output: Joined<["--"], "output=">, Alias<o>;
321def alias_o_output2 : Separate<["--"], "output">, Alias<o>;
322def alias_pie_pic_executable: F<"pic-executable">, Alias<pie>;
323def alias_print_map_M: Flag<["-"], "M">, Alias<print_map>;
324def alias_relocatable_r: Flag<["-"], "r">, Alias<relocatable>;
325def alias_reproduce_eq: J<"reproduce=">, Alias<reproduce>;
326def alias_retain_symbols_file: S<"retain-symbols-file">, Alias<retain_symbols_file>;
327def alias_rpath_R: JoinedOrSeparate<["-"], "R">, Alias<rpath>;
328def alias_rpath_rpath: J<"rpath=">, Alias<rpath>;
329def alias_script_T: JoinedOrSeparate<["-"], "T">, Alias<script>;
330def alias_shared_Bshareable: F<"Bshareable">, Alias<shared>;
331def alias_soname_h: JoinedOrSeparate<["-"], "h">, Alias<soname>;
332def alias_soname_soname: S<"soname">, Alias<soname>;
333def alias_sort_section: J<"sort-section=">, Alias<sort_section>;
334def alias_script: J<"script=">, Alias<script>;
335def alias_strip_all: Flag<["-"], "s">, Alias<strip_all>;
336def alias_strip_debug_S: Flag<["-"], "S">, Alias<strip_debug>;
337def alias_Tbss: J<"Tbss=">, Alias<Tbss>;
338def alias_Tdata: J<"Tdata=">, Alias<Tdata>;
339def alias_trace: Flag<["-"], "t">, Alias<trace>;
340def trace_trace_symbol_eq : J<"trace-symbol=">, Alias<trace_symbol>;
341def alias_trace_symbol_y : JoinedOrSeparate<["-"], "y">, Alias<trace_symbol>;
342def alias_Ttext: J<"Ttext=">, Alias<Ttext>;
343def alias_Ttext_segment: S<"Ttext-segment">, Alias<Ttext>;
344def alias_Ttext_segment_eq: J<"Ttext-segment=">, Alias<Ttext>;
345def alias_undefined_eq: J<"undefined=">, Alias<undefined>;
346def alias_undefined_u: JoinedOrSeparate<["-"], "u">, Alias<undefined>;
347def alias_version_script_eq: J<"version-script=">, Alias<version_script>;
348def alias_version_V: Flag<["-"], "V">, Alias<version>;
349def alias_wrap_wrap: J<"wrap=">, Alias<wrap>;
350
351// Our symbol resolution algorithm handles symbols in archive files differently
352// than traditional linkers, so we don't need --start-group and --end-group.
353// These options are recongized for compatibility but ignored.
354def end_group: F<"end-group">;
355def end_group_paren: Flag<["-"], ")">;
356def start_group: F<"start-group">;
357def start_group_paren: Flag<["-"], "(">;
358
359// LTO-related options.
360def lto_aa_pipeline: J<"lto-aa-pipeline=">,
361 HelpText<"AA pipeline to run during LTO. Used in conjunction with -lto-newpm-passes">;
362def lto_newpm_passes: J<"lto-newpm-passes=">,
363 HelpText<"Passes to run during LTO">;
364def lto_partitions: J<"lto-partitions=">,
365 HelpText<"Number of LTO codegen partitions">;
366def disable_verify: F<"disable-verify">;
367def mllvm: S<"mllvm">;
368def opt_remarks_filename: Separate<["--"], "opt-remarks-filename">,
369 HelpText<"YAML output file for optimization remarks">;
370def opt_remarks_with_hotness: Flag<["--"], "opt-remarks-with-hotness">,
371 HelpText<"Include hotness informations in the optimization remarks file">;
372def save_temps: F<"save-temps">;
373def thinlto_cache_dir: J<"thinlto-cache-dir=">,
374 HelpText<"Path to ThinLTO cached object file directory">;
375def thinlto_cache_policy: S<"thinlto-cache-policy">,
376 HelpText<"Pruning policy for the ThinLTO cache">;
377def thinlto_jobs: J<"thinlto-jobs=">, HelpText<"Number of ThinLTO jobs">;
378
379// Ignore LTO plugin-related options.
380// clang -flto passes -plugin and -plugin-opt to the linker. This is required
381// for ld.gold and ld.bfd to get LTO working. But it's not for lld which doesn't
382// rely on a plugin. Instead of detecting which linker is used on clang side we
383// just ignore the option on lld side as it's easier. In fact, the linker could
384// be called 'ld' and understanding which linker is used would require parsing of
385// --version output.
386def plugin: S<"plugin">;
387def plugin_eq: J<"plugin=">;
388def plugin_opt: S<"plugin-opt">;
389def plugin_opt_eq: J<"plugin-opt=">;
390
391// Options listed below are silently ignored for now for compatibility.
392def allow_shlib_undefined: F<"allow-shlib-undefined">;
393def cref: Flag<["--"], "cref">;
394def detect_odr_violations: F<"detect-odr-violations">;
395def g: Flag<["-"], "g">;
396def no_add_needed: F<"no-add-needed">;
397def no_allow_shlib_undefined: F<"no-allow-shlib-undefined">;
398def no_copy_dt_needed_entries: F<"no-copy-dt-needed-entries">,
399 Alias<no_add_needed>;
400def no_keep_memory: F<"no-keep-memory">;
401def no_mmap_output_file: F<"no-mmap-output-file">;
402def no_warn_common: F<"no-warn-common">;
403def no_warn_mismatch: F<"no-warn-mismatch">;
404def rpath_link: S<"rpath-link">;
405def rpath_link_eq: J<"rpath-link=">;
406def sort_common: F<"sort-common">;
407def stats: F<"stats">;
408def warn_execstack: F<"warn-execstack">;
409def warn_shared_textrel: F<"warn-shared-textrel">;
410def EB : F<"EB">;
411def EL : F<"EL">;
412def G: JoinedOrSeparate<["-"], "G">;
413def Qy : F<"Qy">;
414
deps/lld/ELF/OutputSections.cpp created+277
......@@ -0,0 +1,277 @@
1//===- OutputSections.cpp -------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "OutputSections.h"
11#include "Config.h"
12#include "LinkerScript.h"
13#include "Memory.h"
14#include "Strings.h"
15#include "SymbolTable.h"
16#include "SyntheticSections.h"
17#include "Target.h"
18#include "Threads.h"
19#include "llvm/BinaryFormat/Dwarf.h"
20#include "llvm/Support/MD5.h"
21#include "llvm/Support/MathExtras.h"
22#include "llvm/Support/SHA1.h"
23
24using namespace llvm;
25using namespace llvm::dwarf;
26using namespace llvm::object;
27using namespace llvm::support::endian;
28using namespace llvm::ELF;
29
30using namespace lld;
31using namespace lld::elf;
32
33uint8_t Out::First;
34OutputSection *Out::Opd;
35uint8_t *Out::OpdBuf;
36PhdrEntry *Out::TlsPhdr;
37OutputSection *Out::DebugInfo;
38OutputSection *Out::ElfHeader;
39OutputSection *Out::ProgramHeaders;
40OutputSection *Out::PreinitArray;
41OutputSection *Out::InitArray;
42OutputSection *Out::FiniArray;
43
44std::vector<OutputSection *> elf::OutputSections;
45std::vector<OutputSectionCommand *> elf::OutputSectionCommands;
46
47uint32_t OutputSection::getPhdrFlags() const {
48 uint32_t Ret = PF_R;
49 if (Flags & SHF_WRITE)
50 Ret |= PF_W;
51 if (Flags & SHF_EXECINSTR)
52 Ret |= PF_X;
53 return Ret;
54}
55
56template <class ELFT>
57void OutputSection::writeHeaderTo(typename ELFT::Shdr *Shdr) {
58 Shdr->sh_entsize = Entsize;
59 Shdr->sh_addralign = Alignment;
60 Shdr->sh_type = Type;
61 Shdr->sh_offset = Offset;
62 Shdr->sh_flags = Flags;
63 Shdr->sh_info = Info;
64 Shdr->sh_link = Link;
65 Shdr->sh_addr = Addr;
66 Shdr->sh_size = Size;
67 Shdr->sh_name = ShName;
68}
69
70OutputSection::OutputSection(StringRef Name, uint32_t Type, uint64_t Flags)
71 : SectionBase(Output, Name, Flags, /*Entsize*/ 0, /*Alignment*/ 1, Type,
72 /*Info*/ 0,
73 /*Link*/ 0),
74 SectionIndex(INT_MAX) {}
75
76static uint64_t updateOffset(uint64_t Off, InputSection *S) {
77 Off = alignTo(Off, S->Alignment);
78 S->OutSecOff = Off;
79 return Off + S->getSize();
80}
81
82void OutputSection::addSection(InputSection *S) {
83 assert(S->Live);
84 Sections.push_back(S);
85 S->Parent = this;
86 this->updateAlignment(S->Alignment);
87
88 // The actual offsets will be computed by assignAddresses. For now, use
89 // crude approximation so that it is at least easy for other code to know the
90 // section order. It is also used to calculate the output section size early
91 // for compressed debug sections.
92 this->Size = updateOffset(Size, S);
93
94 // If this section contains a table of fixed-size entries, sh_entsize
95 // holds the element size. Consequently, if this contains two or more
96 // input sections, all of them must have the same sh_entsize. However,
97 // you can put different types of input sections into one output
98 // sectin by using linker scripts. I don't know what to do here.
99 // Probably we sholuld handle that as an error. But for now we just
100 // pick the largest sh_entsize.
101 this->Entsize = std::max(this->Entsize, S->Entsize);
102}
103
104static SectionKey createKey(InputSectionBase *C, StringRef OutsecName) {
105 // The ELF spec just says
106 // ----------------------------------------------------------------
107 // In the first phase, input sections that match in name, type and
108 // attribute flags should be concatenated into single sections.
109 // ----------------------------------------------------------------
110 //
111 // However, it is clear that at least some flags have to be ignored for
112 // section merging. At the very least SHF_GROUP and SHF_COMPRESSED have to be
113 // ignored. We should not have two output .text sections just because one was
114 // in a group and another was not for example.
115 //
116 // It also seems that that wording was a late addition and didn't get the
117 // necessary scrutiny.
118 //
119 // Merging sections with different flags is expected by some users. One
120 // reason is that if one file has
121 //
122 // int *const bar __attribute__((section(".foo"))) = (int *)0;
123 //
124 // gcc with -fPIC will produce a read only .foo section. But if another
125 // file has
126 //
127 // int zed;
128 // int *const bar __attribute__((section(".foo"))) = (int *)&zed;
129 //
130 // gcc with -fPIC will produce a read write section.
131 //
132 // Last but not least, when using linker script the merge rules are forced by
133 // the script. Unfortunately, linker scripts are name based. This means that
134 // expressions like *(.foo*) can refer to multiple input sections with
135 // different flags. We cannot put them in different output sections or we
136 // would produce wrong results for
137 //
138 // start = .; *(.foo.*) end = .; *(.bar)
139 //
140 // and a mapping of .foo1 and .bar1 to one section and .foo2 and .bar2 to
141 // another. The problem is that there is no way to layout those output
142 // sections such that the .foo sections are the only thing between the start
143 // and end symbols.
144 //
145 // Given the above issues, we instead merge sections by name and error on
146 // incompatible types and flags.
147
148 uint32_t Alignment = 0;
149 uint64_t Flags = 0;
150 if (Config->Relocatable && (C->Flags & SHF_MERGE)) {
151 Alignment = std::max<uint64_t>(C->Alignment, C->Entsize);
152 Flags = C->Flags & (SHF_MERGE | SHF_STRINGS);
153 }
154
155 return SectionKey{OutsecName, Flags, Alignment};
156}
157
158OutputSectionFactory::OutputSectionFactory() {}
159
160static uint64_t getIncompatibleFlags(uint64_t Flags) {
161 return Flags & (SHF_ALLOC | SHF_TLS);
162}
163
164// We allow sections of types listed below to merged into a
165// single progbits section. This is typically done by linker
166// scripts. Merging nobits and progbits will force disk space
167// to be allocated for nobits sections. Other ones don't require
168// any special treatment on top of progbits, so there doesn't
169// seem to be a harm in merging them.
170static bool canMergeToProgbits(unsigned Type) {
171 return Type == SHT_NOBITS || Type == SHT_PROGBITS || Type == SHT_INIT_ARRAY ||
172 Type == SHT_PREINIT_ARRAY || Type == SHT_FINI_ARRAY ||
173 Type == SHT_NOTE;
174}
175
176void elf::reportDiscarded(InputSectionBase *IS) {
177 if (!Config->PrintGcSections)
178 return;
179 message("removing unused section from '" + IS->Name + "' in file '" +
180 IS->File->getName() + "'");
181}
182
183void OutputSectionFactory::addInputSec(InputSectionBase *IS,
184 StringRef OutsecName) {
185 // Sections with the SHT_GROUP attribute reach here only when the - r option
186 // is given. Such sections define "section groups", and InputFiles.cpp has
187 // dedup'ed section groups by their signatures. For the -r, we want to pass
188 // through all SHT_GROUP sections without merging them because merging them
189 // creates broken section contents.
190 if (IS->Type == SHT_GROUP) {
191 OutputSection *Out = nullptr;
192 addInputSec(IS, OutsecName, Out);
193 return;
194 }
195
196 // Imagine .zed : { *(.foo) *(.bar) } script. Both foo and bar may have
197 // relocation sections .rela.foo and .rela.bar for example. Most tools do
198 // not allow multiple REL[A] sections for output section. Hence we
199 // should combine these relocation sections into single output.
200 // We skip synthetic sections because it can be .rela.dyn/.rela.plt or any
201 // other REL[A] sections created by linker itself.
202 if (!isa<SyntheticSection>(IS) &&
203 (IS->Type == SHT_REL || IS->Type == SHT_RELA)) {
204 auto *Sec = cast<InputSection>(IS);
205 OutputSection *Out = Sec->getRelocatedSection()->getOutputSection();
206 addInputSec(IS, OutsecName, Out->RelocationSection);
207 return;
208 }
209
210 SectionKey Key = createKey(IS, OutsecName);
211 OutputSection *&Sec = Map[Key];
212 addInputSec(IS, OutsecName, Sec);
213}
214
215void OutputSectionFactory::addInputSec(InputSectionBase *IS,
216 StringRef OutsecName,
217 OutputSection *&Sec) {
218 if (!IS->Live) {
219 reportDiscarded(IS);
220 return;
221 }
222
223 if (Sec) {
224 if (getIncompatibleFlags(Sec->Flags) != getIncompatibleFlags(IS->Flags))
225 error("incompatible section flags for " + Sec->Name + "\n>>> " +
226 toString(IS) + ": 0x" + utohexstr(IS->Flags) +
227 "\n>>> output section " + Sec->Name + ": 0x" +
228 utohexstr(Sec->Flags));
229 if (Sec->Type != IS->Type) {
230 if (canMergeToProgbits(Sec->Type) && canMergeToProgbits(IS->Type))
231 Sec->Type = SHT_PROGBITS;
232 else
233 error("section type mismatch for " + IS->Name + "\n>>> " +
234 toString(IS) + ": " +
235 getELFSectionTypeName(Config->EMachine, IS->Type) +
236 "\n>>> output section " + Sec->Name + ": " +
237 getELFSectionTypeName(Config->EMachine, Sec->Type));
238 }
239 Sec->Flags |= IS->Flags;
240 } else {
241 Sec = make<OutputSection>(OutsecName, IS->Type, IS->Flags);
242 OutputSections.push_back(Sec);
243 }
244
245 Sec->addSection(cast<InputSection>(IS));
246}
247
248OutputSectionFactory::~OutputSectionFactory() {}
249
250SectionKey DenseMapInfo<SectionKey>::getEmptyKey() {
251 return SectionKey{DenseMapInfo<StringRef>::getEmptyKey(), 0, 0};
252}
253
254SectionKey DenseMapInfo<SectionKey>::getTombstoneKey() {
255 return SectionKey{DenseMapInfo<StringRef>::getTombstoneKey(), 0, 0};
256}
257
258unsigned DenseMapInfo<SectionKey>::getHashValue(const SectionKey &Val) {
259 return hash_combine(Val.Name, Val.Flags, Val.Alignment);
260}
261
262bool DenseMapInfo<SectionKey>::isEqual(const SectionKey &LHS,
263 const SectionKey &RHS) {
264 return DenseMapInfo<StringRef>::isEqual(LHS.Name, RHS.Name) &&
265 LHS.Flags == RHS.Flags && LHS.Alignment == RHS.Alignment;
266}
267
268uint64_t elf::getHeaderSize() {
269 if (Config->OFormatBinary)
270 return 0;
271 return Out::ElfHeader->Size + Out::ProgramHeaders->Size;
272}
273
274template void OutputSection::writeHeaderTo<ELF32LE>(ELF32LE::Shdr *Shdr);
275template void OutputSection::writeHeaderTo<ELF32BE>(ELF32BE::Shdr *Shdr);
276template void OutputSection::writeHeaderTo<ELF64LE>(ELF64LE::Shdr *Shdr);
277template void OutputSection::writeHeaderTo<ELF64BE>(ELF64BE::Shdr *Shdr);
deps/lld/ELF/OutputSections.h created+153
......@@ -0,0 +1,153 @@
1//===- OutputSections.h -----------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_ELF_OUTPUT_SECTIONS_H
11#define LLD_ELF_OUTPUT_SECTIONS_H
12
13#include "Config.h"
14#include "InputSection.h"
15#include "Relocations.h"
16
17#include "lld/Core/LLVM.h"
18#include "llvm/MC/StringTableBuilder.h"
19#include "llvm/Object/ELF.h"
20
21namespace lld {
22namespace elf {
23
24struct PhdrEntry;
25class SymbolBody;
26struct EhSectionPiece;
27class EhInputSection;
28class InputSection;
29class InputSectionBase;
30class MergeInputSection;
31class OutputSection;
32template <class ELFT> class ObjectFile;
33template <class ELFT> class SharedFile;
34class SharedSymbol;
35class DefinedRegular;
36
37// This represents a section in an output file.
38// It is composed of multiple InputSections.
39// The writer creates multiple OutputSections and assign them unique,
40// non-overlapping file offsets and VAs.
41class OutputSection final : public SectionBase {
42public:
43 OutputSection(StringRef Name, uint32_t Type, uint64_t Flags);
44
45 static bool classof(const SectionBase *S) {
46 return S->kind() == SectionBase::Output;
47 }
48
49 uint64_t getLMA() const { return Addr + LMAOffset; }
50 template <typename ELFT> void writeHeaderTo(typename ELFT::Shdr *SHdr);
51
52 unsigned SectionIndex;
53 unsigned SortRank;
54
55 uint32_t getPhdrFlags() const;
56
57 void updateAlignment(uint32_t Val) {
58 if (Val > Alignment)
59 Alignment = Val;
60 }
61
62 // Pointer to the first section in PT_LOAD segment, which this section
63 // also resides in. This field is used to correctly compute file offset
64 // of a section. When two sections share the same load segment, difference
65 // between their file offsets should be equal to difference between their
66 // virtual addresses. To compute some section offset we use the following
67 // formula: Off = Off_first + VA - VA_first.
68 OutputSection *FirstInPtLoad = nullptr;
69
70 // Pointer to a relocation section for this section. Usually nullptr because
71 // we consume relocations, but if --emit-relocs is specified (which is rare),
72 // it may have a non-null value.
73 OutputSection *RelocationSection = nullptr;
74
75 // The following fields correspond to Elf_Shdr members.
76 uint64_t Size = 0;
77 uint64_t Offset = 0;
78 uint64_t LMAOffset = 0;
79 uint64_t Addr = 0;
80 uint32_t ShName = 0;
81
82 void addSection(InputSection *S);
83 std::vector<InputSection *> Sections;
84
85 // Used for implementation of --compress-debug-sections option.
86 std::vector<uint8_t> ZDebugHeader;
87 llvm::SmallVector<char, 1> CompressedData;
88
89 // Location in the output buffer.
90 uint8_t *Loc = nullptr;
91};
92
93// All output sections that are handled by the linker specially are
94// globally accessible. Writer initializes them, so don't use them
95// until Writer is initialized.
96struct Out {
97 static uint8_t First;
98 static OutputSection *Opd;
99 static uint8_t *OpdBuf;
100 static PhdrEntry *TlsPhdr;
101 static OutputSection *DebugInfo;
102 static OutputSection *ElfHeader;
103 static OutputSection *ProgramHeaders;
104 static OutputSection *PreinitArray;
105 static OutputSection *InitArray;
106 static OutputSection *FiniArray;
107};
108
109struct SectionKey {
110 StringRef Name;
111 uint64_t Flags;
112 uint32_t Alignment;
113};
114} // namespace elf
115} // namespace lld
116namespace llvm {
117template <> struct DenseMapInfo<lld::elf::SectionKey> {
118 static lld::elf::SectionKey getEmptyKey();
119 static lld::elf::SectionKey getTombstoneKey();
120 static unsigned getHashValue(const lld::elf::SectionKey &Val);
121 static bool isEqual(const lld::elf::SectionKey &LHS,
122 const lld::elf::SectionKey &RHS);
123};
124} // namespace llvm
125namespace lld {
126namespace elf {
127
128// This class knows how to create an output section for a given
129// input section. Output section type is determined by various
130// factors, including input section's sh_flags, sh_type and
131// linker scripts.
132class OutputSectionFactory {
133public:
134 OutputSectionFactory();
135 ~OutputSectionFactory();
136
137 void addInputSec(InputSectionBase *IS, StringRef OutsecName);
138 void addInputSec(InputSectionBase *IS, StringRef OutsecName,
139 OutputSection *&Sec);
140
141private:
142 llvm::SmallDenseMap<SectionKey, OutputSection *> Map;
143};
144
145uint64_t getHeaderSize();
146void reportDiscarded(InputSectionBase *IS);
147
148extern std::vector<OutputSection *> OutputSections;
149extern std::vector<OutputSectionCommand *> OutputSectionCommands;
150} // namespace elf
151} // namespace lld
152
153#endif
deps/lld/ELF/README.md created+1
......@@ -0,0 +1 @@
1See docs/NewLLD.rst
deps/lld/ELF/Relocations.cpp created+1144
......@@ -0,0 +1,1144 @@
1//===- Relocations.cpp ----------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains platform-independent functions to process relocations.
11// I'll describe the overview of this file here.
12//
13// Simple relocations are easy to handle for the linker. For example,
14// for R_X86_64_PC64 relocs, the linker just has to fix up locations
15// with the relative offsets to the target symbols. It would just be
16// reading records from relocation sections and applying them to output.
17//
18// But not all relocations are that easy to handle. For example, for
19// R_386_GOTOFF relocs, the linker has to create new GOT entries for
20// symbols if they don't exist, and fix up locations with GOT entry
21// offsets from the beginning of GOT section. So there is more than
22// fixing addresses in relocation processing.
23//
24// ELF defines a large number of complex relocations.
25//
26// The functions in this file analyze relocations and do whatever needs
27// to be done. It includes, but not limited to, the following.
28//
29// - create GOT/PLT entries
30// - create new relocations in .dynsym to let the dynamic linker resolve
31// them at runtime (since ELF supports dynamic linking, not all
32// relocations can be resolved at link-time)
33// - create COPY relocs and reserve space in .bss
34// - replace expensive relocs (in terms of runtime cost) with cheap ones
35// - error out infeasible combinations such as PIC and non-relative relocs
36//
37// Note that the functions in this file don't actually apply relocations
38// because it doesn't know about the output file nor the output file buffer.
39// It instead stores Relocation objects to InputSection's Relocations
40// vector to let it apply later in InputSection::writeTo.
41//
42//===----------------------------------------------------------------------===//
43
44#include "Relocations.h"
45#include "Config.h"
46#include "LinkerScript.h"
47#include "Memory.h"
48#include "OutputSections.h"
49#include "Strings.h"
50#include "SymbolTable.h"
51#include "SyntheticSections.h"
52#include "Target.h"
53#include "Thunks.h"
54
55#include "llvm/Support/Endian.h"
56#include "llvm/Support/raw_ostream.h"
57#include <algorithm>
58
59using namespace llvm;
60using namespace llvm::ELF;
61using namespace llvm::object;
62using namespace llvm::support::endian;
63
64using namespace lld;
65using namespace lld::elf;
66
67// Construct a message in the following format.
68//
69// >>> defined in /home/alice/src/foo.o
70// >>> referenced by bar.c:12 (/home/alice/src/bar.c:12)
71// >>> /home/alice/src/bar.o:(.text+0x1)
72template <class ELFT>
73static std::string getLocation(InputSectionBase &S, const SymbolBody &Sym,
74 uint64_t Off) {
75 std::string Msg =
76 "\n>>> defined in " + toString(Sym.File) + "\n>>> referenced by ";
77 std::string Src = S.getSrcMsg<ELFT>(Off);
78 if (!Src.empty())
79 Msg += Src + "\n>>> ";
80 return Msg + S.getObjMsg<ELFT>(Off);
81}
82
83static bool isPreemptible(const SymbolBody &Body, uint32_t Type) {
84 // In case of MIPS GP-relative relocations always resolve to a definition
85 // in a regular input file, ignoring the one-definition rule. So we,
86 // for example, should not attempt to create a dynamic relocation even
87 // if the target symbol is preemptible. There are two two MIPS GP-relative
88 // relocations R_MIPS_GPREL16 and R_MIPS_GPREL32. But only R_MIPS_GPREL16
89 // can be against a preemptible symbol.
90 // To get MIPS relocation type we apply 0xff mask. In case of O32 ABI all
91 // relocation types occupy eight bit. In case of N64 ABI we extract first
92 // relocation from 3-in-1 packet because only the first relocation can
93 // be against a real symbol.
94 if (Config->EMachine == EM_MIPS && (Type & 0xff) == R_MIPS_GPREL16)
95 return false;
96 return Body.isPreemptible();
97}
98
99// This function is similar to the `handleTlsRelocation`. MIPS does not
100// support any relaxations for TLS relocations so by factoring out MIPS
101// handling in to the separate function we can simplify the code and do not
102// pollute other `handleTlsRelocation` by MIPS `ifs` statements.
103// Mips has a custom MipsGotSection that handles the writing of GOT entries
104// without dynamic relocations.
105template <class ELFT>
106static unsigned handleMipsTlsRelocation(uint32_t Type, SymbolBody &Body,
107 InputSectionBase &C, uint64_t Offset,
108 int64_t Addend, RelExpr Expr) {
109 if (Expr == R_MIPS_TLSLD) {
110 if (InX::MipsGot->addTlsIndex() && Config->Pic)
111 In<ELFT>::RelaDyn->addReloc({Target->TlsModuleIndexRel, InX::MipsGot,
112 InX::MipsGot->getTlsIndexOff(), false,
113 nullptr, 0});
114 C.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
115 return 1;
116 }
117
118 if (Expr == R_MIPS_TLSGD) {
119 if (InX::MipsGot->addDynTlsEntry(Body) && Body.isPreemptible()) {
120 uint64_t Off = InX::MipsGot->getGlobalDynOffset(Body);
121 In<ELFT>::RelaDyn->addReloc(
122 {Target->TlsModuleIndexRel, InX::MipsGot, Off, false, &Body, 0});
123 if (Body.isPreemptible())
124 In<ELFT>::RelaDyn->addReloc({Target->TlsOffsetRel, InX::MipsGot,
125 Off + Config->Wordsize, false, &Body, 0});
126 }
127 C.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
128 return 1;
129 }
130 return 0;
131}
132
133// This function is similar to the `handleMipsTlsRelocation`. ARM also does not
134// support any relaxations for TLS relocations. ARM is logically similar to Mips
135// in how it handles TLS, but Mips uses its own custom GOT which handles some
136// of the cases that ARM uses GOT relocations for.
137//
138// We look for TLS global dynamic and local dynamic relocations, these may
139// require the generation of a pair of GOT entries that have associated
140// dynamic relocations. When the results of the dynamic relocations can be
141// resolved at static link time we do so. This is necessary for static linking
142// as there will be no dynamic loader to resolve them at load-time.
143//
144// The pair of GOT entries created are of the form
145// GOT[e0] Module Index (Used to find pointer to TLS block at run-time)
146// GOT[e1] Offset of symbol in TLS block
147template <class ELFT>
148static unsigned handleARMTlsRelocation(uint32_t Type, SymbolBody &Body,
149 InputSectionBase &C, uint64_t Offset,
150 int64_t Addend, RelExpr Expr) {
151 // The Dynamic TLS Module Index Relocation for a symbol defined in an
152 // executable is always 1. If the target Symbol is not preemtible then
153 // we know the offset into the TLS block at static link time.
154 bool NeedDynId = Body.isPreemptible() || Config->Shared;
155 bool NeedDynOff = Body.isPreemptible();
156
157 auto AddTlsReloc = [&](uint64_t Off, uint32_t Type, SymbolBody *Dest,
158 bool Dyn) {
159 if (Dyn)
160 In<ELFT>::RelaDyn->addReloc({Type, InX::Got, Off, false, Dest, 0});
161 else
162 InX::Got->Relocations.push_back({R_ABS, Type, Off, 0, Dest});
163 };
164
165 // Local Dynamic is for access to module local TLS variables, while still
166 // being suitable for being dynamically loaded via dlopen.
167 // GOT[e0] is the module index, with a special value of 0 for the current
168 // module. GOT[e1] is unused. There only needs to be one module index entry.
169 if (Expr == R_TLSLD_PC && InX::Got->addTlsIndex()) {
170 AddTlsReloc(InX::Got->getTlsIndexOff(), Target->TlsModuleIndexRel,
171 NeedDynId ? nullptr : &Body, NeedDynId);
172 C.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
173 return 1;
174 }
175
176 // Global Dynamic is the most general purpose access model. When we know
177 // the module index and offset of symbol in TLS block we can fill these in
178 // using static GOT relocations.
179 if (Expr == R_TLSGD_PC) {
180 if (InX::Got->addDynTlsEntry(Body)) {
181 uint64_t Off = InX::Got->getGlobalDynOffset(Body);
182 AddTlsReloc(Off, Target->TlsModuleIndexRel, &Body, NeedDynId);
183 AddTlsReloc(Off + Config->Wordsize, Target->TlsOffsetRel, &Body,
184 NeedDynOff);
185 }
186 C.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
187 return 1;
188 }
189 return 0;
190}
191
192// Returns the number of relocations processed.
193template <class ELFT>
194static unsigned
195handleTlsRelocation(uint32_t Type, SymbolBody &Body, InputSectionBase &C,
196 typename ELFT::uint Offset, int64_t Addend, RelExpr Expr) {
197 if (!(C.Flags & SHF_ALLOC))
198 return 0;
199
200 if (!Body.isTls())
201 return 0;
202
203 if (Config->EMachine == EM_ARM)
204 return handleARMTlsRelocation<ELFT>(Type, Body, C, Offset, Addend, Expr);
205 if (Config->EMachine == EM_MIPS)
206 return handleMipsTlsRelocation<ELFT>(Type, Body, C, Offset, Addend, Expr);
207
208 bool IsPreemptible = isPreemptible(Body, Type);
209 if (isRelExprOneOf<R_TLSDESC, R_TLSDESC_PAGE, R_TLSDESC_CALL>(Expr) &&
210 Config->Shared) {
211 if (InX::Got->addDynTlsEntry(Body)) {
212 uint64_t Off = InX::Got->getGlobalDynOffset(Body);
213 In<ELFT>::RelaDyn->addReloc(
214 {Target->TlsDescRel, InX::Got, Off, !IsPreemptible, &Body, 0});
215 }
216 if (Expr != R_TLSDESC_CALL)
217 C.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
218 return 1;
219 }
220
221 if (isRelExprOneOf<R_TLSLD_PC, R_TLSLD>(Expr)) {
222 // Local-Dynamic relocs can be relaxed to Local-Exec.
223 if (!Config->Shared) {
224 C.Relocations.push_back(
225 {R_RELAX_TLS_LD_TO_LE, Type, Offset, Addend, &Body});
226 return 2;
227 }
228 if (InX::Got->addTlsIndex())
229 In<ELFT>::RelaDyn->addReloc({Target->TlsModuleIndexRel, InX::Got,
230 InX::Got->getTlsIndexOff(), false, nullptr,
231 0});
232 C.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
233 return 1;
234 }
235
236 // Local-Dynamic relocs can be relaxed to Local-Exec.
237 if (isRelExprOneOf<R_ABS, R_TLSLD, R_TLSLD_PC>(Expr) && !Config->Shared) {
238 C.Relocations.push_back(
239 {R_RELAX_TLS_LD_TO_LE, Type, Offset, Addend, &Body});
240 return 1;
241 }
242
243 if (isRelExprOneOf<R_TLSDESC, R_TLSDESC_PAGE, R_TLSDESC_CALL, R_TLSGD,
244 R_TLSGD_PC>(Expr)) {
245 if (Config->Shared) {
246 if (InX::Got->addDynTlsEntry(Body)) {
247 uint64_t Off = InX::Got->getGlobalDynOffset(Body);
248 In<ELFT>::RelaDyn->addReloc(
249 {Target->TlsModuleIndexRel, InX::Got, Off, false, &Body, 0});
250
251 // If the symbol is preemptible we need the dynamic linker to write
252 // the offset too.
253 uint64_t OffsetOff = Off + Config->Wordsize;
254 if (IsPreemptible)
255 In<ELFT>::RelaDyn->addReloc(
256 {Target->TlsOffsetRel, InX::Got, OffsetOff, false, &Body, 0});
257 else
258 InX::Got->Relocations.push_back(
259 {R_ABS, Target->TlsOffsetRel, OffsetOff, 0, &Body});
260 }
261 C.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
262 return 1;
263 }
264
265 // Global-Dynamic relocs can be relaxed to Initial-Exec or Local-Exec
266 // depending on the symbol being locally defined or not.
267 if (IsPreemptible) {
268 C.Relocations.push_back(
269 {Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_GD_TO_IE), Type,
270 Offset, Addend, &Body});
271 if (!Body.isInGot()) {
272 InX::Got->addEntry(Body);
273 In<ELFT>::RelaDyn->addReloc({Target->TlsGotRel, InX::Got,
274 Body.getGotOffset(), false, &Body, 0});
275 }
276 } else {
277 C.Relocations.push_back(
278 {Target->adjustRelaxExpr(Type, nullptr, R_RELAX_TLS_GD_TO_LE), Type,
279 Offset, Addend, &Body});
280 }
281 return Target->TlsGdRelaxSkip;
282 }
283
284 // Initial-Exec relocs can be relaxed to Local-Exec if the symbol is locally
285 // defined.
286 if (isRelExprOneOf<R_GOT, R_GOT_FROM_END, R_GOT_PC, R_GOT_PAGE_PC>(Expr) &&
287 !Config->Shared && !IsPreemptible) {
288 C.Relocations.push_back(
289 {R_RELAX_TLS_IE_TO_LE, Type, Offset, Addend, &Body});
290 return 1;
291 }
292
293 if (Expr == R_TLSDESC_CALL)
294 return 1;
295 return 0;
296}
297
298static uint32_t getMipsPairType(uint32_t Type, const SymbolBody &Sym) {
299 switch (Type) {
300 case R_MIPS_HI16:
301 return R_MIPS_LO16;
302 case R_MIPS_GOT16:
303 return Sym.isLocal() ? R_MIPS_LO16 : R_MIPS_NONE;
304 case R_MIPS_PCHI16:
305 return R_MIPS_PCLO16;
306 case R_MICROMIPS_HI16:
307 return R_MICROMIPS_LO16;
308 default:
309 return R_MIPS_NONE;
310 }
311}
312
313// True if non-preemptable symbol always has the same value regardless of where
314// the DSO is loaded.
315static bool isAbsolute(const SymbolBody &Body) {
316 if (Body.isUndefined())
317 return !Body.isLocal() && Body.symbol()->isWeak();
318 if (const auto *DR = dyn_cast<DefinedRegular>(&Body))
319 return DR->Section == nullptr; // Absolute symbol.
320 return false;
321}
322
323static bool isAbsoluteValue(const SymbolBody &Body) {
324 return isAbsolute(Body) || Body.isTls();
325}
326
327// Returns true if Expr refers a PLT entry.
328static bool needsPlt(RelExpr Expr) {
329 return isRelExprOneOf<R_PLT_PC, R_PPC_PLT_OPD, R_PLT, R_PLT_PAGE_PC>(Expr);
330}
331
332// Returns true if Expr refers a GOT entry. Note that this function
333// returns false for TLS variables even though they need GOT, because
334// TLS variables uses GOT differently than the regular variables.
335static bool needsGot(RelExpr Expr) {
336 return isRelExprOneOf<R_GOT, R_GOT_OFF, R_MIPS_GOT_LOCAL_PAGE, R_MIPS_GOT_OFF,
337 R_MIPS_GOT_OFF32, R_GOT_PAGE_PC, R_GOT_PC,
338 R_GOT_FROM_END>(Expr);
339}
340
341// True if this expression is of the form Sym - X, where X is a position in the
342// file (PC, or GOT for example).
343static bool isRelExpr(RelExpr Expr) {
344 return isRelExprOneOf<R_PC, R_GOTREL, R_GOTREL_FROM_END, R_MIPS_GOTREL,
345 R_PAGE_PC, R_RELAX_GOT_PC>(Expr);
346}
347
348// Returns true if a given relocation can be computed at link-time.
349//
350// For instance, we know the offset from a relocation to its target at
351// link-time if the relocation is PC-relative and refers a
352// non-interposable function in the same executable. This function
353// will return true for such relocation.
354//
355// If this function returns false, that means we need to emit a
356// dynamic relocation so that the relocation will be fixed at load-time.
357template <class ELFT>
358static bool isStaticLinkTimeConstant(RelExpr E, uint32_t Type,
359 const SymbolBody &Body,
360 InputSectionBase &S, uint64_t RelOff) {
361 // These expressions always compute a constant
362 if (isRelExprOneOf<R_SIZE, R_GOT_FROM_END, R_GOT_OFF, R_MIPS_GOT_LOCAL_PAGE,
363 R_MIPS_GOT_OFF, R_MIPS_GOT_OFF32, R_MIPS_GOT_GP_PC,
364 R_MIPS_TLSGD, R_GOT_PAGE_PC, R_GOT_PC, R_GOTONLY_PC,
365 R_GOTONLY_PC_FROM_END, R_PLT_PC, R_TLSGD_PC, R_TLSGD,
366 R_PPC_PLT_OPD, R_TLSDESC_CALL, R_TLSDESC_PAGE, R_HINT>(E))
367 return true;
368
369 // These never do, except if the entire file is position dependent or if
370 // only the low bits are used.
371 if (E == R_GOT || E == R_PLT || E == R_TLSDESC)
372 return Target->usesOnlyLowPageBits(Type) || !Config->Pic;
373
374 if (isPreemptible(Body, Type))
375 return false;
376 if (!Config->Pic)
377 return true;
378
379 // For the target and the relocation, we want to know if they are
380 // absolute or relative.
381 bool AbsVal = isAbsoluteValue(Body);
382 bool RelE = isRelExpr(E);
383 if (AbsVal && !RelE)
384 return true;
385 if (!AbsVal && RelE)
386 return true;
387 if (!AbsVal && !RelE)
388 return Target->usesOnlyLowPageBits(Type);
389
390 // Relative relocation to an absolute value. This is normally unrepresentable,
391 // but if the relocation refers to a weak undefined symbol, we allow it to
392 // resolve to the image base. This is a little strange, but it allows us to
393 // link function calls to such symbols. Normally such a call will be guarded
394 // with a comparison, which will load a zero from the GOT.
395 // Another special case is MIPS _gp_disp symbol which represents offset
396 // between start of a function and '_gp' value and defined as absolute just
397 // to simplify the code.
398 assert(AbsVal && RelE);
399 if (Body.isUndefined() && !Body.isLocal() && Body.symbol()->isWeak())
400 return true;
401
402 error("relocation " + toString(Type) + " cannot refer to absolute symbol: " +
403 toString(Body) + getLocation<ELFT>(S, Body, RelOff));
404 return true;
405}
406
407static RelExpr toPlt(RelExpr Expr) {
408 if (Expr == R_PPC_OPD)
409 return R_PPC_PLT_OPD;
410 if (Expr == R_PC)
411 return R_PLT_PC;
412 if (Expr == R_PAGE_PC)
413 return R_PLT_PAGE_PC;
414 if (Expr == R_ABS)
415 return R_PLT;
416 return Expr;
417}
418
419static RelExpr fromPlt(RelExpr Expr) {
420 // We decided not to use a plt. Optimize a reference to the plt to a
421 // reference to the symbol itself.
422 if (Expr == R_PLT_PC)
423 return R_PC;
424 if (Expr == R_PPC_PLT_OPD)
425 return R_PPC_OPD;
426 if (Expr == R_PLT)
427 return R_ABS;
428 return Expr;
429}
430
431// Returns true if a given shared symbol is in a read-only segment in a DSO.
432template <class ELFT> static bool isReadOnly(SharedSymbol *SS) {
433 typedef typename ELFT::Phdr Elf_Phdr;
434 uint64_t Value = SS->getValue<ELFT>();
435
436 // Determine if the symbol is read-only by scanning the DSO's program headers.
437 auto *File = cast<SharedFile<ELFT>>(SS->File);
438 for (const Elf_Phdr &Phdr : check(File->getObj().program_headers()))
439 if ((Phdr.p_type == ELF::PT_LOAD || Phdr.p_type == ELF::PT_GNU_RELRO) &&
440 !(Phdr.p_flags & ELF::PF_W) && Value >= Phdr.p_vaddr &&
441 Value < Phdr.p_vaddr + Phdr.p_memsz)
442 return true;
443 return false;
444}
445
446// Returns symbols at the same offset as a given symbol, including SS itself.
447//
448// If two or more symbols are at the same offset, and at least one of
449// them are copied by a copy relocation, all of them need to be copied.
450// Otherwise, they would refer different places at runtime.
451template <class ELFT>
452static std::vector<SharedSymbol *> getSymbolsAt(SharedSymbol *SS) {
453 typedef typename ELFT::Sym Elf_Sym;
454
455 auto *File = cast<SharedFile<ELFT>>(SS->File);
456 uint64_t Shndx = SS->getShndx<ELFT>();
457 uint64_t Value = SS->getValue<ELFT>();
458
459 std::vector<SharedSymbol *> Ret;
460 for (const Elf_Sym &S : File->getGlobalSymbols()) {
461 if (S.st_shndx != Shndx || S.st_value != Value)
462 continue;
463 StringRef Name = check(S.getName(File->getStringTable()));
464 SymbolBody *Sym = Symtab<ELFT>::X->find(Name);
465 if (auto *Alias = dyn_cast_or_null<SharedSymbol>(Sym))
466 Ret.push_back(Alias);
467 }
468 return Ret;
469}
470
471// Reserve space in .bss or .bss.rel.ro for copy relocation.
472//
473// The copy relocation is pretty much a hack. If you use a copy relocation
474// in your program, not only the symbol name but the symbol's size, RW/RO
475// bit and alignment become part of the ABI. In addition to that, if the
476// symbol has aliases, the aliases become part of the ABI. That's subtle,
477// but if you violate that implicit ABI, that can cause very counter-
478// intuitive consequences.
479//
480// So, what is the copy relocation? It's for linking non-position
481// independent code to DSOs. In an ideal world, all references to data
482// exported by DSOs should go indirectly through GOT. But if object files
483// are compiled as non-PIC, all data references are direct. There is no
484// way for the linker to transform the code to use GOT, as machine
485// instructions are already set in stone in object files. This is where
486// the copy relocation takes a role.
487//
488// A copy relocation instructs the dynamic linker to copy data from a DSO
489// to a specified address (which is usually in .bss) at load-time. If the
490// static linker (that's us) finds a direct data reference to a DSO
491// symbol, it creates a copy relocation, so that the symbol can be
492// resolved as if it were in .bss rather than in a DSO.
493//
494// As you can see in this function, we create a copy relocation for the
495// dynamic linker, and the relocation contains not only symbol name but
496// various other informtion about the symbol. So, such attributes become a
497// part of the ABI.
498//
499// Note for application developers: I can give you a piece of advice if
500// you are writing a shared library. You probably should export only
501// functions from your library. You shouldn't export variables.
502//
503// As an example what can happen when you export variables without knowing
504// the semantics of copy relocations, assume that you have an exported
505// variable of type T. It is an ABI-breaking change to add new members at
506// end of T even though doing that doesn't change the layout of the
507// existing members. That's because the space for the new members are not
508// reserved in .bss unless you recompile the main program. That means they
509// are likely to overlap with other data that happens to be laid out next
510// to the variable in .bss. This kind of issue is sometimes very hard to
511// debug. What's a solution? Instead of exporting a varaible V from a DSO,
512// define an accessor getV().
513template <class ELFT> static void addCopyRelSymbol(SharedSymbol *SS) {
514 // Copy relocation against zero-sized symbol doesn't make sense.
515 uint64_t SymSize = SS->template getSize<ELFT>();
516 if (SymSize == 0)
517 fatal("cannot create a copy relocation for symbol " + toString(*SS));
518
519 // See if this symbol is in a read-only segment. If so, preserve the symbol's
520 // memory protection by reserving space in the .bss.rel.ro section.
521 bool IsReadOnly = isReadOnly<ELFT>(SS);
522 BssSection *Sec = IsReadOnly ? InX::BssRelRo : InX::Bss;
523 uint64_t Off = Sec->reserveSpace(SymSize, SS->getAlignment<ELFT>());
524
525 // Look through the DSO's dynamic symbol table for aliases and create a
526 // dynamic symbol for each one. This causes the copy relocation to correctly
527 // interpose any aliases.
528 for (SharedSymbol *Sym : getSymbolsAt<ELFT>(SS)) {
529 Sym->NeedsCopy = true;
530 Sym->CopyRelSec = Sec;
531 Sym->CopyRelSecOff = Off;
532 Sym->symbol()->IsUsedInRegularObj = true;
533 }
534
535 In<ELFT>::RelaDyn->addReloc({Target->CopyRel, Sec, Off, false, SS, 0});
536}
537
538template <class ELFT>
539static RelExpr adjustExpr(SymbolBody &Body, RelExpr Expr, uint32_t Type,
540 const uint8_t *Data, InputSectionBase &S,
541 typename ELFT::uint RelOff) {
542 if (Body.isGnuIFunc()) {
543 Expr = toPlt(Expr);
544 } else if (!isPreemptible(Body, Type)) {
545 if (needsPlt(Expr))
546 Expr = fromPlt(Expr);
547 if (Expr == R_GOT_PC && !isAbsoluteValue(Body))
548 Expr = Target->adjustRelaxExpr(Type, Data, Expr);
549 }
550
551 bool IsWrite = !Config->ZText || (S.Flags & SHF_WRITE);
552 if (IsWrite || isStaticLinkTimeConstant<ELFT>(Expr, Type, Body, S, RelOff))
553 return Expr;
554
555 // This relocation would require the dynamic linker to write a value to read
556 // only memory. We can hack around it if we are producing an executable and
557 // the refered symbol can be preemepted to refer to the executable.
558 if (Config->Shared || (Config->Pic && !isRelExpr(Expr))) {
559 error("can't create dynamic relocation " + toString(Type) + " against " +
560 (Body.getName().empty() ? "local symbol"
561 : "symbol: " + toString(Body)) +
562 " in readonly segment" + getLocation<ELFT>(S, Body, RelOff));
563 return Expr;
564 }
565
566 if (Body.getVisibility() != STV_DEFAULT) {
567 error("cannot preempt symbol: " + toString(Body) +
568 getLocation<ELFT>(S, Body, RelOff));
569 return Expr;
570 }
571
572 if (Body.isObject()) {
573 // Produce a copy relocation.
574 auto *B = cast<SharedSymbol>(&Body);
575 if (!B->NeedsCopy) {
576 if (Config->ZNocopyreloc)
577 error("unresolvable relocation " + toString(Type) +
578 " against symbol '" + toString(*B) +
579 "'; recompile with -fPIC or remove '-z nocopyreloc'" +
580 getLocation<ELFT>(S, Body, RelOff));
581
582 addCopyRelSymbol<ELFT>(B);
583 }
584 return Expr;
585 }
586
587 if (Body.isFunc()) {
588 // This handles a non PIC program call to function in a shared library. In
589 // an ideal world, we could just report an error saying the relocation can
590 // overflow at runtime. In the real world with glibc, crt1.o has a
591 // R_X86_64_PC32 pointing to libc.so.
592 //
593 // The general idea on how to handle such cases is to create a PLT entry and
594 // use that as the function value.
595 //
596 // For the static linking part, we just return a plt expr and everything
597 // else will use the the PLT entry as the address.
598 //
599 // The remaining problem is making sure pointer equality still works. We
600 // need the help of the dynamic linker for that. We let it know that we have
601 // a direct reference to a so symbol by creating an undefined symbol with a
602 // non zero st_value. Seeing that, the dynamic linker resolves the symbol to
603 // the value of the symbol we created. This is true even for got entries, so
604 // pointer equality is maintained. To avoid an infinite loop, the only entry
605 // that points to the real function is a dedicated got entry used by the
606 // plt. That is identified by special relocation types (R_X86_64_JUMP_SLOT,
607 // R_386_JMP_SLOT, etc).
608 Body.NeedsPltAddr = true;
609 return toPlt(Expr);
610 }
611
612 error("symbol '" + toString(Body) + "' defined in " + toString(Body.File) +
613 " has no type");
614 return Expr;
615}
616
617// Returns an addend of a given relocation. If it is RELA, an addend
618// is in a relocation itself. If it is REL, we need to read it from an
619// input section.
620template <class ELFT, class RelTy>
621static int64_t computeAddend(const RelTy &Rel, const uint8_t *Buf) {
622 uint32_t Type = Rel.getType(Config->IsMips64EL);
623 int64_t A = RelTy::IsRela
624 ? getAddend<ELFT>(Rel)
625 : Target->getImplicitAddend(Buf + Rel.r_offset, Type);
626
627 if (Config->EMachine == EM_PPC64 && Config->Pic && Type == R_PPC64_TOC)
628 A += getPPC64TocBase();
629 return A;
630}
631
632// MIPS has an odd notion of "paired" relocations to calculate addends.
633// For example, if a relocation is of R_MIPS_HI16, there must be a
634// R_MIPS_LO16 relocation after that, and an addend is calculated using
635// the two relocations.
636template <class ELFT, class RelTy>
637static int64_t computeMipsAddend(const RelTy &Rel, InputSectionBase &Sec,
638 RelExpr Expr, SymbolBody &Body,
639 const RelTy *End) {
640 if (Expr == R_MIPS_GOTREL && Body.isLocal())
641 return Sec.getFile<ELFT>()->MipsGp0;
642
643 // The ABI says that the paired relocation is used only for REL.
644 // See p. 4-17 at ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
645 if (RelTy::IsRela)
646 return 0;
647
648 uint32_t Type = Rel.getType(Config->IsMips64EL);
649 uint32_t PairTy = getMipsPairType(Type, Body);
650 if (PairTy == R_MIPS_NONE)
651 return 0;
652
653 const uint8_t *Buf = Sec.Data.data();
654 uint32_t SymIndex = Rel.getSymbol(Config->IsMips64EL);
655
656 // To make things worse, paired relocations might not be contiguous in
657 // the relocation table, so we need to do linear search. *sigh*
658 for (const RelTy *RI = &Rel; RI != End; ++RI) {
659 if (RI->getType(Config->IsMips64EL) != PairTy)
660 continue;
661 if (RI->getSymbol(Config->IsMips64EL) != SymIndex)
662 continue;
663
664 endianness E = Config->Endianness;
665 int32_t Hi = (read32(Buf + Rel.r_offset, E) & 0xffff) << 16;
666 int32_t Lo = SignExtend32<16>(read32(Buf + RI->r_offset, E));
667 return Hi + Lo;
668 }
669
670 warn("can't find matching " + toString(PairTy) + " relocation for " +
671 toString(Type));
672 return 0;
673}
674
675template <class ELFT>
676static void reportUndefined(SymbolBody &Sym, InputSectionBase &S,
677 uint64_t Offset) {
678 if (Config->UnresolvedSymbols == UnresolvedPolicy::IgnoreAll)
679 return;
680
681 bool CanBeExternal = Sym.symbol()->computeBinding() != STB_LOCAL &&
682 Sym.getVisibility() == STV_DEFAULT;
683 if (Config->UnresolvedSymbols == UnresolvedPolicy::Ignore && CanBeExternal)
684 return;
685
686 std::string Msg =
687 "undefined symbol: " + toString(Sym) + "\n>>> referenced by ";
688
689 std::string Src = S.getSrcMsg<ELFT>(Offset);
690 if (!Src.empty())
691 Msg += Src + "\n>>> ";
692 Msg += S.getObjMsg<ELFT>(Offset);
693
694 if (Config->UnresolvedSymbols == UnresolvedPolicy::WarnAll ||
695 (Config->UnresolvedSymbols == UnresolvedPolicy::Warn && CanBeExternal)) {
696 warn(Msg);
697 } else {
698 error(Msg);
699 }
700}
701
702template <class RelTy>
703static std::pair<uint32_t, uint32_t>
704mergeMipsN32RelTypes(uint32_t Type, uint32_t Offset, RelTy *I, RelTy *E) {
705 // MIPS N32 ABI treats series of successive relocations with the same offset
706 // as a single relocation. The similar approach used by N64 ABI, but this ABI
707 // packs all relocations into the single relocation record. Here we emulate
708 // this for the N32 ABI. Iterate over relocation with the same offset and put
709 // theirs types into the single bit-set.
710 uint32_t Processed = 0;
711 for (; I != E && Offset == I->r_offset; ++I) {
712 ++Processed;
713 Type |= I->getType(Config->IsMips64EL) << (8 * Processed);
714 }
715 return std::make_pair(Type, Processed);
716}
717
718// .eh_frame sections are mergeable input sections, so their input
719// offsets are not linearly mapped to output section. For each input
720// offset, we need to find a section piece containing the offset and
721// add the piece's base address to the input offset to compute the
722// output offset. That isn't cheap.
723//
724// This class is to speed up the offset computation. When we process
725// relocations, we access offsets in the monotonically increasing
726// order. So we can optimize for that access pattern.
727//
728// For sections other than .eh_frame, this class doesn't do anything.
729namespace {
730class OffsetGetter {
731public:
732 explicit OffsetGetter(InputSectionBase &Sec) {
733 if (auto *Eh = dyn_cast<EhInputSection>(&Sec)) {
734 P = Eh->Pieces;
735 Size = Eh->Pieces.size();
736 }
737 }
738
739 // Translates offsets in input sections to offsets in output sections.
740 // Given offset must increase monotonically. We assume that P is
741 // sorted by InputOff.
742 uint64_t get(uint64_t Off) {
743 if (P.empty())
744 return Off;
745
746 while (I != Size && P[I].InputOff + P[I].size() <= Off)
747 ++I;
748 if (I == Size)
749 return Off;
750
751 // P must be contiguous, so there must be no holes in between.
752 assert(P[I].InputOff <= Off && "Relocation not in any piece");
753
754 // Offset -1 means that the piece is dead (i.e. garbage collected).
755 if (P[I].OutputOff == -1)
756 return -1;
757 return P[I].OutputOff + Off - P[I].InputOff;
758 }
759
760private:
761 ArrayRef<EhSectionPiece> P;
762 size_t I = 0;
763 size_t Size;
764};
765} // namespace
766
767template <class ELFT, class GotPltSection>
768static void addPltEntry(PltSection *Plt, GotPltSection *GotPlt,
769 RelocationSection<ELFT> *Rel, uint32_t Type,
770 SymbolBody &Sym, bool UseSymVA) {
771 Plt->addEntry<ELFT>(Sym);
772 GotPlt->addEntry(Sym);
773 Rel->addReloc({Type, GotPlt, Sym.getGotPltOffset(), UseSymVA, &Sym, 0});
774}
775
776template <class ELFT>
777static void addGotEntry(SymbolBody &Sym, bool Preemptible) {
778 InX::Got->addEntry(Sym);
779
780 uint64_t Off = Sym.getGotOffset();
781 uint32_t DynType;
782 RelExpr Expr = R_ABS;
783
784 if (Sym.isTls()) {
785 DynType = Target->TlsGotRel;
786 Expr = R_TLS;
787 } else if (!Preemptible && Config->Pic && !isAbsolute(Sym)) {
788 DynType = Target->RelativeRel;
789 } else {
790 DynType = Target->GotRel;
791 }
792
793 bool Constant = !Preemptible && !(Config->Pic && !isAbsolute(Sym));
794 if (!Constant)
795 In<ELFT>::RelaDyn->addReloc(
796 {DynType, InX::Got, Off, !Preemptible, &Sym, 0});
797
798 if (Constant || (!Config->IsRela && !Preemptible))
799 InX::Got->Relocations.push_back({Expr, DynType, Off, 0, &Sym});
800}
801
802// The reason we have to do this early scan is as follows
803// * To mmap the output file, we need to know the size
804// * For that, we need to know how many dynamic relocs we will have.
805// It might be possible to avoid this by outputting the file with write:
806// * Write the allocated output sections, computing addresses.
807// * Apply relocations, recording which ones require a dynamic reloc.
808// * Write the dynamic relocations.
809// * Write the rest of the file.
810// This would have some drawbacks. For example, we would only know if .rela.dyn
811// is needed after applying relocations. If it is, it will go after rw and rx
812// sections. Given that it is ro, we will need an extra PT_LOAD. This
813// complicates things for the dynamic linker and means we would have to reserve
814// space for the extra PT_LOAD even if we end up not using it.
815template <class ELFT, class RelTy>
816static void scanRelocs(InputSectionBase &Sec, ArrayRef<RelTy> Rels) {
817 OffsetGetter GetOffset(Sec);
818
819 for (auto I = Rels.begin(), End = Rels.end(); I != End; ++I) {
820 const RelTy &Rel = *I;
821 SymbolBody &Body = Sec.getFile<ELFT>()->getRelocTargetSym(Rel);
822 uint32_t Type = Rel.getType(Config->IsMips64EL);
823
824 if (Config->MipsN32Abi) {
825 uint32_t Processed;
826 std::tie(Type, Processed) =
827 mergeMipsN32RelTypes(Type, Rel.r_offset, I + 1, End);
828 I += Processed;
829 }
830
831 // Compute the offset of this section in the output section.
832 uint64_t Offset = GetOffset.get(Rel.r_offset);
833 if (Offset == uint64_t(-1))
834 continue;
835
836 // Report undefined symbols. The fact that we report undefined
837 // symbols here means that we report undefined symbols only when
838 // they have relocations pointing to them. We don't care about
839 // undefined symbols that are in dead-stripped sections.
840 if (!Body.isLocal() && Body.isUndefined() && !Body.symbol()->isWeak())
841 reportUndefined<ELFT>(Body, Sec, Rel.r_offset);
842
843 RelExpr Expr =
844 Target->getRelExpr(Type, Body, Sec.Data.begin() + Rel.r_offset);
845
846 // Ignore "hint" relocations because they are only markers for relaxation.
847 if (isRelExprOneOf<R_HINT, R_NONE>(Expr))
848 continue;
849
850 bool Preemptible = isPreemptible(Body, Type);
851 Expr = adjustExpr<ELFT>(Body, Expr, Type, Sec.Data.data() + Rel.r_offset,
852 Sec, Rel.r_offset);
853 if (ErrorCount)
854 continue;
855
856 // This relocation does not require got entry, but it is relative to got and
857 // needs it to be created. Here we request for that.
858 if (isRelExprOneOf<R_GOTONLY_PC, R_GOTONLY_PC_FROM_END, R_GOTREL,
859 R_GOTREL_FROM_END, R_PPC_TOC>(Expr))
860 InX::Got->HasGotOffRel = true;
861
862 // Read an addend.
863 int64_t Addend = computeAddend<ELFT>(Rel, Sec.Data.data());
864 if (Config->EMachine == EM_MIPS)
865 Addend += computeMipsAddend<ELFT>(Rel, Sec, Expr, Body, End);
866
867 // Process some TLS relocations, including relaxing TLS relocations.
868 // Note that this function does not handle all TLS relocations.
869 if (unsigned Processed =
870 handleTlsRelocation<ELFT>(Type, Body, Sec, Offset, Addend, Expr)) {
871 I += (Processed - 1);
872 continue;
873 }
874
875 // If a relocation needs PLT, we create PLT and GOTPLT slots for the symbol.
876 if (needsPlt(Expr) && !Body.isInPlt()) {
877 if (Body.isGnuIFunc() && !Preemptible)
878 addPltEntry(InX::Iplt, InX::IgotPlt, In<ELFT>::RelaIplt,
879 Target->IRelativeRel, Body, true);
880 else
881 addPltEntry(InX::Plt, InX::GotPlt, In<ELFT>::RelaPlt, Target->PltRel,
882 Body, !Preemptible);
883 }
884
885 // Create a GOT slot if a relocation needs GOT.
886 if (needsGot(Expr)) {
887 if (Config->EMachine == EM_MIPS) {
888 // MIPS ABI has special rules to process GOT entries and doesn't
889 // require relocation entries for them. A special case is TLS
890 // relocations. In that case dynamic loader applies dynamic
891 // relocations to initialize TLS GOT entries.
892 // See "Global Offset Table" in Chapter 5 in the following document
893 // for detailed description:
894 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
895 InX::MipsGot->addEntry(Body, Addend, Expr);
896 if (Body.isTls() && Body.isPreemptible())
897 In<ELFT>::RelaDyn->addReloc({Target->TlsGotRel, InX::MipsGot,
898 Body.getGotOffset(), false, &Body, 0});
899 } else if (!Body.isInGot()) {
900 addGotEntry<ELFT>(Body, Preemptible);
901 }
902 }
903
904 if (!needsPlt(Expr) && !needsGot(Expr) && isPreemptible(Body, Type)) {
905 // We don't know anything about the finaly symbol. Just ask the dynamic
906 // linker to handle the relocation for us.
907 if (!Target->isPicRel(Type))
908 error("relocation " + toString(Type) +
909 " cannot be used against shared object; recompile with -fPIC" +
910 getLocation<ELFT>(Sec, Body, Offset));
911
912 In<ELFT>::RelaDyn->addReloc(
913 {Target->getDynRel(Type), &Sec, Offset, false, &Body, Addend});
914
915 // MIPS ABI turns using of GOT and dynamic relocations inside out.
916 // While regular ABI uses dynamic relocations to fill up GOT entries
917 // MIPS ABI requires dynamic linker to fills up GOT entries using
918 // specially sorted dynamic symbol table. This affects even dynamic
919 // relocations against symbols which do not require GOT entries
920 // creation explicitly, i.e. do not have any GOT-relocations. So if
921 // a preemptible symbol has a dynamic relocation we anyway have
922 // to create a GOT entry for it.
923 // If a non-preemptible symbol has a dynamic relocation against it,
924 // dynamic linker takes it st_value, adds offset and writes down
925 // result of the dynamic relocation. In case of preemptible symbol
926 // dynamic linker performs symbol resolution, writes the symbol value
927 // to the GOT entry and reads the GOT entry when it needs to perform
928 // a dynamic relocation.
929 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf p.4-19
930 if (Config->EMachine == EM_MIPS)
931 InX::MipsGot->addEntry(Body, Addend, Expr);
932 continue;
933 }
934
935 // If the relocation points to something in the file, we can process it.
936 bool IsConstant =
937 isStaticLinkTimeConstant<ELFT>(Expr, Type, Body, Sec, Rel.r_offset);
938
939 // The size is not going to change, so we fold it in here.
940 if (Expr == R_SIZE)
941 Addend += Body.getSize<ELFT>();
942
943 // If the output being produced is position independent, the final value
944 // is still not known. In that case we still need some help from the
945 // dynamic linker. We can however do better than just copying the incoming
946 // relocation. We can process some of it and and just ask the dynamic
947 // linker to add the load address.
948 if (!IsConstant)
949 In<ELFT>::RelaDyn->addReloc(
950 {Target->RelativeRel, &Sec, Offset, true, &Body, Addend});
951
952 // If the produced value is a constant, we just remember to write it
953 // when outputting this section. We also have to do it if the format
954 // uses Elf_Rel, since in that case the written value is the addend.
955 if (IsConstant || !RelTy::IsRela)
956 Sec.Relocations.push_back({Expr, Type, Offset, Addend, &Body});
957 }
958}
959
960template <class ELFT> void elf::scanRelocations(InputSectionBase &S) {
961 if (S.AreRelocsRela)
962 scanRelocs<ELFT>(S, S.relas<ELFT>());
963 else
964 scanRelocs<ELFT>(S, S.rels<ELFT>());
965}
966
967// Insert the Thunks for OutputSection OS into their designated place
968// in the Sections vector, and recalculate the InputSection output section
969// offsets.
970// This may invalidate any output section offsets stored outside of InputSection
971void ThunkCreator::mergeThunks() {
972 for (auto &KV : ThunkSections) {
973 std::vector<InputSection *> *ISR = KV.first;
974 std::vector<ThunkSection *> &Thunks = KV.second;
975
976 // Order Thunks in ascending OutSecOff
977 auto ThunkCmp = [](const ThunkSection *A, const ThunkSection *B) {
978 return A->OutSecOff < B->OutSecOff;
979 };
980 std::stable_sort(Thunks.begin(), Thunks.end(), ThunkCmp);
981
982 // Merge sorted vectors of Thunks and InputSections by OutSecOff
983 std::vector<InputSection *> Tmp;
984 Tmp.reserve(ISR->size() + Thunks.size());
985 auto MergeCmp = [](const InputSection *A, const InputSection *B) {
986 // std::merge requires a strict weak ordering.
987 if (A->OutSecOff < B->OutSecOff)
988 return true;
989 if (A->OutSecOff == B->OutSecOff)
990 // Check if Thunk is immediately before any specific Target InputSection
991 // for example Mips LA25 Thunks.
992 if (auto *TA = dyn_cast<ThunkSection>(A))
993 if (TA && TA->getTargetInputSection() == B)
994 return true;
995 return false;
996 };
997 std::merge(ISR->begin(), ISR->end(), Thunks.begin(), Thunks.end(),
998 std::back_inserter(Tmp), MergeCmp);
999 *ISR = std::move(Tmp);
1000 }
1001}
1002
1003static uint32_t findEndOfFirstNonExec(OutputSectionCommand &Cmd) {
1004 for (BaseCommand *Base : Cmd.Commands)
1005 if (auto *ISD = dyn_cast<InputSectionDescription>(Base))
1006 for (auto *IS : ISD->Sections)
1007 if ((IS->Flags & SHF_EXECINSTR) == 0)
1008 return IS->OutSecOff + IS->getSize();
1009 return 0;
1010}
1011
1012ThunkSection *ThunkCreator::getOSThunkSec(OutputSectionCommand *Cmd,
1013 std::vector<InputSection *> *ISR) {
1014 if (CurTS == nullptr) {
1015 uint32_t Off = findEndOfFirstNonExec(*Cmd);
1016 CurTS = addThunkSection(Cmd->Sec, ISR, Off);
1017 }
1018 return CurTS;
1019}
1020
1021ThunkSection *ThunkCreator::getISThunkSec(InputSection *IS, OutputSection *OS) {
1022 ThunkSection *TS = ThunkedSections.lookup(IS);
1023 if (TS)
1024 return TS;
1025 auto *TOS = IS->getParent();
1026
1027 // Find InputSectionRange within TOS that IS is in
1028 OutputSectionCommand *C = Script->getCmd(TOS);
1029 std::vector<InputSection *> *Range = nullptr;
1030 for (BaseCommand *BC : C->Commands)
1031 if (auto *ISD = dyn_cast<InputSectionDescription>(BC)) {
1032 InputSection *first = ISD->Sections.front();
1033 InputSection *last = ISD->Sections.back();
1034 if (IS->OutSecOff >= first->OutSecOff &&
1035 IS->OutSecOff <= last->OutSecOff) {
1036 Range = &ISD->Sections;
1037 break;
1038 }
1039 }
1040 TS = addThunkSection(TOS, Range, IS->OutSecOff);
1041 ThunkedSections[IS] = TS;
1042 return TS;
1043}
1044
1045ThunkSection *ThunkCreator::addThunkSection(OutputSection *OS,
1046 std::vector<InputSection *> *ISR,
1047 uint64_t Off) {
1048 auto *TS = make<ThunkSection>(OS, Off);
1049 ThunkSections[ISR].push_back(TS);
1050 return TS;
1051}
1052
1053std::pair<Thunk *, bool> ThunkCreator::getThunk(SymbolBody &Body,
1054 uint32_t Type) {
1055 auto Res = ThunkedSymbols.insert({&Body, std::vector<Thunk *>()});
1056 if (!Res.second) {
1057 // Check existing Thunks for Body to see if they can be reused
1058 for (Thunk *ET : Res.first->second)
1059 if (ET->isCompatibleWith(Type))
1060 return std::make_pair(ET, false);
1061 }
1062 // No existing compatible Thunk in range, create a new one
1063 Thunk *T = addThunk(Type, Body);
1064 Res.first->second.push_back(T);
1065 return std::make_pair(T, true);
1066}
1067
1068// Call Fn on every executable InputSection accessed via the linker script
1069// InputSectionDescription::Sections.
1070void ThunkCreator::forEachExecInputSection(
1071 ArrayRef<OutputSectionCommand *> OutputSections,
1072 std::function<void(OutputSectionCommand *, std::vector<InputSection *> *,
1073 InputSection *)>
1074 Fn) {
1075 for (OutputSectionCommand *Cmd : OutputSections) {
1076 OutputSection *OS = Cmd->Sec;
1077 if (!(OS->Flags & SHF_ALLOC) || !(OS->Flags & SHF_EXECINSTR))
1078 continue;
1079 for (BaseCommand *BC : Cmd->Commands)
1080 if (auto *ISD = dyn_cast<InputSectionDescription>(BC)) {
1081 CurTS = nullptr;
1082 for (InputSection *IS : ISD->Sections)
1083 Fn(Cmd, &ISD->Sections, IS);
1084 }
1085 }
1086}
1087
1088// Process all relocations from the InputSections that have been assigned
1089// to OutputSections and redirect through Thunks if needed.
1090//
1091// createThunks must be called after scanRelocs has created the Relocations for
1092// each InputSection. It must be called before the static symbol table is
1093// finalized. If any Thunks are added to an OutputSection the output section
1094// offsets of the InputSections will change.
1095//
1096// FIXME: All Thunks are assumed to be in range of the relocation. Range
1097// extension Thunks are not yet supported.
1098bool ThunkCreator::createThunks(
1099 ArrayRef<OutputSectionCommand *> OutputSections) {
1100 if (Pass > 0)
1101 ThunkSections.clear();
1102
1103 // Create all the Thunks and insert them into synthetic ThunkSections. The
1104 // ThunkSections are later inserted back into the OutputSection.
1105
1106 // We separate the creation of ThunkSections from the insertion of the
1107 // ThunkSections back into the OutputSection as ThunkSections are not always
1108 // inserted into the same OutputSection as the caller.
1109 forEachExecInputSection(OutputSections, [&](OutputSectionCommand *Cmd,
1110 std::vector<InputSection *> *ISR,
1111 InputSection *IS) {
1112 for (Relocation &Rel : IS->Relocations) {
1113 SymbolBody &Body = *Rel.Sym;
1114 if (Thunks.find(&Body) != Thunks.end() ||
1115 !Target->needsThunk(Rel.Expr, Rel.Type, IS->File, Body))
1116 continue;
1117 Thunk *T;
1118 bool IsNew;
1119 std::tie(T, IsNew) = getThunk(Body, Rel.Type);
1120 if (IsNew) {
1121 // Find or create a ThunkSection for the new Thunk
1122 ThunkSection *TS;
1123 if (auto *TIS = T->getTargetInputSection())
1124 TS = getISThunkSec(TIS, Cmd->Sec);
1125 else
1126 TS = getOSThunkSec(Cmd, ISR);
1127 TS->addThunk(T);
1128 Thunks[T->ThunkSym] = T;
1129 }
1130 // Redirect relocation to Thunk, we never go via the PLT to a Thunk
1131 Rel.Sym = T->ThunkSym;
1132 Rel.Expr = fromPlt(Rel.Expr);
1133 }
1134 });
1135 // Merge all created synthetic ThunkSections back into OutputSection
1136 mergeThunks();
1137 ++Pass;
1138 return !ThunkSections.empty();
1139}
1140
1141template void elf::scanRelocations<ELF32LE>(InputSectionBase &);
1142template void elf::scanRelocations<ELF32BE>(InputSectionBase &);
1143template void elf::scanRelocations<ELF64LE>(InputSectionBase &);
1144template void elf::scanRelocations<ELF64BE>(InputSectionBase &);
deps/lld/ELF/Relocations.h created+185
......@@ -0,0 +1,185 @@
1//===- Relocations.h -------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_ELF_RELOCATIONS_H
11#define LLD_ELF_RELOCATIONS_H
12
13#include "lld/Core/LLVM.h"
14#include "llvm/ADT/DenseMap.h"
15#include <map>
16#include <vector>
17
18namespace lld {
19namespace elf {
20class SymbolBody;
21class InputSection;
22class InputSectionBase;
23class OutputSection;
24struct OutputSectionCommand;
25
26// List of target-independent relocation types. Relocations read
27// from files are converted to these types so that the main code
28// doesn't have to know about architecture-specific details.
29enum RelExpr {
30 R_ABS,
31 R_ARM_SBREL,
32 R_GOT,
33 R_GOTONLY_PC,
34 R_GOTONLY_PC_FROM_END,
35 R_GOTREL,
36 R_GOTREL_FROM_END,
37 R_GOT_FROM_END,
38 R_GOT_OFF,
39 R_GOT_PAGE_PC,
40 R_GOT_PC,
41 R_HINT,
42 R_MIPS_GOTREL,
43 R_MIPS_GOT_GP,
44 R_MIPS_GOT_GP_PC,
45 R_MIPS_GOT_LOCAL_PAGE,
46 R_MIPS_GOT_OFF,
47 R_MIPS_GOT_OFF32,
48 R_MIPS_TLSGD,
49 R_MIPS_TLSLD,
50 R_NEG_TLS,
51 R_NONE,
52 R_PAGE_PC,
53 R_PC,
54 R_PLT,
55 R_PLT_PAGE_PC,
56 R_PLT_PC,
57 R_PPC_OPD,
58 R_PPC_PLT_OPD,
59 R_PPC_TOC,
60 R_RELAX_GOT_PC,
61 R_RELAX_GOT_PC_NOPIC,
62 R_RELAX_TLS_GD_TO_IE,
63 R_RELAX_TLS_GD_TO_IE_ABS,
64 R_RELAX_TLS_GD_TO_IE_END,
65 R_RELAX_TLS_GD_TO_IE_PAGE_PC,
66 R_RELAX_TLS_GD_TO_LE,
67 R_RELAX_TLS_GD_TO_LE_NEG,
68 R_RELAX_TLS_IE_TO_LE,
69 R_RELAX_TLS_LD_TO_LE,
70 R_SIZE,
71 R_TLS,
72 R_TLSDESC,
73 R_TLSDESC_CALL,
74 R_TLSDESC_PAGE,
75 R_TLSGD,
76 R_TLSGD_PC,
77 R_TLSLD,
78 R_TLSLD_PC,
79};
80
81// Build a bitmask with one bit set for each RelExpr.
82//
83// Constexpr function arguments can't be used in static asserts, so we
84// use template arguments to build the mask.
85// But function template partial specializations don't exist (needed
86// for base case of the recursion), so we need a dummy struct.
87template <RelExpr... Exprs> struct RelExprMaskBuilder {
88 static inline uint64_t build() { return 0; }
89};
90
91// Specialization for recursive case.
92template <RelExpr Head, RelExpr... Tail>
93struct RelExprMaskBuilder<Head, Tail...> {
94 static inline uint64_t build() {
95 static_assert(0 <= Head && Head < 64,
96 "RelExpr is too large for 64-bit mask!");
97 return (uint64_t(1) << Head) | RelExprMaskBuilder<Tail...>::build();
98 }
99};
100
101// Return true if `Expr` is one of `Exprs`.
102// There are fewer than 64 RelExpr's, so we can represent any set of
103// RelExpr's as a constant bit mask and test for membership with a
104// couple cheap bitwise operations.
105template <RelExpr... Exprs> bool isRelExprOneOf(RelExpr Expr) {
106 assert(0 <= Expr && (int)Expr < 64 &&
107 "RelExpr is too large for 64-bit mask!");
108 return (uint64_t(1) << Expr) & RelExprMaskBuilder<Exprs...>::build();
109}
110
111// Architecture-neutral representation of relocation.
112struct Relocation {
113 RelExpr Expr;
114 uint32_t Type;
115 uint64_t Offset;
116 int64_t Addend;
117 SymbolBody *Sym;
118};
119
120template <class ELFT> void scanRelocations(InputSectionBase &);
121
122class ThunkSection;
123class Thunk;
124
125class ThunkCreator {
126public:
127 // Return true if Thunks have been added to OutputSections
128 bool createThunks(ArrayRef<OutputSectionCommand *> OutputSections);
129
130 // The number of completed passes of createThunks this permits us
131 // to do one time initialization on Pass 0 and put a limit on the
132 // number of times it can be called to prevent infinite loops.
133 uint32_t Pass = 0;
134
135private:
136 void mergeThunks();
137 ThunkSection *getOSThunkSec(OutputSectionCommand *Cmd,
138 std::vector<InputSection *> *ISR);
139 ThunkSection *getISThunkSec(InputSection *IS, OutputSection *OS);
140 void forEachExecInputSection(
141 ArrayRef<OutputSectionCommand *> OutputSections,
142 std::function<void(OutputSectionCommand *, std::vector<InputSection *> *,
143 InputSection *)>
144 Fn);
145 std::pair<Thunk *, bool> getThunk(SymbolBody &Body, uint32_t Type);
146 ThunkSection *addThunkSection(OutputSection *OS,
147 std::vector<InputSection *> *, uint64_t Off);
148 // Record all the available Thunks for a Symbol
149 llvm::DenseMap<SymbolBody *, std::vector<Thunk *>> ThunkedSymbols;
150
151 // Find a Thunk from the Thunks symbol definition, we can use this to find
152 // the Thunk from a relocation to the Thunks symbol definition.
153 llvm::DenseMap<SymbolBody *, Thunk *> Thunks;
154
155 // Track InputSections that have an inline ThunkSection placed in front
156 // an inline ThunkSection may have control fall through to the section below
157 // so we need to make sure that there is only one of them.
158 // The Mips LA25 Thunk is an example of an inline ThunkSection.
159 llvm::DenseMap<InputSection *, ThunkSection *> ThunkedSections;
160
161 // All the ThunkSections that we have created, organised by OutputSection
162 // will contain a mix of ThunkSections that have been created this pass, and
163 // ThunkSections that have been merged into the OutputSection on previous
164 // passes
165 std::map<std::vector<InputSection *> *, std::vector<ThunkSection *>>
166 ThunkSections;
167
168 // The ThunkSection for this vector of InputSections
169 ThunkSection *CurTS;
170};
171
172// Return a int64_t to make sure we get the sign extension out of the way as
173// early as possible.
174template <class ELFT>
175static inline int64_t getAddend(const typename ELFT::Rel &Rel) {
176 return 0;
177}
178template <class ELFT>
179static inline int64_t getAddend(const typename ELFT::Rela &Rel) {
180 return Rel.r_addend;
181}
182} // namespace elf
183} // namespace lld
184
185#endif
deps/lld/ELF/ScriptLexer.cpp created+285
......@@ -0,0 +1,285 @@
1//===- ScriptLexer.cpp ----------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines a lexer for the linker script.
11//
12// The linker script's grammar is not complex but ambiguous due to the
13// lack of the formal specification of the language. What we are trying to
14// do in this and other files in LLD is to make a "reasonable" linker
15// script processor.
16//
17// Among simplicity, compatibility and efficiency, we put the most
18// emphasis on simplicity when we wrote this lexer. Compatibility with the
19// GNU linkers is important, but we did not try to clone every tiny corner
20// case of their lexers, as even ld.bfd and ld.gold are subtly different
21// in various corner cases. We do not care much about efficiency because
22// the time spent in parsing linker scripts is usually negligible.
23//
24// Our grammar of the linker script is LL(2), meaning that it needs at
25// most two-token lookahead to parse. The only place we need two-token
26// lookahead is labels in version scripts, where we need to parse "local :"
27// as if "local:".
28//
29// Overall, this lexer works fine for most linker scripts. There might
30// be room for improving compatibility, but that's probably not at the
31// top of our todo list.
32//
33//===----------------------------------------------------------------------===//
34
35#include "ScriptLexer.h"
36#include "Error.h"
37#include "llvm/ADT/Twine.h"
38
39using namespace llvm;
40using namespace lld;
41using namespace lld::elf;
42
43// Returns a whole line containing the current token.
44StringRef ScriptLexer::getLine() {
45 StringRef S = getCurrentMB().getBuffer();
46 StringRef Tok = Tokens[Pos - 1];
47
48 size_t Pos = S.rfind('\n', Tok.data() - S.data());
49 if (Pos != StringRef::npos)
50 S = S.substr(Pos + 1);
51 return S.substr(0, S.find_first_of("\r\n"));
52}
53
54// Returns 1-based line number of the current token.
55size_t ScriptLexer::getLineNumber() {
56 StringRef S = getCurrentMB().getBuffer();
57 StringRef Tok = Tokens[Pos - 1];
58 return S.substr(0, Tok.data() - S.data()).count('\n') + 1;
59}
60
61// Returns 0-based column number of the current token.
62size_t ScriptLexer::getColumnNumber() {
63 StringRef Tok = Tokens[Pos - 1];
64 return Tok.data() - getLine().data();
65}
66
67std::string ScriptLexer::getCurrentLocation() {
68 std::string Filename = getCurrentMB().getBufferIdentifier();
69 if (!Pos)
70 return Filename;
71 return (Filename + ":" + Twine(getLineNumber())).str();
72}
73
74ScriptLexer::ScriptLexer(MemoryBufferRef MB) { tokenize(MB); }
75
76// We don't want to record cascading errors. Keep only the first one.
77void ScriptLexer::setError(const Twine &Msg) {
78 if (Error)
79 return;
80 Error = true;
81
82 if (!Pos) {
83 error(getCurrentLocation() + ": " + Msg);
84 return;
85 }
86
87 std::string S = getCurrentLocation() + ": ";
88 error(S + Msg);
89 error(S + getLine());
90 error(S + std::string(getColumnNumber(), ' ') + "^");
91}
92
93// Split S into linker script tokens.
94void ScriptLexer::tokenize(MemoryBufferRef MB) {
95 std::vector<StringRef> Vec;
96 MBs.push_back(MB);
97 StringRef S = MB.getBuffer();
98 StringRef Begin = S;
99
100 for (;;) {
101 S = skipSpace(S);
102 if (S.empty())
103 break;
104
105 // Quoted token. Note that double-quote characters are parts of a token
106 // because, in a glob match context, only unquoted tokens are interpreted
107 // as glob patterns. Double-quoted tokens are literal patterns in that
108 // context.
109 if (S.startswith("\"")) {
110 size_t E = S.find("\"", 1);
111 if (E == StringRef::npos) {
112 StringRef Filename = MB.getBufferIdentifier();
113 size_t Lineno = Begin.substr(0, S.data() - Begin.data()).count('\n');
114 error(Filename + ":" + Twine(Lineno + 1) + ": unclosed quote");
115 return;
116 }
117
118 Vec.push_back(S.take_front(E + 1));
119 S = S.substr(E + 1);
120 continue;
121 }
122
123 // Unquoted token. This is more relaxed than tokens in C-like language,
124 // so that you can write "file-name.cpp" as one bare token, for example.
125 size_t Pos = S.find_first_not_of(
126 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
127 "0123456789_.$/\\~=+[]*?-!<>^:");
128
129 // A character that cannot start a word (which is usually a
130 // punctuation) forms a single character token.
131 if (Pos == 0)
132 Pos = 1;
133 Vec.push_back(S.substr(0, Pos));
134 S = S.substr(Pos);
135 }
136
137 Tokens.insert(Tokens.begin() + Pos, Vec.begin(), Vec.end());
138}
139
140// Skip leading whitespace characters or comments.
141StringRef ScriptLexer::skipSpace(StringRef S) {
142 for (;;) {
143 if (S.startswith("/*")) {
144 size_t E = S.find("*/", 2);
145 if (E == StringRef::npos) {
146 error("unclosed comment in a linker script");
147 return "";
148 }
149 S = S.substr(E + 2);
150 continue;
151 }
152 if (S.startswith("#")) {
153 size_t E = S.find('\n', 1);
154 if (E == StringRef::npos)
155 E = S.size() - 1;
156 S = S.substr(E + 1);
157 continue;
158 }
159 size_t Size = S.size();
160 S = S.ltrim();
161 if (S.size() == Size)
162 return S;
163 }
164}
165
166// An erroneous token is handled as if it were the last token before EOF.
167bool ScriptLexer::atEOF() { return Error || Tokens.size() == Pos; }
168
169// Split a given string as an expression.
170// This function returns "3", "*" and "5" for "3*5" for example.
171static std::vector<StringRef> tokenizeExpr(StringRef S) {
172 StringRef Ops = "+-*/:"; // List of operators
173
174 // Quoted strings are literal strings, so we don't want to split it.
175 if (S.startswith("\""))
176 return {S};
177
178 // Split S with +-*/ as separators.
179 std::vector<StringRef> Ret;
180 while (!S.empty()) {
181 size_t E = S.find_first_of(Ops);
182
183 // No need to split if there is no operator.
184 if (E == StringRef::npos) {
185 Ret.push_back(S);
186 break;
187 }
188
189 // Get a token before the opreator.
190 if (E != 0)
191 Ret.push_back(S.substr(0, E));
192
193 // Get the operator as a token.
194 Ret.push_back(S.substr(E, 1));
195 S = S.substr(E + 1);
196 }
197 return Ret;
198}
199
200// In contexts where expressions are expected, the lexer should apply
201// different tokenization rules than the default one. By default,
202// arithmetic operator characters are regular characters, but in the
203// expression context, they should be independent tokens.
204//
205// For example, "foo*3" should be tokenized to "foo", "*" and "3" only
206// in the expression context.
207//
208// This function may split the current token into multiple tokens.
209void ScriptLexer::maybeSplitExpr() {
210 if (!InExpr || Error || atEOF())
211 return;
212
213 std::vector<StringRef> V = tokenizeExpr(Tokens[Pos]);
214 if (V.size() == 1)
215 return;
216 Tokens.erase(Tokens.begin() + Pos);
217 Tokens.insert(Tokens.begin() + Pos, V.begin(), V.end());
218}
219
220StringRef ScriptLexer::next() {
221 maybeSplitExpr();
222
223 if (Error)
224 return "";
225 if (atEOF()) {
226 setError("unexpected EOF");
227 return "";
228 }
229 return Tokens[Pos++];
230}
231
232StringRef ScriptLexer::peek() {
233 StringRef Tok = next();
234 if (Error)
235 return "";
236 Pos = Pos - 1;
237 return Tok;
238}
239
240bool ScriptLexer::consume(StringRef Tok) {
241 if (peek() == Tok) {
242 skip();
243 return true;
244 }
245 return false;
246}
247
248// Consumes Tok followed by ":". Space is allowed between Tok and ":".
249bool ScriptLexer::consumeLabel(StringRef Tok) {
250 if (consume((Tok + ":").str()))
251 return true;
252 if (Tokens.size() >= Pos + 2 && Tokens[Pos] == Tok &&
253 Tokens[Pos + 1] == ":") {
254 Pos += 2;
255 return true;
256 }
257 return false;
258}
259
260void ScriptLexer::skip() { (void)next(); }
261
262void ScriptLexer::expect(StringRef Expect) {
263 if (Error)
264 return;
265 StringRef Tok = next();
266 if (Tok != Expect)
267 setError(Expect + " expected, but got " + Tok);
268}
269
270// Returns true if S encloses T.
271static bool encloses(StringRef S, StringRef T) {
272 return S.bytes_begin() <= T.bytes_begin() && T.bytes_end() <= S.bytes_end();
273}
274
275MemoryBufferRef ScriptLexer::getCurrentMB() {
276 // Find input buffer containing the current token.
277 assert(!MBs.empty());
278 if (!Pos)
279 return MBs[0];
280
281 for (MemoryBufferRef MB : MBs)
282 if (encloses(MB.getBuffer(), Tokens[Pos - 1]))
283 return MB;
284 llvm_unreachable("getCurrentMB: failed to find a token");
285}
deps/lld/ELF/ScriptLexer.h created+56
......@@ -0,0 +1,56 @@
1//===- ScriptLexer.h --------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_ELF_SCRIPT_LEXER_H
11#define LLD_ELF_SCRIPT_LEXER_H
12
13#include "lld/Core/LLVM.h"
14#include "llvm/ADT/StringRef.h"
15#include "llvm/Support/MemoryBuffer.h"
16#include <utility>
17#include <vector>
18
19namespace lld {
20namespace elf {
21
22class ScriptLexer {
23public:
24 explicit ScriptLexer(MemoryBufferRef MB);
25
26 void setError(const Twine &Msg);
27 void tokenize(MemoryBufferRef MB);
28 static StringRef skipSpace(StringRef S);
29 bool atEOF();
30 StringRef next();
31 StringRef peek();
32 void skip();
33 bool consume(StringRef Tok);
34 void expect(StringRef Expect);
35 bool consumeLabel(StringRef Tok);
36 std::string getCurrentLocation();
37
38 std::vector<MemoryBufferRef> MBs;
39 std::vector<StringRef> Tokens;
40 bool InExpr = false;
41 size_t Pos = 0;
42 bool Error = false;
43
44private:
45 void maybeSplitExpr();
46 StringRef getLine();
47 size_t getLineNumber();
48 size_t getColumnNumber();
49
50 MemoryBufferRef getCurrentMB();
51};
52
53} // namespace elf
54} // namespace lld
55
56#endif
deps/lld/ELF/ScriptParser.cpp created+1247
......@@ -0,0 +1,1247 @@
1//===- ScriptParser.cpp ---------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains a recursive-descendent parser for linker scripts.
11// Parsed results are stored to Config and Script global objects.
12//
13//===----------------------------------------------------------------------===//
14
15#include "ScriptParser.h"
16#include "Config.h"
17#include "Driver.h"
18#include "InputSection.h"
19#include "LinkerScript.h"
20#include "Memory.h"
21#include "OutputSections.h"
22#include "ScriptLexer.h"
23#include "Symbols.h"
24#include "Target.h"
25#include "llvm/ADT/SmallString.h"
26#include "llvm/ADT/StringRef.h"
27#include "llvm/ADT/StringSwitch.h"
28#include "llvm/BinaryFormat/ELF.h"
29#include "llvm/Support/Casting.h"
30#include "llvm/Support/ErrorHandling.h"
31#include "llvm/Support/FileSystem.h"
32#include "llvm/Support/Path.h"
33#include <cassert>
34#include <limits>
35#include <vector>
36
37using namespace llvm;
38using namespace llvm::ELF;
39using namespace llvm::support::endian;
40using namespace lld;
41using namespace lld::elf;
42
43static bool isUnderSysroot(StringRef Path);
44
45namespace {
46class ScriptParser final : ScriptLexer {
47public:
48 ScriptParser(MemoryBufferRef MB)
49 : ScriptLexer(MB),
50 IsUnderSysroot(isUnderSysroot(MB.getBufferIdentifier())) {}
51
52 void readLinkerScript();
53 void readVersionScript();
54 void readDynamicList();
55
56private:
57 void addFile(StringRef Path);
58 OutputSection *checkSection(OutputSectionCommand *Cmd, StringRef Loccation);
59
60 void readAsNeeded();
61 void readEntry();
62 void readExtern();
63 void readGroup();
64 void readInclude();
65 void readMemory();
66 void readOutput();
67 void readOutputArch();
68 void readOutputFormat();
69 void readPhdrs();
70 void readSearchDir();
71 void readSections();
72 void readVersion();
73 void readVersionScriptCommand();
74
75 SymbolAssignment *readAssignment(StringRef Name);
76 BytesDataCommand *readBytesDataCommand(StringRef Tok);
77 uint32_t readFill();
78 uint32_t parseFill(StringRef Tok);
79 void readSectionAddressType(OutputSectionCommand *Cmd);
80 OutputSectionCommand *readOutputSectionDescription(StringRef OutSec);
81 std::vector<StringRef> readOutputSectionPhdrs();
82 InputSectionDescription *readInputSectionDescription(StringRef Tok);
83 StringMatcher readFilePatterns();
84 std::vector<SectionPattern> readInputSectionsList();
85 InputSectionDescription *readInputSectionRules(StringRef FilePattern);
86 unsigned readPhdrType();
87 SortSectionPolicy readSortKind();
88 SymbolAssignment *readProvideHidden(bool Provide, bool Hidden);
89 SymbolAssignment *readProvideOrAssignment(StringRef Tok);
90 void readSort();
91 AssertCommand *readAssert();
92 Expr readAssertExpr();
93
94 uint64_t readMemoryAssignment(StringRef, StringRef, StringRef);
95 std::pair<uint32_t, uint32_t> readMemoryAttributes();
96
97 Expr readExpr();
98 Expr readExpr1(Expr Lhs, int MinPrec);
99 StringRef readParenLiteral();
100 Expr readPrimary();
101 Expr readTernary(Expr Cond);
102 Expr readParenExpr();
103
104 // For parsing version script.
105 std::vector<SymbolVersion> readVersionExtern();
106 void readAnonymousDeclaration();
107 void readVersionDeclaration(StringRef VerStr);
108
109 std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>>
110 readSymbols();
111
112 bool IsUnderSysroot;
113};
114} // namespace
115
116static StringRef unquote(StringRef S) {
117 if (S.startswith("\""))
118 return S.substr(1, S.size() - 2);
119 return S;
120}
121
122static bool isUnderSysroot(StringRef Path) {
123 if (Config->Sysroot == "")
124 return false;
125 for (; !Path.empty(); Path = sys::path::parent_path(Path))
126 if (sys::fs::equivalent(Config->Sysroot, Path))
127 return true;
128 return false;
129}
130
131// Some operations only support one non absolute value. Move the
132// absolute one to the right hand side for convenience.
133static void moveAbsRight(ExprValue &A, ExprValue &B) {
134 if (A.isAbsolute())
135 std::swap(A, B);
136 if (!B.isAbsolute())
137 error(A.Loc + ": at least one side of the expression must be absolute");
138}
139
140static ExprValue add(ExprValue A, ExprValue B) {
141 moveAbsRight(A, B);
142 return {A.Sec, A.ForceAbsolute, A.Val + B.getValue(), A.Loc};
143}
144
145static ExprValue sub(ExprValue A, ExprValue B) {
146 return {A.Sec, A.Val - B.getValue(), A.Loc};
147}
148
149static ExprValue mul(ExprValue A, ExprValue B) {
150 return A.getValue() * B.getValue();
151}
152
153static ExprValue div(ExprValue A, ExprValue B) {
154 if (uint64_t BV = B.getValue())
155 return A.getValue() / BV;
156 error("division by zero");
157 return 0;
158}
159
160static ExprValue bitAnd(ExprValue A, ExprValue B) {
161 moveAbsRight(A, B);
162 return {A.Sec, A.ForceAbsolute,
163 (A.getValue() & B.getValue()) - A.getSecAddr(), A.Loc};
164}
165
166static ExprValue bitOr(ExprValue A, ExprValue B) {
167 moveAbsRight(A, B);
168 return {A.Sec, A.ForceAbsolute,
169 (A.getValue() | B.getValue()) - A.getSecAddr(), A.Loc};
170}
171
172void ScriptParser::readDynamicList() {
173 expect("{");
174 readAnonymousDeclaration();
175 if (!atEOF())
176 setError("EOF expected, but got " + next());
177}
178
179void ScriptParser::readVersionScript() {
180 readVersionScriptCommand();
181 if (!atEOF())
182 setError("EOF expected, but got " + next());
183}
184
185void ScriptParser::readVersionScriptCommand() {
186 if (consume("{")) {
187 readAnonymousDeclaration();
188 return;
189 }
190
191 while (!atEOF() && !Error && peek() != "}") {
192 StringRef VerStr = next();
193 if (VerStr == "{") {
194 setError("anonymous version definition is used in "
195 "combination with other version definitions");
196 return;
197 }
198 expect("{");
199 readVersionDeclaration(VerStr);
200 }
201}
202
203void ScriptParser::readVersion() {
204 expect("{");
205 readVersionScriptCommand();
206 expect("}");
207}
208
209void ScriptParser::readLinkerScript() {
210 while (!atEOF()) {
211 StringRef Tok = next();
212 if (Tok == ";")
213 continue;
214
215 if (Tok == "ASSERT") {
216 Script->Opt.Commands.push_back(readAssert());
217 } else if (Tok == "ENTRY") {
218 readEntry();
219 } else if (Tok == "EXTERN") {
220 readExtern();
221 } else if (Tok == "GROUP" || Tok == "INPUT") {
222 readGroup();
223 } else if (Tok == "INCLUDE") {
224 readInclude();
225 } else if (Tok == "MEMORY") {
226 readMemory();
227 } else if (Tok == "OUTPUT") {
228 readOutput();
229 } else if (Tok == "OUTPUT_ARCH") {
230 readOutputArch();
231 } else if (Tok == "OUTPUT_FORMAT") {
232 readOutputFormat();
233 } else if (Tok == "PHDRS") {
234 readPhdrs();
235 } else if (Tok == "SEARCH_DIR") {
236 readSearchDir();
237 } else if (Tok == "SECTIONS") {
238 readSections();
239 } else if (Tok == "VERSION") {
240 readVersion();
241 } else if (SymbolAssignment *Cmd = readProvideOrAssignment(Tok)) {
242 Script->Opt.Commands.push_back(Cmd);
243 } else {
244 setError("unknown directive: " + Tok);
245 }
246 }
247}
248
249void ScriptParser::addFile(StringRef S) {
250 if (IsUnderSysroot && S.startswith("/")) {
251 SmallString<128> PathData;
252 StringRef Path = (Config->Sysroot + S).toStringRef(PathData);
253 if (sys::fs::exists(Path)) {
254 Driver->addFile(Saver.save(Path), /*WithLOption=*/false);
255 return;
256 }
257 }
258
259 if (sys::path::is_absolute(S)) {
260 Driver->addFile(S, /*WithLOption=*/false);
261 } else if (S.startswith("=")) {
262 if (Config->Sysroot.empty())
263 Driver->addFile(S.substr(1), /*WithLOption=*/false);
264 else
265 Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1)),
266 /*WithLOption=*/false);
267 } else if (S.startswith("-l")) {
268 Driver->addLibrary(S.substr(2));
269 } else if (sys::fs::exists(S)) {
270 Driver->addFile(S, /*WithLOption=*/false);
271 } else {
272 if (Optional<std::string> Path = findFromSearchPaths(S))
273 Driver->addFile(Saver.save(*Path), /*WithLOption=*/true);
274 else
275 setError("unable to find " + S);
276 }
277}
278
279void ScriptParser::readAsNeeded() {
280 expect("(");
281 bool Orig = Config->AsNeeded;
282 Config->AsNeeded = true;
283 while (!Error && !consume(")"))
284 addFile(unquote(next()));
285 Config->AsNeeded = Orig;
286}
287
288void ScriptParser::readEntry() {
289 // -e <symbol> takes predecence over ENTRY(<symbol>).
290 expect("(");
291 StringRef Tok = next();
292 if (Config->Entry.empty())
293 Config->Entry = Tok;
294 expect(")");
295}
296
297void ScriptParser::readExtern() {
298 expect("(");
299 while (!Error && !consume(")"))
300 Config->Undefined.push_back(next());
301}
302
303void ScriptParser::readGroup() {
304 expect("(");
305 while (!Error && !consume(")")) {
306 if (consume("AS_NEEDED"))
307 readAsNeeded();
308 else
309 addFile(unquote(next()));
310 }
311}
312
313void ScriptParser::readInclude() {
314 StringRef Tok = unquote(next());
315
316 // https://sourceware.org/binutils/docs/ld/File-Commands.html:
317 // The file will be searched for in the current directory, and in any
318 // directory specified with the -L option.
319 if (sys::fs::exists(Tok)) {
320 if (Optional<MemoryBufferRef> MB = readFile(Tok))
321 tokenize(*MB);
322 return;
323 }
324 if (Optional<std::string> Path = findFromSearchPaths(Tok)) {
325 if (Optional<MemoryBufferRef> MB = readFile(*Path))
326 tokenize(*MB);
327 return;
328 }
329 setError("cannot open " + Tok);
330}
331
332void ScriptParser::readOutput() {
333 // -o <file> takes predecence over OUTPUT(<file>).
334 expect("(");
335 StringRef Tok = next();
336 if (Config->OutputFile.empty())
337 Config->OutputFile = unquote(Tok);
338 expect(")");
339}
340
341void ScriptParser::readOutputArch() {
342 // OUTPUT_ARCH is ignored for now.
343 expect("(");
344 while (!Error && !consume(")"))
345 skip();
346}
347
348void ScriptParser::readOutputFormat() {
349 // Error checking only for now.
350 expect("(");
351 skip();
352 if (consume(")"))
353 return;
354 expect(",");
355 skip();
356 expect(",");
357 skip();
358 expect(")");
359}
360
361void ScriptParser::readPhdrs() {
362 expect("{");
363 while (!Error && !consume("}")) {
364 Script->Opt.PhdrsCommands.push_back(
365 {next(), PT_NULL, false, false, UINT_MAX, nullptr});
366
367 PhdrsCommand &PhdrCmd = Script->Opt.PhdrsCommands.back();
368 PhdrCmd.Type = readPhdrType();
369
370 while (!Error && !consume(";")) {
371 if (consume("FILEHDR"))
372 PhdrCmd.HasFilehdr = true;
373 else if (consume("PHDRS"))
374 PhdrCmd.HasPhdrs = true;
375 else if (consume("AT"))
376 PhdrCmd.LMAExpr = readParenExpr();
377 else if (consume("FLAGS"))
378 PhdrCmd.Flags = readParenExpr()().getValue();
379 else
380 setError("unexpected header attribute: " + next());
381 }
382 }
383}
384
385void ScriptParser::readSearchDir() {
386 expect("(");
387 StringRef Tok = next();
388 if (!Config->Nostdlib)
389 Config->SearchPaths.push_back(unquote(Tok));
390 expect(")");
391}
392
393void ScriptParser::readSections() {
394 Script->Opt.HasSections = true;
395
396 // -no-rosegment is used to avoid placing read only non-executable sections in
397 // their own segment. We do the same if SECTIONS command is present in linker
398 // script. See comment for computeFlags().
399 Config->SingleRoRx = true;
400
401 expect("{");
402 while (!Error && !consume("}")) {
403 StringRef Tok = next();
404 BaseCommand *Cmd = readProvideOrAssignment(Tok);
405 if (!Cmd) {
406 if (Tok == "ASSERT")
407 Cmd = readAssert();
408 else
409 Cmd = readOutputSectionDescription(Tok);
410 }
411 Script->Opt.Commands.push_back(Cmd);
412 }
413}
414
415static int precedence(StringRef Op) {
416 return StringSwitch<int>(Op)
417 .Cases("*", "/", 5)
418 .Cases("+", "-", 4)
419 .Cases("<<", ">>", 3)
420 .Cases("<", "<=", ">", ">=", "==", "!=", 2)
421 .Cases("&", "|", 1)
422 .Default(-1);
423}
424
425StringMatcher ScriptParser::readFilePatterns() {
426 std::vector<StringRef> V;
427 while (!Error && !consume(")"))
428 V.push_back(next());
429 return StringMatcher(V);
430}
431
432SortSectionPolicy ScriptParser::readSortKind() {
433 if (consume("SORT") || consume("SORT_BY_NAME"))
434 return SortSectionPolicy::Name;
435 if (consume("SORT_BY_ALIGNMENT"))
436 return SortSectionPolicy::Alignment;
437 if (consume("SORT_BY_INIT_PRIORITY"))
438 return SortSectionPolicy::Priority;
439 if (consume("SORT_NONE"))
440 return SortSectionPolicy::None;
441 return SortSectionPolicy::Default;
442}
443
444// Reads SECTIONS command contents in the following form:
445//
446// <contents> ::= <elem>*
447// <elem> ::= <exclude>? <glob-pattern>
448// <exclude> ::= "EXCLUDE_FILE" "(" <glob-pattern>+ ")"
449//
450// For example,
451//
452// *(.foo EXCLUDE_FILE (a.o) .bar EXCLUDE_FILE (b.o) .baz)
453//
454// is parsed as ".foo", ".bar" with "a.o", and ".baz" with "b.o".
455// The semantics of that is section .foo in any file, section .bar in
456// any file but a.o, and section .baz in any file but b.o.
457std::vector<SectionPattern> ScriptParser::readInputSectionsList() {
458 std::vector<SectionPattern> Ret;
459 while (!Error && peek() != ")") {
460 StringMatcher ExcludeFilePat;
461 if (consume("EXCLUDE_FILE")) {
462 expect("(");
463 ExcludeFilePat = readFilePatterns();
464 }
465
466 std::vector<StringRef> V;
467 while (!Error && peek() != ")" && peek() != "EXCLUDE_FILE")
468 V.push_back(next());
469
470 if (!V.empty())
471 Ret.push_back({std::move(ExcludeFilePat), StringMatcher(V)});
472 else
473 setError("section pattern is expected");
474 }
475 return Ret;
476}
477
478// Reads contents of "SECTIONS" directive. That directive contains a
479// list of glob patterns for input sections. The grammar is as follows.
480//
481// <patterns> ::= <section-list>
482// | <sort> "(" <section-list> ")"
483// | <sort> "(" <sort> "(" <section-list> ")" ")"
484//
485// <sort> ::= "SORT" | "SORT_BY_NAME" | "SORT_BY_ALIGNMENT"
486// | "SORT_BY_INIT_PRIORITY" | "SORT_NONE"
487//
488// <section-list> is parsed by readInputSectionsList().
489InputSectionDescription *
490ScriptParser::readInputSectionRules(StringRef FilePattern) {
491 auto *Cmd = make<InputSectionDescription>(FilePattern);
492 expect("(");
493
494 while (!Error && !consume(")")) {
495 SortSectionPolicy Outer = readSortKind();
496 SortSectionPolicy Inner = SortSectionPolicy::Default;
497 std::vector<SectionPattern> V;
498 if (Outer != SortSectionPolicy::Default) {
499 expect("(");
500 Inner = readSortKind();
501 if (Inner != SortSectionPolicy::Default) {
502 expect("(");
503 V = readInputSectionsList();
504 expect(")");
505 } else {
506 V = readInputSectionsList();
507 }
508 expect(")");
509 } else {
510 V = readInputSectionsList();
511 }
512
513 for (SectionPattern &Pat : V) {
514 Pat.SortInner = Inner;
515 Pat.SortOuter = Outer;
516 }
517
518 std::move(V.begin(), V.end(), std::back_inserter(Cmd->SectionPatterns));
519 }
520 return Cmd;
521}
522
523InputSectionDescription *
524ScriptParser::readInputSectionDescription(StringRef Tok) {
525 // Input section wildcard can be surrounded by KEEP.
526 // https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep
527 if (Tok == "KEEP") {
528 expect("(");
529 StringRef FilePattern = next();
530 InputSectionDescription *Cmd = readInputSectionRules(FilePattern);
531 expect(")");
532 Script->Opt.KeptSections.push_back(Cmd);
533 return Cmd;
534 }
535 return readInputSectionRules(Tok);
536}
537
538void ScriptParser::readSort() {
539 expect("(");
540 expect("CONSTRUCTORS");
541 expect(")");
542}
543
544AssertCommand *ScriptParser::readAssert() {
545 return make<AssertCommand>(readAssertExpr());
546}
547
548Expr ScriptParser::readAssertExpr() {
549 expect("(");
550 Expr E = readExpr();
551 expect(",");
552 StringRef Msg = unquote(next());
553 expect(")");
554
555 return [=] {
556 if (!E().getValue())
557 error(Msg);
558 return Script->getDot();
559 };
560}
561
562// Reads a FILL(expr) command. We handle the FILL command as an
563// alias for =fillexp section attribute, which is different from
564// what GNU linkers do.
565// https://sourceware.org/binutils/docs/ld/Output-Section-Data.html
566uint32_t ScriptParser::readFill() {
567 expect("(");
568 uint32_t V = parseFill(next());
569 expect(")");
570 return V;
571}
572
573// Reads an expression and/or the special directive "(NOLOAD)" for an
574// output section definition.
575//
576// An output section name can be followed by an address expression
577// and/or by "(NOLOAD)". This grammar is not LL(1) because "(" can be
578// interpreted as either the beginning of some expression or "(NOLOAD)".
579//
580// https://sourceware.org/binutils/docs/ld/Output-Section-Address.html
581// https://sourceware.org/binutils/docs/ld/Output-Section-Type.html
582void ScriptParser::readSectionAddressType(OutputSectionCommand *Cmd) {
583 if (consume("(")) {
584 if (consume("NOLOAD")) {
585 expect(")");
586 Cmd->Noload = true;
587 return;
588 }
589 Cmd->AddrExpr = readExpr();
590 expect(")");
591 } else {
592 Cmd->AddrExpr = readExpr();
593 }
594
595 if (consume("(")) {
596 expect("NOLOAD");
597 expect(")");
598 Cmd->Noload = true;
599 }
600}
601
602OutputSectionCommand *
603ScriptParser::readOutputSectionDescription(StringRef OutSec) {
604 OutputSectionCommand *Cmd =
605 Script->createOutputSectionCommand(OutSec, getCurrentLocation());
606
607 if (peek() != ":")
608 readSectionAddressType(Cmd);
609 expect(":");
610
611 if (consume("AT"))
612 Cmd->LMAExpr = readParenExpr();
613 if (consume("ALIGN"))
614 Cmd->AlignExpr = readParenExpr();
615 if (consume("SUBALIGN"))
616 Cmd->SubalignExpr = readParenExpr();
617
618 // Parse constraints.
619 if (consume("ONLY_IF_RO"))
620 Cmd->Constraint = ConstraintKind::ReadOnly;
621 if (consume("ONLY_IF_RW"))
622 Cmd->Constraint = ConstraintKind::ReadWrite;
623 expect("{");
624
625 while (!Error && !consume("}")) {
626 StringRef Tok = next();
627 if (Tok == ";") {
628 // Empty commands are allowed. Do nothing here.
629 } else if (SymbolAssignment *Assign = readProvideOrAssignment(Tok)) {
630 Cmd->Commands.push_back(Assign);
631 } else if (BytesDataCommand *Data = readBytesDataCommand(Tok)) {
632 Cmd->Commands.push_back(Data);
633 } else if (Tok == "ASSERT") {
634 Cmd->Commands.push_back(readAssert());
635 expect(";");
636 } else if (Tok == "CONSTRUCTORS") {
637 // CONSTRUCTORS is a keyword to make the linker recognize C++ ctors/dtors
638 // by name. This is for very old file formats such as ECOFF/XCOFF.
639 // For ELF, we should ignore.
640 } else if (Tok == "FILL") {
641 Cmd->Filler = readFill();
642 } else if (Tok == "SORT") {
643 readSort();
644 } else if (peek() == "(") {
645 Cmd->Commands.push_back(readInputSectionDescription(Tok));
646 } else {
647 setError("unknown command " + Tok);
648 }
649 }
650
651 if (consume(">"))
652 Cmd->MemoryRegionName = next();
653
654 Cmd->Phdrs = readOutputSectionPhdrs();
655
656 if (consume("="))
657 Cmd->Filler = parseFill(next());
658 else if (peek().startswith("="))
659 Cmd->Filler = parseFill(next().drop_front());
660
661 // Consume optional comma following output section command.
662 consume(",");
663
664 return Cmd;
665}
666
667// Parses a given string as a octal/decimal/hexadecimal number and
668// returns it as a big-endian number. Used for `=<fillexp>`.
669// https://sourceware.org/binutils/docs/ld/Output-Section-Fill.html
670//
671// When reading a hexstring, ld.bfd handles it as a blob of arbitrary
672// size, while ld.gold always handles it as a 32-bit big-endian number.
673// We are compatible with ld.gold because it's easier to implement.
674uint32_t ScriptParser::parseFill(StringRef Tok) {
675 uint32_t V = 0;
676 if (!to_integer(Tok, V))
677 setError("invalid filler expression: " + Tok);
678
679 uint32_t Buf;
680 write32be(&Buf, V);
681 return Buf;
682}
683
684SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) {
685 expect("(");
686 SymbolAssignment *Cmd = readAssignment(next());
687 Cmd->Provide = Provide;
688 Cmd->Hidden = Hidden;
689 expect(")");
690 expect(";");
691 return Cmd;
692}
693
694SymbolAssignment *ScriptParser::readProvideOrAssignment(StringRef Tok) {
695 SymbolAssignment *Cmd = nullptr;
696 if (peek() == "=" || peek() == "+=") {
697 Cmd = readAssignment(Tok);
698 expect(";");
699 } else if (Tok == "PROVIDE") {
700 Cmd = readProvideHidden(true, false);
701 } else if (Tok == "HIDDEN") {
702 Cmd = readProvideHidden(false, true);
703 } else if (Tok == "PROVIDE_HIDDEN") {
704 Cmd = readProvideHidden(true, true);
705 }
706 return Cmd;
707}
708
709SymbolAssignment *ScriptParser::readAssignment(StringRef Name) {
710 StringRef Op = next();
711 assert(Op == "=" || Op == "+=");
712 Expr E = readExpr();
713 if (Op == "+=") {
714 std::string Loc = getCurrentLocation();
715 E = [=] { return add(Script->getSymbolValue(Loc, Name), E()); };
716 }
717 return make<SymbolAssignment>(Name, E, getCurrentLocation());
718}
719
720// This is an operator-precedence parser to parse a linker
721// script expression.
722Expr ScriptParser::readExpr() {
723 // Our lexer is context-aware. Set the in-expression bit so that
724 // they apply different tokenization rules.
725 bool Orig = InExpr;
726 InExpr = true;
727 Expr E = readExpr1(readPrimary(), 0);
728 InExpr = Orig;
729 return E;
730}
731
732static Expr combine(StringRef Op, Expr L, Expr R) {
733 if (Op == "+")
734 return [=] { return add(L(), R()); };
735 if (Op == "-")
736 return [=] { return sub(L(), R()); };
737 if (Op == "*")
738 return [=] { return mul(L(), R()); };
739 if (Op == "/")
740 return [=] { return div(L(), R()); };
741 if (Op == "<<")
742 return [=] { return L().getValue() << R().getValue(); };
743 if (Op == ">>")
744 return [=] { return L().getValue() >> R().getValue(); };
745 if (Op == "<")
746 return [=] { return L().getValue() < R().getValue(); };
747 if (Op == ">")
748 return [=] { return L().getValue() > R().getValue(); };
749 if (Op == ">=")
750 return [=] { return L().getValue() >= R().getValue(); };
751 if (Op == "<=")
752 return [=] { return L().getValue() <= R().getValue(); };
753 if (Op == "==")
754 return [=] { return L().getValue() == R().getValue(); };
755 if (Op == "!=")
756 return [=] { return L().getValue() != R().getValue(); };
757 if (Op == "&")
758 return [=] { return bitAnd(L(), R()); };
759 if (Op == "|")
760 return [=] { return bitOr(L(), R()); };
761 llvm_unreachable("invalid operator");
762}
763
764// This is a part of the operator-precedence parser. This function
765// assumes that the remaining token stream starts with an operator.
766Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) {
767 while (!atEOF() && !Error) {
768 // Read an operator and an expression.
769 if (consume("?"))
770 return readTernary(Lhs);
771 StringRef Op1 = peek();
772 if (precedence(Op1) < MinPrec)
773 break;
774 skip();
775 Expr Rhs = readPrimary();
776
777 // Evaluate the remaining part of the expression first if the
778 // next operator has greater precedence than the previous one.
779 // For example, if we have read "+" and "3", and if the next
780 // operator is "*", then we'll evaluate 3 * ... part first.
781 while (!atEOF()) {
782 StringRef Op2 = peek();
783 if (precedence(Op2) <= precedence(Op1))
784 break;
785 Rhs = readExpr1(Rhs, precedence(Op2));
786 }
787
788 Lhs = combine(Op1, Lhs, Rhs);
789 }
790 return Lhs;
791}
792
793uint64_t static getConstant(StringRef S) {
794 if (S == "COMMONPAGESIZE")
795 return Target->PageSize;
796 if (S == "MAXPAGESIZE")
797 return Config->MaxPageSize;
798 error("unknown constant: " + S);
799 return 0;
800}
801
802// Parses Tok as an integer. It recognizes hexadecimal (prefixed with
803// "0x" or suffixed with "H") and decimal numbers. Decimal numbers may
804// have "K" (Ki) or "M" (Mi) suffixes.
805static Optional<uint64_t> parseInt(StringRef Tok) {
806 // Negative number
807 if (Tok.startswith("-")) {
808 if (Optional<uint64_t> Val = parseInt(Tok.substr(1)))
809 return -*Val;
810 return None;
811 }
812
813 // Hexadecimal
814 uint64_t Val;
815 if (Tok.startswith_lower("0x") && to_integer(Tok.substr(2), Val, 16))
816 return Val;
817 if (Tok.endswith_lower("H") && to_integer(Tok.drop_back(), Val, 16))
818 return Val;
819
820 // Decimal
821 if (Tok.endswith_lower("K")) {
822 if (!to_integer(Tok.drop_back(), Val, 10))
823 return None;
824 return Val * 1024;
825 }
826 if (Tok.endswith_lower("M")) {
827 if (!to_integer(Tok.drop_back(), Val, 10))
828 return None;
829 return Val * 1024 * 1024;
830 }
831 if (!to_integer(Tok, Val, 10))
832 return None;
833 return Val;
834}
835
836BytesDataCommand *ScriptParser::readBytesDataCommand(StringRef Tok) {
837 int Size = StringSwitch<int>(Tok)
838 .Case("BYTE", 1)
839 .Case("SHORT", 2)
840 .Case("LONG", 4)
841 .Case("QUAD", 8)
842 .Default(-1);
843 if (Size == -1)
844 return nullptr;
845
846 return make<BytesDataCommand>(readParenExpr(), Size);
847}
848
849StringRef ScriptParser::readParenLiteral() {
850 expect("(");
851 StringRef Tok = next();
852 expect(")");
853 return Tok;
854}
855
856OutputSection *ScriptParser::checkSection(OutputSectionCommand *Cmd,
857 StringRef Location) {
858 if (Cmd->Location.empty() && Script->ErrorOnMissingSection)
859 error(Location + ": undefined section " + Cmd->Name);
860 if (Cmd->Sec)
861 return Cmd->Sec;
862 static OutputSection Dummy("", 0, 0);
863 return &Dummy;
864}
865
866Expr ScriptParser::readPrimary() {
867 if (peek() == "(")
868 return readParenExpr();
869
870 if (consume("~")) {
871 Expr E = readPrimary();
872 return [=] { return ~E().getValue(); };
873 }
874 if (consume("-")) {
875 Expr E = readPrimary();
876 return [=] { return -E().getValue(); };
877 }
878
879 StringRef Tok = next();
880 std::string Location = getCurrentLocation();
881
882 // Built-in functions are parsed here.
883 // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html.
884 if (Tok == "ABSOLUTE") {
885 Expr Inner = readParenExpr();
886 return [=] {
887 ExprValue I = Inner();
888 I.ForceAbsolute = true;
889 return I;
890 };
891 }
892 if (Tok == "ADDR") {
893 StringRef Name = readParenLiteral();
894 OutputSectionCommand *Cmd = Script->getOrCreateOutputSectionCommand(Name);
895 return [=]() -> ExprValue {
896 return {checkSection(Cmd, Location), 0, Location};
897 };
898 }
899 if (Tok == "ALIGN") {
900 expect("(");
901 Expr E = readExpr();
902 if (consume(")"))
903 return [=] { return alignTo(Script->getDot(), E().getValue()); };
904 expect(",");
905 Expr E2 = readExpr();
906 expect(")");
907 return [=] {
908 ExprValue V = E();
909 V.Alignment = E2().getValue();
910 return V;
911 };
912 }
913 if (Tok == "ALIGNOF") {
914 StringRef Name = readParenLiteral();
915 OutputSectionCommand *Cmd = Script->getOrCreateOutputSectionCommand(Name);
916 return [=] { return checkSection(Cmd, Location)->Alignment; };
917 }
918 if (Tok == "ASSERT")
919 return readAssertExpr();
920 if (Tok == "CONSTANT") {
921 StringRef Name = readParenLiteral();
922 return [=] { return getConstant(Name); };
923 }
924 if (Tok == "DATA_SEGMENT_ALIGN") {
925 expect("(");
926 Expr E = readExpr();
927 expect(",");
928 readExpr();
929 expect(")");
930 return [=] { return alignTo(Script->getDot(), E().getValue()); };
931 }
932 if (Tok == "DATA_SEGMENT_END") {
933 expect("(");
934 expect(".");
935 expect(")");
936 return [] { return Script->getDot(); };
937 }
938 if (Tok == "DATA_SEGMENT_RELRO_END") {
939 // GNU linkers implements more complicated logic to handle
940 // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and
941 // just align to the next page boundary for simplicity.
942 expect("(");
943 readExpr();
944 expect(",");
945 readExpr();
946 expect(")");
947 return [] { return alignTo(Script->getDot(), Target->PageSize); };
948 }
949 if (Tok == "DEFINED") {
950 StringRef Name = readParenLiteral();
951 return [=] { return Script->isDefined(Name) ? 1 : 0; };
952 }
953 if (Tok == "LENGTH") {
954 StringRef Name = readParenLiteral();
955 if (Script->Opt.MemoryRegions.count(Name) == 0)
956 setError("memory region not defined: " + Name);
957 return [=] { return Script->Opt.MemoryRegions[Name].Length; };
958 }
959 if (Tok == "LOADADDR") {
960 StringRef Name = readParenLiteral();
961 OutputSectionCommand *Cmd = Script->getOrCreateOutputSectionCommand(Name);
962 return [=] { return checkSection(Cmd, Location)->getLMA(); };
963 }
964 if (Tok == "ORIGIN") {
965 StringRef Name = readParenLiteral();
966 if (Script->Opt.MemoryRegions.count(Name) == 0)
967 setError("memory region not defined: " + Name);
968 return [=] { return Script->Opt.MemoryRegions[Name].Origin; };
969 }
970 if (Tok == "SEGMENT_START") {
971 expect("(");
972 skip();
973 expect(",");
974 Expr E = readExpr();
975 expect(")");
976 return [=] { return E(); };
977 }
978 if (Tok == "SIZEOF") {
979 StringRef Name = readParenLiteral();
980 OutputSectionCommand *Cmd = Script->getOrCreateOutputSectionCommand(Name);
981 // Linker script does not create an output section if its content is empty.
982 // We want to allow SIZEOF(.foo) where .foo is a section which happened to
983 // be empty.
984 return [=] { return Cmd->Sec ? Cmd->Sec->Size : 0; };
985 }
986 if (Tok == "SIZEOF_HEADERS")
987 return [=] { return elf::getHeaderSize(); };
988
989 // Tok is the dot.
990 if (Tok == ".")
991 return [=] { return Script->getSymbolValue(Location, Tok); };
992
993 // Tok is a literal number.
994 if (Optional<uint64_t> Val = parseInt(Tok))
995 return [=] { return *Val; };
996
997 // Tok is a symbol name.
998 if (!isValidCIdentifier(Tok))
999 setError("malformed number: " + Tok);
1000 Script->Opt.ReferencedSymbols.push_back(Tok);
1001 return [=] { return Script->getSymbolValue(Location, Tok); };
1002}
1003
1004Expr ScriptParser::readTernary(Expr Cond) {
1005 Expr L = readExpr();
1006 expect(":");
1007 Expr R = readExpr();
1008 return [=] { return Cond().getValue() ? L() : R(); };
1009}
1010
1011Expr ScriptParser::readParenExpr() {
1012 expect("(");
1013 Expr E = readExpr();
1014 expect(")");
1015 return E;
1016}
1017
1018std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() {
1019 std::vector<StringRef> Phdrs;
1020 while (!Error && peek().startswith(":")) {
1021 StringRef Tok = next();
1022 Phdrs.push_back((Tok.size() == 1) ? next() : Tok.substr(1));
1023 }
1024 return Phdrs;
1025}
1026
1027// Read a program header type name. The next token must be a
1028// name of a program header type or a constant (e.g. "0x3").
1029unsigned ScriptParser::readPhdrType() {
1030 StringRef Tok = next();
1031 if (Optional<uint64_t> Val = parseInt(Tok))
1032 return *Val;
1033
1034 unsigned Ret = StringSwitch<unsigned>(Tok)
1035 .Case("PT_NULL", PT_NULL)
1036 .Case("PT_LOAD", PT_LOAD)
1037 .Case("PT_DYNAMIC", PT_DYNAMIC)
1038 .Case("PT_INTERP", PT_INTERP)
1039 .Case("PT_NOTE", PT_NOTE)
1040 .Case("PT_SHLIB", PT_SHLIB)
1041 .Case("PT_PHDR", PT_PHDR)
1042 .Case("PT_TLS", PT_TLS)
1043 .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME)
1044 .Case("PT_GNU_STACK", PT_GNU_STACK)
1045 .Case("PT_GNU_RELRO", PT_GNU_RELRO)
1046 .Case("PT_OPENBSD_RANDOMIZE", PT_OPENBSD_RANDOMIZE)
1047 .Case("PT_OPENBSD_WXNEEDED", PT_OPENBSD_WXNEEDED)
1048 .Case("PT_OPENBSD_BOOTDATA", PT_OPENBSD_BOOTDATA)
1049 .Default(-1);
1050
1051 if (Ret == (unsigned)-1) {
1052 setError("invalid program header type: " + Tok);
1053 return PT_NULL;
1054 }
1055 return Ret;
1056}
1057
1058// Reads an anonymous version declaration.
1059void ScriptParser::readAnonymousDeclaration() {
1060 std::vector<SymbolVersion> Locals;
1061 std::vector<SymbolVersion> Globals;
1062 std::tie(Locals, Globals) = readSymbols();
1063
1064 for (SymbolVersion V : Locals) {
1065 if (V.Name == "*")
1066 Config->DefaultSymbolVersion = VER_NDX_LOCAL;
1067 else
1068 Config->VersionScriptLocals.push_back(V);
1069 }
1070
1071 for (SymbolVersion V : Globals)
1072 Config->VersionScriptGlobals.push_back(V);
1073
1074 expect(";");
1075}
1076
1077// Reads a non-anonymous version definition,
1078// e.g. "VerStr { global: foo; bar; local: *; };".
1079void ScriptParser::readVersionDeclaration(StringRef VerStr) {
1080 // Read a symbol list.
1081 std::vector<SymbolVersion> Locals;
1082 std::vector<SymbolVersion> Globals;
1083 std::tie(Locals, Globals) = readSymbols();
1084
1085 for (SymbolVersion V : Locals) {
1086 if (V.Name == "*")
1087 Config->DefaultSymbolVersion = VER_NDX_LOCAL;
1088 else
1089 Config->VersionScriptLocals.push_back(V);
1090 }
1091
1092 // Create a new version definition and add that to the global symbols.
1093 VersionDefinition Ver;
1094 Ver.Name = VerStr;
1095 Ver.Globals = Globals;
1096
1097 // User-defined version number starts from 2 because 0 and 1 are
1098 // reserved for VER_NDX_LOCAL and VER_NDX_GLOBAL, respectively.
1099 Ver.Id = Config->VersionDefinitions.size() + 2;
1100 Config->VersionDefinitions.push_back(Ver);
1101
1102 // Each version may have a parent version. For example, "Ver2"
1103 // defined as "Ver2 { global: foo; local: *; } Ver1;" has "Ver1"
1104 // as a parent. This version hierarchy is, probably against your
1105 // instinct, purely for hint; the runtime doesn't care about it
1106 // at all. In LLD, we simply ignore it.
1107 if (peek() != ";")
1108 skip();
1109 expect(";");
1110}
1111
1112static bool hasWildcard(StringRef S) {
1113 return S.find_first_of("?*[") != StringRef::npos;
1114}
1115
1116// Reads a list of symbols, e.g. "{ global: foo; bar; local: *; };".
1117std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>>
1118ScriptParser::readSymbols() {
1119 std::vector<SymbolVersion> Locals;
1120 std::vector<SymbolVersion> Globals;
1121 std::vector<SymbolVersion> *V = &Globals;
1122
1123 while (!Error) {
1124 if (consume("}"))
1125 break;
1126 if (consumeLabel("local")) {
1127 V = &Locals;
1128 continue;
1129 }
1130 if (consumeLabel("global")) {
1131 V = &Globals;
1132 continue;
1133 }
1134
1135 if (consume("extern")) {
1136 std::vector<SymbolVersion> Ext = readVersionExtern();
1137 V->insert(V->end(), Ext.begin(), Ext.end());
1138 } else {
1139 StringRef Tok = next();
1140 V->push_back({unquote(Tok), false, hasWildcard(Tok)});
1141 }
1142 expect(";");
1143 }
1144 return {Locals, Globals};
1145}
1146
1147// Reads an "extern C++" directive, e.g.,
1148// "extern "C++" { ns::*; "f(int, double)"; };"
1149std::vector<SymbolVersion> ScriptParser::readVersionExtern() {
1150 StringRef Tok = next();
1151 bool IsCXX = Tok == "\"C++\"";
1152 if (!IsCXX && Tok != "\"C\"")
1153 setError("Unknown language");
1154 expect("{");
1155
1156 std::vector<SymbolVersion> Ret;
1157 while (!Error && peek() != "}") {
1158 StringRef Tok = next();
1159 bool HasWildcard = !Tok.startswith("\"") && hasWildcard(Tok);
1160 Ret.push_back({unquote(Tok), IsCXX, HasWildcard});
1161 expect(";");
1162 }
1163
1164 expect("}");
1165 return Ret;
1166}
1167
1168uint64_t ScriptParser::readMemoryAssignment(StringRef S1, StringRef S2,
1169 StringRef S3) {
1170 if (!consume(S1) && !consume(S2) && !consume(S3)) {
1171 setError("expected one of: " + S1 + ", " + S2 + ", or " + S3);
1172 return 0;
1173 }
1174 expect("=");
1175 return readExpr()().getValue();
1176}
1177
1178// Parse the MEMORY command as specified in:
1179// https://sourceware.org/binutils/docs/ld/MEMORY.html
1180//
1181// MEMORY { name [(attr)] : ORIGIN = origin, LENGTH = len ... }
1182void ScriptParser::readMemory() {
1183 expect("{");
1184 while (!Error && !consume("}")) {
1185 StringRef Name = next();
1186
1187 uint32_t Flags = 0;
1188 uint32_t NegFlags = 0;
1189 if (consume("(")) {
1190 std::tie(Flags, NegFlags) = readMemoryAttributes();
1191 expect(")");
1192 }
1193 expect(":");
1194
1195 uint64_t Origin = readMemoryAssignment("ORIGIN", "org", "o");
1196 expect(",");
1197 uint64_t Length = readMemoryAssignment("LENGTH", "len", "l");
1198
1199 // Add the memory region to the region map (if it doesn't already exist).
1200 auto It = Script->Opt.MemoryRegions.find(Name);
1201 if (It != Script->Opt.MemoryRegions.end())
1202 setError("region '" + Name + "' already defined");
1203 else
1204 Script->Opt.MemoryRegions[Name] = {Name, Origin, Length, Flags, NegFlags};
1205 }
1206}
1207
1208// This function parses the attributes used to match against section
1209// flags when placing output sections in a memory region. These flags
1210// are only used when an explicit memory region name is not used.
1211std::pair<uint32_t, uint32_t> ScriptParser::readMemoryAttributes() {
1212 uint32_t Flags = 0;
1213 uint32_t NegFlags = 0;
1214 bool Invert = false;
1215
1216 for (char C : next().lower()) {
1217 uint32_t Flag = 0;
1218 if (C == '!')
1219 Invert = !Invert;
1220 else if (C == 'w')
1221 Flag = SHF_WRITE;
1222 else if (C == 'x')
1223 Flag = SHF_EXECINSTR;
1224 else if (C == 'a')
1225 Flag = SHF_ALLOC;
1226 else if (C != 'r')
1227 setError("invalid memory region attribute");
1228
1229 if (Invert)
1230 NegFlags |= Flag;
1231 else
1232 Flags |= Flag;
1233 }
1234 return {Flags, NegFlags};
1235}
1236
1237void elf::readLinkerScript(MemoryBufferRef MB) {
1238 ScriptParser(MB).readLinkerScript();
1239}
1240
1241void elf::readVersionScript(MemoryBufferRef MB) {
1242 ScriptParser(MB).readVersionScript();
1243}
1244
1245void elf::readDynamicList(MemoryBufferRef MB) {
1246 ScriptParser(MB).readDynamicList();
1247}
deps/lld/ELF/ScriptParser.h created+31
......@@ -0,0 +1,31 @@
1//===- ScriptParser.h -------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_ELF_SCRIPT_PARSER_H
11#define LLD_ELF_SCRIPT_PARSER_H
12
13#include "lld/Core/LLVM.h"
14#include "llvm/Support/MemoryBuffer.h"
15
16namespace lld {
17namespace elf {
18
19// Parses a linker script. Calling this function updates
20// Config and ScriptConfig.
21void readLinkerScript(MemoryBufferRef MB);
22
23// Parses a version script.
24void readVersionScript(MemoryBufferRef MB);
25
26void readDynamicList(MemoryBufferRef MB);
27
28} // namespace elf
29} // namespace lld
30
31#endif
deps/lld/ELF/Strings.cpp created+85
......@@ -0,0 +1,85 @@
1//===- Strings.cpp -------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "Strings.h"
11#include "Config.h"
12#include "Error.h"
13#include "llvm/ADT/ArrayRef.h"
14#include "llvm/ADT/StringRef.h"
15#include "llvm/ADT/Twine.h"
16#include "llvm/Demangle/Demangle.h"
17#include <algorithm>
18#include <cstring>
19
20using namespace llvm;
21using namespace lld;
22using namespace lld::elf;
23
24StringMatcher::StringMatcher(ArrayRef<StringRef> Pat) {
25 for (StringRef S : Pat) {
26 Expected<GlobPattern> Pat = GlobPattern::create(S);
27 if (!Pat)
28 error(toString(Pat.takeError()));
29 else
30 Patterns.push_back(*Pat);
31 }
32}
33
34bool StringMatcher::match(StringRef S) const {
35 for (const GlobPattern &Pat : Patterns)
36 if (Pat.match(S))
37 return true;
38 return false;
39}
40
41// Converts a hex string (e.g. "deadbeef") to a vector.
42std::vector<uint8_t> elf::parseHex(StringRef S) {
43 std::vector<uint8_t> Hex;
44 while (!S.empty()) {
45 StringRef B = S.substr(0, 2);
46 S = S.substr(2);
47 uint8_t H;
48 if (!to_integer(B, H, 16)) {
49 error("not a hexadecimal value: " + B);
50 return {};
51 }
52 Hex.push_back(H);
53 }
54 return Hex;
55}
56
57static bool isAlpha(char C) {
58 return ('a' <= C && C <= 'z') || ('A' <= C && C <= 'Z') || C == '_';
59}
60
61static bool isAlnum(char C) { return isAlpha(C) || ('0' <= C && C <= '9'); }
62
63// Returns true if S is valid as a C language identifier.
64bool elf::isValidCIdentifier(StringRef S) {
65 return !S.empty() && isAlpha(S[0]) &&
66 std::all_of(S.begin() + 1, S.end(), isAlnum);
67}
68
69// Returns the demangled C++ symbol name for Name.
70Optional<std::string> elf::demangle(StringRef Name) {
71 // itaniumDemangle can be used to demangle strings other than symbol
72 // names which do not necessarily start with "_Z". Name can be
73 // either a C or C++ symbol. Don't call itaniumDemangle if the name
74 // does not look like a C++ symbol name to avoid getting unexpected
75 // result for a C symbol that happens to match a mangled type name.
76 if (!Name.startswith("_Z"))
77 return None;
78
79 char *Buf = itaniumDemangle(Name.str().c_str(), nullptr, nullptr, nullptr);
80 if (!Buf)
81 return None;
82 std::string S(Buf);
83 free(Buf);
84 return S;
85}
deps/lld/ELF/Strings.h created+79
......@@ -0,0 +1,79 @@
1//===- Strings.h ------------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_ELF_STRINGS_H
11#define LLD_ELF_STRINGS_H
12
13#include "lld/Core/LLVM.h"
14#include "llvm/ADT/ArrayRef.h"
15#include "llvm/ADT/BitVector.h"
16#include "llvm/ADT/Optional.h"
17#include "llvm/ADT/StringRef.h"
18#include "llvm/Support/GlobPattern.h"
19#include <vector>
20
21namespace lld {
22namespace elf {
23
24std::vector<uint8_t> parseHex(StringRef S);
25bool isValidCIdentifier(StringRef S);
26
27// This is a lazy version of StringRef. String size is computed lazily
28// when it is needed. It is more efficient than StringRef to instantiate
29// if you have a string whose size is unknown.
30//
31// ELF string tables contain a lot of null-terminated strings.
32// Most of them are not necessary for the linker because they are names
33// of local symbols and the linker doesn't use local symbol names for
34// name resolution. So, we use this class to represents strings read
35// from string tables.
36class StringRefZ {
37public:
38 StringRefZ() : Start(nullptr), Size(0) {}
39 StringRefZ(const char *S, size_t Size) : Start(S), Size(Size) {}
40
41 /*implicit*/ StringRefZ(const char *S) : Start(S), Size(-1) {}
42
43 /*implicit*/ StringRefZ(llvm::StringRef S)
44 : Start(S.data()), Size(S.size()) {}
45
46 operator llvm::StringRef() const {
47 if (Size == (size_t)-1)
48 Size = strlen(Start);
49 return {Start, Size};
50 }
51
52private:
53 const char *Start;
54 mutable size_t Size;
55};
56
57// This class represents multiple glob patterns.
58class StringMatcher {
59public:
60 StringMatcher() = default;
61 explicit StringMatcher(ArrayRef<StringRef> Pat);
62
63 bool match(StringRef S) const;
64
65private:
66 std::vector<llvm::GlobPattern> Patterns;
67};
68
69// Returns a demangled C++ symbol name. If Name is not a mangled
70// name, it returns Optional::None.
71llvm::Optional<std::string> demangle(StringRef Name);
72
73inline ArrayRef<uint8_t> toArrayRef(StringRef S) {
74 return {(const uint8_t *)S.data(), S.size()};
75}
76} // namespace elf
77} // namespace lld
78
79#endif
deps/lld/ELF/SymbolTable.cpp created+782
......@@ -0,0 +1,782 @@
1//===- SymbolTable.cpp ----------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Symbol table is a bag of all known symbols. We put all symbols of
11// all input files to the symbol table. The symbol table is basically
12// a hash table with the logic to resolve symbol name conflicts using
13// the symbol types.
14//
15//===----------------------------------------------------------------------===//
16
17#include "SymbolTable.h"
18#include "Config.h"
19#include "Error.h"
20#include "LinkerScript.h"
21#include "Memory.h"
22#include "Symbols.h"
23#include "llvm/ADT/STLExtras.h"
24
25using namespace llvm;
26using namespace llvm::object;
27using namespace llvm::ELF;
28
29using namespace lld;
30using namespace lld::elf;
31
32// All input object files must be for the same architecture
33// (e.g. it does not make sense to link x86 object files with
34// MIPS object files.) This function checks for that error.
35template <class ELFT> static bool isCompatible(InputFile *F) {
36 if (!isa<ELFFileBase<ELFT>>(F) && !isa<BitcodeFile>(F))
37 return true;
38
39 if (F->EKind == Config->EKind && F->EMachine == Config->EMachine) {
40 if (Config->EMachine != EM_MIPS)
41 return true;
42 if (isMipsN32Abi(F) == Config->MipsN32Abi)
43 return true;
44 }
45
46 if (!Config->Emulation.empty())
47 error(toString(F) + " is incompatible with " + Config->Emulation);
48 else
49 error(toString(F) + " is incompatible with " + toString(Config->FirstElf));
50 return false;
51}
52
53// Add symbols in File to the symbol table.
54template <class ELFT> void SymbolTable<ELFT>::addFile(InputFile *File) {
55 if (!Config->FirstElf && isa<ELFFileBase<ELFT>>(File))
56 Config->FirstElf = File;
57
58 if (!isCompatible<ELFT>(File))
59 return;
60
61 // Binary file
62 if (auto *F = dyn_cast<BinaryFile>(File)) {
63 BinaryFiles.push_back(F);
64 F->parse<ELFT>();
65 return;
66 }
67
68 // .a file
69 if (auto *F = dyn_cast<ArchiveFile>(File)) {
70 F->parse<ELFT>();
71 return;
72 }
73
74 // Lazy object file
75 if (auto *F = dyn_cast<LazyObjectFile>(File)) {
76 F->parse<ELFT>();
77 return;
78 }
79
80 if (Config->Trace)
81 message(toString(File));
82
83 // .so file
84 if (auto *F = dyn_cast<SharedFile<ELFT>>(File)) {
85 // DSOs are uniquified not by filename but by soname.
86 F->parseSoName();
87 if (ErrorCount || !SoNames.insert(F->SoName).second)
88 return;
89 SharedFiles.push_back(F);
90 F->parseRest();
91 return;
92 }
93
94 // LLVM bitcode file
95 if (auto *F = dyn_cast<BitcodeFile>(File)) {
96 BitcodeFiles.push_back(F);
97 F->parse<ELFT>(ComdatGroups);
98 return;
99 }
100
101 // Regular object file
102 auto *F = cast<ObjectFile<ELFT>>(File);
103 ObjectFiles.push_back(F);
104 F->parse(ComdatGroups);
105}
106
107// This function is where all the optimizations of link-time
108// optimization happens. When LTO is in use, some input files are
109// not in native object file format but in the LLVM bitcode format.
110// This function compiles bitcode files into a few big native files
111// using LLVM functions and replaces bitcode symbols with the results.
112// Because all bitcode files that consist of a program are passed
113// to the compiler at once, it can do whole-program optimization.
114template <class ELFT> void SymbolTable<ELFT>::addCombinedLTOObject() {
115 if (BitcodeFiles.empty())
116 return;
117
118 // Compile bitcode files and replace bitcode symbols.
119 LTO.reset(new BitcodeCompiler);
120 for (BitcodeFile *F : BitcodeFiles)
121 LTO->add(*F);
122
123 for (InputFile *File : LTO->compile()) {
124 ObjectFile<ELFT> *Obj = cast<ObjectFile<ELFT>>(File);
125 DenseSet<CachedHashStringRef> DummyGroups;
126 Obj->parse(DummyGroups);
127 ObjectFiles.push_back(Obj);
128 }
129}
130
131template <class ELFT>
132DefinedRegular *SymbolTable<ELFT>::addAbsolute(StringRef Name,
133 uint8_t Visibility,
134 uint8_t Binding) {
135 Symbol *Sym =
136 addRegular(Name, Visibility, STT_NOTYPE, 0, 0, Binding, nullptr, nullptr);
137 return cast<DefinedRegular>(Sym->body());
138}
139
140// Add Name as an "ignored" symbol. An ignored symbol is a regular
141// linker-synthesized defined symbol, but is only defined if needed.
142template <class ELFT>
143DefinedRegular *SymbolTable<ELFT>::addIgnored(StringRef Name,
144 uint8_t Visibility) {
145 SymbolBody *S = find(Name);
146 if (!S || S->isInCurrentDSO())
147 return nullptr;
148 return addAbsolute(Name, Visibility);
149}
150
151// Set a flag for --trace-symbol so that we can print out a log message
152// if a new symbol with the same name is inserted into the symbol table.
153template <class ELFT> void SymbolTable<ELFT>::trace(StringRef Name) {
154 Symtab.insert({CachedHashStringRef(Name), {-1, true}});
155}
156
157// Rename SYM as __wrap_SYM. The original symbol is preserved as __real_SYM.
158// Used to implement --wrap.
159template <class ELFT> void SymbolTable<ELFT>::addSymbolWrap(StringRef Name) {
160 SymbolBody *B = find(Name);
161 if (!B)
162 return;
163 Symbol *Sym = B->symbol();
164 Symbol *Real = addUndefined(Saver.save("__real_" + Name));
165 Symbol *Wrap = addUndefined(Saver.save("__wrap_" + Name));
166
167 // Tell LTO not to eliminate this symbol
168 Wrap->IsUsedInRegularObj = true;
169
170 Config->RenamedSymbols[Real] = {Sym, Real->Binding};
171 Config->RenamedSymbols[Sym] = {Wrap, Sym->Binding};
172}
173
174// Creates alias for symbol. Used to implement --defsym=ALIAS=SYM.
175template <class ELFT>
176void SymbolTable<ELFT>::addSymbolAlias(StringRef Alias, StringRef Name) {
177 SymbolBody *B = find(Name);
178 if (!B) {
179 error("-defsym: undefined symbol: " + Name);
180 return;
181 }
182 Symbol *Sym = B->symbol();
183 Symbol *AliasSym = addUndefined(Alias);
184
185 // Tell LTO not to eliminate this symbol
186 Sym->IsUsedInRegularObj = true;
187 Config->RenamedSymbols[AliasSym] = {Sym, AliasSym->Binding};
188}
189
190// Apply symbol renames created by -wrap and -defsym. The renames are created
191// before LTO in addSymbolWrap() and addSymbolAlias() to have a chance to inform
192// LTO (if LTO is running) not to include these symbols in IPO. Now that the
193// symbols are finalized, we can perform the replacement.
194template <class ELFT> void SymbolTable<ELFT>::applySymbolRenames() {
195 for (auto &KV : Config->RenamedSymbols) {
196 Symbol *Dst = KV.first;
197 Symbol *Src = KV.second.Target;
198 Dst->body()->copy(Src->body());
199 Dst->Binding = KV.second.OriginalBinding;
200 }
201}
202
203static uint8_t getMinVisibility(uint8_t VA, uint8_t VB) {
204 if (VA == STV_DEFAULT)
205 return VB;
206 if (VB == STV_DEFAULT)
207 return VA;
208 return std::min(VA, VB);
209}
210
211// Find an existing symbol or create and insert a new one.
212template <class ELFT>
213std::pair<Symbol *, bool> SymbolTable<ELFT>::insert(StringRef Name) {
214 // <name>@@<version> means the symbol is the default version. In that
215 // case <name>@@<version> will be used to resolve references to <name>.
216 size_t Pos = Name.find("@@");
217 if (Pos != StringRef::npos)
218 Name = Name.take_front(Pos);
219
220 auto P = Symtab.insert(
221 {CachedHashStringRef(Name), SymIndex((int)SymVector.size(), false)});
222 SymIndex &V = P.first->second;
223 bool IsNew = P.second;
224
225 if (V.Idx == -1) {
226 IsNew = true;
227 V = SymIndex((int)SymVector.size(), true);
228 }
229
230 Symbol *Sym;
231 if (IsNew) {
232 Sym = make<Symbol>();
233 Sym->InVersionScript = false;
234 Sym->Binding = STB_WEAK;
235 Sym->Visibility = STV_DEFAULT;
236 Sym->IsUsedInRegularObj = false;
237 Sym->ExportDynamic = false;
238 Sym->Traced = V.Traced;
239 Sym->VersionId = Config->DefaultSymbolVersion;
240 SymVector.push_back(Sym);
241 } else {
242 Sym = SymVector[V.Idx];
243 }
244 return {Sym, IsNew};
245}
246
247// Find an existing symbol or create and insert a new one, then apply the given
248// attributes.
249template <class ELFT>
250std::pair<Symbol *, bool>
251SymbolTable<ELFT>::insert(StringRef Name, uint8_t Type, uint8_t Visibility,
252 bool CanOmitFromDynSym, InputFile *File) {
253 bool IsUsedInRegularObj = !File || File->kind() == InputFile::ObjectKind;
254 Symbol *S;
255 bool WasInserted;
256 std::tie(S, WasInserted) = insert(Name);
257
258 // Merge in the new symbol's visibility.
259 S->Visibility = getMinVisibility(S->Visibility, Visibility);
260
261 if (!CanOmitFromDynSym && (Config->Shared || Config->ExportDynamic))
262 S->ExportDynamic = true;
263
264 if (IsUsedInRegularObj)
265 S->IsUsedInRegularObj = true;
266
267 if (!WasInserted && S->body()->Type != SymbolBody::UnknownType &&
268 ((Type == STT_TLS) != S->body()->isTls())) {
269 error("TLS attribute mismatch: " + toString(*S->body()) +
270 "\n>>> defined in " + toString(S->body()->File) +
271 "\n>>> defined in " + toString(File));
272 }
273
274 return {S, WasInserted};
275}
276
277template <class ELFT> Symbol *SymbolTable<ELFT>::addUndefined(StringRef Name) {
278 return addUndefined(Name, /*IsLocal=*/false, STB_GLOBAL, STV_DEFAULT,
279 /*Type*/ 0,
280 /*CanOmitFromDynSym*/ false, /*File*/ nullptr);
281}
282
283static uint8_t getVisibility(uint8_t StOther) { return StOther & 3; }
284
285template <class ELFT>
286Symbol *SymbolTable<ELFT>::addUndefined(StringRef Name, bool IsLocal,
287 uint8_t Binding, uint8_t StOther,
288 uint8_t Type, bool CanOmitFromDynSym,
289 InputFile *File) {
290 Symbol *S;
291 bool WasInserted;
292 uint8_t Visibility = getVisibility(StOther);
293 std::tie(S, WasInserted) =
294 insert(Name, Type, Visibility, CanOmitFromDynSym, File);
295 // An undefined symbol with non default visibility must be satisfied
296 // in the same DSO.
297 if (WasInserted ||
298 (isa<SharedSymbol>(S->body()) && Visibility != STV_DEFAULT)) {
299 S->Binding = Binding;
300 replaceBody<Undefined>(S, Name, IsLocal, StOther, Type, File);
301 return S;
302 }
303 if (Binding != STB_WEAK) {
304 SymbolBody *B = S->body();
305 if (B->isShared() || B->isLazy() || B->isUndefined())
306 S->Binding = Binding;
307 if (auto *SS = dyn_cast<SharedSymbol>(B))
308 cast<SharedFile<ELFT>>(SS->File)->IsUsed = true;
309 }
310 if (auto *L = dyn_cast<Lazy>(S->body())) {
311 // An undefined weak will not fetch archive members, but we have to remember
312 // its type. See also comment in addLazyArchive.
313 if (S->isWeak())
314 L->Type = Type;
315 else if (InputFile *F = L->fetch())
316 addFile(F);
317 }
318 return S;
319}
320
321// Using .symver foo,foo@@VER unfortunately creates two symbols: foo and
322// foo@@VER. We want to effectively ignore foo, so give precedence to
323// foo@@VER.
324// FIXME: If users can transition to using
325// .symver foo,foo@@@VER
326// we can delete this hack.
327static int compareVersion(Symbol *S, StringRef Name) {
328 if (Name.find("@@") != StringRef::npos &&
329 S->body()->getName().find("@@") == StringRef::npos)
330 return 1;
331 if (Name.find("@@") == StringRef::npos &&
332 S->body()->getName().find("@@") != StringRef::npos)
333 return -1;
334 return 0;
335}
336
337// We have a new defined symbol with the specified binding. Return 1 if the new
338// symbol should win, -1 if the new symbol should lose, or 0 if both symbols are
339// strong defined symbols.
340static int compareDefined(Symbol *S, bool WasInserted, uint8_t Binding,
341 StringRef Name) {
342 if (WasInserted)
343 return 1;
344 SymbolBody *Body = S->body();
345 if (!Body->isInCurrentDSO())
346 return 1;
347
348 if (int R = compareVersion(S, Name))
349 return R;
350
351 if (Binding == STB_WEAK)
352 return -1;
353 if (S->isWeak())
354 return 1;
355 return 0;
356}
357
358// We have a new non-common defined symbol with the specified binding. Return 1
359// if the new symbol should win, -1 if the new symbol should lose, or 0 if there
360// is a conflict. If the new symbol wins, also update the binding.
361template <typename ELFT>
362static int compareDefinedNonCommon(Symbol *S, bool WasInserted, uint8_t Binding,
363 bool IsAbsolute, typename ELFT::uint Value,
364 StringRef Name) {
365 if (int Cmp = compareDefined(S, WasInserted, Binding, Name)) {
366 if (Cmp > 0)
367 S->Binding = Binding;
368 return Cmp;
369 }
370 SymbolBody *B = S->body();
371 if (isa<DefinedCommon>(B)) {
372 // Non-common symbols take precedence over common symbols.
373 if (Config->WarnCommon)
374 warn("common " + S->body()->getName() + " is overridden");
375 return 1;
376 } else if (auto *R = dyn_cast<DefinedRegular>(B)) {
377 if (R->Section == nullptr && Binding == STB_GLOBAL && IsAbsolute &&
378 R->Value == Value)
379 return -1;
380 }
381 return 0;
382}
383
384template <class ELFT>
385Symbol *SymbolTable<ELFT>::addCommon(StringRef N, uint64_t Size,
386 uint32_t Alignment, uint8_t Binding,
387 uint8_t StOther, uint8_t Type,
388 InputFile *File) {
389 Symbol *S;
390 bool WasInserted;
391 std::tie(S, WasInserted) = insert(N, Type, getVisibility(StOther),
392 /*CanOmitFromDynSym*/ false, File);
393 int Cmp = compareDefined(S, WasInserted, Binding, N);
394 if (Cmp > 0) {
395 S->Binding = Binding;
396 replaceBody<DefinedCommon>(S, N, Size, Alignment, StOther, Type, File);
397 } else if (Cmp == 0) {
398 auto *C = dyn_cast<DefinedCommon>(S->body());
399 if (!C) {
400 // Non-common symbols take precedence over common symbols.
401 if (Config->WarnCommon)
402 warn("common " + S->body()->getName() + " is overridden");
403 return S;
404 }
405
406 if (Config->WarnCommon)
407 warn("multiple common of " + S->body()->getName());
408
409 Alignment = C->Alignment = std::max(C->Alignment, Alignment);
410 if (Size > C->Size)
411 replaceBody<DefinedCommon>(S, N, Size, Alignment, StOther, Type, File);
412 }
413 return S;
414}
415
416static void warnOrError(const Twine &Msg) {
417 if (Config->AllowMultipleDefinition)
418 warn(Msg);
419 else
420 error(Msg);
421}
422
423static void reportDuplicate(SymbolBody *Sym, InputFile *NewFile) {
424 warnOrError("duplicate symbol: " + toString(*Sym) + "\n>>> defined in " +
425 toString(Sym->File) + "\n>>> defined in " + toString(NewFile));
426}
427
428template <class ELFT>
429static void reportDuplicate(SymbolBody *Sym, InputSectionBase *ErrSec,
430 typename ELFT::uint ErrOffset) {
431 DefinedRegular *D = dyn_cast<DefinedRegular>(Sym);
432 if (!D || !D->Section || !ErrSec) {
433 reportDuplicate(Sym, ErrSec ? ErrSec->getFile<ELFT>() : nullptr);
434 return;
435 }
436
437 // Construct and print an error message in the form of:
438 //
439 // ld.lld: error: duplicate symbol: foo
440 // >>> defined at bar.c:30
441 // >>> bar.o (/home/alice/src/bar.o)
442 // >>> defined at baz.c:563
443 // >>> baz.o in archive libbaz.a
444 auto *Sec1 = cast<InputSectionBase>(D->Section);
445 std::string Src1 = Sec1->getSrcMsg<ELFT>(D->Value);
446 std::string Obj1 = Sec1->getObjMsg<ELFT>(D->Value);
447 std::string Src2 = ErrSec->getSrcMsg<ELFT>(ErrOffset);
448 std::string Obj2 = ErrSec->getObjMsg<ELFT>(ErrOffset);
449
450 std::string Msg = "duplicate symbol: " + toString(*Sym) + "\n>>> defined at ";
451 if (!Src1.empty())
452 Msg += Src1 + "\n>>> ";
453 Msg += Obj1 + "\n>>> defined at ";
454 if (!Src2.empty())
455 Msg += Src2 + "\n>>> ";
456 Msg += Obj2;
457 warnOrError(Msg);
458}
459
460template <typename ELFT>
461Symbol *SymbolTable<ELFT>::addRegular(StringRef Name, uint8_t StOther,
462 uint8_t Type, uint64_t Value,
463 uint64_t Size, uint8_t Binding,
464 SectionBase *Section, InputFile *File) {
465 Symbol *S;
466 bool WasInserted;
467 std::tie(S, WasInserted) = insert(Name, Type, getVisibility(StOther),
468 /*CanOmitFromDynSym*/ false, File);
469 int Cmp = compareDefinedNonCommon<ELFT>(S, WasInserted, Binding,
470 Section == nullptr, Value, Name);
471 if (Cmp > 0)
472 replaceBody<DefinedRegular>(S, Name, /*IsLocal=*/false, StOther, Type,
473 Value, Size, Section, File);
474 else if (Cmp == 0)
475 reportDuplicate<ELFT>(S->body(),
476 dyn_cast_or_null<InputSectionBase>(Section), Value);
477 return S;
478}
479
480template <typename ELFT>
481void SymbolTable<ELFT>::addShared(SharedFile<ELFT> *File, StringRef Name,
482 const Elf_Sym &Sym,
483 const typename ELFT::Verdef *Verdef) {
484 // DSO symbols do not affect visibility in the output, so we pass STV_DEFAULT
485 // as the visibility, which will leave the visibility in the symbol table
486 // unchanged.
487 Symbol *S;
488 bool WasInserted;
489 std::tie(S, WasInserted) = insert(Name, Sym.getType(), STV_DEFAULT,
490 /*CanOmitFromDynSym*/ true, File);
491 // Make sure we preempt DSO symbols with default visibility.
492 if (Sym.getVisibility() == STV_DEFAULT)
493 S->ExportDynamic = true;
494
495 SymbolBody *Body = S->body();
496 // An undefined symbol with non default visibility must be satisfied
497 // in the same DSO.
498 if (WasInserted ||
499 (isa<Undefined>(Body) && Body->getVisibility() == STV_DEFAULT)) {
500 replaceBody<SharedSymbol>(S, File, Name, Sym.st_other, Sym.getType(), &Sym,
501 Verdef);
502 if (!S->isWeak())
503 File->IsUsed = true;
504 }
505}
506
507template <class ELFT>
508Symbol *SymbolTable<ELFT>::addBitcode(StringRef Name, uint8_t Binding,
509 uint8_t StOther, uint8_t Type,
510 bool CanOmitFromDynSym, BitcodeFile *F) {
511 Symbol *S;
512 bool WasInserted;
513 std::tie(S, WasInserted) =
514 insert(Name, Type, getVisibility(StOther), CanOmitFromDynSym, F);
515 int Cmp = compareDefinedNonCommon<ELFT>(S, WasInserted, Binding,
516 /*IsAbs*/ false, /*Value*/ 0, Name);
517 if (Cmp > 0)
518 replaceBody<DefinedRegular>(S, Name, /*IsLocal=*/false, StOther, Type, 0, 0,
519 nullptr, F);
520 else if (Cmp == 0)
521 reportDuplicate(S->body(), F);
522 return S;
523}
524
525template <class ELFT> SymbolBody *SymbolTable<ELFT>::find(StringRef Name) {
526 auto It = Symtab.find(CachedHashStringRef(Name));
527 if (It == Symtab.end())
528 return nullptr;
529 SymIndex V = It->second;
530 if (V.Idx == -1)
531 return nullptr;
532 return SymVector[V.Idx]->body();
533}
534
535template <class ELFT>
536SymbolBody *SymbolTable<ELFT>::findInCurrentDSO(StringRef Name) {
537 if (SymbolBody *S = find(Name))
538 if (S->isInCurrentDSO())
539 return S;
540 return nullptr;
541}
542
543template <class ELFT>
544Symbol *SymbolTable<ELFT>::addLazyArchive(ArchiveFile *F,
545 const object::Archive::Symbol Sym) {
546 Symbol *S;
547 bool WasInserted;
548 StringRef Name = Sym.getName();
549 std::tie(S, WasInserted) = insert(Name);
550 if (WasInserted) {
551 replaceBody<LazyArchive>(S, *F, Sym, SymbolBody::UnknownType);
552 return S;
553 }
554 if (!S->body()->isUndefined())
555 return S;
556
557 // Weak undefined symbols should not fetch members from archives. If we were
558 // to keep old symbol we would not know that an archive member was available
559 // if a strong undefined symbol shows up afterwards in the link. If a strong
560 // undefined symbol never shows up, this lazy symbol will get to the end of
561 // the link and must be treated as the weak undefined one. We already marked
562 // this symbol as used when we added it to the symbol table, but we also need
563 // to preserve its type. FIXME: Move the Type field to Symbol.
564 if (S->isWeak()) {
565 replaceBody<LazyArchive>(S, *F, Sym, S->body()->Type);
566 return S;
567 }
568 std::pair<MemoryBufferRef, uint64_t> MBInfo = F->getMember(&Sym);
569 if (!MBInfo.first.getBuffer().empty())
570 addFile(createObjectFile(MBInfo.first, F->getName(), MBInfo.second));
571 return S;
572}
573
574template <class ELFT>
575void SymbolTable<ELFT>::addLazyObject(StringRef Name, LazyObjectFile &Obj) {
576 Symbol *S;
577 bool WasInserted;
578 std::tie(S, WasInserted) = insert(Name);
579 if (WasInserted) {
580 replaceBody<LazyObject>(S, Name, Obj, SymbolBody::UnknownType);
581 return;
582 }
583 if (!S->body()->isUndefined())
584 return;
585
586 // See comment for addLazyArchive above.
587 if (S->isWeak())
588 replaceBody<LazyObject>(S, Name, Obj, S->body()->Type);
589 else if (InputFile *F = Obj.fetch())
590 addFile(F);
591}
592
593// Process undefined (-u) flags by loading lazy symbols named by those flags.
594template <class ELFT> void SymbolTable<ELFT>::scanUndefinedFlags() {
595 for (StringRef S : Config->Undefined)
596 if (auto *L = dyn_cast_or_null<Lazy>(find(S)))
597 if (InputFile *File = L->fetch())
598 addFile(File);
599}
600
601// This function takes care of the case in which shared libraries depend on
602// the user program (not the other way, which is usual). Shared libraries
603// may have undefined symbols, expecting that the user program provides
604// the definitions for them. An example is BSD's __progname symbol.
605// We need to put such symbols to the main program's .dynsym so that
606// shared libraries can find them.
607// Except this, we ignore undefined symbols in DSOs.
608template <class ELFT> void SymbolTable<ELFT>::scanShlibUndefined() {
609 for (SharedFile<ELFT> *File : SharedFiles) {
610 for (StringRef U : File->getUndefinedSymbols()) {
611 SymbolBody *Sym = find(U);
612 if (!Sym || !Sym->isDefined())
613 continue;
614 Sym->symbol()->ExportDynamic = true;
615
616 // If -dynamic-list is given, the default version is set to
617 // VER_NDX_LOCAL, which prevents a symbol to be exported via .dynsym.
618 // Set to VER_NDX_GLOBAL so the symbol will be handled as if it were
619 // specified by -dynamic-list.
620 Sym->symbol()->VersionId = VER_NDX_GLOBAL;
621 }
622 }
623}
624
625// Initialize DemangledSyms with a map from demangled symbols to symbol
626// objects. Used to handle "extern C++" directive in version scripts.
627//
628// The map will contain all demangled symbols. That can be very large,
629// and in LLD we generally want to avoid do anything for each symbol.
630// Then, why are we doing this? Here's why.
631//
632// Users can use "extern C++ {}" directive to match against demangled
633// C++ symbols. For example, you can write a pattern such as
634// "llvm::*::foo(int, ?)". Obviously, there's no way to handle this
635// other than trying to match a pattern against all demangled symbols.
636// So, if "extern C++" feature is used, we need to demangle all known
637// symbols.
638template <class ELFT>
639StringMap<std::vector<SymbolBody *>> &SymbolTable<ELFT>::getDemangledSyms() {
640 if (!DemangledSyms) {
641 DemangledSyms.emplace();
642 for (Symbol *Sym : SymVector) {
643 SymbolBody *B = Sym->body();
644 if (B->isUndefined())
645 continue;
646 if (Optional<std::string> S = demangle(B->getName()))
647 (*DemangledSyms)[*S].push_back(B);
648 else
649 (*DemangledSyms)[B->getName()].push_back(B);
650 }
651 }
652 return *DemangledSyms;
653}
654
655template <class ELFT>
656std::vector<SymbolBody *> SymbolTable<ELFT>::findByVersion(SymbolVersion Ver) {
657 if (Ver.IsExternCpp)
658 return getDemangledSyms().lookup(Ver.Name);
659 if (SymbolBody *B = find(Ver.Name))
660 if (!B->isUndefined())
661 return {B};
662 return {};
663}
664
665template <class ELFT>
666std::vector<SymbolBody *>
667SymbolTable<ELFT>::findAllByVersion(SymbolVersion Ver) {
668 std::vector<SymbolBody *> Res;
669 StringMatcher M(Ver.Name);
670
671 if (Ver.IsExternCpp) {
672 for (auto &P : getDemangledSyms())
673 if (M.match(P.first()))
674 Res.insert(Res.end(), P.second.begin(), P.second.end());
675 return Res;
676 }
677
678 for (Symbol *Sym : SymVector) {
679 SymbolBody *B = Sym->body();
680 if (!B->isUndefined() && M.match(B->getName()))
681 Res.push_back(B);
682 }
683 return Res;
684}
685
686// If there's only one anonymous version definition in a version
687// script file, the script does not actually define any symbol version,
688// but just specifies symbols visibilities.
689template <class ELFT> void SymbolTable<ELFT>::handleAnonymousVersion() {
690 for (SymbolVersion &Ver : Config->VersionScriptGlobals)
691 assignExactVersion(Ver, VER_NDX_GLOBAL, "global");
692 for (SymbolVersion &Ver : Config->VersionScriptGlobals)
693 assignWildcardVersion(Ver, VER_NDX_GLOBAL);
694 for (SymbolVersion &Ver : Config->VersionScriptLocals)
695 assignExactVersion(Ver, VER_NDX_LOCAL, "local");
696 for (SymbolVersion &Ver : Config->VersionScriptLocals)
697 assignWildcardVersion(Ver, VER_NDX_LOCAL);
698}
699
700// Set symbol versions to symbols. This function handles patterns
701// containing no wildcard characters.
702template <class ELFT>
703void SymbolTable<ELFT>::assignExactVersion(SymbolVersion Ver,
704 uint16_t VersionId,
705 StringRef VersionName) {
706 if (Ver.HasWildcard)
707 return;
708
709 // Get a list of symbols which we need to assign the version to.
710 std::vector<SymbolBody *> Syms = findByVersion(Ver);
711 if (Syms.empty()) {
712 if (Config->NoUndefinedVersion)
713 error("version script assignment of '" + VersionName + "' to symbol '" +
714 Ver.Name + "' failed: symbol not defined");
715 return;
716 }
717
718 // Assign the version.
719 for (SymbolBody *B : Syms) {
720 // Skip symbols containing version info because symbol versions
721 // specified by symbol names take precedence over version scripts.
722 // See parseSymbolVersion().
723 if (B->getName().find('@') != StringRef::npos)
724 continue;
725
726 Symbol *Sym = B->symbol();
727 if (Sym->InVersionScript)
728 warn("duplicate symbol '" + Ver.Name + "' in version script");
729 Sym->VersionId = VersionId;
730 Sym->InVersionScript = true;
731 }
732}
733
734template <class ELFT>
735void SymbolTable<ELFT>::assignWildcardVersion(SymbolVersion Ver,
736 uint16_t VersionId) {
737 if (!Ver.HasWildcard)
738 return;
739
740 // Exact matching takes precendence over fuzzy matching,
741 // so we set a version to a symbol only if no version has been assigned
742 // to the symbol. This behavior is compatible with GNU.
743 for (SymbolBody *B : findAllByVersion(Ver))
744 if (B->symbol()->VersionId == Config->DefaultSymbolVersion)
745 B->symbol()->VersionId = VersionId;
746}
747
748// This function processes version scripts by updating VersionId
749// member of symbols.
750template <class ELFT> void SymbolTable<ELFT>::scanVersionScript() {
751 // Handle edge cases first.
752 handleAnonymousVersion();
753
754 // Now we have version definitions, so we need to set version ids to symbols.
755 // Each version definition has a glob pattern, and all symbols that match
756 // with the pattern get that version.
757
758 // First, we assign versions to exact matching symbols,
759 // i.e. version definitions not containing any glob meta-characters.
760 for (VersionDefinition &V : Config->VersionDefinitions)
761 for (SymbolVersion &Ver : V.Globals)
762 assignExactVersion(Ver, V.Id, V.Name);
763
764 // Next, we assign versions to fuzzy matching symbols,
765 // i.e. version definitions containing glob meta-characters.
766 // Note that because the last match takes precedence over previous matches,
767 // we iterate over the definitions in the reverse order.
768 for (VersionDefinition &V : llvm::reverse(Config->VersionDefinitions))
769 for (SymbolVersion &Ver : V.Globals)
770 assignWildcardVersion(Ver, V.Id);
771
772 // Symbol themselves might know their versions because symbols
773 // can contain versions in the form of <name>@<version>.
774 // Let them parse and update their names to exclude version suffix.
775 for (Symbol *Sym : SymVector)
776 Sym->body()->parseSymbolVersion();
777}
778
779template class elf::SymbolTable<ELF32LE>;
780template class elf::SymbolTable<ELF32BE>;
781template class elf::SymbolTable<ELF64LE>;
782template class elf::SymbolTable<ELF64BE>;
deps/lld/ELF/SymbolTable.h created+147
......@@ -0,0 +1,147 @@
1//===- SymbolTable.h --------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_ELF_SYMBOL_TABLE_H
11#define LLD_ELF_SYMBOL_TABLE_H
12
13#include "InputFiles.h"
14#include "LTO.h"
15#include "Strings.h"
16#include "llvm/ADT/CachedHashString.h"
17#include "llvm/ADT/DenseMap.h"
18
19namespace lld {
20namespace elf {
21
22struct Symbol;
23
24// SymbolTable is a bucket of all known symbols, including defined,
25// undefined, or lazy symbols (the last one is symbols in archive
26// files whose archive members are not yet loaded).
27//
28// We put all symbols of all files to a SymbolTable, and the
29// SymbolTable selects the "best" symbols if there are name
30// conflicts. For example, obviously, a defined symbol is better than
31// an undefined symbol. Or, if there's a conflict between a lazy and a
32// undefined, it'll read an archive member to read a real definition
33// to replace the lazy symbol. The logic is implemented in the
34// add*() functions, which are called by input files as they are parsed. There
35// is one add* function per symbol type.
36template <class ELFT> class SymbolTable {
37 typedef typename ELFT::Sym Elf_Sym;
38
39public:
40 void addFile(InputFile *File);
41 void addCombinedLTOObject();
42 void addSymbolAlias(StringRef Alias, StringRef Name);
43 void addSymbolWrap(StringRef Name);
44 void applySymbolRenames();
45
46 ArrayRef<Symbol *> getSymbols() const { return SymVector; }
47 ArrayRef<ObjectFile<ELFT> *> getObjectFiles() const { return ObjectFiles; }
48 ArrayRef<BinaryFile *> getBinaryFiles() const { return BinaryFiles; }
49 ArrayRef<SharedFile<ELFT> *> getSharedFiles() const { return SharedFiles; }
50
51 DefinedRegular *addAbsolute(StringRef Name,
52 uint8_t Visibility = llvm::ELF::STV_HIDDEN,
53 uint8_t Binding = llvm::ELF::STB_GLOBAL);
54 DefinedRegular *addIgnored(StringRef Name,
55 uint8_t Visibility = llvm::ELF::STV_HIDDEN);
56
57 Symbol *addUndefined(StringRef Name);
58 Symbol *addUndefined(StringRef Name, bool IsLocal, uint8_t Binding,
59 uint8_t StOther, uint8_t Type, bool CanOmitFromDynSym,
60 InputFile *File);
61
62 Symbol *addRegular(StringRef Name, uint8_t StOther, uint8_t Type,
63 uint64_t Value, uint64_t Size, uint8_t Binding,
64 SectionBase *Section, InputFile *File);
65
66 void addShared(SharedFile<ELFT> *F, StringRef Name, const Elf_Sym &Sym,
67 const typename ELFT::Verdef *Verdef);
68
69 Symbol *addLazyArchive(ArchiveFile *F, const llvm::object::Archive::Symbol S);
70 void addLazyObject(StringRef Name, LazyObjectFile &Obj);
71 Symbol *addBitcode(StringRef Name, uint8_t Binding, uint8_t StOther,
72 uint8_t Type, bool CanOmitFromDynSym, BitcodeFile *File);
73
74 Symbol *addCommon(StringRef N, uint64_t Size, uint32_t Alignment,
75 uint8_t Binding, uint8_t StOther, uint8_t Type,
76 InputFile *File);
77
78 std::pair<Symbol *, bool> insert(StringRef Name);
79 std::pair<Symbol *, bool> insert(StringRef Name, uint8_t Type,
80 uint8_t Visibility, bool CanOmitFromDynSym,
81 InputFile *File);
82
83 void scanUndefinedFlags();
84 void scanShlibUndefined();
85 void scanVersionScript();
86
87 SymbolBody *find(StringRef Name);
88 SymbolBody *findInCurrentDSO(StringRef Name);
89
90 void trace(StringRef Name);
91
92private:
93 std::vector<SymbolBody *> findByVersion(SymbolVersion Ver);
94 std::vector<SymbolBody *> findAllByVersion(SymbolVersion Ver);
95
96 llvm::StringMap<std::vector<SymbolBody *>> &getDemangledSyms();
97 void handleAnonymousVersion();
98 void assignExactVersion(SymbolVersion Ver, uint16_t VersionId,
99 StringRef VersionName);
100 void assignWildcardVersion(SymbolVersion Ver, uint16_t VersionId);
101
102 struct SymIndex {
103 SymIndex(int Idx, bool Traced) : Idx(Idx), Traced(Traced) {}
104 int Idx : 31;
105 unsigned Traced : 1;
106 };
107
108 // The order the global symbols are in is not defined. We can use an arbitrary
109 // order, but it has to be reproducible. That is true even when cross linking.
110 // The default hashing of StringRef produces different results on 32 and 64
111 // bit systems so we use a map to a vector. That is arbitrary, deterministic
112 // but a bit inefficient.
113 // FIXME: Experiment with passing in a custom hashing or sorting the symbols
114 // once symbol resolution is finished.
115 llvm::DenseMap<llvm::CachedHashStringRef, SymIndex> Symtab;
116 std::vector<Symbol *> SymVector;
117
118 // Comdat groups define "link once" sections. If two comdat groups have the
119 // same name, only one of them is linked, and the other is ignored. This set
120 // is used to uniquify them.
121 llvm::DenseSet<llvm::CachedHashStringRef> ComdatGroups;
122
123 std::vector<ObjectFile<ELFT> *> ObjectFiles;
124 std::vector<SharedFile<ELFT> *> SharedFiles;
125 std::vector<BitcodeFile *> BitcodeFiles;
126 std::vector<BinaryFile *> BinaryFiles;
127
128 // Set of .so files to not link the same shared object file more than once.
129 llvm::DenseSet<StringRef> SoNames;
130
131 // A map from demangled symbol names to their symbol objects.
132 // This mapping is 1:N because two symbols with different versions
133 // can have the same name. We use this map to handle "extern C++ {}"
134 // directive in version scripts.
135 llvm::Optional<llvm::StringMap<std::vector<SymbolBody *>>> DemangledSyms;
136
137 // For LTO.
138 std::unique_ptr<BitcodeCompiler> LTO;
139};
140
141template <class ELFT> struct Symtab { static SymbolTable<ELFT> *X; };
142template <class ELFT> SymbolTable<ELFT> *Symtab<ELFT>::X;
143
144} // namespace elf
145} // namespace lld
146
147#endif
deps/lld/ELF/Symbols.cpp created+399
......@@ -0,0 +1,399 @@
1//===- Symbols.cpp --------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "Symbols.h"
11#include "Error.h"
12#include "InputFiles.h"
13#include "InputSection.h"
14#include "OutputSections.h"
15#include "Strings.h"
16#include "SyntheticSections.h"
17#include "Target.h"
18#include "Writer.h"
19
20#include "llvm/ADT/STLExtras.h"
21#include "llvm/Support/Path.h"
22#include <cstring>
23
24using namespace llvm;
25using namespace llvm::object;
26using namespace llvm::ELF;
27
28using namespace lld;
29using namespace lld::elf;
30
31DefinedRegular *ElfSym::Bss;
32DefinedRegular *ElfSym::Etext1;
33DefinedRegular *ElfSym::Etext2;
34DefinedRegular *ElfSym::Edata1;
35DefinedRegular *ElfSym::Edata2;
36DefinedRegular *ElfSym::End1;
37DefinedRegular *ElfSym::End2;
38DefinedRegular *ElfSym::GlobalOffsetTable;
39DefinedRegular *ElfSym::MipsGp;
40DefinedRegular *ElfSym::MipsGpDisp;
41DefinedRegular *ElfSym::MipsLocalGp;
42
43static uint64_t getSymVA(const SymbolBody &Body, int64_t &Addend) {
44 switch (Body.kind()) {
45 case SymbolBody::DefinedRegularKind: {
46 auto &D = cast<DefinedRegular>(Body);
47 SectionBase *IS = D.Section;
48 if (auto *ISB = dyn_cast_or_null<InputSectionBase>(IS))
49 IS = ISB->Repl;
50
51 // According to the ELF spec reference to a local symbol from outside
52 // the group are not allowed. Unfortunately .eh_frame breaks that rule
53 // and must be treated specially. For now we just replace the symbol with
54 // 0.
55 if (IS == &InputSection::Discarded)
56 return 0;
57
58 // This is an absolute symbol.
59 if (!IS)
60 return D.Value;
61
62 uint64_t Offset = D.Value;
63
64 // An object in an SHF_MERGE section might be referenced via a
65 // section symbol (as a hack for reducing the number of local
66 // symbols).
67 // Depending on the addend, the reference via a section symbol
68 // refers to a different object in the merge section.
69 // Since the objects in the merge section are not necessarily
70 // contiguous in the output, the addend can thus affect the final
71 // VA in a non-linear way.
72 // To make this work, we incorporate the addend into the section
73 // offset (and zero out the addend for later processing) so that
74 // we find the right object in the section.
75 if (D.isSection()) {
76 Offset += Addend;
77 Addend = 0;
78 }
79
80 const OutputSection *OutSec = IS->getOutputSection();
81
82 // In the typical case, this is actually very simple and boils
83 // down to adding together 3 numbers:
84 // 1. The address of the output section.
85 // 2. The offset of the input section within the output section.
86 // 3. The offset within the input section (this addition happens
87 // inside InputSection::getOffset).
88 //
89 // If you understand the data structures involved with this next
90 // line (and how they get built), then you have a pretty good
91 // understanding of the linker.
92 uint64_t VA = (OutSec ? OutSec->Addr : 0) + IS->getOffset(Offset);
93
94 if (D.isTls() && !Config->Relocatable) {
95 if (!Out::TlsPhdr)
96 fatal(toString(D.File) +
97 " has an STT_TLS symbol but doesn't have an SHF_TLS section");
98 return VA - Out::TlsPhdr->p_vaddr;
99 }
100 return VA;
101 }
102 case SymbolBody::DefinedCommonKind:
103 if (!Config->DefineCommon)
104 return 0;
105 return InX::Common->getParent()->Addr + InX::Common->OutSecOff +
106 cast<DefinedCommon>(Body).Offset;
107 case SymbolBody::SharedKind: {
108 auto &SS = cast<SharedSymbol>(Body);
109 if (SS.NeedsCopy)
110 return SS.CopyRelSec->getParent()->Addr + SS.CopyRelSec->OutSecOff +
111 SS.CopyRelSecOff;
112 if (SS.NeedsPltAddr)
113 return Body.getPltVA();
114 return 0;
115 }
116 case SymbolBody::UndefinedKind:
117 return 0;
118 case SymbolBody::LazyArchiveKind:
119 case SymbolBody::LazyObjectKind:
120 assert(Body.symbol()->IsUsedInRegularObj && "lazy symbol reached writer");
121 return 0;
122 }
123 llvm_unreachable("invalid symbol kind");
124}
125
126SymbolBody::SymbolBody(Kind K, StringRefZ Name, bool IsLocal, uint8_t StOther,
127 uint8_t Type)
128 : SymbolKind(K), NeedsCopy(false), NeedsPltAddr(false), IsLocal(IsLocal),
129 IsInGlobalMipsGot(false), Is32BitMipsGot(false), IsInIplt(false),
130 IsInIgot(false), Type(Type), StOther(StOther), Name(Name) {}
131
132// Returns true if a symbol can be replaced at load-time by a symbol
133// with the same name defined in other ELF executable or DSO.
134bool SymbolBody::isPreemptible() const {
135 if (isLocal())
136 return false;
137
138 // Shared symbols resolve to the definition in the DSO. The exceptions are
139 // symbols with copy relocations (which resolve to .bss) or preempt plt
140 // entries (which resolve to that plt entry).
141 if (isShared())
142 return !NeedsCopy && !NeedsPltAddr;
143
144 // That's all that can be preempted in a non-DSO.
145 if (!Config->Shared)
146 return false;
147
148 // Only symbols that appear in dynsym can be preempted.
149 if (!symbol()->includeInDynsym())
150 return false;
151
152 // Only default visibility symbols can be preempted.
153 if (symbol()->Visibility != STV_DEFAULT)
154 return false;
155
156 // -Bsymbolic means that definitions are not preempted.
157 if (Config->Bsymbolic || (Config->BsymbolicFunctions && isFunc()))
158 return !isDefined();
159 return true;
160}
161
162// Overwrites all attributes with Other's so that this symbol becomes
163// an alias to Other. This is useful for handling some options such as
164// --wrap.
165void SymbolBody::copy(SymbolBody *Other) {
166 memcpy(symbol()->Body.buffer, Other->symbol()->Body.buffer,
167 sizeof(Symbol::Body));
168}
169
170uint64_t SymbolBody::getVA(int64_t Addend) const {
171 uint64_t OutVA = getSymVA(*this, Addend);
172 return OutVA + Addend;
173}
174
175uint64_t SymbolBody::getGotVA() const {
176 return InX::Got->getVA() + getGotOffset();
177}
178
179uint64_t SymbolBody::getGotOffset() const {
180 return GotIndex * Target->GotEntrySize;
181}
182
183uint64_t SymbolBody::getGotPltVA() const {
184 if (this->IsInIgot)
185 return InX::IgotPlt->getVA() + getGotPltOffset();
186 return InX::GotPlt->getVA() + getGotPltOffset();
187}
188
189uint64_t SymbolBody::getGotPltOffset() const {
190 return GotPltIndex * Target->GotPltEntrySize;
191}
192
193uint64_t SymbolBody::getPltVA() const {
194 if (this->IsInIplt)
195 return InX::Iplt->getVA() + PltIndex * Target->PltEntrySize;
196 return InX::Plt->getVA() + Target->PltHeaderSize +
197 PltIndex * Target->PltEntrySize;
198}
199
200template <class ELFT> typename ELFT::uint SymbolBody::getSize() const {
201 if (const auto *C = dyn_cast<DefinedCommon>(this))
202 return C->Size;
203 if (const auto *DR = dyn_cast<DefinedRegular>(this))
204 return DR->Size;
205 if (const auto *S = dyn_cast<SharedSymbol>(this))
206 return S->getSize<ELFT>();
207 return 0;
208}
209
210OutputSection *SymbolBody::getOutputSection() const {
211 if (auto *S = dyn_cast<DefinedRegular>(this)) {
212 if (S->Section)
213 return S->Section->getOutputSection();
214 return nullptr;
215 }
216
217 if (auto *S = dyn_cast<SharedSymbol>(this)) {
218 if (S->NeedsCopy)
219 return S->CopyRelSec->getParent();
220 return nullptr;
221 }
222
223 if (isa<DefinedCommon>(this)) {
224 if (Config->DefineCommon)
225 return InX::Common->getParent();
226 return nullptr;
227 }
228
229 return nullptr;
230}
231
232// If a symbol name contains '@', the characters after that is
233// a symbol version name. This function parses that.
234void SymbolBody::parseSymbolVersion() {
235 StringRef S = getName();
236 size_t Pos = S.find('@');
237 if (Pos == 0 || Pos == StringRef::npos)
238 return;
239 StringRef Verstr = S.substr(Pos + 1);
240 if (Verstr.empty())
241 return;
242
243 // Truncate the symbol name so that it doesn't include the version string.
244 Name = {S.data(), Pos};
245
246 // If this is not in this DSO, it is not a definition.
247 if (!isInCurrentDSO())
248 return;
249
250 // '@@' in a symbol name means the default version.
251 // It is usually the most recent one.
252 bool IsDefault = (Verstr[0] == '@');
253 if (IsDefault)
254 Verstr = Verstr.substr(1);
255
256 for (VersionDefinition &Ver : Config->VersionDefinitions) {
257 if (Ver.Name != Verstr)
258 continue;
259
260 if (IsDefault)
261 symbol()->VersionId = Ver.Id;
262 else
263 symbol()->VersionId = Ver.Id | VERSYM_HIDDEN;
264 return;
265 }
266
267 // It is an error if the specified version is not defined.
268 // Usually version script is not provided when linking executable,
269 // but we may still want to override a versioned symbol from DSO,
270 // so we do not report error in this case.
271 if (Config->Shared)
272 error(toString(File) + ": symbol " + S + " has undefined version " +
273 Verstr);
274}
275
276Defined::Defined(Kind K, StringRefZ Name, bool IsLocal, uint8_t StOther,
277 uint8_t Type)
278 : SymbolBody(K, Name, IsLocal, StOther, Type) {}
279
280template <class ELFT> bool DefinedRegular::isMipsPIC() const {
281 typedef typename ELFT::Ehdr Elf_Ehdr;
282 if (!Section || !isFunc())
283 return false;
284
285 auto *Sec = cast<InputSectionBase>(Section);
286 const Elf_Ehdr *Hdr = Sec->template getFile<ELFT>()->getObj().getHeader();
287 return (this->StOther & STO_MIPS_MIPS16) == STO_MIPS_PIC ||
288 (Hdr->e_flags & EF_MIPS_PIC);
289}
290
291Undefined::Undefined(StringRefZ Name, bool IsLocal, uint8_t StOther,
292 uint8_t Type, InputFile *File)
293 : SymbolBody(SymbolBody::UndefinedKind, Name, IsLocal, StOther, Type) {
294 this->File = File;
295}
296
297DefinedCommon::DefinedCommon(StringRef Name, uint64_t Size, uint32_t Alignment,
298 uint8_t StOther, uint8_t Type, InputFile *File)
299 : Defined(SymbolBody::DefinedCommonKind, Name, /*IsLocal=*/false, StOther,
300 Type),
301 Alignment(Alignment), Size(Size) {
302 this->File = File;
303}
304
305// If a shared symbol is referred via a copy relocation, its alignment
306// becomes part of the ABI. This function returns a symbol alignment.
307// Because symbols don't have alignment attributes, we need to infer that.
308template <class ELFT> uint32_t SharedSymbol::getAlignment() const {
309 auto *File = cast<SharedFile<ELFT>>(this->File);
310 uint32_t SecAlign = File->getSection(getSym<ELFT>())->sh_addralign;
311 uint64_t SymValue = getSym<ELFT>().st_value;
312 uint32_t SymAlign = uint32_t(1) << countTrailingZeros(SymValue);
313 return std::min(SecAlign, SymAlign);
314}
315
316InputFile *Lazy::fetch() {
317 if (auto *S = dyn_cast<LazyArchive>(this))
318 return S->fetch();
319 return cast<LazyObject>(this)->fetch();
320}
321
322LazyArchive::LazyArchive(ArchiveFile &File,
323 const llvm::object::Archive::Symbol S, uint8_t Type)
324 : Lazy(LazyArchiveKind, S.getName(), Type), Sym(S) {
325 this->File = &File;
326}
327
328LazyObject::LazyObject(StringRef Name, LazyObjectFile &File, uint8_t Type)
329 : Lazy(LazyObjectKind, Name, Type) {
330 this->File = &File;
331}
332
333InputFile *LazyArchive::fetch() {
334 std::pair<MemoryBufferRef, uint64_t> MBInfo = file()->getMember(&Sym);
335
336 // getMember returns an empty buffer if the member was already
337 // read from the library.
338 if (MBInfo.first.getBuffer().empty())
339 return nullptr;
340 return createObjectFile(MBInfo.first, file()->getName(), MBInfo.second);
341}
342
343InputFile *LazyObject::fetch() { return file()->fetch(); }
344
345uint8_t Symbol::computeBinding() const {
346 if (Config->Relocatable)
347 return Binding;
348 if (Visibility != STV_DEFAULT && Visibility != STV_PROTECTED)
349 return STB_LOCAL;
350 if (VersionId == VER_NDX_LOCAL && body()->isInCurrentDSO())
351 return STB_LOCAL;
352 if (Config->NoGnuUnique && Binding == STB_GNU_UNIQUE)
353 return STB_GLOBAL;
354 return Binding;
355}
356
357bool Symbol::includeInDynsym() const {
358 if (computeBinding() == STB_LOCAL)
359 return false;
360 return ExportDynamic || body()->isShared() ||
361 (body()->isUndefined() && Config->Shared);
362}
363
364// Print out a log message for --trace-symbol.
365void elf::printTraceSymbol(Symbol *Sym) {
366 SymbolBody *B = Sym->body();
367 std::string S;
368 if (B->isUndefined())
369 S = ": reference to ";
370 else if (B->isCommon())
371 S = ": common definition of ";
372 else
373 S = ": definition of ";
374
375 message(toString(B->File) + S + B->getName());
376}
377
378// Returns a symbol for an error message.
379std::string lld::toString(const SymbolBody &B) {
380 if (Config->Demangle)
381 if (Optional<std::string> S = demangle(B.getName()))
382 return *S;
383 return B.getName();
384}
385
386template uint32_t SymbolBody::template getSize<ELF32LE>() const;
387template uint32_t SymbolBody::template getSize<ELF32BE>() const;
388template uint64_t SymbolBody::template getSize<ELF64LE>() const;
389template uint64_t SymbolBody::template getSize<ELF64BE>() const;
390
391template bool DefinedRegular::template isMipsPIC<ELF32LE>() const;
392template bool DefinedRegular::template isMipsPIC<ELF32BE>() const;
393template bool DefinedRegular::template isMipsPIC<ELF64LE>() const;
394template bool DefinedRegular::template isMipsPIC<ELF64BE>() const;
395
396template uint32_t SharedSymbol::template getAlignment<ELF32LE>() const;
397template uint32_t SharedSymbol::template getAlignment<ELF32BE>() const;
398template uint32_t SharedSymbol::template getAlignment<ELF64LE>() const;
399template uint32_t SharedSymbol::template getAlignment<ELF64BE>() const;
deps/lld/ELF/Symbols.h created+414
......@@ -0,0 +1,414 @@
1//===- Symbols.h ------------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// All symbols are handled as SymbolBodies regardless of their types.
11// This file defines various types of SymbolBodies.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLD_ELF_SYMBOLS_H
16#define LLD_ELF_SYMBOLS_H
17
18#include "InputSection.h"
19#include "Strings.h"
20
21#include "lld/Core/LLVM.h"
22#include "llvm/Object/Archive.h"
23#include "llvm/Object/ELF.h"
24
25namespace lld {
26namespace elf {
27
28class ArchiveFile;
29class BitcodeFile;
30class InputFile;
31class LazyObjectFile;
32template <class ELFT> class ObjectFile;
33class OutputSection;
34template <class ELFT> class SharedFile;
35
36struct Symbol;
37
38// The base class for real symbol classes.
39class SymbolBody {
40public:
41 enum Kind {
42 DefinedFirst,
43 DefinedRegularKind = DefinedFirst,
44 SharedKind,
45 DefinedCommonKind,
46 DefinedLast = DefinedCommonKind,
47 UndefinedKind,
48 LazyArchiveKind,
49 LazyObjectKind,
50 };
51
52 SymbolBody(Kind K) : SymbolKind(K) {}
53
54 Symbol *symbol();
55 const Symbol *symbol() const {
56 return const_cast<SymbolBody *>(this)->symbol();
57 }
58
59 Kind kind() const { return static_cast<Kind>(SymbolKind); }
60
61 bool isUndefined() const { return SymbolKind == UndefinedKind; }
62 bool isDefined() const { return SymbolKind <= DefinedLast; }
63 bool isCommon() const { return SymbolKind == DefinedCommonKind; }
64 bool isLazy() const {
65 return SymbolKind == LazyArchiveKind || SymbolKind == LazyObjectKind;
66 }
67 bool isShared() const { return SymbolKind == SharedKind; }
68 bool isInCurrentDSO() const {
69 return !isUndefined() && !isShared() && !isLazy();
70 }
71 bool isLocal() const { return IsLocal; }
72 bool isPreemptible() const;
73 StringRef getName() const { return Name; }
74 uint8_t getVisibility() const { return StOther & 0x3; }
75 void parseSymbolVersion();
76 void copy(SymbolBody *Other);
77
78 bool isInGot() const { return GotIndex != -1U; }
79 bool isInPlt() const { return PltIndex != -1U; }
80
81 uint64_t getVA(int64_t Addend = 0) const;
82
83 uint64_t getGotOffset() const;
84 uint64_t getGotVA() const;
85 uint64_t getGotPltOffset() const;
86 uint64_t getGotPltVA() const;
87 uint64_t getPltVA() const;
88 template <class ELFT> typename ELFT::uint getSize() const;
89 OutputSection *getOutputSection() const;
90
91 // The file from which this symbol was created.
92 InputFile *File = nullptr;
93
94 uint32_t DynsymIndex = 0;
95 uint32_t GotIndex = -1;
96 uint32_t GotPltIndex = -1;
97 uint32_t PltIndex = -1;
98 uint32_t GlobalDynIndex = -1;
99
100protected:
101 SymbolBody(Kind K, StringRefZ Name, bool IsLocal, uint8_t StOther,
102 uint8_t Type);
103
104 const unsigned SymbolKind : 8;
105
106public:
107 // True if the linker has to generate a copy relocation.
108 // For SharedSymbol only.
109 unsigned NeedsCopy : 1;
110
111 // True the symbol should point to its PLT entry.
112 // For SharedSymbol only.
113 unsigned NeedsPltAddr : 1;
114
115 // True if this is a local symbol.
116 unsigned IsLocal : 1;
117
118 // True if this symbol has an entry in the global part of MIPS GOT.
119 unsigned IsInGlobalMipsGot : 1;
120
121 // True if this symbol is referenced by 32-bit GOT relocations.
122 unsigned Is32BitMipsGot : 1;
123
124 // True if this symbol is in the Iplt sub-section of the Plt.
125 unsigned IsInIplt : 1;
126
127 // True if this symbol is in the Igot sub-section of the .got.plt or .got.
128 unsigned IsInIgot : 1;
129
130 // The following fields have the same meaning as the ELF symbol attributes.
131 uint8_t Type; // symbol type
132 uint8_t StOther; // st_other field value
133
134 // The Type field may also have this value. It means that we have not yet seen
135 // a non-Lazy symbol with this name, so we don't know what its type is. The
136 // Type field is normally set to this value for Lazy symbols unless we saw a
137 // weak undefined symbol first, in which case we need to remember the original
138 // symbol's type in order to check for TLS mismatches.
139 enum { UnknownType = 255 };
140
141 bool isSection() const { return Type == llvm::ELF::STT_SECTION; }
142 bool isTls() const { return Type == llvm::ELF::STT_TLS; }
143 bool isFunc() const { return Type == llvm::ELF::STT_FUNC; }
144 bool isGnuIFunc() const { return Type == llvm::ELF::STT_GNU_IFUNC; }
145 bool isObject() const { return Type == llvm::ELF::STT_OBJECT; }
146 bool isFile() const { return Type == llvm::ELF::STT_FILE; }
147
148protected:
149 StringRefZ Name;
150};
151
152// The base class for any defined symbols.
153class Defined : public SymbolBody {
154public:
155 Defined(Kind K, StringRefZ Name, bool IsLocal, uint8_t StOther, uint8_t Type);
156 static bool classof(const SymbolBody *S) { return S->isDefined(); }
157};
158
159class DefinedCommon : public Defined {
160public:
161 DefinedCommon(StringRef N, uint64_t Size, uint32_t Alignment, uint8_t StOther,
162 uint8_t Type, InputFile *File);
163
164 static bool classof(const SymbolBody *S) {
165 return S->kind() == SymbolBody::DefinedCommonKind;
166 }
167
168 // The output offset of this common symbol in the output bss. Computed by the
169 // writer.
170 uint64_t Offset;
171
172 // The maximum alignment we have seen for this symbol.
173 uint32_t Alignment;
174
175 uint64_t Size;
176};
177
178// Regular defined symbols read from object file symbol tables.
179class DefinedRegular : public Defined {
180public:
181 DefinedRegular(StringRefZ Name, bool IsLocal, uint8_t StOther, uint8_t Type,
182 uint64_t Value, uint64_t Size, SectionBase *Section,
183 InputFile *File)
184 : Defined(SymbolBody::DefinedRegularKind, Name, IsLocal, StOther, Type),
185 Value(Value), Size(Size), Section(Section) {
186 this->File = File;
187 }
188
189 // Return true if the symbol is a PIC function.
190 template <class ELFT> bool isMipsPIC() const;
191
192 static bool classof(const SymbolBody *S) {
193 return S->kind() == SymbolBody::DefinedRegularKind;
194 }
195
196 uint64_t Value;
197 uint64_t Size;
198 SectionBase *Section;
199};
200
201class Undefined : public SymbolBody {
202public:
203 Undefined(StringRefZ Name, bool IsLocal, uint8_t StOther, uint8_t Type,
204 InputFile *F);
205
206 static bool classof(const SymbolBody *S) {
207 return S->kind() == UndefinedKind;
208 }
209};
210
211class SharedSymbol : public Defined {
212public:
213 static bool classof(const SymbolBody *S) {
214 return S->kind() == SymbolBody::SharedKind;
215 }
216
217 SharedSymbol(InputFile *File, StringRef Name, uint8_t StOther, uint8_t Type,
218 const void *ElfSym, const void *Verdef)
219 : Defined(SymbolBody::SharedKind, Name, /*IsLocal=*/false, StOther, Type),
220 Verdef(Verdef), ElfSym(ElfSym) {
221 // IFuncs defined in DSOs are treated as functions by the static linker.
222 if (isGnuIFunc())
223 this->Type = llvm::ELF::STT_FUNC;
224 this->File = File;
225 }
226
227 template <class ELFT> uint64_t getShndx() const {
228 return getSym<ELFT>().st_shndx;
229 }
230
231 template <class ELFT> uint64_t getValue() const {
232 return getSym<ELFT>().st_value;
233 }
234
235 template <class ELFT> uint64_t getSize() const {
236 return getSym<ELFT>().st_size;
237 }
238
239 template <class ELFT> uint32_t getAlignment() const;
240
241 // This field is a pointer to the symbol's version definition.
242 const void *Verdef;
243
244 // CopyRelSec and CopyRelSecOff are significant only when NeedsCopy is true.
245 InputSection *CopyRelSec;
246 uint64_t CopyRelSecOff;
247
248private:
249 template <class ELFT> const typename ELFT::Sym &getSym() const {
250 return *(const typename ELFT::Sym *)ElfSym;
251 }
252
253 const void *ElfSym;
254};
255
256// This class represents a symbol defined in an archive file. It is
257// created from an archive file header, and it knows how to load an
258// object file from an archive to replace itself with a defined
259// symbol. If the resolver finds both Undefined and Lazy for
260// the same name, it will ask the Lazy to load a file.
261class Lazy : public SymbolBody {
262public:
263 static bool classof(const SymbolBody *S) { return S->isLazy(); }
264
265 // Returns an object file for this symbol, or a nullptr if the file
266 // was already returned.
267 InputFile *fetch();
268
269protected:
270 Lazy(SymbolBody::Kind K, StringRef Name, uint8_t Type)
271 : SymbolBody(K, Name, /*IsLocal=*/false, llvm::ELF::STV_DEFAULT, Type) {}
272};
273
274// LazyArchive symbols represents symbols in archive files.
275class LazyArchive : public Lazy {
276public:
277 LazyArchive(ArchiveFile &File, const llvm::object::Archive::Symbol S,
278 uint8_t Type);
279
280 static bool classof(const SymbolBody *S) {
281 return S->kind() == LazyArchiveKind;
282 }
283
284 ArchiveFile *file() { return (ArchiveFile *)this->File; }
285 InputFile *fetch();
286
287private:
288 const llvm::object::Archive::Symbol Sym;
289};
290
291// LazyObject symbols represents symbols in object files between
292// --start-lib and --end-lib options.
293class LazyObject : public Lazy {
294public:
295 LazyObject(StringRef Name, LazyObjectFile &File, uint8_t Type);
296
297 static bool classof(const SymbolBody *S) {
298 return S->kind() == LazyObjectKind;
299 }
300
301 LazyObjectFile *file() { return (LazyObjectFile *)this->File; }
302 InputFile *fetch();
303};
304
305// Some linker-generated symbols need to be created as
306// DefinedRegular symbols.
307struct ElfSym {
308 // __bss_start
309 static DefinedRegular *Bss;
310
311 // etext and _etext
312 static DefinedRegular *Etext1;
313 static DefinedRegular *Etext2;
314
315 // edata and _edata
316 static DefinedRegular *Edata1;
317 static DefinedRegular *Edata2;
318
319 // end and _end
320 static DefinedRegular *End1;
321 static DefinedRegular *End2;
322
323 // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to
324 // be at some offset from the base of the .got section, usually 0 or
325 // the end of the .got.
326 static DefinedRegular *GlobalOffsetTable;
327
328 // _gp, _gp_disp and __gnu_local_gp symbols. Only for MIPS.
329 static DefinedRegular *MipsGp;
330 static DefinedRegular *MipsGpDisp;
331 static DefinedRegular *MipsLocalGp;
332};
333
334// A real symbol object, SymbolBody, is usually stored within a Symbol. There's
335// always one Symbol for each symbol name. The resolver updates the SymbolBody
336// stored in the Body field of this object as it resolves symbols. Symbol also
337// holds computed properties of symbol names.
338struct Symbol {
339 // Symbol binding. This is on the Symbol to track changes during resolution.
340 // In particular:
341 // An undefined weak is still weak when it resolves to a shared library.
342 // An undefined weak will not fetch archive members, but we have to remember
343 // it is weak.
344 uint8_t Binding;
345
346 // Version definition index.
347 uint16_t VersionId;
348
349 // Symbol visibility. This is the computed minimum visibility of all
350 // observed non-DSO symbols.
351 unsigned Visibility : 2;
352
353 // True if the symbol was used for linking and thus need to be added to the
354 // output file's symbol table. This is true for all symbols except for
355 // unreferenced DSO symbols and bitcode symbols that are unreferenced except
356 // by other bitcode objects.
357 unsigned IsUsedInRegularObj : 1;
358
359 // If this flag is true and the symbol has protected or default visibility, it
360 // will appear in .dynsym. This flag is set by interposable DSO symbols in
361 // executables, by most symbols in DSOs and executables built with
362 // --export-dynamic, and by dynamic lists.
363 unsigned ExportDynamic : 1;
364
365 // True if this symbol is specified by --trace-symbol option.
366 unsigned Traced : 1;
367
368 // This symbol version was found in a version script.
369 unsigned InVersionScript : 1;
370
371 bool includeInDynsym() const;
372 uint8_t computeBinding() const;
373 bool isWeak() const { return Binding == llvm::ELF::STB_WEAK; }
374
375 // This field is used to store the Symbol's SymbolBody. This instantiation of
376 // AlignedCharArrayUnion gives us a struct with a char array field that is
377 // large and aligned enough to store any derived class of SymbolBody.
378 llvm::AlignedCharArrayUnion<DefinedCommon, DefinedRegular, Undefined,
379 SharedSymbol, LazyArchive, LazyObject>
380 Body;
381
382 SymbolBody *body() { return reinterpret_cast<SymbolBody *>(Body.buffer); }
383 const SymbolBody *body() const { return const_cast<Symbol *>(this)->body(); }
384};
385
386void printTraceSymbol(Symbol *Sym);
387
388template <typename T, typename... ArgT>
389void replaceBody(Symbol *S, ArgT &&... Arg) {
390 static_assert(sizeof(T) <= sizeof(S->Body), "Body too small");
391 static_assert(alignof(T) <= alignof(decltype(S->Body)),
392 "Body not aligned enough");
393 assert(static_cast<SymbolBody *>(static_cast<T *>(nullptr)) == nullptr &&
394 "Not a SymbolBody");
395
396 new (S->Body.buffer) T(std::forward<ArgT>(Arg)...);
397
398 // Print out a log message if --trace-symbol was specified.
399 // This is for debugging.
400 if (S->Traced)
401 printTraceSymbol(S);
402}
403
404inline Symbol *SymbolBody::symbol() {
405 assert(!isLocal());
406 return reinterpret_cast<Symbol *>(reinterpret_cast<char *>(this) -
407 offsetof(Symbol, Body));
408}
409} // namespace elf
410
411std::string toString(const elf::SymbolBody &B);
412} // namespace lld
413
414#endif
deps/lld/ELF/SyntheticSections.cpp created+2431
......@@ -0,0 +1,2431 @@
1//===- SyntheticSections.cpp ----------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains linker-synthesized sections. Currently,
11// synthetic sections are created either output sections or input sections,
12// but we are rewriting code so that all synthetic sections are created as
13// input sections.
14//
15//===----------------------------------------------------------------------===//
16
17#include "SyntheticSections.h"
18#include "Config.h"
19#include "Error.h"
20#include "InputFiles.h"
21#include "LinkerScript.h"
22#include "Memory.h"
23#include "OutputSections.h"
24#include "Strings.h"
25#include "SymbolTable.h"
26#include "Target.h"
27#include "Threads.h"
28#include "Writer.h"
29#include "lld/Config/Version.h"
30#include "llvm/BinaryFormat/Dwarf.h"
31#include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
32#include "llvm/Object/Decompressor.h"
33#include "llvm/Object/ELFObjectFile.h"
34#include "llvm/Support/Endian.h"
35#include "llvm/Support/MD5.h"
36#include "llvm/Support/RandomNumberGenerator.h"
37#include "llvm/Support/SHA1.h"
38#include "llvm/Support/xxhash.h"
39#include <cstdlib>
40
41using namespace llvm;
42using namespace llvm::dwarf;
43using namespace llvm::ELF;
44using namespace llvm::object;
45using namespace llvm::support;
46using namespace llvm::support::endian;
47
48using namespace lld;
49using namespace lld::elf;
50
51uint64_t SyntheticSection::getVA() const {
52 if (OutputSection *Sec = getParent())
53 return Sec->Addr + OutSecOff;
54 return 0;
55}
56
57template <class ELFT> static std::vector<DefinedCommon *> getCommonSymbols() {
58 std::vector<DefinedCommon *> V;
59 for (Symbol *S : Symtab<ELFT>::X->getSymbols())
60 if (auto *B = dyn_cast<DefinedCommon>(S->body()))
61 V.push_back(B);
62 return V;
63}
64
65// Find all common symbols and allocate space for them.
66template <class ELFT> InputSection *elf::createCommonSection() {
67 if (!Config->DefineCommon)
68 return nullptr;
69
70 // Sort the common symbols by alignment as an heuristic to pack them better.
71 std::vector<DefinedCommon *> Syms = getCommonSymbols<ELFT>();
72 if (Syms.empty())
73 return nullptr;
74
75 std::stable_sort(Syms.begin(), Syms.end(),
76 [](const DefinedCommon *A, const DefinedCommon *B) {
77 return A->Alignment > B->Alignment;
78 });
79
80 BssSection *Sec = make<BssSection>("COMMON");
81 for (DefinedCommon *Sym : Syms)
82 Sym->Offset = Sec->reserveSpace(Sym->Size, Sym->Alignment);
83 return Sec;
84}
85
86// Returns an LLD version string.
87static ArrayRef<uint8_t> getVersion() {
88 // Check LLD_VERSION first for ease of testing.
89 // You can get consitent output by using the environment variable.
90 // This is only for testing.
91 StringRef S = getenv("LLD_VERSION");
92 if (S.empty())
93 S = Saver.save(Twine("Linker: ") + getLLDVersion());
94
95 // +1 to include the terminating '\0'.
96 return {(const uint8_t *)S.data(), S.size() + 1};
97}
98
99// Creates a .comment section containing LLD version info.
100// With this feature, you can identify LLD-generated binaries easily
101// by "readelf --string-dump .comment <file>".
102// The returned object is a mergeable string section.
103template <class ELFT> MergeInputSection *elf::createCommentSection() {
104 typename ELFT::Shdr Hdr = {};
105 Hdr.sh_flags = SHF_MERGE | SHF_STRINGS;
106 Hdr.sh_type = SHT_PROGBITS;
107 Hdr.sh_entsize = 1;
108 Hdr.sh_addralign = 1;
109
110 auto *Ret =
111 make<MergeInputSection>((ObjectFile<ELFT> *)nullptr, &Hdr, ".comment");
112 Ret->Data = getVersion();
113 Ret->splitIntoPieces();
114 return Ret;
115}
116
117// .MIPS.abiflags section.
118template <class ELFT>
119MipsAbiFlagsSection<ELFT>::MipsAbiFlagsSection(Elf_Mips_ABIFlags Flags)
120 : SyntheticSection(SHF_ALLOC, SHT_MIPS_ABIFLAGS, 8, ".MIPS.abiflags"),
121 Flags(Flags) {
122 this->Entsize = sizeof(Elf_Mips_ABIFlags);
123}
124
125template <class ELFT> void MipsAbiFlagsSection<ELFT>::writeTo(uint8_t *Buf) {
126 memcpy(Buf, &Flags, sizeof(Flags));
127}
128
129template <class ELFT>
130MipsAbiFlagsSection<ELFT> *MipsAbiFlagsSection<ELFT>::create() {
131 Elf_Mips_ABIFlags Flags = {};
132 bool Create = false;
133
134 for (InputSectionBase *Sec : InputSections) {
135 if (Sec->Type != SHT_MIPS_ABIFLAGS)
136 continue;
137 Sec->Live = false;
138 Create = true;
139
140 std::string Filename = toString(Sec->getFile<ELFT>());
141 const size_t Size = Sec->Data.size();
142 // Older version of BFD (such as the default FreeBSD linker) concatenate
143 // .MIPS.abiflags instead of merging. To allow for this case (or potential
144 // zero padding) we ignore everything after the first Elf_Mips_ABIFlags
145 if (Size < sizeof(Elf_Mips_ABIFlags)) {
146 error(Filename + ": invalid size of .MIPS.abiflags section: got " +
147 Twine(Size) + " instead of " + Twine(sizeof(Elf_Mips_ABIFlags)));
148 return nullptr;
149 }
150 auto *S = reinterpret_cast<const Elf_Mips_ABIFlags *>(Sec->Data.data());
151 if (S->version != 0) {
152 error(Filename + ": unexpected .MIPS.abiflags version " +
153 Twine(S->version));
154 return nullptr;
155 }
156
157 // LLD checks ISA compatibility in getMipsEFlags(). Here we just
158 // select the highest number of ISA/Rev/Ext.
159 Flags.isa_level = std::max(Flags.isa_level, S->isa_level);
160 Flags.isa_rev = std::max(Flags.isa_rev, S->isa_rev);
161 Flags.isa_ext = std::max(Flags.isa_ext, S->isa_ext);
162 Flags.gpr_size = std::max(Flags.gpr_size, S->gpr_size);
163 Flags.cpr1_size = std::max(Flags.cpr1_size, S->cpr1_size);
164 Flags.cpr2_size = std::max(Flags.cpr2_size, S->cpr2_size);
165 Flags.ases |= S->ases;
166 Flags.flags1 |= S->flags1;
167 Flags.flags2 |= S->flags2;
168 Flags.fp_abi = elf::getMipsFpAbiFlag(Flags.fp_abi, S->fp_abi, Filename);
169 };
170
171 if (Create)
172 return make<MipsAbiFlagsSection<ELFT>>(Flags);
173 return nullptr;
174}
175
176// .MIPS.options section.
177template <class ELFT>
178MipsOptionsSection<ELFT>::MipsOptionsSection(Elf_Mips_RegInfo Reginfo)
179 : SyntheticSection(SHF_ALLOC, SHT_MIPS_OPTIONS, 8, ".MIPS.options"),
180 Reginfo(Reginfo) {
181 this->Entsize = sizeof(Elf_Mips_Options) + sizeof(Elf_Mips_RegInfo);
182}
183
184template <class ELFT> void MipsOptionsSection<ELFT>::writeTo(uint8_t *Buf) {
185 auto *Options = reinterpret_cast<Elf_Mips_Options *>(Buf);
186 Options->kind = ODK_REGINFO;
187 Options->size = getSize();
188
189 if (!Config->Relocatable)
190 Reginfo.ri_gp_value = InX::MipsGot->getGp();
191 memcpy(Buf + sizeof(Elf_Mips_Options), &Reginfo, sizeof(Reginfo));
192}
193
194template <class ELFT>
195MipsOptionsSection<ELFT> *MipsOptionsSection<ELFT>::create() {
196 // N64 ABI only.
197 if (!ELFT::Is64Bits)
198 return nullptr;
199
200 Elf_Mips_RegInfo Reginfo = {};
201 bool Create = false;
202
203 for (InputSectionBase *Sec : InputSections) {
204 if (Sec->Type != SHT_MIPS_OPTIONS)
205 continue;
206 Sec->Live = false;
207 Create = true;
208
209 std::string Filename = toString(Sec->getFile<ELFT>());
210 ArrayRef<uint8_t> D = Sec->Data;
211
212 while (!D.empty()) {
213 if (D.size() < sizeof(Elf_Mips_Options)) {
214 error(Filename + ": invalid size of .MIPS.options section");
215 break;
216 }
217
218 auto *Opt = reinterpret_cast<const Elf_Mips_Options *>(D.data());
219 if (Opt->kind == ODK_REGINFO) {
220 if (Config->Relocatable && Opt->getRegInfo().ri_gp_value)
221 error(Filename + ": unsupported non-zero ri_gp_value");
222 Reginfo.ri_gprmask |= Opt->getRegInfo().ri_gprmask;
223 Sec->getFile<ELFT>()->MipsGp0 = Opt->getRegInfo().ri_gp_value;
224 break;
225 }
226
227 if (!Opt->size)
228 fatal(Filename + ": zero option descriptor size");
229 D = D.slice(Opt->size);
230 }
231 };
232
233 if (Create)
234 return make<MipsOptionsSection<ELFT>>(Reginfo);
235 return nullptr;
236}
237
238// MIPS .reginfo section.
239template <class ELFT>
240MipsReginfoSection<ELFT>::MipsReginfoSection(Elf_Mips_RegInfo Reginfo)
241 : SyntheticSection(SHF_ALLOC, SHT_MIPS_REGINFO, 4, ".reginfo"),
242 Reginfo(Reginfo) {
243 this->Entsize = sizeof(Elf_Mips_RegInfo);
244}
245
246template <class ELFT> void MipsReginfoSection<ELFT>::writeTo(uint8_t *Buf) {
247 if (!Config->Relocatable)
248 Reginfo.ri_gp_value = InX::MipsGot->getGp();
249 memcpy(Buf, &Reginfo, sizeof(Reginfo));
250}
251
252template <class ELFT>
253MipsReginfoSection<ELFT> *MipsReginfoSection<ELFT>::create() {
254 // Section should be alive for O32 and N32 ABIs only.
255 if (ELFT::Is64Bits)
256 return nullptr;
257
258 Elf_Mips_RegInfo Reginfo = {};
259 bool Create = false;
260
261 for (InputSectionBase *Sec : InputSections) {
262 if (Sec->Type != SHT_MIPS_REGINFO)
263 continue;
264 Sec->Live = false;
265 Create = true;
266
267 if (Sec->Data.size() != sizeof(Elf_Mips_RegInfo)) {
268 error(toString(Sec->getFile<ELFT>()) +
269 ": invalid size of .reginfo section");
270 return nullptr;
271 }
272 auto *R = reinterpret_cast<const Elf_Mips_RegInfo *>(Sec->Data.data());
273 if (Config->Relocatable && R->ri_gp_value)
274 error(toString(Sec->getFile<ELFT>()) +
275 ": unsupported non-zero ri_gp_value");
276
277 Reginfo.ri_gprmask |= R->ri_gprmask;
278 Sec->getFile<ELFT>()->MipsGp0 = R->ri_gp_value;
279 };
280
281 if (Create)
282 return make<MipsReginfoSection<ELFT>>(Reginfo);
283 return nullptr;
284}
285
286InputSection *elf::createInterpSection() {
287 // StringSaver guarantees that the returned string ends with '\0'.
288 StringRef S = Saver.save(Config->DynamicLinker);
289 ArrayRef<uint8_t> Contents = {(const uint8_t *)S.data(), S.size() + 1};
290
291 auto *Sec =
292 make<InputSection>(SHF_ALLOC, SHT_PROGBITS, 1, Contents, ".interp");
293 Sec->Live = true;
294 return Sec;
295}
296
297SymbolBody *elf::addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value,
298 uint64_t Size, InputSectionBase *Section) {
299 auto *S = make<DefinedRegular>(Name, /*IsLocal*/ true, STV_DEFAULT, Type,
300 Value, Size, Section, nullptr);
301 if (InX::SymTab)
302 InX::SymTab->addSymbol(S);
303 return S;
304}
305
306static size_t getHashSize() {
307 switch (Config->BuildId) {
308 case BuildIdKind::Fast:
309 return 8;
310 case BuildIdKind::Md5:
311 case BuildIdKind::Uuid:
312 return 16;
313 case BuildIdKind::Sha1:
314 return 20;
315 case BuildIdKind::Hexstring:
316 return Config->BuildIdVector.size();
317 default:
318 llvm_unreachable("unknown BuildIdKind");
319 }
320}
321
322BuildIdSection::BuildIdSection()
323 : SyntheticSection(SHF_ALLOC, SHT_NOTE, 1, ".note.gnu.build-id"),
324 HashSize(getHashSize()) {}
325
326void BuildIdSection::writeTo(uint8_t *Buf) {
327 endianness E = Config->Endianness;
328 write32(Buf, 4, E); // Name size
329 write32(Buf + 4, HashSize, E); // Content size
330 write32(Buf + 8, NT_GNU_BUILD_ID, E); // Type
331 memcpy(Buf + 12, "GNU", 4); // Name string
332 HashBuf = Buf + 16;
333}
334
335// Split one uint8 array into small pieces of uint8 arrays.
336static std::vector<ArrayRef<uint8_t>> split(ArrayRef<uint8_t> Arr,
337 size_t ChunkSize) {
338 std::vector<ArrayRef<uint8_t>> Ret;
339 while (Arr.size() > ChunkSize) {
340 Ret.push_back(Arr.take_front(ChunkSize));
341 Arr = Arr.drop_front(ChunkSize);
342 }
343 if (!Arr.empty())
344 Ret.push_back(Arr);
345 return Ret;
346}
347
348// Computes a hash value of Data using a given hash function.
349// In order to utilize multiple cores, we first split data into 1MB
350// chunks, compute a hash for each chunk, and then compute a hash value
351// of the hash values.
352void BuildIdSection::computeHash(
353 llvm::ArrayRef<uint8_t> Data,
354 std::function<void(uint8_t *Dest, ArrayRef<uint8_t> Arr)> HashFn) {
355 std::vector<ArrayRef<uint8_t>> Chunks = split(Data, 1024 * 1024);
356 std::vector<uint8_t> Hashes(Chunks.size() * HashSize);
357
358 // Compute hash values.
359 parallelForEachN(0, Chunks.size(), [&](size_t I) {
360 HashFn(Hashes.data() + I * HashSize, Chunks[I]);
361 });
362
363 // Write to the final output buffer.
364 HashFn(HashBuf, Hashes);
365}
366
367BssSection::BssSection(StringRef Name)
368 : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_NOBITS, 0, Name) {}
369
370size_t BssSection::reserveSpace(uint64_t Size, uint32_t Alignment) {
371 if (OutputSection *Sec = getParent())
372 Sec->updateAlignment(Alignment);
373 this->Size = alignTo(this->Size, Alignment) + Size;
374 this->Alignment = std::max(this->Alignment, Alignment);
375 return this->Size - Size;
376}
377
378void BuildIdSection::writeBuildId(ArrayRef<uint8_t> Buf) {
379 switch (Config->BuildId) {
380 case BuildIdKind::Fast:
381 computeHash(Buf, [](uint8_t *Dest, ArrayRef<uint8_t> Arr) {
382 write64le(Dest, xxHash64(toStringRef(Arr)));
383 });
384 break;
385 case BuildIdKind::Md5:
386 computeHash(Buf, [](uint8_t *Dest, ArrayRef<uint8_t> Arr) {
387 memcpy(Dest, MD5::hash(Arr).data(), 16);
388 });
389 break;
390 case BuildIdKind::Sha1:
391 computeHash(Buf, [](uint8_t *Dest, ArrayRef<uint8_t> Arr) {
392 memcpy(Dest, SHA1::hash(Arr).data(), 20);
393 });
394 break;
395 case BuildIdKind::Uuid:
396 if (getRandomBytes(HashBuf, HashSize))
397 error("entropy source failure");
398 break;
399 case BuildIdKind::Hexstring:
400 memcpy(HashBuf, Config->BuildIdVector.data(), Config->BuildIdVector.size());
401 break;
402 default:
403 llvm_unreachable("unknown BuildIdKind");
404 }
405}
406
407template <class ELFT>
408EhFrameSection<ELFT>::EhFrameSection()
409 : SyntheticSection(SHF_ALLOC, SHT_PROGBITS, 1, ".eh_frame") {}
410
411// Search for an existing CIE record or create a new one.
412// CIE records from input object files are uniquified by their contents
413// and where their relocations point to.
414template <class ELFT>
415template <class RelTy>
416CieRecord *EhFrameSection<ELFT>::addCie(EhSectionPiece &Piece,
417 ArrayRef<RelTy> Rels) {
418 auto *Sec = cast<EhInputSection>(Piece.ID);
419 const endianness E = ELFT::TargetEndianness;
420 if (read32<E>(Piece.data().data() + 4) != 0)
421 fatal(toString(Sec) + ": CIE expected at beginning of .eh_frame");
422
423 SymbolBody *Personality = nullptr;
424 unsigned FirstRelI = Piece.FirstRelocation;
425 if (FirstRelI != (unsigned)-1)
426 Personality =
427 &Sec->template getFile<ELFT>()->getRelocTargetSym(Rels[FirstRelI]);
428
429 // Search for an existing CIE by CIE contents/relocation target pair.
430 CieRecord *Cie = &CieMap[{Piece.data(), Personality}];
431
432 // If not found, create a new one.
433 if (Cie->Piece == nullptr) {
434 Cie->Piece = &Piece;
435 Cies.push_back(Cie);
436 }
437 return Cie;
438}
439
440// There is one FDE per function. Returns true if a given FDE
441// points to a live function.
442template <class ELFT>
443template <class RelTy>
444bool EhFrameSection<ELFT>::isFdeLive(EhSectionPiece &Piece,
445 ArrayRef<RelTy> Rels) {
446 auto *Sec = cast<EhInputSection>(Piece.ID);
447 unsigned FirstRelI = Piece.FirstRelocation;
448 if (FirstRelI == (unsigned)-1)
449 return false;
450 const RelTy &Rel = Rels[FirstRelI];
451 SymbolBody &B = Sec->template getFile<ELFT>()->getRelocTargetSym(Rel);
452 auto *D = dyn_cast<DefinedRegular>(&B);
453 if (!D || !D->Section)
454 return false;
455 auto *Target =
456 cast<InputSectionBase>(cast<InputSectionBase>(D->Section)->Repl);
457 return Target && Target->Live;
458}
459
460// .eh_frame is a sequence of CIE or FDE records. In general, there
461// is one CIE record per input object file which is followed by
462// a list of FDEs. This function searches an existing CIE or create a new
463// one and associates FDEs to the CIE.
464template <class ELFT>
465template <class RelTy>
466void EhFrameSection<ELFT>::addSectionAux(EhInputSection *Sec,
467 ArrayRef<RelTy> Rels) {
468 const endianness E = ELFT::TargetEndianness;
469
470 DenseMap<size_t, CieRecord *> OffsetToCie;
471 for (EhSectionPiece &Piece : Sec->Pieces) {
472 // The empty record is the end marker.
473 if (Piece.size() == 4)
474 return;
475
476 size_t Offset = Piece.InputOff;
477 uint32_t ID = read32<E>(Piece.data().data() + 4);
478 if (ID == 0) {
479 OffsetToCie[Offset] = addCie(Piece, Rels);
480 continue;
481 }
482
483 uint32_t CieOffset = Offset + 4 - ID;
484 CieRecord *Cie = OffsetToCie[CieOffset];
485 if (!Cie)
486 fatal(toString(Sec) + ": invalid CIE reference");
487
488 if (!isFdeLive(Piece, Rels))
489 continue;
490 Cie->FdePieces.push_back(&Piece);
491 NumFdes++;
492 }
493}
494
495template <class ELFT>
496void EhFrameSection<ELFT>::addSection(InputSectionBase *C) {
497 auto *Sec = cast<EhInputSection>(C);
498 Sec->Parent = this;
499 updateAlignment(Sec->Alignment);
500 Sections.push_back(Sec);
501 for (auto *DS : Sec->DependentSections)
502 DependentSections.push_back(DS);
503
504 // .eh_frame is a sequence of CIE or FDE records. This function
505 // splits it into pieces so that we can call
506 // SplitInputSection::getSectionPiece on the section.
507 Sec->split<ELFT>();
508 if (Sec->Pieces.empty())
509 return;
510
511 if (Sec->NumRelocations) {
512 if (Sec->AreRelocsRela)
513 addSectionAux(Sec, Sec->template relas<ELFT>());
514 else
515 addSectionAux(Sec, Sec->template rels<ELFT>());
516 return;
517 }
518 addSectionAux(Sec, makeArrayRef<Elf_Rela>(nullptr, nullptr));
519}
520
521template <class ELFT>
522static void writeCieFde(uint8_t *Buf, ArrayRef<uint8_t> D) {
523 memcpy(Buf, D.data(), D.size());
524
525 // Fix the size field. -4 since size does not include the size field itself.
526 const endianness E = ELFT::TargetEndianness;
527 write32<E>(Buf, alignTo(D.size(), sizeof(typename ELFT::uint)) - 4);
528}
529
530template <class ELFT> void EhFrameSection<ELFT>::finalizeContents() {
531 if (this->Size)
532 return; // Already finalized.
533
534 size_t Off = 0;
535 for (CieRecord *Cie : Cies) {
536 Cie->Piece->OutputOff = Off;
537 Off += alignTo(Cie->Piece->size(), Config->Wordsize);
538
539 for (EhSectionPiece *Fde : Cie->FdePieces) {
540 Fde->OutputOff = Off;
541 Off += alignTo(Fde->size(), Config->Wordsize);
542 }
543 }
544
545 // The LSB standard does not allow a .eh_frame section with zero
546 // Call Frame Information records. Therefore add a CIE record length
547 // 0 as a terminator if this .eh_frame section is empty.
548 if (Off == 0)
549 Off = 4;
550
551 this->Size = Off;
552}
553
554template <class ELFT> static uint64_t readFdeAddr(uint8_t *Buf, int Size) {
555 const endianness E = ELFT::TargetEndianness;
556 switch (Size) {
557 case DW_EH_PE_udata2:
558 return read16<E>(Buf);
559 case DW_EH_PE_udata4:
560 return read32<E>(Buf);
561 case DW_EH_PE_udata8:
562 return read64<E>(Buf);
563 case DW_EH_PE_absptr:
564 if (ELFT::Is64Bits)
565 return read64<E>(Buf);
566 return read32<E>(Buf);
567 }
568 fatal("unknown FDE size encoding");
569}
570
571// Returns the VA to which a given FDE (on a mmap'ed buffer) is applied to.
572// We need it to create .eh_frame_hdr section.
573template <class ELFT>
574uint64_t EhFrameSection<ELFT>::getFdePc(uint8_t *Buf, size_t FdeOff,
575 uint8_t Enc) {
576 // The starting address to which this FDE applies is
577 // stored at FDE + 8 byte.
578 size_t Off = FdeOff + 8;
579 uint64_t Addr = readFdeAddr<ELFT>(Buf + Off, Enc & 0x7);
580 if ((Enc & 0x70) == DW_EH_PE_absptr)
581 return Addr;
582 if ((Enc & 0x70) == DW_EH_PE_pcrel)
583 return Addr + getParent()->Addr + Off;
584 fatal("unknown FDE size relative encoding");
585}
586
587template <class ELFT> void EhFrameSection<ELFT>::writeTo(uint8_t *Buf) {
588 const endianness E = ELFT::TargetEndianness;
589 for (CieRecord *Cie : Cies) {
590 size_t CieOffset = Cie->Piece->OutputOff;
591 writeCieFde<ELFT>(Buf + CieOffset, Cie->Piece->data());
592
593 for (EhSectionPiece *Fde : Cie->FdePieces) {
594 size_t Off = Fde->OutputOff;
595 writeCieFde<ELFT>(Buf + Off, Fde->data());
596
597 // FDE's second word should have the offset to an associated CIE.
598 // Write it.
599 write32<E>(Buf + Off + 4, Off + 4 - CieOffset);
600 }
601 }
602
603 for (EhInputSection *S : Sections)
604 S->relocateAlloc(Buf, nullptr);
605
606 // Construct .eh_frame_hdr. .eh_frame_hdr is a binary search table
607 // to get a FDE from an address to which FDE is applied. So here
608 // we obtain two addresses and pass them to EhFrameHdr object.
609 if (In<ELFT>::EhFrameHdr) {
610 for (CieRecord *Cie : Cies) {
611 uint8_t Enc = getFdeEncoding<ELFT>(Cie->Piece);
612 for (SectionPiece *Fde : Cie->FdePieces) {
613 uint64_t Pc = getFdePc(Buf, Fde->OutputOff, Enc);
614 uint64_t FdeVA = getParent()->Addr + Fde->OutputOff;
615 In<ELFT>::EhFrameHdr->addFde(Pc, FdeVA);
616 }
617 }
618 }
619}
620
621GotSection::GotSection()
622 : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS,
623 Target->GotEntrySize, ".got") {}
624
625void GotSection::addEntry(SymbolBody &Sym) {
626 Sym.GotIndex = NumEntries;
627 ++NumEntries;
628}
629
630bool GotSection::addDynTlsEntry(SymbolBody &Sym) {
631 if (Sym.GlobalDynIndex != -1U)
632 return false;
633 Sym.GlobalDynIndex = NumEntries;
634 // Global Dynamic TLS entries take two GOT slots.
635 NumEntries += 2;
636 return true;
637}
638
639// Reserves TLS entries for a TLS module ID and a TLS block offset.
640// In total it takes two GOT slots.
641bool GotSection::addTlsIndex() {
642 if (TlsIndexOff != uint32_t(-1))
643 return false;
644 TlsIndexOff = NumEntries * Config->Wordsize;
645 NumEntries += 2;
646 return true;
647}
648
649uint64_t GotSection::getGlobalDynAddr(const SymbolBody &B) const {
650 return this->getVA() + B.GlobalDynIndex * Config->Wordsize;
651}
652
653uint64_t GotSection::getGlobalDynOffset(const SymbolBody &B) const {
654 return B.GlobalDynIndex * Config->Wordsize;
655}
656
657void GotSection::finalizeContents() { Size = NumEntries * Config->Wordsize; }
658
659bool GotSection::empty() const {
660 // If we have a relocation that is relative to GOT (such as GOTOFFREL),
661 // we need to emit a GOT even if it's empty.
662 return NumEntries == 0 && !HasGotOffRel;
663}
664
665void GotSection::writeTo(uint8_t *Buf) {
666 // Buf points to the start of this section's buffer,
667 // whereas InputSectionBase::relocateAlloc() expects its argument
668 // to point to the start of the output section.
669 relocateAlloc(Buf - OutSecOff, Buf - OutSecOff + Size);
670}
671
672MipsGotSection::MipsGotSection()
673 : SyntheticSection(SHF_ALLOC | SHF_WRITE | SHF_MIPS_GPREL, SHT_PROGBITS, 16,
674 ".got") {}
675
676void MipsGotSection::addEntry(SymbolBody &Sym, int64_t Addend, RelExpr Expr) {
677 // For "true" local symbols which can be referenced from the same module
678 // only compiler creates two instructions for address loading:
679 //
680 // lw $8, 0($gp) # R_MIPS_GOT16
681 // addi $8, $8, 0 # R_MIPS_LO16
682 //
683 // The first instruction loads high 16 bits of the symbol address while
684 // the second adds an offset. That allows to reduce number of required
685 // GOT entries because only one global offset table entry is necessary
686 // for every 64 KBytes of local data. So for local symbols we need to
687 // allocate number of GOT entries to hold all required "page" addresses.
688 //
689 // All global symbols (hidden and regular) considered by compiler uniformly.
690 // It always generates a single `lw` instruction and R_MIPS_GOT16 relocation
691 // to load address of the symbol. So for each such symbol we need to
692 // allocate dedicated GOT entry to store its address.
693 //
694 // If a symbol is preemptible we need help of dynamic linker to get its
695 // final address. The corresponding GOT entries are allocated in the
696 // "global" part of GOT. Entries for non preemptible global symbol allocated
697 // in the "local" part of GOT.
698 //
699 // See "Global Offset Table" in Chapter 5:
700 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
701 if (Expr == R_MIPS_GOT_LOCAL_PAGE) {
702 // At this point we do not know final symbol value so to reduce number
703 // of allocated GOT entries do the following trick. Save all output
704 // sections referenced by GOT relocations. Then later in the `finalize`
705 // method calculate number of "pages" required to cover all saved output
706 // section and allocate appropriate number of GOT entries.
707 PageIndexMap.insert({Sym.getOutputSection(), 0});
708 return;
709 }
710 if (Sym.isTls()) {
711 // GOT entries created for MIPS TLS relocations behave like
712 // almost GOT entries from other ABIs. They go to the end
713 // of the global offset table.
714 Sym.GotIndex = TlsEntries.size();
715 TlsEntries.push_back(&Sym);
716 return;
717 }
718 auto AddEntry = [&](SymbolBody &S, uint64_t A, GotEntries &Items) {
719 if (S.isInGot() && !A)
720 return;
721 size_t NewIndex = Items.size();
722 if (!EntryIndexMap.insert({{&S, A}, NewIndex}).second)
723 return;
724 Items.emplace_back(&S, A);
725 if (!A)
726 S.GotIndex = NewIndex;
727 };
728 if (Sym.isPreemptible()) {
729 // Ignore addends for preemptible symbols. They got single GOT entry anyway.
730 AddEntry(Sym, 0, GlobalEntries);
731 Sym.IsInGlobalMipsGot = true;
732 } else if (Expr == R_MIPS_GOT_OFF32) {
733 AddEntry(Sym, Addend, LocalEntries32);
734 Sym.Is32BitMipsGot = true;
735 } else {
736 // Hold local GOT entries accessed via a 16-bit index separately.
737 // That allows to write them in the beginning of the GOT and keep
738 // their indexes as less as possible to escape relocation's overflow.
739 AddEntry(Sym, Addend, LocalEntries);
740 }
741}
742
743bool MipsGotSection::addDynTlsEntry(SymbolBody &Sym) {
744 if (Sym.GlobalDynIndex != -1U)
745 return false;
746 Sym.GlobalDynIndex = TlsEntries.size();
747 // Global Dynamic TLS entries take two GOT slots.
748 TlsEntries.push_back(nullptr);
749 TlsEntries.push_back(&Sym);
750 return true;
751}
752
753// Reserves TLS entries for a TLS module ID and a TLS block offset.
754// In total it takes two GOT slots.
755bool MipsGotSection::addTlsIndex() {
756 if (TlsIndexOff != uint32_t(-1))
757 return false;
758 TlsIndexOff = TlsEntries.size() * Config->Wordsize;
759 TlsEntries.push_back(nullptr);
760 TlsEntries.push_back(nullptr);
761 return true;
762}
763
764static uint64_t getMipsPageAddr(uint64_t Addr) {
765 return (Addr + 0x8000) & ~0xffff;
766}
767
768static uint64_t getMipsPageCount(uint64_t Size) {
769 return (Size + 0xfffe) / 0xffff + 1;
770}
771
772uint64_t MipsGotSection::getPageEntryOffset(const SymbolBody &B,
773 int64_t Addend) const {
774 const OutputSection *OutSec = B.getOutputSection();
775 uint64_t SecAddr = getMipsPageAddr(OutSec->Addr);
776 uint64_t SymAddr = getMipsPageAddr(B.getVA(Addend));
777 uint64_t Index = PageIndexMap.lookup(OutSec) + (SymAddr - SecAddr) / 0xffff;
778 assert(Index < PageEntriesNum);
779 return (HeaderEntriesNum + Index) * Config->Wordsize;
780}
781
782uint64_t MipsGotSection::getBodyEntryOffset(const SymbolBody &B,
783 int64_t Addend) const {
784 // Calculate offset of the GOT entries block: TLS, global, local.
785 uint64_t Index = HeaderEntriesNum + PageEntriesNum;
786 if (B.isTls())
787 Index += LocalEntries.size() + LocalEntries32.size() + GlobalEntries.size();
788 else if (B.IsInGlobalMipsGot)
789 Index += LocalEntries.size() + LocalEntries32.size();
790 else if (B.Is32BitMipsGot)
791 Index += LocalEntries.size();
792 // Calculate offset of the GOT entry in the block.
793 if (B.isInGot())
794 Index += B.GotIndex;
795 else {
796 auto It = EntryIndexMap.find({&B, Addend});
797 assert(It != EntryIndexMap.end());
798 Index += It->second;
799 }
800 return Index * Config->Wordsize;
801}
802
803uint64_t MipsGotSection::getTlsOffset() const {
804 return (getLocalEntriesNum() + GlobalEntries.size()) * Config->Wordsize;
805}
806
807uint64_t MipsGotSection::getGlobalDynOffset(const SymbolBody &B) const {
808 return B.GlobalDynIndex * Config->Wordsize;
809}
810
811const SymbolBody *MipsGotSection::getFirstGlobalEntry() const {
812 return GlobalEntries.empty() ? nullptr : GlobalEntries.front().first;
813}
814
815unsigned MipsGotSection::getLocalEntriesNum() const {
816 return HeaderEntriesNum + PageEntriesNum + LocalEntries.size() +
817 LocalEntries32.size();
818}
819
820void MipsGotSection::finalizeContents() { updateAllocSize(); }
821
822void MipsGotSection::updateAllocSize() {
823 PageEntriesNum = 0;
824 for (std::pair<const OutputSection *, size_t> &P : PageIndexMap) {
825 // For each output section referenced by GOT page relocations calculate
826 // and save into PageIndexMap an upper bound of MIPS GOT entries required
827 // to store page addresses of local symbols. We assume the worst case -
828 // each 64kb page of the output section has at least one GOT relocation
829 // against it. And take in account the case when the section intersects
830 // page boundaries.
831 P.second = PageEntriesNum;
832 PageEntriesNum += getMipsPageCount(P.first->Size);
833 }
834 Size = (getLocalEntriesNum() + GlobalEntries.size() + TlsEntries.size()) *
835 Config->Wordsize;
836}
837
838bool MipsGotSection::empty() const {
839 // We add the .got section to the result for dynamic MIPS target because
840 // its address and properties are mentioned in the .dynamic section.
841 return Config->Relocatable;
842}
843
844uint64_t MipsGotSection::getGp() const { return ElfSym::MipsGp->getVA(0); }
845
846static uint64_t readUint(uint8_t *Buf) {
847 if (Config->Is64)
848 return read64(Buf, Config->Endianness);
849 return read32(Buf, Config->Endianness);
850}
851
852static void writeUint(uint8_t *Buf, uint64_t Val) {
853 if (Config->Is64)
854 write64(Buf, Val, Config->Endianness);
855 else
856 write32(Buf, Val, Config->Endianness);
857}
858
859void MipsGotSection::writeTo(uint8_t *Buf) {
860 // Set the MSB of the second GOT slot. This is not required by any
861 // MIPS ABI documentation, though.
862 //
863 // There is a comment in glibc saying that "The MSB of got[1] of a
864 // gnu object is set to identify gnu objects," and in GNU gold it
865 // says "the second entry will be used by some runtime loaders".
866 // But how this field is being used is unclear.
867 //
868 // We are not really willing to mimic other linkers behaviors
869 // without understanding why they do that, but because all files
870 // generated by GNU tools have this special GOT value, and because
871 // we've been doing this for years, it is probably a safe bet to
872 // keep doing this for now. We really need to revisit this to see
873 // if we had to do this.
874 writeUint(Buf + Config->Wordsize, (uint64_t)1 << (Config->Wordsize * 8 - 1));
875 Buf += HeaderEntriesNum * Config->Wordsize;
876 // Write 'page address' entries to the local part of the GOT.
877 for (std::pair<const OutputSection *, size_t> &L : PageIndexMap) {
878 size_t PageCount = getMipsPageCount(L.first->Size);
879 uint64_t FirstPageAddr = getMipsPageAddr(L.first->Addr);
880 for (size_t PI = 0; PI < PageCount; ++PI) {
881 uint8_t *Entry = Buf + (L.second + PI) * Config->Wordsize;
882 writeUint(Entry, FirstPageAddr + PI * 0x10000);
883 }
884 }
885 Buf += PageEntriesNum * Config->Wordsize;
886 auto AddEntry = [&](const GotEntry &SA) {
887 uint8_t *Entry = Buf;
888 Buf += Config->Wordsize;
889 const SymbolBody *Body = SA.first;
890 uint64_t VA = Body->getVA(SA.second);
891 writeUint(Entry, VA);
892 };
893 std::for_each(std::begin(LocalEntries), std::end(LocalEntries), AddEntry);
894 std::for_each(std::begin(LocalEntries32), std::end(LocalEntries32), AddEntry);
895 std::for_each(std::begin(GlobalEntries), std::end(GlobalEntries), AddEntry);
896 // Initialize TLS-related GOT entries. If the entry has a corresponding
897 // dynamic relocations, leave it initialized by zero. Write down adjusted
898 // TLS symbol's values otherwise. To calculate the adjustments use offsets
899 // for thread-local storage.
900 // https://www.linux-mips.org/wiki/NPTL
901 if (TlsIndexOff != -1U && !Config->Pic)
902 writeUint(Buf + TlsIndexOff, 1);
903 for (const SymbolBody *B : TlsEntries) {
904 if (!B || B->isPreemptible())
905 continue;
906 uint64_t VA = B->getVA();
907 if (B->GotIndex != -1U) {
908 uint8_t *Entry = Buf + B->GotIndex * Config->Wordsize;
909 writeUint(Entry, VA - 0x7000);
910 }
911 if (B->GlobalDynIndex != -1U) {
912 uint8_t *Entry = Buf + B->GlobalDynIndex * Config->Wordsize;
913 writeUint(Entry, 1);
914 Entry += Config->Wordsize;
915 writeUint(Entry, VA - 0x8000);
916 }
917 }
918}
919
920GotPltSection::GotPltSection()
921 : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS,
922 Target->GotPltEntrySize, ".got.plt") {}
923
924void GotPltSection::addEntry(SymbolBody &Sym) {
925 Sym.GotPltIndex = Target->GotPltHeaderEntriesNum + Entries.size();
926 Entries.push_back(&Sym);
927}
928
929size_t GotPltSection::getSize() const {
930 return (Target->GotPltHeaderEntriesNum + Entries.size()) *
931 Target->GotPltEntrySize;
932}
933
934void GotPltSection::writeTo(uint8_t *Buf) {
935 Target->writeGotPltHeader(Buf);
936 Buf += Target->GotPltHeaderEntriesNum * Target->GotPltEntrySize;
937 for (const SymbolBody *B : Entries) {
938 Target->writeGotPlt(Buf, *B);
939 Buf += Config->Wordsize;
940 }
941}
942
943// On ARM the IgotPltSection is part of the GotSection, on other Targets it is
944// part of the .got.plt
945IgotPltSection::IgotPltSection()
946 : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS,
947 Target->GotPltEntrySize,
948 Config->EMachine == EM_ARM ? ".got" : ".got.plt") {}
949
950void IgotPltSection::addEntry(SymbolBody &Sym) {
951 Sym.IsInIgot = true;
952 Sym.GotPltIndex = Entries.size();
953 Entries.push_back(&Sym);
954}
955
956size_t IgotPltSection::getSize() const {
957 return Entries.size() * Target->GotPltEntrySize;
958}
959
960void IgotPltSection::writeTo(uint8_t *Buf) {
961 for (const SymbolBody *B : Entries) {
962 Target->writeIgotPlt(Buf, *B);
963 Buf += Config->Wordsize;
964 }
965}
966
967StringTableSection::StringTableSection(StringRef Name, bool Dynamic)
968 : SyntheticSection(Dynamic ? (uint64_t)SHF_ALLOC : 0, SHT_STRTAB, 1, Name),
969 Dynamic(Dynamic) {
970 // ELF string tables start with a NUL byte.
971 addString("");
972}
973
974// Adds a string to the string table. If HashIt is true we hash and check for
975// duplicates. It is optional because the name of global symbols are already
976// uniqued and hashing them again has a big cost for a small value: uniquing
977// them with some other string that happens to be the same.
978unsigned StringTableSection::addString(StringRef S, bool HashIt) {
979 if (HashIt) {
980 auto R = StringMap.insert(std::make_pair(S, this->Size));
981 if (!R.second)
982 return R.first->second;
983 }
984 unsigned Ret = this->Size;
985 this->Size = this->Size + S.size() + 1;
986 Strings.push_back(S);
987 return Ret;
988}
989
990void StringTableSection::writeTo(uint8_t *Buf) {
991 for (StringRef S : Strings) {
992 memcpy(Buf, S.data(), S.size());
993 Buf += S.size() + 1;
994 }
995}
996
997// Returns the number of version definition entries. Because the first entry
998// is for the version definition itself, it is the number of versioned symbols
999// plus one. Note that we don't support multiple versions yet.
1000static unsigned getVerDefNum() { return Config->VersionDefinitions.size() + 1; }
1001
1002template <class ELFT>
1003DynamicSection<ELFT>::DynamicSection()
1004 : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_DYNAMIC, Config->Wordsize,
1005 ".dynamic") {
1006 this->Entsize = ELFT::Is64Bits ? 16 : 8;
1007
1008 // .dynamic section is not writable on MIPS and on Fuchsia OS
1009 // which passes -z rodynamic.
1010 // See "Special Section" in Chapter 4 in the following document:
1011 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
1012 if (Config->EMachine == EM_MIPS || Config->ZRodynamic)
1013 this->Flags = SHF_ALLOC;
1014
1015 addEntries();
1016}
1017
1018// There are some dynamic entries that don't depend on other sections.
1019// Such entries can be set early.
1020template <class ELFT> void DynamicSection<ELFT>::addEntries() {
1021 // Add strings to .dynstr early so that .dynstr's size will be
1022 // fixed early.
1023 for (StringRef S : Config->FilterList)
1024 add({DT_FILTER, InX::DynStrTab->addString(S)});
1025 for (StringRef S : Config->AuxiliaryList)
1026 add({DT_AUXILIARY, InX::DynStrTab->addString(S)});
1027 if (!Config->Rpath.empty())
1028 add({Config->EnableNewDtags ? DT_RUNPATH : DT_RPATH,
1029 InX::DynStrTab->addString(Config->Rpath)});
1030 for (SharedFile<ELFT> *F : Symtab<ELFT>::X->getSharedFiles())
1031 if (F->isNeeded())
1032 add({DT_NEEDED, InX::DynStrTab->addString(F->SoName)});
1033 if (!Config->SoName.empty())
1034 add({DT_SONAME, InX::DynStrTab->addString(Config->SoName)});
1035
1036 // Set DT_FLAGS and DT_FLAGS_1.
1037 uint32_t DtFlags = 0;
1038 uint32_t DtFlags1 = 0;
1039 if (Config->Bsymbolic)
1040 DtFlags |= DF_SYMBOLIC;
1041 if (Config->ZNodelete)
1042 DtFlags1 |= DF_1_NODELETE;
1043 if (Config->ZNodlopen)
1044 DtFlags1 |= DF_1_NOOPEN;
1045 if (Config->ZNow) {
1046 DtFlags |= DF_BIND_NOW;
1047 DtFlags1 |= DF_1_NOW;
1048 }
1049 if (Config->ZOrigin) {
1050 DtFlags |= DF_ORIGIN;
1051 DtFlags1 |= DF_1_ORIGIN;
1052 }
1053
1054 if (DtFlags)
1055 add({DT_FLAGS, DtFlags});
1056 if (DtFlags1)
1057 add({DT_FLAGS_1, DtFlags1});
1058
1059 // DT_DEBUG is a pointer to debug informaion used by debuggers at runtime. We
1060 // need it for each process, so we don't write it for DSOs. The loader writes
1061 // the pointer into this entry.
1062 //
1063 // DT_DEBUG is the only .dynamic entry that needs to be written to. Some
1064 // systems (currently only Fuchsia OS) provide other means to give the
1065 // debugger this information. Such systems may choose make .dynamic read-only.
1066 // If the target is such a system (used -z rodynamic) don't write DT_DEBUG.
1067 if (!Config->Shared && !Config->Relocatable && !Config->ZRodynamic)
1068 add({DT_DEBUG, (uint64_t)0});
1069}
1070
1071// Add remaining entries to complete .dynamic contents.
1072template <class ELFT> void DynamicSection<ELFT>::finalizeContents() {
1073 if (this->Size)
1074 return; // Already finalized.
1075
1076 this->Link = InX::DynStrTab->getParent()->SectionIndex;
1077 if (In<ELFT>::RelaDyn->getParent() && !In<ELFT>::RelaDyn->empty()) {
1078 bool IsRela = Config->IsRela;
1079 add({IsRela ? DT_RELA : DT_REL, In<ELFT>::RelaDyn});
1080 add({IsRela ? DT_RELASZ : DT_RELSZ, In<ELFT>::RelaDyn->getParent(),
1081 Entry::SecSize});
1082 add({IsRela ? DT_RELAENT : DT_RELENT,
1083 uint64_t(IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel))});
1084
1085 // MIPS dynamic loader does not support RELCOUNT tag.
1086 // The problem is in the tight relation between dynamic
1087 // relocations and GOT. So do not emit this tag on MIPS.
1088 if (Config->EMachine != EM_MIPS) {
1089 size_t NumRelativeRels = In<ELFT>::RelaDyn->getRelativeRelocCount();
1090 if (Config->ZCombreloc && NumRelativeRels)
1091 add({IsRela ? DT_RELACOUNT : DT_RELCOUNT, NumRelativeRels});
1092 }
1093 }
1094 if (In<ELFT>::RelaPlt->getParent() && !In<ELFT>::RelaPlt->empty()) {
1095 add({DT_JMPREL, In<ELFT>::RelaPlt});
1096 add({DT_PLTRELSZ, In<ELFT>::RelaPlt->getParent(), Entry::SecSize});
1097 switch (Config->EMachine) {
1098 case EM_MIPS:
1099 add({DT_MIPS_PLTGOT, In<ELFT>::GotPlt});
1100 break;
1101 case EM_SPARCV9:
1102 add({DT_PLTGOT, In<ELFT>::Plt});
1103 break;
1104 default:
1105 add({DT_PLTGOT, In<ELFT>::GotPlt});
1106 break;
1107 }
1108 add({DT_PLTREL, uint64_t(Config->IsRela ? DT_RELA : DT_REL)});
1109 }
1110
1111 add({DT_SYMTAB, InX::DynSymTab});
1112 add({DT_SYMENT, sizeof(Elf_Sym)});
1113 add({DT_STRTAB, InX::DynStrTab});
1114 add({DT_STRSZ, InX::DynStrTab->getSize()});
1115 if (!Config->ZText)
1116 add({DT_TEXTREL, (uint64_t)0});
1117 if (InX::GnuHashTab)
1118 add({DT_GNU_HASH, InX::GnuHashTab});
1119 if (In<ELFT>::HashTab)
1120 add({DT_HASH, In<ELFT>::HashTab});
1121
1122 if (Out::PreinitArray) {
1123 add({DT_PREINIT_ARRAY, Out::PreinitArray});
1124 add({DT_PREINIT_ARRAYSZ, Out::PreinitArray, Entry::SecSize});
1125 }
1126 if (Out::InitArray) {
1127 add({DT_INIT_ARRAY, Out::InitArray});
1128 add({DT_INIT_ARRAYSZ, Out::InitArray, Entry::SecSize});
1129 }
1130 if (Out::FiniArray) {
1131 add({DT_FINI_ARRAY, Out::FiniArray});
1132 add({DT_FINI_ARRAYSZ, Out::FiniArray, Entry::SecSize});
1133 }
1134
1135 if (SymbolBody *B = Symtab<ELFT>::X->findInCurrentDSO(Config->Init))
1136 add({DT_INIT, B});
1137 if (SymbolBody *B = Symtab<ELFT>::X->findInCurrentDSO(Config->Fini))
1138 add({DT_FINI, B});
1139
1140 bool HasVerNeed = In<ELFT>::VerNeed->getNeedNum() != 0;
1141 if (HasVerNeed || In<ELFT>::VerDef)
1142 add({DT_VERSYM, In<ELFT>::VerSym});
1143 if (In<ELFT>::VerDef) {
1144 add({DT_VERDEF, In<ELFT>::VerDef});
1145 add({DT_VERDEFNUM, getVerDefNum()});
1146 }
1147 if (HasVerNeed) {
1148 add({DT_VERNEED, In<ELFT>::VerNeed});
1149 add({DT_VERNEEDNUM, In<ELFT>::VerNeed->getNeedNum()});
1150 }
1151
1152 if (Config->EMachine == EM_MIPS) {
1153 add({DT_MIPS_RLD_VERSION, 1});
1154 add({DT_MIPS_FLAGS, RHF_NOTPOT});
1155 add({DT_MIPS_BASE_ADDRESS, Config->ImageBase});
1156 add({DT_MIPS_SYMTABNO, InX::DynSymTab->getNumSymbols()});
1157 add({DT_MIPS_LOCAL_GOTNO, InX::MipsGot->getLocalEntriesNum()});
1158 if (const SymbolBody *B = InX::MipsGot->getFirstGlobalEntry())
1159 add({DT_MIPS_GOTSYM, B->DynsymIndex});
1160 else
1161 add({DT_MIPS_GOTSYM, InX::DynSymTab->getNumSymbols()});
1162 add({DT_PLTGOT, InX::MipsGot});
1163 if (InX::MipsRldMap)
1164 add({DT_MIPS_RLD_MAP, InX::MipsRldMap});
1165 }
1166
1167 getParent()->Link = this->Link;
1168
1169 // +1 for DT_NULL
1170 this->Size = (Entries.size() + 1) * this->Entsize;
1171}
1172
1173template <class ELFT> void DynamicSection<ELFT>::writeTo(uint8_t *Buf) {
1174 auto *P = reinterpret_cast<Elf_Dyn *>(Buf);
1175
1176 for (const Entry &E : Entries) {
1177 P->d_tag = E.Tag;
1178 switch (E.Kind) {
1179 case Entry::SecAddr:
1180 P->d_un.d_ptr = E.OutSec->Addr;
1181 break;
1182 case Entry::InSecAddr:
1183 P->d_un.d_ptr = E.InSec->getParent()->Addr + E.InSec->OutSecOff;
1184 break;
1185 case Entry::SecSize:
1186 P->d_un.d_val = E.OutSec->Size;
1187 break;
1188 case Entry::SymAddr:
1189 P->d_un.d_ptr = E.Sym->getVA();
1190 break;
1191 case Entry::PlainInt:
1192 P->d_un.d_val = E.Val;
1193 break;
1194 }
1195 ++P;
1196 }
1197}
1198
1199uint64_t DynamicReloc::getOffset() const {
1200 return InputSec->getOutputSection()->Addr + InputSec->getOffset(OffsetInSec);
1201}
1202
1203int64_t DynamicReloc::getAddend() const {
1204 if (UseSymVA)
1205 return Sym->getVA(Addend);
1206 return Addend;
1207}
1208
1209uint32_t DynamicReloc::getSymIndex() const {
1210 if (Sym && !UseSymVA)
1211 return Sym->DynsymIndex;
1212 return 0;
1213}
1214
1215template <class ELFT>
1216RelocationSection<ELFT>::RelocationSection(StringRef Name, bool Sort)
1217 : SyntheticSection(SHF_ALLOC, Config->IsRela ? SHT_RELA : SHT_REL,
1218 Config->Wordsize, Name),
1219 Sort(Sort) {
1220 this->Entsize = Config->IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
1221}
1222
1223template <class ELFT>
1224void RelocationSection<ELFT>::addReloc(const DynamicReloc &Reloc) {
1225 if (Reloc.Type == Target->RelativeRel)
1226 ++NumRelativeRelocs;
1227 Relocs.push_back(Reloc);
1228}
1229
1230template <class ELFT, class RelTy>
1231static bool compRelocations(const RelTy &A, const RelTy &B) {
1232 bool AIsRel = A.getType(Config->IsMips64EL) == Target->RelativeRel;
1233 bool BIsRel = B.getType(Config->IsMips64EL) == Target->RelativeRel;
1234 if (AIsRel != BIsRel)
1235 return AIsRel;
1236
1237 return A.getSymbol(Config->IsMips64EL) < B.getSymbol(Config->IsMips64EL);
1238}
1239
1240template <class ELFT> void RelocationSection<ELFT>::writeTo(uint8_t *Buf) {
1241 uint8_t *BufBegin = Buf;
1242 for (const DynamicReloc &Rel : Relocs) {
1243 auto *P = reinterpret_cast<Elf_Rela *>(Buf);
1244 Buf += Config->IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
1245
1246 if (Config->IsRela)
1247 P->r_addend = Rel.getAddend();
1248 P->r_offset = Rel.getOffset();
1249 if (Config->EMachine == EM_MIPS && Rel.getInputSec() == InX::MipsGot)
1250 // Dynamic relocation against MIPS GOT section make deal TLS entries
1251 // allocated in the end of the GOT. We need to adjust the offset to take
1252 // in account 'local' and 'global' GOT entries.
1253 P->r_offset += InX::MipsGot->getTlsOffset();
1254 P->setSymbolAndType(Rel.getSymIndex(), Rel.Type, Config->IsMips64EL);
1255 }
1256
1257 if (Sort) {
1258 if (Config->IsRela)
1259 std::stable_sort((Elf_Rela *)BufBegin,
1260 (Elf_Rela *)BufBegin + Relocs.size(),
1261 compRelocations<ELFT, Elf_Rela>);
1262 else
1263 std::stable_sort((Elf_Rel *)BufBegin, (Elf_Rel *)BufBegin + Relocs.size(),
1264 compRelocations<ELFT, Elf_Rel>);
1265 }
1266}
1267
1268template <class ELFT> unsigned RelocationSection<ELFT>::getRelocOffset() {
1269 return this->Entsize * Relocs.size();
1270}
1271
1272template <class ELFT> void RelocationSection<ELFT>::finalizeContents() {
1273 this->Link = InX::DynSymTab ? InX::DynSymTab->getParent()->SectionIndex
1274 : InX::SymTab->getParent()->SectionIndex;
1275
1276 // Set required output section properties.
1277 getParent()->Link = this->Link;
1278}
1279
1280SymbolTableBaseSection::SymbolTableBaseSection(StringTableSection &StrTabSec)
1281 : SyntheticSection(StrTabSec.isDynamic() ? (uint64_t)SHF_ALLOC : 0,
1282 StrTabSec.isDynamic() ? SHT_DYNSYM : SHT_SYMTAB,
1283 Config->Wordsize,
1284 StrTabSec.isDynamic() ? ".dynsym" : ".symtab"),
1285 StrTabSec(StrTabSec) {}
1286
1287// Orders symbols according to their positions in the GOT,
1288// in compliance with MIPS ABI rules.
1289// See "Global Offset Table" in Chapter 5 in the following document
1290// for detailed description:
1291// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
1292static bool sortMipsSymbols(const SymbolTableEntry &L,
1293 const SymbolTableEntry &R) {
1294 // Sort entries related to non-local preemptible symbols by GOT indexes.
1295 // All other entries go to the first part of GOT in arbitrary order.
1296 bool LIsInLocalGot = !L.Symbol->IsInGlobalMipsGot;
1297 bool RIsInLocalGot = !R.Symbol->IsInGlobalMipsGot;
1298 if (LIsInLocalGot || RIsInLocalGot)
1299 return !RIsInLocalGot;
1300 return L.Symbol->GotIndex < R.Symbol->GotIndex;
1301}
1302
1303// Finalize a symbol table. The ELF spec requires that all local
1304// symbols precede global symbols, so we sort symbol entries in this
1305// function. (For .dynsym, we don't do that because symbols for
1306// dynamic linking are inherently all globals.)
1307void SymbolTableBaseSection::finalizeContents() {
1308 getParent()->Link = StrTabSec.getParent()->SectionIndex;
1309
1310 // If it is a .dynsym, there should be no local symbols, but we need
1311 // to do a few things for the dynamic linker.
1312 if (this->Type == SHT_DYNSYM) {
1313 // Section's Info field has the index of the first non-local symbol.
1314 // Because the first symbol entry is a null entry, 1 is the first.
1315 getParent()->Info = 1;
1316
1317 if (InX::GnuHashTab) {
1318 // NB: It also sorts Symbols to meet the GNU hash table requirements.
1319 InX::GnuHashTab->addSymbols(Symbols);
1320 } else if (Config->EMachine == EM_MIPS) {
1321 std::stable_sort(Symbols.begin(), Symbols.end(), sortMipsSymbols);
1322 }
1323
1324 size_t I = 0;
1325 for (const SymbolTableEntry &S : Symbols)
1326 S.Symbol->DynsymIndex = ++I;
1327 return;
1328 }
1329}
1330
1331void SymbolTableBaseSection::postThunkContents() {
1332 if (this->Type == SHT_DYNSYM)
1333 return;
1334 // move all local symbols before global symbols.
1335 auto It = std::stable_partition(
1336 Symbols.begin(), Symbols.end(), [](const SymbolTableEntry &S) {
1337 return S.Symbol->isLocal() ||
1338 S.Symbol->symbol()->computeBinding() == STB_LOCAL;
1339 });
1340 size_t NumLocals = It - Symbols.begin();
1341 getParent()->Info = NumLocals + 1;
1342}
1343
1344void SymbolTableBaseSection::addSymbol(SymbolBody *B) {
1345 // Adding a local symbol to a .dynsym is a bug.
1346 assert(this->Type != SHT_DYNSYM || !B->isLocal());
1347
1348 bool HashIt = B->isLocal();
1349 Symbols.push_back({B, StrTabSec.addString(B->getName(), HashIt)});
1350}
1351
1352size_t SymbolTableBaseSection::getSymbolIndex(SymbolBody *Body) {
1353 auto I = llvm::find_if(Symbols, [&](const SymbolTableEntry &E) {
1354 if (E.Symbol == Body)
1355 return true;
1356 // This is used for -r, so we have to handle multiple section
1357 // symbols being combined.
1358 if (Body->Type == STT_SECTION && E.Symbol->Type == STT_SECTION)
1359 return Body->getOutputSection() == E.Symbol->getOutputSection();
1360 return false;
1361 });
1362 if (I == Symbols.end())
1363 return 0;
1364 return I - Symbols.begin() + 1;
1365}
1366
1367template <class ELFT>
1368SymbolTableSection<ELFT>::SymbolTableSection(StringTableSection &StrTabSec)
1369 : SymbolTableBaseSection(StrTabSec) {
1370 this->Entsize = sizeof(Elf_Sym);
1371}
1372
1373// Write the internal symbol table contents to the output symbol table.
1374template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *Buf) {
1375 // The first entry is a null entry as per the ELF spec.
1376 Buf += sizeof(Elf_Sym);
1377
1378 auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);
1379
1380 for (SymbolTableEntry &Ent : Symbols) {
1381 SymbolBody *Body = Ent.Symbol;
1382
1383 // Set st_info and st_other.
1384 if (Body->isLocal()) {
1385 ESym->setBindingAndType(STB_LOCAL, Body->Type);
1386 } else {
1387 ESym->setBindingAndType(Body->symbol()->computeBinding(), Body->Type);
1388 ESym->setVisibility(Body->symbol()->Visibility);
1389 }
1390
1391 ESym->st_name = Ent.StrTabOffset;
1392
1393 // Set a section index.
1394 if (const OutputSection *OutSec = Body->getOutputSection())
1395 ESym->st_shndx = OutSec->SectionIndex;
1396 else if (isa<DefinedRegular>(Body))
1397 ESym->st_shndx = SHN_ABS;
1398 else if (isa<DefinedCommon>(Body))
1399 ESym->st_shndx = SHN_COMMON;
1400
1401 // Copy symbol size if it is a defined symbol. st_size is not significant
1402 // for undefined symbols, so whether copying it or not is up to us if that's
1403 // the case. We'll leave it as zero because by not setting a value, we can
1404 // get the exact same outputs for two sets of input files that differ only
1405 // in undefined symbol size in DSOs.
1406 if (ESym->st_shndx != SHN_UNDEF)
1407 ESym->st_size = Body->getSize<ELFT>();
1408
1409 // st_value is usually an address of a symbol, but that has a
1410 // special meaining for uninstantiated common symbols (this can
1411 // occur if -r is given).
1412 if (!Config->DefineCommon && isa<DefinedCommon>(Body))
1413 ESym->st_value = cast<DefinedCommon>(Body)->Alignment;
1414 else
1415 ESym->st_value = Body->getVA();
1416
1417 ++ESym;
1418 }
1419
1420 // On MIPS we need to mark symbol which has a PLT entry and requires
1421 // pointer equality by STO_MIPS_PLT flag. That is necessary to help
1422 // dynamic linker distinguish such symbols and MIPS lazy-binding stubs.
1423 // https://sourceware.org/ml/binutils/2008-07/txt00000.txt
1424 if (Config->EMachine == EM_MIPS) {
1425 auto *ESym = reinterpret_cast<Elf_Sym *>(Buf);
1426
1427 for (SymbolTableEntry &Ent : Symbols) {
1428 SymbolBody *Body = Ent.Symbol;
1429 if (Body->isInPlt() && Body->NeedsPltAddr)
1430 ESym->st_other |= STO_MIPS_PLT;
1431
1432 if (Config->Relocatable)
1433 if (auto *D = dyn_cast<DefinedRegular>(Body))
1434 if (D->isMipsPIC<ELFT>())
1435 ESym->st_other |= STO_MIPS_PIC;
1436 ++ESym;
1437 }
1438 }
1439}
1440
1441// .hash and .gnu.hash sections contain on-disk hash tables that map
1442// symbol names to their dynamic symbol table indices. Their purpose
1443// is to help the dynamic linker resolve symbols quickly. If ELF files
1444// don't have them, the dynamic linker has to do linear search on all
1445// dynamic symbols, which makes programs slower. Therefore, a .hash
1446// section is added to a DSO by default. A .gnu.hash is added if you
1447// give the -hash-style=gnu or -hash-style=both option.
1448//
1449// The Unix semantics of resolving dynamic symbols is somewhat expensive.
1450// Each ELF file has a list of DSOs that the ELF file depends on and a
1451// list of dynamic symbols that need to be resolved from any of the
1452// DSOs. That means resolving all dynamic symbols takes O(m)*O(n)
1453// where m is the number of DSOs and n is the number of dynamic
1454// symbols. For modern large programs, both m and n are large. So
1455// making each step faster by using hash tables substiantially
1456// improves time to load programs.
1457//
1458// (Note that this is not the only way to design the shared library.
1459// For instance, the Windows DLL takes a different approach. On
1460// Windows, each dynamic symbol has a name of DLL from which the symbol
1461// has to be resolved. That makes the cost of symbol resolution O(n).
1462// This disables some hacky techniques you can use on Unix such as
1463// LD_PRELOAD, but this is arguably better semantics than the Unix ones.)
1464//
1465// Due to historical reasons, we have two different hash tables, .hash
1466// and .gnu.hash. They are for the same purpose, and .gnu.hash is a new
1467// and better version of .hash. .hash is just an on-disk hash table, but
1468// .gnu.hash has a bloom filter in addition to a hash table to skip
1469// DSOs very quickly. If you are sure that your dynamic linker knows
1470// about .gnu.hash, you want to specify -hash-style=gnu. Otherwise, a
1471// safe bet is to specify -hash-style=both for backward compatibilty.
1472GnuHashTableSection::GnuHashTableSection()
1473 : SyntheticSection(SHF_ALLOC, SHT_GNU_HASH, Config->Wordsize, ".gnu.hash") {
1474}
1475
1476void GnuHashTableSection::finalizeContents() {
1477 getParent()->Link = InX::DynSymTab->getParent()->SectionIndex;
1478
1479 // Computes bloom filter size in word size. We want to allocate 8
1480 // bits for each symbol. It must be a power of two.
1481 if (Symbols.empty())
1482 MaskWords = 1;
1483 else
1484 MaskWords = NextPowerOf2((Symbols.size() - 1) / Config->Wordsize);
1485
1486 Size = 16; // Header
1487 Size += Config->Wordsize * MaskWords; // Bloom filter
1488 Size += NBuckets * 4; // Hash buckets
1489 Size += Symbols.size() * 4; // Hash values
1490}
1491
1492void GnuHashTableSection::writeTo(uint8_t *Buf) {
1493 // Write a header.
1494 write32(Buf, NBuckets, Config->Endianness);
1495 write32(Buf + 4, InX::DynSymTab->getNumSymbols() - Symbols.size(),
1496 Config->Endianness);
1497 write32(Buf + 8, MaskWords, Config->Endianness);
1498 write32(Buf + 12, getShift2(), Config->Endianness);
1499 Buf += 16;
1500
1501 // Write a bloom filter and a hash table.
1502 writeBloomFilter(Buf);
1503 Buf += Config->Wordsize * MaskWords;
1504 writeHashTable(Buf);
1505}
1506
1507// This function writes a 2-bit bloom filter. This bloom filter alone
1508// usually filters out 80% or more of all symbol lookups [1].
1509// The dynamic linker uses the hash table only when a symbol is not
1510// filtered out by a bloom filter.
1511//
1512// [1] Ulrich Drepper (2011), "How To Write Shared Libraries" (Ver. 4.1.2),
1513// p.9, https://www.akkadia.org/drepper/dsohowto.pdf
1514void GnuHashTableSection::writeBloomFilter(uint8_t *Buf) {
1515 const unsigned C = Config->Wordsize * 8;
1516 for (const Entry &Sym : Symbols) {
1517 size_t I = (Sym.Hash / C) & (MaskWords - 1);
1518 uint64_t Val = readUint(Buf + I * Config->Wordsize);
1519 Val |= uint64_t(1) << (Sym.Hash % C);
1520 Val |= uint64_t(1) << ((Sym.Hash >> getShift2()) % C);
1521 writeUint(Buf + I * Config->Wordsize, Val);
1522 }
1523}
1524
1525void GnuHashTableSection::writeHashTable(uint8_t *Buf) {
1526 // Group symbols by hash value.
1527 std::vector<std::vector<Entry>> Syms(NBuckets);
1528 for (const Entry &Ent : Symbols)
1529 Syms[Ent.Hash % NBuckets].push_back(Ent);
1530
1531 // Write hash buckets. Hash buckets contain indices in the following
1532 // hash value table.
1533 uint32_t *Buckets = reinterpret_cast<uint32_t *>(Buf);
1534 for (size_t I = 0; I < NBuckets; ++I)
1535 if (!Syms[I].empty())
1536 write32(Buckets + I, Syms[I][0].Body->DynsymIndex, Config->Endianness);
1537
1538 // Write a hash value table. It represents a sequence of chains that
1539 // share the same hash modulo value. The last element of each chain
1540 // is terminated by LSB 1.
1541 uint32_t *Values = Buckets + NBuckets;
1542 size_t I = 0;
1543 for (std::vector<Entry> &Vec : Syms) {
1544 if (Vec.empty())
1545 continue;
1546 for (const Entry &Ent : makeArrayRef(Vec).drop_back())
1547 write32(Values + I++, Ent.Hash & ~1, Config->Endianness);
1548 write32(Values + I++, Vec.back().Hash | 1, Config->Endianness);
1549 }
1550}
1551
1552static uint32_t hashGnu(StringRef Name) {
1553 uint32_t H = 5381;
1554 for (uint8_t C : Name)
1555 H = (H << 5) + H + C;
1556 return H;
1557}
1558
1559// Returns a number of hash buckets to accomodate given number of elements.
1560// We want to choose a moderate number that is not too small (which
1561// causes too many hash collisions) and not too large (which wastes
1562// disk space.)
1563//
1564// We return a prime number because it (is believed to) achieve good
1565// hash distribution.
1566static size_t getBucketSize(size_t NumSymbols) {
1567 // List of largest prime numbers that are not greater than 2^n + 1.
1568 for (size_t N : {131071, 65521, 32749, 16381, 8191, 4093, 2039, 1021, 509,
1569 251, 127, 61, 31, 13, 7, 3, 1})
1570 if (N <= NumSymbols)
1571 return N;
1572 return 0;
1573}
1574
1575// Add symbols to this symbol hash table. Note that this function
1576// destructively sort a given vector -- which is needed because
1577// GNU-style hash table places some sorting requirements.
1578void GnuHashTableSection::addSymbols(std::vector<SymbolTableEntry> &V) {
1579 // We cannot use 'auto' for Mid because GCC 6.1 cannot deduce
1580 // its type correctly.
1581 std::vector<SymbolTableEntry>::iterator Mid =
1582 std::stable_partition(V.begin(), V.end(), [](const SymbolTableEntry &S) {
1583 return S.Symbol->isUndefined();
1584 });
1585 if (Mid == V.end())
1586 return;
1587
1588 for (SymbolTableEntry &Ent : llvm::make_range(Mid, V.end())) {
1589 SymbolBody *B = Ent.Symbol;
1590 Symbols.push_back({B, Ent.StrTabOffset, hashGnu(B->getName())});
1591 }
1592
1593 NBuckets = getBucketSize(Symbols.size());
1594 std::stable_sort(Symbols.begin(), Symbols.end(),
1595 [&](const Entry &L, const Entry &R) {
1596 return L.Hash % NBuckets < R.Hash % NBuckets;
1597 });
1598
1599 V.erase(Mid, V.end());
1600 for (const Entry &Ent : Symbols)
1601 V.push_back({Ent.Body, Ent.StrTabOffset});
1602}
1603
1604template <class ELFT>
1605HashTableSection<ELFT>::HashTableSection()
1606 : SyntheticSection(SHF_ALLOC, SHT_HASH, 4, ".hash") {
1607 this->Entsize = 4;
1608}
1609
1610template <class ELFT> void HashTableSection<ELFT>::finalizeContents() {
1611 getParent()->Link = InX::DynSymTab->getParent()->SectionIndex;
1612
1613 unsigned NumEntries = 2; // nbucket and nchain.
1614 NumEntries += InX::DynSymTab->getNumSymbols(); // The chain entries.
1615
1616 // Create as many buckets as there are symbols.
1617 // FIXME: This is simplistic. We can try to optimize it, but implementing
1618 // support for SHT_GNU_HASH is probably even more profitable.
1619 NumEntries += InX::DynSymTab->getNumSymbols();
1620 this->Size = NumEntries * 4;
1621}
1622
1623template <class ELFT> void HashTableSection<ELFT>::writeTo(uint8_t *Buf) {
1624 // A 32-bit integer type in the target endianness.
1625 typedef typename ELFT::Word Elf_Word;
1626
1627 unsigned NumSymbols = InX::DynSymTab->getNumSymbols();
1628
1629 auto *P = reinterpret_cast<Elf_Word *>(Buf);
1630 *P++ = NumSymbols; // nbucket
1631 *P++ = NumSymbols; // nchain
1632
1633 Elf_Word *Buckets = P;
1634 Elf_Word *Chains = P + NumSymbols;
1635
1636 for (const SymbolTableEntry &S : InX::DynSymTab->getSymbols()) {
1637 SymbolBody *Body = S.Symbol;
1638 StringRef Name = Body->getName();
1639 unsigned I = Body->DynsymIndex;
1640 uint32_t Hash = hashSysV(Name) % NumSymbols;
1641 Chains[I] = Buckets[Hash];
1642 Buckets[Hash] = I;
1643 }
1644}
1645
1646PltSection::PltSection(size_t S)
1647 : SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS, 16, ".plt"),
1648 HeaderSize(S) {
1649 // The PLT needs to be writable on SPARC as the dynamic linker will
1650 // modify the instructions in the PLT entries.
1651 if (Config->EMachine == EM_SPARCV9)
1652 this->Flags |= SHF_WRITE;
1653}
1654
1655void PltSection::writeTo(uint8_t *Buf) {
1656 // At beginning of PLT but not the IPLT, we have code to call the dynamic
1657 // linker to resolve dynsyms at runtime. Write such code.
1658 if (HeaderSize != 0)
1659 Target->writePltHeader(Buf);
1660 size_t Off = HeaderSize;
1661 // The IPlt is immediately after the Plt, account for this in RelOff
1662 unsigned PltOff = getPltRelocOff();
1663
1664 for (auto &I : Entries) {
1665 const SymbolBody *B = I.first;
1666 unsigned RelOff = I.second + PltOff;
1667 uint64_t Got = B->getGotPltVA();
1668 uint64_t Plt = this->getVA() + Off;
1669 Target->writePlt(Buf + Off, Got, Plt, B->PltIndex, RelOff);
1670 Off += Target->PltEntrySize;
1671 }
1672}
1673
1674template <class ELFT> void PltSection::addEntry(SymbolBody &Sym) {
1675 Sym.PltIndex = Entries.size();
1676 RelocationSection<ELFT> *PltRelocSection = In<ELFT>::RelaPlt;
1677 if (HeaderSize == 0) {
1678 PltRelocSection = In<ELFT>::RelaIplt;
1679 Sym.IsInIplt = true;
1680 }
1681 unsigned RelOff = PltRelocSection->getRelocOffset();
1682 Entries.push_back(std::make_pair(&Sym, RelOff));
1683}
1684
1685size_t PltSection::getSize() const {
1686 return HeaderSize + Entries.size() * Target->PltEntrySize;
1687}
1688
1689// Some architectures such as additional symbols in the PLT section. For
1690// example ARM uses mapping symbols to aid disassembly
1691void PltSection::addSymbols() {
1692 // The PLT may have symbols defined for the Header, the IPLT has no header
1693 if (HeaderSize != 0)
1694 Target->addPltHeaderSymbols(this);
1695 size_t Off = HeaderSize;
1696 for (size_t I = 0; I < Entries.size(); ++I) {
1697 Target->addPltSymbols(this, Off);
1698 Off += Target->PltEntrySize;
1699 }
1700}
1701
1702unsigned PltSection::getPltRelocOff() const {
1703 return (HeaderSize == 0) ? InX::Plt->getSize() : 0;
1704}
1705
1706GdbIndexSection::GdbIndexSection(std::vector<GdbIndexChunk> &&Chunks)
1707 : SyntheticSection(0, SHT_PROGBITS, 1, ".gdb_index"),
1708 StringPool(llvm::StringTableBuilder::ELF), Chunks(std::move(Chunks)) {}
1709
1710// Iterative hash function for symbol's name is described in .gdb_index format
1711// specification. Note that we use one for version 5 to 7 here, it is different
1712// for version 4.
1713static uint32_t hash(StringRef Str) {
1714 uint32_t R = 0;
1715 for (uint8_t C : Str)
1716 R = R * 67 + tolower(C) - 113;
1717 return R;
1718}
1719
1720static std::vector<CompilationUnitEntry> readCuList(DWARFContext &Dwarf) {
1721 std::vector<CompilationUnitEntry> Ret;
1722 for (std::unique_ptr<DWARFCompileUnit> &CU : Dwarf.compile_units())
1723 Ret.push_back({CU->getOffset(), CU->getLength() + 4});
1724 return Ret;
1725}
1726
1727static std::vector<AddressEntry> readAddressArea(DWARFContext &Dwarf,
1728 InputSection *Sec) {
1729 std::vector<AddressEntry> Ret;
1730
1731 uint32_t CurrentCu = 0;
1732 for (std::unique_ptr<DWARFCompileUnit> &CU : Dwarf.compile_units()) {
1733 DWARFAddressRangesVector Ranges;
1734 CU->collectAddressRanges(Ranges);
1735
1736 ArrayRef<InputSectionBase *> Sections = Sec->File->getSections();
1737 for (DWARFAddressRange &R : Ranges) {
1738 InputSectionBase *S = Sections[R.SectionIndex];
1739 if (!S || S == &InputSection::Discarded || !S->Live)
1740 continue;
1741 // Range list with zero size has no effect.
1742 if (R.LowPC == R.HighPC)
1743 continue;
1744 Ret.push_back({cast<InputSection>(S), R.LowPC, R.HighPC, CurrentCu});
1745 }
1746 ++CurrentCu;
1747 }
1748 return Ret;
1749}
1750
1751static std::vector<NameTypeEntry> readPubNamesAndTypes(DWARFContext &Dwarf,
1752 bool IsLE) {
1753 StringRef Data[] = {Dwarf.getGnuPubNamesSection(),
1754 Dwarf.getGnuPubTypesSection()};
1755
1756 std::vector<NameTypeEntry> Ret;
1757 for (StringRef D : Data) {
1758 DWARFDebugPubTable PubTable(D, IsLE, true);
1759 for (const DWARFDebugPubTable::Set &Set : PubTable.getData())
1760 for (const DWARFDebugPubTable::Entry &Ent : Set.Entries)
1761 Ret.push_back({Ent.Name, Ent.Descriptor.toBits()});
1762 }
1763 return Ret;
1764}
1765
1766static std::vector<InputSection *> getDebugInfoSections() {
1767 std::vector<InputSection *> Ret;
1768 for (InputSectionBase *S : InputSections)
1769 if (InputSection *IS = dyn_cast<InputSection>(S))
1770 if (IS->Name == ".debug_info")
1771 Ret.push_back(IS);
1772 return Ret;
1773}
1774
1775void GdbIndexSection::buildIndex() {
1776 if (Chunks.empty())
1777 return;
1778
1779 uint32_t CuId = 0;
1780 for (GdbIndexChunk &D : Chunks) {
1781 for (AddressEntry &E : D.AddressArea)
1782 E.CuIndex += CuId;
1783
1784 // Populate constant pool area.
1785 for (NameTypeEntry &NameType : D.NamesAndTypes) {
1786 uint32_t Hash = hash(NameType.Name);
1787 size_t Offset = StringPool.add(NameType.Name);
1788
1789 bool IsNew;
1790 GdbSymbol *Sym;
1791 std::tie(IsNew, Sym) = SymbolTable.add(Hash, Offset);
1792 if (IsNew) {
1793 Sym->CuVectorIndex = CuVectors.size();
1794 CuVectors.resize(CuVectors.size() + 1);
1795 }
1796
1797 CuVectors[Sym->CuVectorIndex].insert(CuId | (NameType.Type << 24));
1798 }
1799
1800 CuId += D.CompilationUnits.size();
1801 }
1802}
1803
1804static GdbIndexChunk readDwarf(DWARFContextInMemory &Dwarf, InputSection *Sec) {
1805 GdbIndexChunk Ret;
1806 Ret.DebugInfoSec = Sec;
1807 Ret.CompilationUnits = readCuList(Dwarf);
1808 Ret.AddressArea = readAddressArea(Dwarf, Sec);
1809 Ret.NamesAndTypes = readPubNamesAndTypes(Dwarf, Config->IsLE);
1810 return Ret;
1811}
1812
1813template <class ELFT> GdbIndexSection *elf::createGdbIndex() {
1814 std::vector<GdbIndexChunk> Chunks;
1815 for (InputSection *Sec : getDebugInfoSections()) {
1816 InputFile *F = Sec->File;
1817 std::error_code EC;
1818 ELFObjectFile<ELFT> Obj(F->MB, EC);
1819 if (EC)
1820 fatal(EC.message());
1821 DWARFContextInMemory Dwarf(Obj, nullptr, [&](Error E) {
1822 error(toString(F) + ": error parsing DWARF data:\n>>> " +
1823 toString(std::move(E)));
1824 return ErrorPolicy::Continue;
1825 });
1826 Chunks.push_back(readDwarf(Dwarf, Sec));
1827 }
1828 return make<GdbIndexSection>(std::move(Chunks));
1829}
1830
1831static size_t getCuSize(std::vector<GdbIndexChunk> &C) {
1832 size_t Ret = 0;
1833 for (GdbIndexChunk &D : C)
1834 Ret += D.CompilationUnits.size();
1835 return Ret;
1836}
1837
1838static size_t getAddressAreaSize(std::vector<GdbIndexChunk> &C) {
1839 size_t Ret = 0;
1840 for (GdbIndexChunk &D : C)
1841 Ret += D.AddressArea.size();
1842 return Ret;
1843}
1844
1845void GdbIndexSection::finalizeContents() {
1846 if (Finalized)
1847 return;
1848 Finalized = true;
1849
1850 buildIndex();
1851
1852 SymbolTable.finalizeContents();
1853
1854 // GdbIndex header consist from version fields
1855 // and 5 more fields with different kinds of offsets.
1856 CuTypesOffset = CuListOffset + getCuSize(Chunks) * CompilationUnitSize;
1857 SymTabOffset = CuTypesOffset + getAddressAreaSize(Chunks) * AddressEntrySize;
1858
1859 ConstantPoolOffset =
1860 SymTabOffset + SymbolTable.getCapacity() * SymTabEntrySize;
1861
1862 for (std::set<uint32_t> &CuVec : CuVectors) {
1863 CuVectorsOffset.push_back(CuVectorsSize);
1864 CuVectorsSize += OffsetTypeSize * (CuVec.size() + 1);
1865 }
1866 StringPoolOffset = ConstantPoolOffset + CuVectorsSize;
1867
1868 StringPool.finalizeInOrder();
1869}
1870
1871size_t GdbIndexSection::getSize() const {
1872 const_cast<GdbIndexSection *>(this)->finalizeContents();
1873 return StringPoolOffset + StringPool.getSize();
1874}
1875
1876void GdbIndexSection::writeTo(uint8_t *Buf) {
1877 write32le(Buf, 7); // Write version.
1878 write32le(Buf + 4, CuListOffset); // CU list offset.
1879 write32le(Buf + 8, CuTypesOffset); // Types CU list offset.
1880 write32le(Buf + 12, CuTypesOffset); // Address area offset.
1881 write32le(Buf + 16, SymTabOffset); // Symbol table offset.
1882 write32le(Buf + 20, ConstantPoolOffset); // Constant pool offset.
1883 Buf += 24;
1884
1885 // Write the CU list.
1886 for (GdbIndexChunk &D : Chunks) {
1887 for (CompilationUnitEntry &Cu : D.CompilationUnits) {
1888 write64le(Buf, D.DebugInfoSec->OutSecOff + Cu.CuOffset);
1889 write64le(Buf + 8, Cu.CuLength);
1890 Buf += 16;
1891 }
1892 }
1893
1894 // Write the address area.
1895 for (GdbIndexChunk &D : Chunks) {
1896 for (AddressEntry &E : D.AddressArea) {
1897 uint64_t BaseAddr =
1898 E.Section->getParent()->Addr + E.Section->getOffset(0);
1899 write64le(Buf, BaseAddr + E.LowAddress);
1900 write64le(Buf + 8, BaseAddr + E.HighAddress);
1901 write32le(Buf + 16, E.CuIndex);
1902 Buf += 20;
1903 }
1904 }
1905
1906 // Write the symbol table.
1907 for (size_t I = 0; I < SymbolTable.getCapacity(); ++I) {
1908 GdbSymbol *Sym = SymbolTable.getSymbol(I);
1909 if (Sym) {
1910 size_t NameOffset =
1911 Sym->NameOffset + StringPoolOffset - ConstantPoolOffset;
1912 size_t CuVectorOffset = CuVectorsOffset[Sym->CuVectorIndex];
1913 write32le(Buf, NameOffset);
1914 write32le(Buf + 4, CuVectorOffset);
1915 }
1916 Buf += 8;
1917 }
1918
1919 // Write the CU vectors into the constant pool.
1920 for (std::set<uint32_t> &CuVec : CuVectors) {
1921 write32le(Buf, CuVec.size());
1922 Buf += 4;
1923 for (uint32_t Val : CuVec) {
1924 write32le(Buf, Val);
1925 Buf += 4;
1926 }
1927 }
1928
1929 StringPool.write(Buf);
1930}
1931
1932bool GdbIndexSection::empty() const { return !Out::DebugInfo; }
1933
1934template <class ELFT>
1935EhFrameHeader<ELFT>::EhFrameHeader()
1936 : SyntheticSection(SHF_ALLOC, SHT_PROGBITS, 1, ".eh_frame_hdr") {}
1937
1938// .eh_frame_hdr contains a binary search table of pointers to FDEs.
1939// Each entry of the search table consists of two values,
1940// the starting PC from where FDEs covers, and the FDE's address.
1941// It is sorted by PC.
1942template <class ELFT> void EhFrameHeader<ELFT>::writeTo(uint8_t *Buf) {
1943 const endianness E = ELFT::TargetEndianness;
1944
1945 // Sort the FDE list by their PC and uniqueify. Usually there is only
1946 // one FDE for a PC (i.e. function), but if ICF merges two functions
1947 // into one, there can be more than one FDEs pointing to the address.
1948 auto Less = [](const FdeData &A, const FdeData &B) { return A.Pc < B.Pc; };
1949 std::stable_sort(Fdes.begin(), Fdes.end(), Less);
1950 auto Eq = [](const FdeData &A, const FdeData &B) { return A.Pc == B.Pc; };
1951 Fdes.erase(std::unique(Fdes.begin(), Fdes.end(), Eq), Fdes.end());
1952
1953 Buf[0] = 1;
1954 Buf[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4;
1955 Buf[2] = DW_EH_PE_udata4;
1956 Buf[3] = DW_EH_PE_datarel | DW_EH_PE_sdata4;
1957 write32<E>(Buf + 4, In<ELFT>::EhFrame->getParent()->Addr - this->getVA() - 4);
1958 write32<E>(Buf + 8, Fdes.size());
1959 Buf += 12;
1960
1961 uint64_t VA = this->getVA();
1962 for (FdeData &Fde : Fdes) {
1963 write32<E>(Buf, Fde.Pc - VA);
1964 write32<E>(Buf + 4, Fde.FdeVA - VA);
1965 Buf += 8;
1966 }
1967}
1968
1969template <class ELFT> size_t EhFrameHeader<ELFT>::getSize() const {
1970 // .eh_frame_hdr has a 12 bytes header followed by an array of FDEs.
1971 return 12 + In<ELFT>::EhFrame->NumFdes * 8;
1972}
1973
1974template <class ELFT>
1975void EhFrameHeader<ELFT>::addFde(uint32_t Pc, uint32_t FdeVA) {
1976 Fdes.push_back({Pc, FdeVA});
1977}
1978
1979template <class ELFT> bool EhFrameHeader<ELFT>::empty() const {
1980 return In<ELFT>::EhFrame->empty();
1981}
1982
1983template <class ELFT>
1984VersionDefinitionSection<ELFT>::VersionDefinitionSection()
1985 : SyntheticSection(SHF_ALLOC, SHT_GNU_verdef, sizeof(uint32_t),
1986 ".gnu.version_d") {}
1987
1988static StringRef getFileDefName() {
1989 if (!Config->SoName.empty())
1990 return Config->SoName;
1991 return Config->OutputFile;
1992}
1993
1994template <class ELFT> void VersionDefinitionSection<ELFT>::finalizeContents() {
1995 FileDefNameOff = InX::DynStrTab->addString(getFileDefName());
1996 for (VersionDefinition &V : Config->VersionDefinitions)
1997 V.NameOff = InX::DynStrTab->addString(V.Name);
1998
1999 getParent()->Link = InX::DynStrTab->getParent()->SectionIndex;
2000
2001 // sh_info should be set to the number of definitions. This fact is missed in
2002 // documentation, but confirmed by binutils community:
2003 // https://sourceware.org/ml/binutils/2014-11/msg00355.html
2004 getParent()->Info = getVerDefNum();
2005}
2006
2007template <class ELFT>
2008void VersionDefinitionSection<ELFT>::writeOne(uint8_t *Buf, uint32_t Index,
2009 StringRef Name, size_t NameOff) {
2010 auto *Verdef = reinterpret_cast<Elf_Verdef *>(Buf);
2011 Verdef->vd_version = 1;
2012 Verdef->vd_cnt = 1;
2013 Verdef->vd_aux = sizeof(Elf_Verdef);
2014 Verdef->vd_next = sizeof(Elf_Verdef) + sizeof(Elf_Verdaux);
2015 Verdef->vd_flags = (Index == 1 ? VER_FLG_BASE : 0);
2016 Verdef->vd_ndx = Index;
2017 Verdef->vd_hash = hashSysV(Name);
2018
2019 auto *Verdaux = reinterpret_cast<Elf_Verdaux *>(Buf + sizeof(Elf_Verdef));
2020 Verdaux->vda_name = NameOff;
2021 Verdaux->vda_next = 0;
2022}
2023
2024template <class ELFT>
2025void VersionDefinitionSection<ELFT>::writeTo(uint8_t *Buf) {
2026 writeOne(Buf, 1, getFileDefName(), FileDefNameOff);
2027
2028 for (VersionDefinition &V : Config->VersionDefinitions) {
2029 Buf += sizeof(Elf_Verdef) + sizeof(Elf_Verdaux);
2030 writeOne(Buf, V.Id, V.Name, V.NameOff);
2031 }
2032
2033 // Need to terminate the last version definition.
2034 Elf_Verdef *Verdef = reinterpret_cast<Elf_Verdef *>(Buf);
2035 Verdef->vd_next = 0;
2036}
2037
2038template <class ELFT> size_t VersionDefinitionSection<ELFT>::getSize() const {
2039 return (sizeof(Elf_Verdef) + sizeof(Elf_Verdaux)) * getVerDefNum();
2040}
2041
2042template <class ELFT>
2043VersionTableSection<ELFT>::VersionTableSection()
2044 : SyntheticSection(SHF_ALLOC, SHT_GNU_versym, sizeof(uint16_t),
2045 ".gnu.version") {
2046 this->Entsize = sizeof(Elf_Versym);
2047}
2048
2049template <class ELFT> void VersionTableSection<ELFT>::finalizeContents() {
2050 // At the moment of june 2016 GNU docs does not mention that sh_link field
2051 // should be set, but Sun docs do. Also readelf relies on this field.
2052 getParent()->Link = InX::DynSymTab->getParent()->SectionIndex;
2053}
2054
2055template <class ELFT> size_t VersionTableSection<ELFT>::getSize() const {
2056 return sizeof(Elf_Versym) * (InX::DynSymTab->getSymbols().size() + 1);
2057}
2058
2059template <class ELFT> void VersionTableSection<ELFT>::writeTo(uint8_t *Buf) {
2060 auto *OutVersym = reinterpret_cast<Elf_Versym *>(Buf) + 1;
2061 for (const SymbolTableEntry &S : InX::DynSymTab->getSymbols()) {
2062 OutVersym->vs_index = S.Symbol->symbol()->VersionId;
2063 ++OutVersym;
2064 }
2065}
2066
2067template <class ELFT> bool VersionTableSection<ELFT>::empty() const {
2068 return !In<ELFT>::VerDef && In<ELFT>::VerNeed->empty();
2069}
2070
2071template <class ELFT>
2072VersionNeedSection<ELFT>::VersionNeedSection()
2073 : SyntheticSection(SHF_ALLOC, SHT_GNU_verneed, sizeof(uint32_t),
2074 ".gnu.version_r") {
2075 // Identifiers in verneed section start at 2 because 0 and 1 are reserved
2076 // for VER_NDX_LOCAL and VER_NDX_GLOBAL.
2077 // First identifiers are reserved by verdef section if it exist.
2078 NextIndex = getVerDefNum() + 1;
2079}
2080
2081template <class ELFT>
2082void VersionNeedSection<ELFT>::addSymbol(SharedSymbol *SS) {
2083 auto *Ver = reinterpret_cast<const typename ELFT::Verdef *>(SS->Verdef);
2084 if (!Ver) {
2085 SS->symbol()->VersionId = VER_NDX_GLOBAL;
2086 return;
2087 }
2088
2089 auto *File = cast<SharedFile<ELFT>>(SS->File);
2090
2091 // If we don't already know that we need an Elf_Verneed for this DSO, prepare
2092 // to create one by adding it to our needed list and creating a dynstr entry
2093 // for the soname.
2094 if (File->VerdefMap.empty())
2095 Needed.push_back({File, InX::DynStrTab->addString(File->SoName)});
2096 typename SharedFile<ELFT>::NeededVer &NV = File->VerdefMap[Ver];
2097 // If we don't already know that we need an Elf_Vernaux for this Elf_Verdef,
2098 // prepare to create one by allocating a version identifier and creating a
2099 // dynstr entry for the version name.
2100 if (NV.Index == 0) {
2101 NV.StrTab = InX::DynStrTab->addString(File->getStringTable().data() +
2102 Ver->getAux()->vda_name);
2103 NV.Index = NextIndex++;
2104 }
2105 SS->symbol()->VersionId = NV.Index;
2106}
2107
2108template <class ELFT> void VersionNeedSection<ELFT>::writeTo(uint8_t *Buf) {
2109 // The Elf_Verneeds need to appear first, followed by the Elf_Vernauxs.
2110 auto *Verneed = reinterpret_cast<Elf_Verneed *>(Buf);
2111 auto *Vernaux = reinterpret_cast<Elf_Vernaux *>(Verneed + Needed.size());
2112
2113 for (std::pair<SharedFile<ELFT> *, size_t> &P : Needed) {
2114 // Create an Elf_Verneed for this DSO.
2115 Verneed->vn_version = 1;
2116 Verneed->vn_cnt = P.first->VerdefMap.size();
2117 Verneed->vn_file = P.second;
2118 Verneed->vn_aux =
2119 reinterpret_cast<char *>(Vernaux) - reinterpret_cast<char *>(Verneed);
2120 Verneed->vn_next = sizeof(Elf_Verneed);
2121 ++Verneed;
2122
2123 // Create the Elf_Vernauxs for this Elf_Verneed. The loop iterates over
2124 // VerdefMap, which will only contain references to needed version
2125 // definitions. Each Elf_Vernaux is based on the information contained in
2126 // the Elf_Verdef in the source DSO. This loop iterates over a std::map of
2127 // pointers, but is deterministic because the pointers refer to Elf_Verdef
2128 // data structures within a single input file.
2129 for (auto &NV : P.first->VerdefMap) {
2130 Vernaux->vna_hash = NV.first->vd_hash;
2131 Vernaux->vna_flags = 0;
2132 Vernaux->vna_other = NV.second.Index;
2133 Vernaux->vna_name = NV.second.StrTab;
2134 Vernaux->vna_next = sizeof(Elf_Vernaux);
2135 ++Vernaux;
2136 }
2137
2138 Vernaux[-1].vna_next = 0;
2139 }
2140 Verneed[-1].vn_next = 0;
2141}
2142
2143template <class ELFT> void VersionNeedSection<ELFT>::finalizeContents() {
2144 getParent()->Link = InX::DynStrTab->getParent()->SectionIndex;
2145 getParent()->Info = Needed.size();
2146}
2147
2148template <class ELFT> size_t VersionNeedSection<ELFT>::getSize() const {
2149 unsigned Size = Needed.size() * sizeof(Elf_Verneed);
2150 for (const std::pair<SharedFile<ELFT> *, size_t> &P : Needed)
2151 Size += P.first->VerdefMap.size() * sizeof(Elf_Vernaux);
2152 return Size;
2153}
2154
2155template <class ELFT> bool VersionNeedSection<ELFT>::empty() const {
2156 return getNeedNum() == 0;
2157}
2158
2159MergeSyntheticSection::MergeSyntheticSection(StringRef Name, uint32_t Type,
2160 uint64_t Flags, uint32_t Alignment)
2161 : SyntheticSection(Flags, Type, Alignment, Name),
2162 Builder(StringTableBuilder::RAW, Alignment) {}
2163
2164void MergeSyntheticSection::addSection(MergeInputSection *MS) {
2165 MS->Parent = this;
2166 Sections.push_back(MS);
2167}
2168
2169void MergeSyntheticSection::writeTo(uint8_t *Buf) { Builder.write(Buf); }
2170
2171bool MergeSyntheticSection::shouldTailMerge() const {
2172 return (this->Flags & SHF_STRINGS) && Config->Optimize >= 2;
2173}
2174
2175void MergeSyntheticSection::finalizeTailMerge() {
2176 // Add all string pieces to the string table builder to create section
2177 // contents.
2178 for (MergeInputSection *Sec : Sections)
2179 for (size_t I = 0, E = Sec->Pieces.size(); I != E; ++I)
2180 if (Sec->Pieces[I].Live)
2181 Builder.add(Sec->getData(I));
2182
2183 // Fix the string table content. After this, the contents will never change.
2184 Builder.finalize();
2185
2186 // finalize() fixed tail-optimized strings, so we can now get
2187 // offsets of strings. Get an offset for each string and save it
2188 // to a corresponding StringPiece for easy access.
2189 for (MergeInputSection *Sec : Sections)
2190 for (size_t I = 0, E = Sec->Pieces.size(); I != E; ++I)
2191 if (Sec->Pieces[I].Live)
2192 Sec->Pieces[I].OutputOff = Builder.getOffset(Sec->getData(I));
2193}
2194
2195void MergeSyntheticSection::finalizeNoTailMerge() {
2196 // Add all string pieces to the string table builder to create section
2197 // contents. Because we are not tail-optimizing, offsets of strings are
2198 // fixed when they are added to the builder (string table builder contains
2199 // a hash table from strings to offsets).
2200 for (MergeInputSection *Sec : Sections)
2201 for (size_t I = 0, E = Sec->Pieces.size(); I != E; ++I)
2202 if (Sec->Pieces[I].Live)
2203 Sec->Pieces[I].OutputOff = Builder.add(Sec->getData(I));
2204
2205 Builder.finalizeInOrder();
2206}
2207
2208void MergeSyntheticSection::finalizeContents() {
2209 if (shouldTailMerge())
2210 finalizeTailMerge();
2211 else
2212 finalizeNoTailMerge();
2213}
2214
2215size_t MergeSyntheticSection::getSize() const { return Builder.getSize(); }
2216
2217// This function decompresses compressed sections and scans over the input
2218// sections to create mergeable synthetic sections. It removes
2219// MergeInputSections from the input section array and adds new synthetic
2220// sections at the location of the first input section that it replaces. It then
2221// finalizes each synthetic section in order to compute an output offset for
2222// each piece of each input section.
2223void elf::decompressAndMergeSections() {
2224 // splitIntoPieces needs to be called on each MergeInputSection before calling
2225 // finalizeContents(). Do that first.
2226 parallelForEach(InputSections.begin(), InputSections.end(),
2227 [](InputSectionBase *S) {
2228 if (!S->Live)
2229 return;
2230 if (Decompressor::isCompressedELFSection(S->Flags, S->Name))
2231 S->uncompress();
2232 if (auto *MS = dyn_cast<MergeInputSection>(S))
2233 MS->splitIntoPieces();
2234 });
2235
2236 std::vector<MergeSyntheticSection *> MergeSections;
2237 for (InputSectionBase *&S : InputSections) {
2238 MergeInputSection *MS = dyn_cast<MergeInputSection>(S);
2239 if (!MS)
2240 continue;
2241
2242 // We do not want to handle sections that are not alive, so just remove
2243 // them instead of trying to merge.
2244 if (!MS->Live)
2245 continue;
2246
2247 StringRef OutsecName = getOutputSectionName(MS->Name);
2248 uint64_t Flags = MS->Flags & ~(uint64_t)SHF_GROUP;
2249 uint32_t Alignment = std::max<uint32_t>(MS->Alignment, MS->Entsize);
2250
2251 auto I = llvm::find_if(MergeSections, [=](MergeSyntheticSection *Sec) {
2252 return Sec->Name == OutsecName && Sec->Flags == Flags &&
2253 Sec->Alignment == Alignment;
2254 });
2255 if (I == MergeSections.end()) {
2256 MergeSyntheticSection *Syn =
2257 make<MergeSyntheticSection>(OutsecName, MS->Type, Flags, Alignment);
2258 MergeSections.push_back(Syn);
2259 I = std::prev(MergeSections.end());
2260 S = Syn;
2261 } else {
2262 S = nullptr;
2263 }
2264 (*I)->addSection(MS);
2265 }
2266 for (auto *MS : MergeSections)
2267 MS->finalizeContents();
2268
2269 std::vector<InputSectionBase *> &V = InputSections;
2270 V.erase(std::remove(V.begin(), V.end(), nullptr), V.end());
2271}
2272
2273MipsRldMapSection::MipsRldMapSection()
2274 : SyntheticSection(SHF_ALLOC | SHF_WRITE, SHT_PROGBITS, Config->Wordsize,
2275 ".rld_map") {}
2276
2277ARMExidxSentinelSection::ARMExidxSentinelSection()
2278 : SyntheticSection(SHF_ALLOC | SHF_LINK_ORDER, SHT_ARM_EXIDX,
2279 Config->Wordsize, ".ARM.exidx") {}
2280
2281// Write a terminating sentinel entry to the end of the .ARM.exidx table.
2282// This section will have been sorted last in the .ARM.exidx table.
2283// This table entry will have the form:
2284// | PREL31 upper bound of code that has exception tables | EXIDX_CANTUNWIND |
2285// The sentinel must have the PREL31 value of an address higher than any
2286// address described by any other table entry.
2287void ARMExidxSentinelSection::writeTo(uint8_t *Buf) {
2288 // The Sections are sorted in order of ascending PREL31 address with the
2289 // sentinel last. We need to find the InputSection that precedes the
2290 // sentinel. By construction the Sentinel is in the last
2291 // InputSectionDescription as the InputSection that precedes it.
2292 OutputSectionCommand *C = Script->getCmd(getParent());
2293 auto ISD = std::find_if(C->Commands.rbegin(), C->Commands.rend(),
2294 [](const BaseCommand *Base) {
2295 return isa<InputSectionDescription>(Base);
2296 });
2297 auto L = cast<InputSectionDescription>(*ISD);
2298 InputSection *Highest = L->Sections[L->Sections.size() - 2];
2299 InputSection *LS = Highest->getLinkOrderDep();
2300 uint64_t S = LS->getParent()->Addr + LS->getOffset(LS->getSize());
2301 uint64_t P = getVA();
2302 Target->relocateOne(Buf, R_ARM_PREL31, S - P);
2303 write32le(Buf + 4, 0x1);
2304}
2305
2306ThunkSection::ThunkSection(OutputSection *OS, uint64_t Off)
2307 : SyntheticSection(SHF_ALLOC | SHF_EXECINSTR, SHT_PROGBITS,
2308 Config->Wordsize, ".text.thunk") {
2309 this->Parent = OS;
2310 this->OutSecOff = Off;
2311}
2312
2313void ThunkSection::addThunk(Thunk *T) {
2314 uint64_t Off = alignTo(Size, T->Alignment);
2315 T->Offset = Off;
2316 Thunks.push_back(T);
2317 T->addSymbols(*this);
2318 Size = Off + T->size();
2319}
2320
2321void ThunkSection::writeTo(uint8_t *Buf) {
2322 for (const Thunk *T : Thunks)
2323 T->writeTo(Buf + T->Offset, *this);
2324}
2325
2326InputSection *ThunkSection::getTargetInputSection() const {
2327 const Thunk *T = Thunks.front();
2328 return T->getTargetInputSection();
2329}
2330
2331InputSection *InX::ARMAttributes;
2332BssSection *InX::Bss;
2333BssSection *InX::BssRelRo;
2334BuildIdSection *InX::BuildId;
2335InputSection *InX::Common;
2336SyntheticSection *InX::Dynamic;
2337StringTableSection *InX::DynStrTab;
2338SymbolTableBaseSection *InX::DynSymTab;
2339InputSection *InX::Interp;
2340GdbIndexSection *InX::GdbIndex;
2341GotSection *InX::Got;
2342GotPltSection *InX::GotPlt;
2343GnuHashTableSection *InX::GnuHashTab;
2344IgotPltSection *InX::IgotPlt;
2345MipsGotSection *InX::MipsGot;
2346MipsRldMapSection *InX::MipsRldMap;
2347PltSection *InX::Plt;
2348PltSection *InX::Iplt;
2349StringTableSection *InX::ShStrTab;
2350StringTableSection *InX::StrTab;
2351SymbolTableBaseSection *InX::SymTab;
2352
2353template GdbIndexSection *elf::createGdbIndex<ELF32LE>();
2354template GdbIndexSection *elf::createGdbIndex<ELF32BE>();
2355template GdbIndexSection *elf::createGdbIndex<ELF64LE>();
2356template GdbIndexSection *elf::createGdbIndex<ELF64BE>();
2357
2358template void PltSection::addEntry<ELF32LE>(SymbolBody &Sym);
2359template void PltSection::addEntry<ELF32BE>(SymbolBody &Sym);
2360template void PltSection::addEntry<ELF64LE>(SymbolBody &Sym);
2361template void PltSection::addEntry<ELF64BE>(SymbolBody &Sym);
2362
2363template InputSection *elf::createCommonSection<ELF32LE>();
2364template InputSection *elf::createCommonSection<ELF32BE>();
2365template InputSection *elf::createCommonSection<ELF64LE>();
2366template InputSection *elf::createCommonSection<ELF64BE>();
2367
2368template MergeInputSection *elf::createCommentSection<ELF32LE>();
2369template MergeInputSection *elf::createCommentSection<ELF32BE>();
2370template MergeInputSection *elf::createCommentSection<ELF64LE>();
2371template MergeInputSection *elf::createCommentSection<ELF64BE>();
2372
2373template class elf::MipsAbiFlagsSection<ELF32LE>;
2374template class elf::MipsAbiFlagsSection<ELF32BE>;
2375template class elf::MipsAbiFlagsSection<ELF64LE>;
2376template class elf::MipsAbiFlagsSection<ELF64BE>;
2377
2378template class elf::MipsOptionsSection<ELF32LE>;
2379template class elf::MipsOptionsSection<ELF32BE>;
2380template class elf::MipsOptionsSection<ELF64LE>;
2381template class elf::MipsOptionsSection<ELF64BE>;
2382
2383template class elf::MipsReginfoSection<ELF32LE>;
2384template class elf::MipsReginfoSection<ELF32BE>;
2385template class elf::MipsReginfoSection<ELF64LE>;
2386template class elf::MipsReginfoSection<ELF64BE>;
2387
2388template class elf::DynamicSection<ELF32LE>;
2389template class elf::DynamicSection<ELF32BE>;
2390template class elf::DynamicSection<ELF64LE>;
2391template class elf::DynamicSection<ELF64BE>;
2392
2393template class elf::RelocationSection<ELF32LE>;
2394template class elf::RelocationSection<ELF32BE>;
2395template class elf::RelocationSection<ELF64LE>;
2396template class elf::RelocationSection<ELF64BE>;
2397
2398template class elf::SymbolTableSection<ELF32LE>;
2399template class elf::SymbolTableSection<ELF32BE>;
2400template class elf::SymbolTableSection<ELF64LE>;
2401template class elf::SymbolTableSection<ELF64BE>;
2402
2403template class elf::HashTableSection<ELF32LE>;
2404template class elf::HashTableSection<ELF32BE>;
2405template class elf::HashTableSection<ELF64LE>;
2406template class elf::HashTableSection<ELF64BE>;
2407
2408template class elf::EhFrameHeader<ELF32LE>;
2409template class elf::EhFrameHeader<ELF32BE>;
2410template class elf::EhFrameHeader<ELF64LE>;
2411template class elf::EhFrameHeader<ELF64BE>;
2412
2413template class elf::VersionTableSection<ELF32LE>;
2414template class elf::VersionTableSection<ELF32BE>;
2415template class elf::VersionTableSection<ELF64LE>;
2416template class elf::VersionTableSection<ELF64BE>;
2417
2418template class elf::VersionNeedSection<ELF32LE>;
2419template class elf::VersionNeedSection<ELF32BE>;
2420template class elf::VersionNeedSection<ELF64LE>;
2421template class elf::VersionNeedSection<ELF64BE>;
2422
2423template class elf::VersionDefinitionSection<ELF32LE>;
2424template class elf::VersionDefinitionSection<ELF32BE>;
2425template class elf::VersionDefinitionSection<ELF64LE>;
2426template class elf::VersionDefinitionSection<ELF64BE>;
2427
2428template class elf::EhFrameSection<ELF32LE>;
2429template class elf::EhFrameSection<ELF32BE>;
2430template class elf::EhFrameSection<ELF64LE>;
2431template class elf::EhFrameSection<ELF64BE>;
deps/lld/ELF/SyntheticSections.h created+805
......@@ -0,0 +1,805 @@
1//===- SyntheticSection.h ---------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Synthetic sections represent chunks of linker-created data. If you
11// need to create a chunk of data that to be included in some section
12// in the result, you probably want to create that as a synthetic section.
13//
14// Synthetic sections are designed as input sections as opposed to
15// output sections because we want to allow them to be manipulated
16// using linker scripts just like other input sections from regular
17// files.
18//
19//===----------------------------------------------------------------------===//
20
21#ifndef LLD_ELF_SYNTHETIC_SECTION_H
22#define LLD_ELF_SYNTHETIC_SECTION_H
23
24#include "EhFrame.h"
25#include "GdbIndex.h"
26#include "InputSection.h"
27#include "llvm/ADT/MapVector.h"
28#include "llvm/MC/StringTableBuilder.h"
29
30#include <set>
31
32namespace lld {
33namespace elf {
34
35class SyntheticSection : public InputSection {
36public:
37 SyntheticSection(uint64_t Flags, uint32_t Type, uint32_t Alignment,
38 StringRef Name)
39 : InputSection(Flags, Type, Alignment, {}, Name,
40 InputSectionBase::Synthetic) {
41 this->Live = true;
42 }
43
44 virtual ~SyntheticSection() = default;
45 virtual void writeTo(uint8_t *Buf) = 0;
46 virtual size_t getSize() const = 0;
47 virtual void finalizeContents() {}
48 // If the section has the SHF_ALLOC flag and the size may be changed if
49 // thunks are added, update the section size.
50 virtual void updateAllocSize() {}
51 // If any additional finalization of contents are needed post thunk creation.
52 virtual void postThunkContents() {}
53 virtual bool empty() const { return false; }
54 uint64_t getVA() const;
55
56 static bool classof(const SectionBase *D) {
57 return D->kind() == InputSectionBase::Synthetic;
58 }
59};
60
61struct CieRecord {
62 EhSectionPiece *Piece = nullptr;
63 std::vector<EhSectionPiece *> FdePieces;
64};
65
66// Section for .eh_frame.
67template <class ELFT> class EhFrameSection final : public SyntheticSection {
68 typedef typename ELFT::Shdr Elf_Shdr;
69 typedef typename ELFT::Rel Elf_Rel;
70 typedef typename ELFT::Rela Elf_Rela;
71
72 void updateAlignment(uint64_t Val) {
73 if (Val > this->Alignment)
74 this->Alignment = Val;
75 }
76
77public:
78 EhFrameSection();
79 void writeTo(uint8_t *Buf) override;
80 void finalizeContents() override;
81 bool empty() const override { return Sections.empty(); }
82 size_t getSize() const override { return Size; }
83
84 void addSection(InputSectionBase *S);
85
86 size_t NumFdes = 0;
87
88 std::vector<EhInputSection *> Sections;
89
90private:
91 uint64_t Size = 0;
92 template <class RelTy>
93 void addSectionAux(EhInputSection *S, llvm::ArrayRef<RelTy> Rels);
94
95 template <class RelTy>
96 CieRecord *addCie(EhSectionPiece &Piece, ArrayRef<RelTy> Rels);
97
98 template <class RelTy>
99 bool isFdeLive(EhSectionPiece &Piece, ArrayRef<RelTy> Rels);
100
101 uint64_t getFdePc(uint8_t *Buf, size_t Off, uint8_t Enc);
102
103 std::vector<CieRecord *> Cies;
104
105 // CIE records are uniquified by their contents and personality functions.
106 llvm::DenseMap<std::pair<ArrayRef<uint8_t>, SymbolBody *>, CieRecord> CieMap;
107};
108
109class GotSection : public SyntheticSection {
110public:
111 GotSection();
112 size_t getSize() const override { return Size; }
113 void finalizeContents() override;
114 bool empty() const override;
115 void writeTo(uint8_t *Buf) override;
116
117 void addEntry(SymbolBody &Sym);
118 bool addDynTlsEntry(SymbolBody &Sym);
119 bool addTlsIndex();
120 uint64_t getGlobalDynAddr(const SymbolBody &B) const;
121 uint64_t getGlobalDynOffset(const SymbolBody &B) const;
122
123 uint64_t getTlsIndexVA() { return this->getVA() + TlsIndexOff; }
124 uint32_t getTlsIndexOff() const { return TlsIndexOff; }
125
126 // Flag to force GOT to be in output if we have relocations
127 // that relies on its address.
128 bool HasGotOffRel = false;
129
130protected:
131 size_t NumEntries = 0;
132 uint32_t TlsIndexOff = -1;
133 uint64_t Size = 0;
134};
135
136// .note.gnu.build-id section.
137class BuildIdSection : public SyntheticSection {
138 // First 16 bytes are a header.
139 static const unsigned HeaderSize = 16;
140
141public:
142 BuildIdSection();
143 void writeTo(uint8_t *Buf) override;
144 size_t getSize() const override { return HeaderSize + HashSize; }
145 void writeBuildId(llvm::ArrayRef<uint8_t> Buf);
146
147private:
148 void computeHash(llvm::ArrayRef<uint8_t> Buf,
149 std::function<void(uint8_t *, ArrayRef<uint8_t>)> Hash);
150
151 size_t HashSize;
152 uint8_t *HashBuf;
153};
154
155// BssSection is used to reserve space for copy relocations and common symbols.
156// We create three instances of this class for .bss, .bss.rel.ro and "COMMON",
157// that are used for writable symbols, read-only symbols and common symbols,
158// respectively.
159class BssSection final : public SyntheticSection {
160public:
161 BssSection(StringRef Name);
162 void writeTo(uint8_t *) override {}
163 bool empty() const override { return getSize() == 0; }
164 size_t reserveSpace(uint64_t Size, uint32_t Alignment);
165 size_t getSize() const override { return Size; }
166
167private:
168 uint64_t Size = 0;
169};
170
171class MipsGotSection final : public SyntheticSection {
172public:
173 MipsGotSection();
174 void writeTo(uint8_t *Buf) override;
175 size_t getSize() const override { return Size; }
176 void updateAllocSize() override;
177 void finalizeContents() override;
178 bool empty() const override;
179 void addEntry(SymbolBody &Sym, int64_t Addend, RelExpr Expr);
180 bool addDynTlsEntry(SymbolBody &Sym);
181 bool addTlsIndex();
182 uint64_t getPageEntryOffset(const SymbolBody &B, int64_t Addend) const;
183 uint64_t getBodyEntryOffset(const SymbolBody &B, int64_t Addend) const;
184 uint64_t getGlobalDynOffset(const SymbolBody &B) const;
185
186 // Returns the symbol which corresponds to the first entry of the global part
187 // of GOT on MIPS platform. It is required to fill up MIPS-specific dynamic
188 // table properties.
189 // Returns nullptr if the global part is empty.
190 const SymbolBody *getFirstGlobalEntry() const;
191
192 // Returns the number of entries in the local part of GOT including
193 // the number of reserved entries.
194 unsigned getLocalEntriesNum() const;
195
196 // Returns offset of TLS part of the MIPS GOT table. This part goes
197 // after 'local' and 'global' entries.
198 uint64_t getTlsOffset() const;
199
200 uint32_t getTlsIndexOff() const { return TlsIndexOff; }
201
202 uint64_t getGp() const;
203
204private:
205 // MIPS GOT consists of three parts: local, global and tls. Each part
206 // contains different types of entries. Here is a layout of GOT:
207 // - Header entries |
208 // - Page entries | Local part
209 // - Local entries (16-bit access) |
210 // - Local entries (32-bit access) |
211 // - Normal global entries || Global part
212 // - Reloc-only global entries ||
213 // - TLS entries ||| TLS part
214 //
215 // Header:
216 // Two entries hold predefined value 0x0 and 0x80000000.
217 // Page entries:
218 // These entries created by R_MIPS_GOT_PAGE relocation and R_MIPS_GOT16
219 // relocation against local symbols. They are initialized by higher 16-bit
220 // of the corresponding symbol's value. So each 64kb of address space
221 // requires a single GOT entry.
222 // Local entries (16-bit access):
223 // These entries created by GOT relocations against global non-preemptible
224 // symbols so dynamic linker is not necessary to resolve the symbol's
225 // values. "16-bit access" means that corresponding relocations address
226 // GOT using 16-bit index. Each unique Symbol-Addend pair has its own
227 // GOT entry.
228 // Local entries (32-bit access):
229 // These entries are the same as above but created by relocations which
230 // address GOT using 32-bit index (R_MIPS_GOT_HI16/LO16 etc).
231 // Normal global entries:
232 // These entries created by GOT relocations against preemptible global
233 // symbols. They need to be initialized by dynamic linker and they ordered
234 // exactly as the corresponding entries in the dynamic symbols table.
235 // Reloc-only global entries:
236 // These entries created for symbols that are referenced by dynamic
237 // relocations R_MIPS_REL32. These entries are not accessed with gp-relative
238 // addressing, but MIPS ABI requires that these entries be present in GOT.
239 // TLS entries:
240 // Entries created by TLS relocations.
241
242 // Number of "Header" entries.
243 static const unsigned HeaderEntriesNum = 2;
244 // Number of allocated "Page" entries.
245 uint32_t PageEntriesNum = 0;
246 // Map output sections referenced by MIPS GOT relocations
247 // to the first index of "Page" entries allocated for this section.
248 llvm::SmallMapVector<const OutputSection *, size_t, 16> PageIndexMap;
249
250 typedef std::pair<const SymbolBody *, uint64_t> GotEntry;
251 typedef std::vector<GotEntry> GotEntries;
252 // Map from Symbol-Addend pair to the GOT index.
253 llvm::DenseMap<GotEntry, size_t> EntryIndexMap;
254 // Local entries (16-bit access).
255 GotEntries LocalEntries;
256 // Local entries (32-bit access).
257 GotEntries LocalEntries32;
258
259 // Normal and reloc-only global entries.
260 GotEntries GlobalEntries;
261
262 // TLS entries.
263 std::vector<const SymbolBody *> TlsEntries;
264
265 uint32_t TlsIndexOff = -1;
266 uint64_t Size = 0;
267};
268
269class GotPltSection final : public SyntheticSection {
270public:
271 GotPltSection();
272 void addEntry(SymbolBody &Sym);
273 size_t getSize() const override;
274 void writeTo(uint8_t *Buf) override;
275 bool empty() const override { return Entries.empty(); }
276
277private:
278 std::vector<const SymbolBody *> Entries;
279};
280
281// The IgotPltSection is a Got associated with the PltSection for GNU Ifunc
282// Symbols that will be relocated by Target->IRelativeRel.
283// On most Targets the IgotPltSection will immediately follow the GotPltSection
284// on ARM the IgotPltSection will immediately follow the GotSection.
285class IgotPltSection final : public SyntheticSection {
286public:
287 IgotPltSection();
288 void addEntry(SymbolBody &Sym);
289 size_t getSize() const override;
290 void writeTo(uint8_t *Buf) override;
291 bool empty() const override { return Entries.empty(); }
292
293private:
294 std::vector<const SymbolBody *> Entries;
295};
296
297class StringTableSection final : public SyntheticSection {
298public:
299 StringTableSection(StringRef Name, bool Dynamic);
300 unsigned addString(StringRef S, bool HashIt = true);
301 void writeTo(uint8_t *Buf) override;
302 size_t getSize() const override { return Size; }
303 bool isDynamic() const { return Dynamic; }
304
305private:
306 const bool Dynamic;
307
308 uint64_t Size = 0;
309
310 llvm::DenseMap<StringRef, unsigned> StringMap;
311 std::vector<StringRef> Strings;
312};
313
314class DynamicReloc {
315public:
316 DynamicReloc(uint32_t Type, const InputSectionBase *InputSec,
317 uint64_t OffsetInSec, bool UseSymVA, SymbolBody *Sym,
318 int64_t Addend)
319 : Type(Type), Sym(Sym), InputSec(InputSec), OffsetInSec(OffsetInSec),
320 UseSymVA(UseSymVA), Addend(Addend) {}
321
322 uint64_t getOffset() const;
323 int64_t getAddend() const;
324 uint32_t getSymIndex() const;
325 const InputSectionBase *getInputSec() const { return InputSec; }
326
327 uint32_t Type;
328
329private:
330 SymbolBody *Sym;
331 const InputSectionBase *InputSec = nullptr;
332 uint64_t OffsetInSec;
333 bool UseSymVA;
334 int64_t Addend;
335};
336
337template <class ELFT> class DynamicSection final : public SyntheticSection {
338 typedef typename ELFT::Dyn Elf_Dyn;
339 typedef typename ELFT::Rel Elf_Rel;
340 typedef typename ELFT::Rela Elf_Rela;
341 typedef typename ELFT::Shdr Elf_Shdr;
342 typedef typename ELFT::Sym Elf_Sym;
343
344 // The .dynamic section contains information for the dynamic linker.
345 // The section consists of fixed size entries, which consist of
346 // type and value fields. Value are one of plain integers, symbol
347 // addresses, or section addresses. This struct represents the entry.
348 struct Entry {
349 int32_t Tag;
350 union {
351 OutputSection *OutSec;
352 InputSection *InSec;
353 uint64_t Val;
354 const SymbolBody *Sym;
355 };
356 enum KindT { SecAddr, SecSize, SymAddr, PlainInt, InSecAddr } Kind;
357 Entry(int32_t Tag, OutputSection *OutSec, KindT Kind = SecAddr)
358 : Tag(Tag), OutSec(OutSec), Kind(Kind) {}
359 Entry(int32_t Tag, InputSection *Sec)
360 : Tag(Tag), InSec(Sec), Kind(InSecAddr) {}
361 Entry(int32_t Tag, uint64_t Val) : Tag(Tag), Val(Val), Kind(PlainInt) {}
362 Entry(int32_t Tag, const SymbolBody *Sym)
363 : Tag(Tag), Sym(Sym), Kind(SymAddr) {}
364 };
365
366 // finalizeContents() fills this vector with the section contents.
367 std::vector<Entry> Entries;
368
369public:
370 DynamicSection();
371 void finalizeContents() override;
372 void writeTo(uint8_t *Buf) override;
373 size_t getSize() const override { return Size; }
374
375private:
376 void addEntries();
377 void add(Entry E) { Entries.push_back(E); }
378 uint64_t Size = 0;
379};
380
381template <class ELFT> class RelocationSection final : public SyntheticSection {
382 typedef typename ELFT::Rel Elf_Rel;
383 typedef typename ELFT::Rela Elf_Rela;
384
385public:
386 RelocationSection(StringRef Name, bool Sort);
387 void addReloc(const DynamicReloc &Reloc);
388 unsigned getRelocOffset();
389 void finalizeContents() override;
390 void writeTo(uint8_t *Buf) override;
391 bool empty() const override { return Relocs.empty(); }
392 size_t getSize() const override { return Relocs.size() * this->Entsize; }
393 size_t getRelativeRelocCount() const { return NumRelativeRelocs; }
394
395private:
396 bool Sort;
397 size_t NumRelativeRelocs = 0;
398 std::vector<DynamicReloc> Relocs;
399};
400
401struct SymbolTableEntry {
402 SymbolBody *Symbol;
403 size_t StrTabOffset;
404};
405
406class SymbolTableBaseSection : public SyntheticSection {
407public:
408 SymbolTableBaseSection(StringTableSection &StrTabSec);
409 void finalizeContents() override;
410 void postThunkContents() override;
411 size_t getSize() const override { return getNumSymbols() * Entsize; }
412 void addSymbol(SymbolBody *Body);
413 unsigned getNumSymbols() const { return Symbols.size() + 1; }
414 size_t getSymbolIndex(SymbolBody *Body);
415 ArrayRef<SymbolTableEntry> getSymbols() const { return Symbols; }
416
417protected:
418 // A vector of symbols and their string table offsets.
419 std::vector<SymbolTableEntry> Symbols;
420
421 StringTableSection &StrTabSec;
422};
423
424template <class ELFT>
425class SymbolTableSection final : public SymbolTableBaseSection {
426 typedef typename ELFT::Sym Elf_Sym;
427
428public:
429 SymbolTableSection(StringTableSection &StrTabSec);
430 void writeTo(uint8_t *Buf) override;
431};
432
433// Outputs GNU Hash section. For detailed explanation see:
434// https://blogs.oracle.com/ali/entry/gnu_hash_elf_sections
435class GnuHashTableSection final : public SyntheticSection {
436public:
437 GnuHashTableSection();
438 void finalizeContents() override;
439 void writeTo(uint8_t *Buf) override;
440 size_t getSize() const override { return Size; }
441
442 // Adds symbols to the hash table.
443 // Sorts the input to satisfy GNU hash section requirements.
444 void addSymbols(std::vector<SymbolTableEntry> &Symbols);
445
446private:
447 size_t getShift2() const { return Config->Is64 ? 6 : 5; }
448
449 void writeBloomFilter(uint8_t *Buf);
450 void writeHashTable(uint8_t *Buf);
451
452 struct Entry {
453 SymbolBody *Body;
454 size_t StrTabOffset;
455 uint32_t Hash;
456 };
457
458 std::vector<Entry> Symbols;
459 size_t MaskWords;
460 size_t NBuckets = 0;
461 size_t Size = 0;
462};
463
464template <class ELFT> class HashTableSection final : public SyntheticSection {
465public:
466 HashTableSection();
467 void finalizeContents() override;
468 void writeTo(uint8_t *Buf) override;
469 size_t getSize() const override { return Size; }
470
471private:
472 size_t Size = 0;
473};
474
475// The PltSection is used for both the Plt and Iplt. The former always has a
476// header as its first entry that is used at run-time to resolve lazy binding.
477// The latter is used for GNU Ifunc symbols, that will be subject to a
478// Target->IRelativeRel.
479class PltSection : public SyntheticSection {
480public:
481 PltSection(size_t HeaderSize);
482 void writeTo(uint8_t *Buf) override;
483 size_t getSize() const override;
484 bool empty() const override { return Entries.empty(); }
485 void addSymbols();
486
487 template <class ELFT> void addEntry(SymbolBody &Sym);
488
489private:
490 void writeHeader(uint8_t *Buf){};
491 void addHeaderSymbols(){};
492 unsigned getPltRelocOff() const;
493 std::vector<std::pair<const SymbolBody *, unsigned>> Entries;
494 // Iplt always has HeaderSize of 0, the Plt HeaderSize is always non-zero
495 size_t HeaderSize;
496};
497
498class GdbIndexSection final : public SyntheticSection {
499 const unsigned OffsetTypeSize = 4;
500 const unsigned CuListOffset = 6 * OffsetTypeSize;
501 const unsigned CompilationUnitSize = 16;
502 const unsigned AddressEntrySize = 16 + OffsetTypeSize;
503 const unsigned SymTabEntrySize = 2 * OffsetTypeSize;
504
505public:
506 GdbIndexSection(std::vector<GdbIndexChunk> &&Chunks);
507 void finalizeContents() override;
508 void writeTo(uint8_t *Buf) override;
509 size_t getSize() const override;
510 bool empty() const override;
511
512 // Symbol table is a hash table for types and names.
513 // It is the area of gdb index.
514 GdbHashTab SymbolTable;
515
516 // CU vector is a part of constant pool area of section.
517 std::vector<std::set<uint32_t>> CuVectors;
518
519 // String pool is also a part of constant pool, it follows CU vectors.
520 llvm::StringTableBuilder StringPool;
521
522 // Each chunk contains information gathered from a debug sections of single
523 // object and used to build different areas of gdb index.
524 std::vector<GdbIndexChunk> Chunks;
525
526private:
527 void buildIndex();
528
529 uint32_t CuTypesOffset;
530 uint32_t SymTabOffset;
531 uint32_t ConstantPoolOffset;
532 uint32_t StringPoolOffset;
533
534 size_t CuVectorsSize = 0;
535 std::vector<size_t> CuVectorsOffset;
536
537 bool Finalized = false;
538};
539
540template <class ELFT> GdbIndexSection *createGdbIndex();
541
542// --eh-frame-hdr option tells linker to construct a header for all the
543// .eh_frame sections. This header is placed to a section named .eh_frame_hdr
544// and also to a PT_GNU_EH_FRAME segment.
545// At runtime the unwinder then can find all the PT_GNU_EH_FRAME segments by
546// calling dl_iterate_phdr.
547// This section contains a lookup table for quick binary search of FDEs.
548// Detailed info about internals can be found in Ian Lance Taylor's blog:
549// http://www.airs.com/blog/archives/460 (".eh_frame")
550// http://www.airs.com/blog/archives/462 (".eh_frame_hdr")
551template <class ELFT> class EhFrameHeader final : public SyntheticSection {
552public:
553 EhFrameHeader();
554 void writeTo(uint8_t *Buf) override;
555 size_t getSize() const override;
556 void addFde(uint32_t Pc, uint32_t FdeVA);
557 bool empty() const override;
558
559private:
560 struct FdeData {
561 uint32_t Pc;
562 uint32_t FdeVA;
563 };
564
565 std::vector<FdeData> Fdes;
566};
567
568// For more information about .gnu.version and .gnu.version_r see:
569// https://www.akkadia.org/drepper/symbol-versioning
570
571// The .gnu.version_d section which has a section type of SHT_GNU_verdef shall
572// contain symbol version definitions. The number of entries in this section
573// shall be contained in the DT_VERDEFNUM entry of the .dynamic section.
574// The section shall contain an array of Elf_Verdef structures, optionally
575// followed by an array of Elf_Verdaux structures.
576template <class ELFT>
577class VersionDefinitionSection final : public SyntheticSection {
578 typedef typename ELFT::Verdef Elf_Verdef;
579 typedef typename ELFT::Verdaux Elf_Verdaux;
580
581public:
582 VersionDefinitionSection();
583 void finalizeContents() override;
584 size_t getSize() const override;
585 void writeTo(uint8_t *Buf) override;
586
587private:
588 void writeOne(uint8_t *Buf, uint32_t Index, StringRef Name, size_t NameOff);
589
590 unsigned FileDefNameOff;
591};
592
593// The .gnu.version section specifies the required version of each symbol in the
594// dynamic symbol table. It contains one Elf_Versym for each dynamic symbol
595// table entry. An Elf_Versym is just a 16-bit integer that refers to a version
596// identifier defined in the either .gnu.version_r or .gnu.version_d section.
597// The values 0 and 1 are reserved. All other values are used for versions in
598// the own object or in any of the dependencies.
599template <class ELFT>
600class VersionTableSection final : public SyntheticSection {
601 typedef typename ELFT::Versym Elf_Versym;
602
603public:
604 VersionTableSection();
605 void finalizeContents() override;
606 size_t getSize() const override;
607 void writeTo(uint8_t *Buf) override;
608 bool empty() const override;
609};
610
611// The .gnu.version_r section defines the version identifiers used by
612// .gnu.version. It contains a linked list of Elf_Verneed data structures. Each
613// Elf_Verneed specifies the version requirements for a single DSO, and contains
614// a reference to a linked list of Elf_Vernaux data structures which define the
615// mapping from version identifiers to version names.
616template <class ELFT> class VersionNeedSection final : public SyntheticSection {
617 typedef typename ELFT::Verneed Elf_Verneed;
618 typedef typename ELFT::Vernaux Elf_Vernaux;
619
620 // A vector of shared files that need Elf_Verneed data structures and the
621 // string table offsets of their sonames.
622 std::vector<std::pair<SharedFile<ELFT> *, size_t>> Needed;
623
624 // The next available version identifier.
625 unsigned NextIndex;
626
627public:
628 VersionNeedSection();
629 void addSymbol(SharedSymbol *SS);
630 void finalizeContents() override;
631 void writeTo(uint8_t *Buf) override;
632 size_t getSize() const override;
633 size_t getNeedNum() const { return Needed.size(); }
634 bool empty() const override;
635};
636
637// MergeSyntheticSection is a class that allows us to put mergeable sections
638// with different attributes in a single output sections. To do that
639// we put them into MergeSyntheticSection synthetic input sections which are
640// attached to regular output sections.
641class MergeSyntheticSection final : public SyntheticSection {
642public:
643 MergeSyntheticSection(StringRef Name, uint32_t Type, uint64_t Flags,
644 uint32_t Alignment);
645 void addSection(MergeInputSection *MS);
646 void writeTo(uint8_t *Buf) override;
647 void finalizeContents() override;
648 bool shouldTailMerge() const;
649 size_t getSize() const override;
650
651private:
652 void finalizeTailMerge();
653 void finalizeNoTailMerge();
654
655 llvm::StringTableBuilder Builder;
656 std::vector<MergeInputSection *> Sections;
657};
658
659// .MIPS.abiflags section.
660template <class ELFT>
661class MipsAbiFlagsSection final : public SyntheticSection {
662 typedef llvm::object::Elf_Mips_ABIFlags<ELFT> Elf_Mips_ABIFlags;
663
664public:
665 static MipsAbiFlagsSection *create();
666
667 MipsAbiFlagsSection(Elf_Mips_ABIFlags Flags);
668 size_t getSize() const override { return sizeof(Elf_Mips_ABIFlags); }
669 void writeTo(uint8_t *Buf) override;
670
671private:
672 Elf_Mips_ABIFlags Flags;
673};
674
675// .MIPS.options section.
676template <class ELFT> class MipsOptionsSection final : public SyntheticSection {
677 typedef llvm::object::Elf_Mips_Options<ELFT> Elf_Mips_Options;
678 typedef llvm::object::Elf_Mips_RegInfo<ELFT> Elf_Mips_RegInfo;
679
680public:
681 static MipsOptionsSection *create();
682
683 MipsOptionsSection(Elf_Mips_RegInfo Reginfo);
684 void writeTo(uint8_t *Buf) override;
685
686 size_t getSize() const override {
687 return sizeof(Elf_Mips_Options) + sizeof(Elf_Mips_RegInfo);
688 }
689
690private:
691 Elf_Mips_RegInfo Reginfo;
692};
693
694// MIPS .reginfo section.
695template <class ELFT> class MipsReginfoSection final : public SyntheticSection {
696 typedef llvm::object::Elf_Mips_RegInfo<ELFT> Elf_Mips_RegInfo;
697
698public:
699 static MipsReginfoSection *create();
700
701 MipsReginfoSection(Elf_Mips_RegInfo Reginfo);
702 size_t getSize() const override { return sizeof(Elf_Mips_RegInfo); }
703 void writeTo(uint8_t *Buf) override;
704
705private:
706 Elf_Mips_RegInfo Reginfo;
707};
708
709// This is a MIPS specific section to hold a space within the data segment
710// of executable file which is pointed to by the DT_MIPS_RLD_MAP entry.
711// See "Dynamic section" in Chapter 5 in the following document:
712// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
713class MipsRldMapSection : public SyntheticSection {
714public:
715 MipsRldMapSection();
716 size_t getSize() const override { return Config->Wordsize; }
717 void writeTo(uint8_t *Buf) override {}
718};
719
720class ARMExidxSentinelSection : public SyntheticSection {
721public:
722 ARMExidxSentinelSection();
723 size_t getSize() const override { return 8; }
724 void writeTo(uint8_t *Buf) override;
725};
726
727// A container for one or more linker generated thunks. Instances of these
728// thunks including ARM interworking and Mips LA25 PI to non-PI thunks.
729class ThunkSection : public SyntheticSection {
730public:
731 // ThunkSection in OS, with desired OutSecOff of Off
732 ThunkSection(OutputSection *OS, uint64_t Off);
733
734 // Add a newly created Thunk to this container:
735 // Thunk is given offset from start of this InputSection
736 // Thunk defines a symbol in this InputSection that can be used as target
737 // of a relocation
738 void addThunk(Thunk *T);
739 size_t getSize() const override { return Size; }
740 void writeTo(uint8_t *Buf) override;
741 InputSection *getTargetInputSection() const;
742
743private:
744 std::vector<const Thunk *> Thunks;
745 size_t Size = 0;
746};
747
748template <class ELFT> InputSection *createCommonSection();
749InputSection *createInterpSection();
750template <class ELFT> MergeInputSection *createCommentSection();
751void decompressAndMergeSections();
752
753SymbolBody *addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value,
754 uint64_t Size, InputSectionBase *Section);
755
756// Linker generated sections which can be used as inputs.
757struct InX {
758 static InputSection *ARMAttributes;
759 static BssSection *Bss;
760 static BssSection *BssRelRo;
761 static BuildIdSection *BuildId;
762 static InputSection *Common;
763 static SyntheticSection *Dynamic;
764 static StringTableSection *DynStrTab;
765 static SymbolTableBaseSection *DynSymTab;
766 static GnuHashTableSection *GnuHashTab;
767 static InputSection *Interp;
768 static GdbIndexSection *GdbIndex;
769 static GotSection *Got;
770 static GotPltSection *GotPlt;
771 static IgotPltSection *IgotPlt;
772 static MipsGotSection *MipsGot;
773 static MipsRldMapSection *MipsRldMap;
774 static PltSection *Plt;
775 static PltSection *Iplt;
776 static StringTableSection *ShStrTab;
777 static StringTableSection *StrTab;
778 static SymbolTableBaseSection *SymTab;
779};
780
781template <class ELFT> struct In : public InX {
782 static EhFrameHeader<ELFT> *EhFrameHdr;
783 static EhFrameSection<ELFT> *EhFrame;
784 static HashTableSection<ELFT> *HashTab;
785 static RelocationSection<ELFT> *RelaDyn;
786 static RelocationSection<ELFT> *RelaPlt;
787 static RelocationSection<ELFT> *RelaIplt;
788 static VersionDefinitionSection<ELFT> *VerDef;
789 static VersionTableSection<ELFT> *VerSym;
790 static VersionNeedSection<ELFT> *VerNeed;
791};
792
793template <class ELFT> EhFrameHeader<ELFT> *In<ELFT>::EhFrameHdr;
794template <class ELFT> EhFrameSection<ELFT> *In<ELFT>::EhFrame;
795template <class ELFT> HashTableSection<ELFT> *In<ELFT>::HashTab;
796template <class ELFT> RelocationSection<ELFT> *In<ELFT>::RelaDyn;
797template <class ELFT> RelocationSection<ELFT> *In<ELFT>::RelaPlt;
798template <class ELFT> RelocationSection<ELFT> *In<ELFT>::RelaIplt;
799template <class ELFT> VersionDefinitionSection<ELFT> *In<ELFT>::VerDef;
800template <class ELFT> VersionTableSection<ELFT> *In<ELFT>::VerSym;
801template <class ELFT> VersionNeedSection<ELFT> *In<ELFT>::VerNeed;
802} // namespace elf
803} // namespace lld
804
805#endif
deps/lld/ELF/Target.cpp created+167
......@@ -0,0 +1,167 @@
1//===- Target.cpp ---------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Machine-specific things, such as applying relocations, creation of
11// GOT or PLT entries, etc., are handled in this file.
12//
13// Refer the ELF spec for the single letter variables, S, A or P, used
14// in this file.
15//
16// Some functions defined in this file has "relaxTls" as part of their names.
17// They do peephole optimization for TLS variables by rewriting instructions.
18// They are not part of the ABI but optional optimization, so you can skip
19// them if you are not interested in how TLS variables are optimized.
20// See the following paper for the details.
21//
22// Ulrich Drepper, ELF Handling For Thread-Local Storage
23// http://www.akkadia.org/drepper/tls.pdf
24//
25//===----------------------------------------------------------------------===//
26
27#include "Target.h"
28#include "Error.h"
29#include "InputFiles.h"
30#include "OutputSections.h"
31#include "SymbolTable.h"
32#include "Symbols.h"
33#include "llvm/Object/ELF.h"
34
35using namespace llvm;
36using namespace llvm::object;
37using namespace llvm::ELF;
38using namespace lld;
39using namespace lld::elf;
40
41TargetInfo *elf::Target;
42
43std::string lld::toString(uint32_t Type) {
44 StringRef S = getELFRelocationTypeName(elf::Config->EMachine, Type);
45 if (S == "Unknown")
46 return ("Unknown (" + Twine(Type) + ")").str();
47 return S;
48}
49
50TargetInfo *elf::getTarget() {
51 switch (Config->EMachine) {
52 case EM_386:
53 case EM_IAMCU:
54 return getX86TargetInfo();
55 case EM_AARCH64:
56 return getAArch64TargetInfo();
57 case EM_AMDGPU:
58 return getAMDGPUTargetInfo();
59 case EM_ARM:
60 return getARMTargetInfo();
61 case EM_AVR:
62 return getAVRTargetInfo();
63 case EM_MIPS:
64 switch (Config->EKind) {
65 case ELF32LEKind:
66 return getMipsTargetInfo<ELF32LE>();
67 case ELF32BEKind:
68 return getMipsTargetInfo<ELF32BE>();
69 case ELF64LEKind:
70 return getMipsTargetInfo<ELF64LE>();
71 case ELF64BEKind:
72 return getMipsTargetInfo<ELF64BE>();
73 default:
74 fatal("unsupported MIPS target");
75 }
76 case EM_PPC:
77 return getPPCTargetInfo();
78 case EM_PPC64:
79 return getPPC64TargetInfo();
80 case EM_SPARCV9:
81 return getSPARCV9TargetInfo();
82 case EM_X86_64:
83 if (Config->EKind == ELF32LEKind)
84 return getX32TargetInfo();
85 return getX86_64TargetInfo();
86 }
87 fatal("unknown target machine");
88}
89
90template <class ELFT> static std::string getErrorLoc(const uint8_t *Loc) {
91 for (InputSectionBase *D : InputSections) {
92 auto *IS = dyn_cast_or_null<InputSection>(D);
93 if (!IS || !IS->getParent())
94 continue;
95
96 uint8_t *ISLoc = IS->getParent()->Loc + IS->OutSecOff;
97 if (ISLoc <= Loc && Loc < ISLoc + IS->getSize())
98 return IS->template getLocation<ELFT>(Loc - ISLoc) + ": ";
99 }
100 return "";
101}
102
103std::string elf::getErrorLocation(const uint8_t *Loc) {
104 switch (Config->EKind) {
105 case ELF32LEKind:
106 return getErrorLoc<ELF32LE>(Loc);
107 case ELF32BEKind:
108 return getErrorLoc<ELF32BE>(Loc);
109 case ELF64LEKind:
110 return getErrorLoc<ELF64LE>(Loc);
111 case ELF64BEKind:
112 return getErrorLoc<ELF64BE>(Loc);
113 default:
114 llvm_unreachable("unknown ELF type");
115 }
116}
117
118TargetInfo::~TargetInfo() {}
119
120int64_t TargetInfo::getImplicitAddend(const uint8_t *Buf, uint32_t Type) const {
121 return 0;
122}
123
124bool TargetInfo::usesOnlyLowPageBits(uint32_t Type) const { return false; }
125
126bool TargetInfo::needsThunk(RelExpr Expr, uint32_t RelocType,
127 const InputFile *File, const SymbolBody &S) const {
128 return false;
129}
130
131bool TargetInfo::inBranchRange(uint32_t RelocType, uint64_t Src,
132 uint64_t Dst) const {
133 return true;
134}
135
136void TargetInfo::writeIgotPlt(uint8_t *Buf, const SymbolBody &S) const {
137 writeGotPlt(Buf, S);
138}
139
140RelExpr TargetInfo::adjustRelaxExpr(uint32_t Type, const uint8_t *Data,
141 RelExpr Expr) const {
142 return Expr;
143}
144
145void TargetInfo::relaxGot(uint8_t *Loc, uint64_t Val) const {
146 llvm_unreachable("Should not have claimed to be relaxable");
147}
148
149void TargetInfo::relaxTlsGdToLe(uint8_t *Loc, uint32_t Type,
150 uint64_t Val) const {
151 llvm_unreachable("Should not have claimed to be relaxable");
152}
153
154void TargetInfo::relaxTlsGdToIe(uint8_t *Loc, uint32_t Type,
155 uint64_t Val) const {
156 llvm_unreachable("Should not have claimed to be relaxable");
157}
158
159void TargetInfo::relaxTlsIeToLe(uint8_t *Loc, uint32_t Type,
160 uint64_t Val) const {
161 llvm_unreachable("Should not have claimed to be relaxable");
162}
163
164void TargetInfo::relaxTlsLdToLe(uint8_t *Loc, uint32_t Type,
165 uint64_t Val) const {
166 llvm_unreachable("Should not have claimed to be relaxable");
167}
deps/lld/ELF/Target.h created+162
......@@ -0,0 +1,162 @@
1//===- Target.h -------------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_ELF_TARGET_H
11#define LLD_ELF_TARGET_H
12
13#include "Error.h"
14#include "InputSection.h"
15#include "llvm/Object/ELF.h"
16
17namespace lld {
18std::string toString(uint32_t RelType);
19
20namespace elf {
21class InputFile;
22class SymbolBody;
23
24class TargetInfo {
25public:
26 virtual bool isPicRel(uint32_t Type) const { return true; }
27 virtual uint32_t getDynRel(uint32_t Type) const { return Type; }
28 virtual void writeGotPltHeader(uint8_t *Buf) const {}
29 virtual void writeGotPlt(uint8_t *Buf, const SymbolBody &S) const {};
30 virtual void writeIgotPlt(uint8_t *Buf, const SymbolBody &S) const;
31 virtual int64_t getImplicitAddend(const uint8_t *Buf, uint32_t Type) const;
32
33 // If lazy binding is supported, the first entry of the PLT has code
34 // to call the dynamic linker to resolve PLT entries the first time
35 // they are called. This function writes that code.
36 virtual void writePltHeader(uint8_t *Buf) const {}
37
38 virtual void writePlt(uint8_t *Buf, uint64_t GotEntryAddr,
39 uint64_t PltEntryAddr, int32_t Index,
40 unsigned RelOff) const {}
41 virtual void addPltHeaderSymbols(InputSectionBase *IS) const {}
42 virtual void addPltSymbols(InputSectionBase *IS, uint64_t Off) const {}
43 // Returns true if a relocation only uses the low bits of a value such that
44 // all those bits are in in the same page. For example, if the relocation
45 // only uses the low 12 bits in a system with 4k pages. If this is true, the
46 // bits will always have the same value at runtime and we don't have to emit
47 // a dynamic relocation.
48 virtual bool usesOnlyLowPageBits(uint32_t Type) const;
49
50 // Decide whether a Thunk is needed for the relocation from File
51 // targeting S.
52 virtual bool needsThunk(RelExpr Expr, uint32_t RelocType,
53 const InputFile *File, const SymbolBody &S) const;
54 // Return true if we can reach Dst from Src with Relocation RelocType
55 virtual bool inBranchRange(uint32_t RelocType, uint64_t Src,
56 uint64_t Dst) const;
57 virtual RelExpr getRelExpr(uint32_t Type, const SymbolBody &S,
58 const uint8_t *Loc) const = 0;
59 virtual void relocateOne(uint8_t *Loc, uint32_t Type, uint64_t Val) const = 0;
60 virtual ~TargetInfo();
61
62 unsigned TlsGdRelaxSkip = 1;
63 unsigned PageSize = 4096;
64 unsigned DefaultMaxPageSize = 4096;
65
66 // On FreeBSD x86_64 the first page cannot be mmaped.
67 // On Linux that is controled by vm.mmap_min_addr. At least on some x86_64
68 // installs that is 65536, so the first 15 pages cannot be used.
69 // Given that, the smallest value that can be used in here is 0x10000.
70 uint64_t DefaultImageBase = 0x10000;
71
72 // Offset of _GLOBAL_OFFSET_TABLE_ from base of .got section. Use -1 for
73 // end of .got
74 uint64_t GotBaseSymOff = 0;
75
76 uint32_t CopyRel;
77 uint32_t GotRel;
78 uint32_t PltRel;
79 uint32_t RelativeRel;
80 uint32_t IRelativeRel;
81 uint32_t TlsDescRel;
82 uint32_t TlsGotRel;
83 uint32_t TlsModuleIndexRel;
84 uint32_t TlsOffsetRel;
85 unsigned GotEntrySize = 0;
86 unsigned GotPltEntrySize = 0;
87 unsigned PltEntrySize;
88 unsigned PltHeaderSize;
89
90 // At least on x86_64 positions 1 and 2 are used by the first plt entry
91 // to support lazy loading.
92 unsigned GotPltHeaderEntriesNum = 3;
93
94 // Set to 0 for variant 2
95 unsigned TcbSize = 0;
96
97 bool NeedsThunks = false;
98
99 // A 4-byte field corresponding to one or more trap instructions, used to pad
100 // executable OutputSections.
101 uint32_t TrapInstr = 0;
102
103 virtual RelExpr adjustRelaxExpr(uint32_t Type, const uint8_t *Data,
104 RelExpr Expr) const;
105 virtual void relaxGot(uint8_t *Loc, uint64_t Val) const;
106 virtual void relaxTlsGdToIe(uint8_t *Loc, uint32_t Type, uint64_t Val) const;
107 virtual void relaxTlsGdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const;
108 virtual void relaxTlsIeToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const;
109 virtual void relaxTlsLdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const;
110};
111
112TargetInfo *getAArch64TargetInfo();
113TargetInfo *getAMDGPUTargetInfo();
114TargetInfo *getARMTargetInfo();
115TargetInfo *getAVRTargetInfo();
116TargetInfo *getPPC64TargetInfo();
117TargetInfo *getPPCTargetInfo();
118TargetInfo *getSPARCV9TargetInfo();
119TargetInfo *getX32TargetInfo();
120TargetInfo *getX86TargetInfo();
121TargetInfo *getX86_64TargetInfo();
122template <class ELFT> TargetInfo *getMipsTargetInfo();
123
124std::string getErrorLocation(const uint8_t *Loc);
125
126uint64_t getPPC64TocBase();
127uint64_t getAArch64Page(uint64_t Expr);
128
129extern TargetInfo *Target;
130TargetInfo *getTarget();
131
132template <unsigned N>
133static void checkInt(uint8_t *Loc, int64_t V, uint32_t Type) {
134 if (!llvm::isInt<N>(V))
135 error(getErrorLocation(Loc) + "relocation " + lld::toString(Type) +
136 " out of range");
137}
138
139template <unsigned N>
140static void checkUInt(uint8_t *Loc, uint64_t V, uint32_t Type) {
141 if (!llvm::isUInt<N>(V))
142 error(getErrorLocation(Loc) + "relocation " + lld::toString(Type) +
143 " out of range");
144}
145
146template <unsigned N>
147static void checkIntUInt(uint8_t *Loc, uint64_t V, uint32_t Type) {
148 if (!llvm::isInt<N>(V) && !llvm::isUInt<N>(V))
149 error(getErrorLocation(Loc) + "relocation " + lld::toString(Type) +
150 " out of range");
151}
152
153template <unsigned N>
154static void checkAlignment(uint8_t *Loc, uint64_t V, uint32_t Type) {
155 if ((V & (N - 1)) != 0)
156 error(getErrorLocation(Loc) + "improper alignment for relocation " +
157 lld::toString(Type));
158}
159} // namespace elf
160} // namespace lld
161
162#endif
deps/lld/ELF/Threads.h created+88
......@@ -0,0 +1,88 @@
1//===- Threads.h ------------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// LLD supports threads to distribute workloads to multiple cores. Using
11// multicore is most effective when more than one core are idle. At the
12// last step of a build, it is often the case that a linker is the only
13// active process on a computer. So, we are naturally interested in using
14// threads wisely to reduce latency to deliver results to users.
15//
16// That said, we don't want to do "too clever" things using threads.
17// Complex multi-threaded algorithms are sometimes extremely hard to
18// reason about and can easily mess up the entire design.
19//
20// Fortunately, when a linker links large programs (when the link time is
21// most critical), it spends most of the time to work on massive number of
22// small pieces of data of the same kind, and there are opportunities for
23// large parallelism there. Here are examples:
24//
25// - We have hundreds of thousands of input sections that need to be
26// copied to a result file at the last step of link. Once we fix a file
27// layout, each section can be copied to its destination and its
28// relocations can be applied independently.
29//
30// - We have tens of millions of small strings when constructing a
31// mergeable string section.
32//
33// For the cases such as the former, we can just use parallel_for_each
34// instead of std::for_each (or a plain for loop). Because tasks are
35// completely independent from each other, we can run them in parallel
36// without any coordination between them. That's very easy to understand
37// and reason about.
38//
39// For the cases such as the latter, we can use parallel algorithms to
40// deal with massive data. We have to write code for a tailored algorithm
41// for each problem, but the complexity of multi-threading is isolated in
42// a single pass and doesn't affect the linker's overall design.
43//
44// The above approach seems to be working fairly well. As an example, when
45// linking Chromium (output size 1.6 GB), using 4 cores reduces latency to
46// 75% compared to single core (from 12.66 seconds to 9.55 seconds) on my
47// Ivy Bridge Xeon 2.8 GHz machine. Using 40 cores reduces it to 63% (from
48// 12.66 seconds to 7.95 seconds). Because of the Amdahl's law, the
49// speedup is not linear, but as you add more cores, it gets faster.
50//
51// On a final note, if you are trying to optimize, keep the axiom "don't
52// guess, measure!" in mind. Some important passes of the linker are not
53// that slow. For example, resolving all symbols is not a very heavy pass,
54// although it would be very hard to parallelize it. You want to first
55// identify a slow pass and then optimize it.
56//
57//===----------------------------------------------------------------------===//
58
59#ifndef LLD_ELF_THREADS_H
60#define LLD_ELF_THREADS_H
61
62#include "Config.h"
63
64#include "llvm/Support/Parallel.h"
65#include <functional>
66
67namespace lld {
68namespace elf {
69
70template <class IterTy, class FuncTy>
71void parallelForEach(IterTy Begin, IterTy End, FuncTy Fn) {
72 if (Config->Threads)
73 for_each(llvm::parallel::par, Begin, End, Fn);
74 else
75 for_each(llvm::parallel::seq, Begin, End, Fn);
76}
77
78inline void parallelForEachN(size_t Begin, size_t End,
79 std::function<void(size_t)> Fn) {
80 if (Config->Threads)
81 for_each_n(llvm::parallel::par, Begin, End, Fn);
82 else
83 for_each_n(llvm::parallel::seq, Begin, End, Fn);
84}
85} // namespace elf
86} // namespace lld
87
88#endif
deps/lld/ELF/Thunks.cpp created+273
......@@ -0,0 +1,273 @@
1//===- Thunks.cpp --------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===---------------------------------------------------------------------===//
9//
10// This file contains Thunk subclasses.
11//
12// A thunk is a small piece of code written after an input section
13// which is used to jump between "incompatible" functions
14// such as MIPS PIC and non-PIC or ARM non-Thumb and Thumb functions.
15//
16// If a jump target is too far and its address doesn't fit to a
17// short jump instruction, we need to create a thunk too, but we
18// haven't supported it yet.
19//
20// i386 and x86-64 don't need thunks.
21//
22//===---------------------------------------------------------------------===//
23
24#include "Thunks.h"
25#include "Config.h"
26#include "Error.h"
27#include "InputSection.h"
28#include "Memory.h"
29#include "OutputSections.h"
30#include "Symbols.h"
31#include "SyntheticSections.h"
32#include "Target.h"
33#include "llvm/BinaryFormat/ELF.h"
34#include "llvm/Support/Casting.h"
35#include "llvm/Support/Endian.h"
36#include "llvm/Support/ErrorHandling.h"
37#include "llvm/Support/MathExtras.h"
38#include <cstdint>
39#include <cstring>
40
41using namespace llvm;
42using namespace llvm::object;
43using namespace llvm::support::endian;
44using namespace llvm::ELF;
45
46namespace lld {
47namespace elf {
48
49namespace {
50
51// Specific ARM Thunk implementations. The naming convention is:
52// Source State, TargetState, Target Requirement, ABS or PI, Range
53class ARMV7ABSLongThunk final : public Thunk {
54public:
55 ARMV7ABSLongThunk(const SymbolBody &Dest) : Thunk(Dest) {}
56
57 uint32_t size() const override { return 12; }
58 void writeTo(uint8_t *Buf, ThunkSection &IS) const override;
59 void addSymbols(ThunkSection &IS) override;
60 bool isCompatibleWith(uint32_t RelocType) const override;
61};
62
63class ARMV7PILongThunk final : public Thunk {
64public:
65 ARMV7PILongThunk(const SymbolBody &Dest) : Thunk(Dest) {}
66
67 uint32_t size() const override { return 16; }
68 void writeTo(uint8_t *Buf, ThunkSection &IS) const override;
69 void addSymbols(ThunkSection &IS) override;
70 bool isCompatibleWith(uint32_t RelocType) const override;
71};
72
73class ThumbV7ABSLongThunk final : public Thunk {
74public:
75 ThumbV7ABSLongThunk(const SymbolBody &Dest) : Thunk(Dest) { Alignment = 2; }
76
77 uint32_t size() const override { return 10; }
78 void writeTo(uint8_t *Buf, ThunkSection &IS) const override;
79 void addSymbols(ThunkSection &IS) override;
80 bool isCompatibleWith(uint32_t RelocType) const override;
81};
82
83class ThumbV7PILongThunk final : public Thunk {
84public:
85 ThumbV7PILongThunk(const SymbolBody &Dest) : Thunk(Dest) { Alignment = 2; }
86
87 uint32_t size() const override { return 12; }
88 void writeTo(uint8_t *Buf, ThunkSection &IS) const override;
89 void addSymbols(ThunkSection &IS) override;
90 bool isCompatibleWith(uint32_t RelocType) const override;
91};
92
93// MIPS LA25 thunk
94class MipsThunk final : public Thunk {
95public:
96 MipsThunk(const SymbolBody &Dest) : Thunk(Dest) {}
97
98 uint32_t size() const override { return 16; }
99 void writeTo(uint8_t *Buf, ThunkSection &IS) const override;
100 void addSymbols(ThunkSection &IS) override;
101 InputSection *getTargetInputSection() const override;
102};
103
104} // end anonymous namespace
105
106// ARM Target Thunks
107static uint64_t getARMThunkDestVA(const SymbolBody &S) {
108 uint64_t V = S.isInPlt() ? S.getPltVA() : S.getVA();
109 return SignExtend64<32>(V);
110}
111
112void ARMV7ABSLongThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const {
113 const uint8_t Data[] = {
114 0x00, 0xc0, 0x00, 0xe3, // movw ip,:lower16:S
115 0x00, 0xc0, 0x40, 0xe3, // movt ip,:upper16:S
116 0x1c, 0xff, 0x2f, 0xe1, // bx ip
117 };
118 uint64_t S = getARMThunkDestVA(Destination);
119 memcpy(Buf, Data, sizeof(Data));
120 Target->relocateOne(Buf, R_ARM_MOVW_ABS_NC, S);
121 Target->relocateOne(Buf + 4, R_ARM_MOVT_ABS, S);
122}
123
124void ARMV7ABSLongThunk::addSymbols(ThunkSection &IS) {
125 ThunkSym = addSyntheticLocal(
126 Saver.save("__ARMv7ABSLongThunk_" + Destination.getName()), STT_FUNC,
127 Offset, size(), &IS);
128 addSyntheticLocal("$a", STT_NOTYPE, Offset, 0, &IS);
129}
130
131bool ARMV7ABSLongThunk::isCompatibleWith(uint32_t RelocType) const {
132 // Thumb branch relocations can't use BLX
133 return RelocType != R_ARM_THM_JUMP19 && RelocType != R_ARM_THM_JUMP24;
134}
135
136void ThumbV7ABSLongThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const {
137 const uint8_t Data[] = {
138 0x40, 0xf2, 0x00, 0x0c, // movw ip, :lower16:S
139 0xc0, 0xf2, 0x00, 0x0c, // movt ip, :upper16:S
140 0x60, 0x47, // bx ip
141 };
142 uint64_t S = getARMThunkDestVA(Destination);
143 memcpy(Buf, Data, sizeof(Data));
144 Target->relocateOne(Buf, R_ARM_THM_MOVW_ABS_NC, S);
145 Target->relocateOne(Buf + 4, R_ARM_THM_MOVT_ABS, S);
146}
147
148void ThumbV7ABSLongThunk::addSymbols(ThunkSection &IS) {
149 ThunkSym = addSyntheticLocal(
150 Saver.save("__Thumbv7ABSLongThunk_" + Destination.getName()), STT_FUNC,
151 Offset | 0x1, size(), &IS);
152 addSyntheticLocal("$t", STT_NOTYPE, Offset, 0, &IS);
153}
154
155bool ThumbV7ABSLongThunk::isCompatibleWith(uint32_t RelocType) const {
156 // ARM branch relocations can't use BLX
157 return RelocType != R_ARM_JUMP24 && RelocType != R_ARM_PC24 &&
158 RelocType != R_ARM_PLT32;
159}
160
161void ARMV7PILongThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const {
162 const uint8_t Data[] = {
163 0xf0, 0xcf, 0x0f, 0xe3, // P: movw ip,:lower16:S - (P + (L1-P) +8)
164 0x00, 0xc0, 0x40, 0xe3, // movt ip,:upper16:S - (P + (L1-P+4) +8)
165 0x0f, 0xc0, 0x8c, 0xe0, // L1: add ip, ip, pc
166 0x1c, 0xff, 0x2f, 0xe1, // bx r12
167 };
168 uint64_t S = getARMThunkDestVA(Destination);
169 uint64_t P = ThunkSym->getVA();
170 memcpy(Buf, Data, sizeof(Data));
171 Target->relocateOne(Buf, R_ARM_MOVW_PREL_NC, S - P - 16);
172 Target->relocateOne(Buf + 4, R_ARM_MOVT_PREL, S - P - 12);
173}
174
175void ARMV7PILongThunk::addSymbols(ThunkSection &IS) {
176 ThunkSym = addSyntheticLocal(
177 Saver.save("__ARMV7PILongThunk_" + Destination.getName()), STT_FUNC,
178 Offset, size(), &IS);
179 addSyntheticLocal("$a", STT_NOTYPE, Offset, 0, &IS);
180}
181
182bool ARMV7PILongThunk::isCompatibleWith(uint32_t RelocType) const {
183 // Thumb branch relocations can't use BLX
184 return RelocType != R_ARM_THM_JUMP19 && RelocType != R_ARM_THM_JUMP24;
185}
186
187void ThumbV7PILongThunk::writeTo(uint8_t *Buf, ThunkSection &IS) const {
188 const uint8_t Data[] = {
189 0x4f, 0xf6, 0xf4, 0x7c, // P: movw ip,:lower16:S - (P + (L1-P) + 4)
190 0xc0, 0xf2, 0x00, 0x0c, // movt ip,:upper16:S - (P + (L1-P+4) + 4)
191 0xfc, 0x44, // L1: add r12, pc
192 0x60, 0x47, // bx r12
193 };
194 uint64_t S = getARMThunkDestVA(Destination);
195 uint64_t P = ThunkSym->getVA() & ~0x1;
196 memcpy(Buf, Data, sizeof(Data));
197 Target->relocateOne(Buf, R_ARM_THM_MOVW_PREL_NC, S - P - 12);
198 Target->relocateOne(Buf + 4, R_ARM_THM_MOVT_PREL, S - P - 8);
199}
200
201void ThumbV7PILongThunk::addSymbols(ThunkSection &IS) {
202 ThunkSym = addSyntheticLocal(
203 Saver.save("__ThumbV7PILongThunk_" + Destination.getName()), STT_FUNC,
204 Offset | 0x1, size(), &IS);
205 addSyntheticLocal("$t", STT_NOTYPE, Offset, 0, &IS);
206}
207
208bool ThumbV7PILongThunk::isCompatibleWith(uint32_t RelocType) const {
209 // ARM branch relocations can't use BLX
210 return RelocType != R_ARM_JUMP24 && RelocType != R_ARM_PC24 &&
211 RelocType != R_ARM_PLT32;
212}
213
214// Write MIPS LA25 thunk code to call PIC function from the non-PIC one.
215void MipsThunk::writeTo(uint8_t *Buf, ThunkSection &) const {
216 uint64_t S = Destination.getVA();
217 write32(Buf, 0x3c190000, Config->Endianness); // lui $25, %hi(func)
218 write32(Buf + 4, 0x08000000 | (S >> 2), Config->Endianness); // j func
219 write32(Buf + 8, 0x27390000, Config->Endianness); // addiu $25, $25, %lo(func)
220 write32(Buf + 12, 0x00000000, Config->Endianness); // nop
221 Target->relocateOne(Buf, R_MIPS_HI16, S);
222 Target->relocateOne(Buf + 8, R_MIPS_LO16, S);
223}
224
225void MipsThunk::addSymbols(ThunkSection &IS) {
226 ThunkSym =
227 addSyntheticLocal(Saver.save("__LA25Thunk_" + Destination.getName()),
228 STT_FUNC, Offset, size(), &IS);
229}
230
231InputSection *MipsThunk::getTargetInputSection() const {
232 auto *DR = dyn_cast<DefinedRegular>(&Destination);
233 return dyn_cast<InputSection>(DR->Section);
234}
235
236Thunk::Thunk(const SymbolBody &D) : Destination(D), Offset(0) {}
237
238Thunk::~Thunk() = default;
239
240// Creates a thunk for Thumb-ARM interworking.
241static Thunk *addThunkArm(uint32_t Reloc, SymbolBody &S) {
242 // ARM relocations need ARM to Thumb interworking Thunks.
243 // Thumb relocations need Thumb to ARM relocations.
244 // Use position independent Thunks if we require position independent code.
245 switch (Reloc) {
246 case R_ARM_PC24:
247 case R_ARM_PLT32:
248 case R_ARM_JUMP24:
249 if (Config->Pic)
250 return make<ARMV7PILongThunk>(S);
251 return make<ARMV7ABSLongThunk>(S);
252 case R_ARM_THM_JUMP19:
253 case R_ARM_THM_JUMP24:
254 if (Config->Pic)
255 return make<ThumbV7PILongThunk>(S);
256 return make<ThumbV7ABSLongThunk>(S);
257 }
258 fatal("unrecognized relocation type");
259}
260
261static Thunk *addThunkMips(SymbolBody &S) { return make<MipsThunk>(S); }
262
263Thunk *addThunk(uint32_t RelocType, SymbolBody &S) {
264 if (Config->EMachine == EM_ARM)
265 return addThunkArm(RelocType, S);
266 else if (Config->EMachine == EM_MIPS)
267 return addThunkMips(S);
268 llvm_unreachable("add Thunk only supported for ARM and Mips");
269 return nullptr;
270}
271
272} // end namespace elf
273} // end namespace lld
deps/lld/ELF/Thunks.h created+63
......@@ -0,0 +1,63 @@
1//===- Thunks.h --------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_ELF_THUNKS_H
11#define LLD_ELF_THUNKS_H
12
13#include "Relocations.h"
14
15namespace lld {
16namespace elf {
17class SymbolBody;
18class ThunkSection;
19// Class to describe an instance of a Thunk.
20// A Thunk is a code-sequence inserted by the linker in between a caller and
21// the callee. The relocation to the callee is redirected to the Thunk, which
22// after executing transfers control to the callee. Typical uses of Thunks
23// include transferring control from non-pi to pi and changing state on
24// targets like ARM.
25//
26// Thunks can be created for DefinedRegular, Shared and Undefined Symbols.
27// Thunks are assigned to synthetic ThunkSections
28class Thunk {
29public:
30 Thunk(const SymbolBody &Destination);
31 virtual ~Thunk();
32
33 virtual uint32_t size() const { return 0; }
34 virtual void writeTo(uint8_t *Buf, ThunkSection &IS) const {}
35
36 // All Thunks must define at least one symbol ThunkSym so that we can
37 // redirect relocations to it.
38 virtual void addSymbols(ThunkSection &IS) {}
39
40 // Some Thunks must be placed immediately before their Target as they elide
41 // a branch and fall through to the first Symbol in the Target.
42 virtual InputSection *getTargetInputSection() const { return nullptr; }
43
44 // To reuse a Thunk the caller as identified by the RelocType must be
45 // compatible with it.
46 virtual bool isCompatibleWith(uint32_t RelocType) const { return true; }
47
48 // The alignment requirement for this Thunk, defaults to the size of the
49 // typical code section alignment.
50 const SymbolBody &Destination;
51 SymbolBody *ThunkSym;
52 uint64_t Offset;
53 uint32_t Alignment = 4;
54};
55
56// For a Relocation to symbol S create a Thunk to be added to a synthetic
57// ThunkSection. At present there are implementations for ARM and Mips Thunks.
58Thunk *addThunk(uint32_t RelocType, SymbolBody &S);
59
60} // namespace elf
61} // namespace lld
62
63#endif
deps/lld/ELF/Writer.cpp created+1913
......@@ -0,0 +1,1913 @@
1//===- Writer.cpp ---------------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "Writer.h"
11#include "Config.h"
12#include "Filesystem.h"
13#include "LinkerScript.h"
14#include "MapFile.h"
15#include "Memory.h"
16#include "OutputSections.h"
17#include "Relocations.h"
18#include "Strings.h"
19#include "SymbolTable.h"
20#include "SyntheticSections.h"
21#include "Target.h"
22#include "Threads.h"
23#include "llvm/ADT/StringMap.h"
24#include "llvm/ADT/StringSwitch.h"
25#include "llvm/Support/FileOutputBuffer.h"
26#include "llvm/Support/raw_ostream.h"
27#include <climits>
28
29using namespace llvm;
30using namespace llvm::ELF;
31using namespace llvm::object;
32using namespace llvm::support;
33using namespace llvm::support::endian;
34
35using namespace lld;
36using namespace lld::elf;
37
38namespace {
39// The writer writes a SymbolTable result to a file.
40template <class ELFT> class Writer {
41public:
42 typedef typename ELFT::Shdr Elf_Shdr;
43 typedef typename ELFT::Ehdr Elf_Ehdr;
44 typedef typename ELFT::Phdr Elf_Phdr;
45
46 void run();
47
48private:
49 void clearOutputSections();
50 void createSyntheticSections();
51 void copyLocalSymbols();
52 void addSectionSymbols();
53 void addReservedSymbols();
54 void createSections();
55 void forEachRelSec(std::function<void(InputSectionBase &)> Fn);
56 void sortSections();
57 void finalizeSections();
58 void addPredefinedSections();
59
60 std::vector<PhdrEntry> createPhdrs();
61 void removeEmptyPTLoad();
62 void addPtArmExid(std::vector<PhdrEntry> &Phdrs);
63 void assignFileOffsets();
64 void assignFileOffsetsBinary();
65 void setPhdrs();
66 void fixSectionAlignments();
67 void fixPredefinedSymbols();
68 void openFile();
69 void writeHeader();
70 void writeSections();
71 void writeSectionsBinary();
72 void writeBuildId();
73
74 std::unique_ptr<FileOutputBuffer> Buffer;
75
76 OutputSectionFactory Factory;
77
78 void addRelIpltSymbols();
79 void addStartEndSymbols();
80 void addStartStopSymbols(OutputSection *Sec);
81 uint64_t getEntryAddr();
82 OutputSection *findSectionInScript(StringRef Name);
83 OutputSectionCommand *findSectionCommand(StringRef Name);
84
85 std::vector<PhdrEntry> Phdrs;
86
87 uint64_t FileSize;
88 uint64_t SectionHeaderOff;
89
90 bool HasGotBaseSym = false;
91};
92} // anonymous namespace
93
94StringRef elf::getOutputSectionName(StringRef Name) {
95 // ".zdebug_" is a prefix for ZLIB-compressed sections.
96 // Because we decompressed input sections, we want to remove 'z'.
97 if (Name.startswith(".zdebug_"))
98 return Saver.save("." + Name.substr(2));
99
100 if (Config->Relocatable)
101 return Name;
102
103 for (StringRef V :
104 {".text.", ".rodata.", ".data.rel.ro.", ".data.", ".bss.rel.ro.",
105 ".bss.", ".init_array.", ".fini_array.", ".ctors.", ".dtors.", ".tbss.",
106 ".gcc_except_table.", ".tdata.", ".ARM.exidx.", ".ARM.extab."}) {
107 StringRef Prefix = V.drop_back();
108 if (Name.startswith(V) || Name == Prefix)
109 return Prefix;
110 }
111
112 // CommonSection is identified as "COMMON" in linker scripts.
113 // By default, it should go to .bss section.
114 if (Name == "COMMON")
115 return ".bss";
116
117 return Name;
118}
119
120template <class ELFT> static bool needsInterpSection() {
121 return !Symtab<ELFT>::X->getSharedFiles().empty() &&
122 !Config->DynamicLinker.empty() && !Script->ignoreInterpSection();
123}
124
125template <class ELFT> void elf::writeResult() { Writer<ELFT>().run(); }
126
127template <class ELFT> void Writer<ELFT>::removeEmptyPTLoad() {
128 auto I = std::remove_if(Phdrs.begin(), Phdrs.end(), [&](const PhdrEntry &P) {
129 if (P.p_type != PT_LOAD)
130 return false;
131 if (!P.First)
132 return true;
133 uint64_t Size = P.Last->Addr + P.Last->Size - P.First->Addr;
134 return Size == 0;
135 });
136 Phdrs.erase(I, Phdrs.end());
137}
138
139template <class ELFT> static void combineEhFrameSections() {
140 for (InputSectionBase *&S : InputSections) {
141 EhInputSection *ES = dyn_cast<EhInputSection>(S);
142 if (!ES || !ES->Live)
143 continue;
144
145 In<ELFT>::EhFrame->addSection(ES);
146 S = nullptr;
147 }
148
149 std::vector<InputSectionBase *> &V = InputSections;
150 V.erase(std::remove(V.begin(), V.end(), nullptr), V.end());
151}
152
153template <class ELFT> void Writer<ELFT>::clearOutputSections() {
154 // Clear the OutputSections to make sure it is not used anymore. Any
155 // code from this point on should be using the linker script
156 // commands.
157 for (OutputSection *Sec : OutputSections)
158 Sec->Sections.clear();
159 OutputSections.clear();
160}
161
162// The main function of the writer.
163template <class ELFT> void Writer<ELFT>::run() {
164 // Create linker-synthesized sections such as .got or .plt.
165 // Such sections are of type input section.
166 createSyntheticSections();
167
168 if (!Config->Relocatable)
169 combineEhFrameSections<ELFT>();
170
171 // We need to create some reserved symbols such as _end. Create them.
172 if (!Config->Relocatable)
173 addReservedSymbols();
174
175 // Create output sections.
176 if (Script->Opt.HasSections) {
177 // If linker script contains SECTIONS commands, let it create sections.
178 Script->processCommands(Factory);
179
180 // Linker scripts may have left some input sections unassigned.
181 // Assign such sections using the default rule.
182 Script->addOrphanSections(Factory);
183 } else {
184 // If linker script does not contain SECTIONS commands, create
185 // output sections by default rules. We still need to give the
186 // linker script a chance to run, because it might contain
187 // non-SECTIONS commands such as ASSERT.
188 Script->processCommands(Factory);
189 createSections();
190 }
191 clearOutputSections();
192
193 if (Config->Discard != DiscardPolicy::All)
194 copyLocalSymbols();
195
196 if (Config->CopyRelocs)
197 addSectionSymbols();
198
199 // Now that we have a complete set of output sections. This function
200 // completes section contents. For example, we need to add strings
201 // to the string table, and add entries to .got and .plt.
202 // finalizeSections does that.
203 finalizeSections();
204 if (ErrorCount)
205 return;
206
207 if (!Script->Opt.HasSections && !Config->Relocatable)
208 fixSectionAlignments();
209
210 // If -compressed-debug-sections is specified, we need to compress
211 // .debug_* sections. Do it right now because it changes the size of
212 // output sections.
213 parallelForEach(
214 OutputSectionCommands.begin(), OutputSectionCommands.end(),
215 [](OutputSectionCommand *Cmd) { Cmd->maybeCompress<ELFT>(); });
216
217 Script->assignAddresses();
218 Script->allocateHeaders(Phdrs);
219
220 // Remove empty PT_LOAD to avoid causing the dynamic linker to try to mmap a
221 // 0 sized region. This has to be done late since only after assignAddresses
222 // we know the size of the sections.
223 removeEmptyPTLoad();
224
225 if (!Config->OFormatBinary)
226 assignFileOffsets();
227 else
228 assignFileOffsetsBinary();
229
230 setPhdrs();
231
232 if (Config->Relocatable) {
233 for (OutputSectionCommand *Cmd : OutputSectionCommands)
234 Cmd->Sec->Addr = 0;
235 } else {
236 fixPredefinedSymbols();
237 }
238
239 // It does not make sense try to open the file if we have error already.
240 if (ErrorCount)
241 return;
242 // Write the result down to a file.
243 openFile();
244 if (ErrorCount)
245 return;
246
247 if (!Config->OFormatBinary) {
248 writeHeader();
249 writeSections();
250 } else {
251 writeSectionsBinary();
252 }
253
254 // Backfill .note.gnu.build-id section content. This is done at last
255 // because the content is usually a hash value of the entire output file.
256 writeBuildId();
257 if (ErrorCount)
258 return;
259
260 // Handle -Map option.
261 writeMapFile<ELFT>(OutputSectionCommands);
262 if (ErrorCount)
263 return;
264
265 if (auto EC = Buffer->commit())
266 error("failed to write to the output file: " + EC.message());
267
268 // Flush the output streams and exit immediately. A full shutdown
269 // is a good test that we are keeping track of all allocated memory,
270 // but actually freeing it is a waste of time in a regular linker run.
271 if (Config->ExitEarly)
272 exitLld(0);
273}
274
275// Initialize Out members.
276template <class ELFT> void Writer<ELFT>::createSyntheticSections() {
277 // Initialize all pointers with NULL. This is needed because
278 // you can call lld::elf::main more than once as a library.
279 memset(&Out::First, 0, sizeof(Out));
280
281 auto Add = [](InputSectionBase *Sec) { InputSections.push_back(Sec); };
282
283 InX::DynStrTab = make<StringTableSection>(".dynstr", true);
284 InX::Dynamic = make<DynamicSection<ELFT>>();
285 In<ELFT>::RelaDyn = make<RelocationSection<ELFT>>(
286 Config->IsRela ? ".rela.dyn" : ".rel.dyn", Config->ZCombreloc);
287 InX::ShStrTab = make<StringTableSection>(".shstrtab", false);
288
289 Out::ElfHeader = make<OutputSection>("", 0, SHF_ALLOC);
290 Out::ElfHeader->Size = sizeof(Elf_Ehdr);
291 Out::ProgramHeaders = make<OutputSection>("", 0, SHF_ALLOC);
292 Out::ProgramHeaders->updateAlignment(Config->Wordsize);
293
294 if (needsInterpSection<ELFT>()) {
295 InX::Interp = createInterpSection();
296 Add(InX::Interp);
297 } else {
298 InX::Interp = nullptr;
299 }
300
301 if (Config->Strip != StripPolicy::All) {
302 InX::StrTab = make<StringTableSection>(".strtab", false);
303 InX::SymTab = make<SymbolTableSection<ELFT>>(*InX::StrTab);
304 }
305
306 if (Config->BuildId != BuildIdKind::None) {
307 InX::BuildId = make<BuildIdSection>();
308 Add(InX::BuildId);
309 }
310
311 InX::Common = createCommonSection<ELFT>();
312 if (InX::Common)
313 Add(InX::Common);
314
315 InX::Bss = make<BssSection>(".bss");
316 Add(InX::Bss);
317 InX::BssRelRo = make<BssSection>(".bss.rel.ro");
318 Add(InX::BssRelRo);
319
320 // Add MIPS-specific sections.
321 bool HasDynSymTab = !Symtab<ELFT>::X->getSharedFiles().empty() ||
322 Config->Pic || Config->ExportDynamic;
323 if (Config->EMachine == EM_MIPS) {
324 if (!Config->Shared && HasDynSymTab) {
325 InX::MipsRldMap = make<MipsRldMapSection>();
326 Add(InX::MipsRldMap);
327 }
328 if (auto *Sec = MipsAbiFlagsSection<ELFT>::create())
329 Add(Sec);
330 if (auto *Sec = MipsOptionsSection<ELFT>::create())
331 Add(Sec);
332 if (auto *Sec = MipsReginfoSection<ELFT>::create())
333 Add(Sec);
334 }
335
336 if (HasDynSymTab) {
337 InX::DynSymTab = make<SymbolTableSection<ELFT>>(*InX::DynStrTab);
338 Add(InX::DynSymTab);
339
340 In<ELFT>::VerSym = make<VersionTableSection<ELFT>>();
341 Add(In<ELFT>::VerSym);
342
343 if (!Config->VersionDefinitions.empty()) {
344 In<ELFT>::VerDef = make<VersionDefinitionSection<ELFT>>();
345 Add(In<ELFT>::VerDef);
346 }
347
348 In<ELFT>::VerNeed = make<VersionNeedSection<ELFT>>();
349 Add(In<ELFT>::VerNeed);
350
351 if (Config->GnuHash) {
352 InX::GnuHashTab = make<GnuHashTableSection>();
353 Add(InX::GnuHashTab);
354 }
355
356 if (Config->SysvHash) {
357 In<ELFT>::HashTab = make<HashTableSection<ELFT>>();
358 Add(In<ELFT>::HashTab);
359 }
360
361 Add(InX::Dynamic);
362 Add(InX::DynStrTab);
363 Add(In<ELFT>::RelaDyn);
364 }
365
366 // Add .got. MIPS' .got is so different from the other archs,
367 // it has its own class.
368 if (Config->EMachine == EM_MIPS) {
369 InX::MipsGot = make<MipsGotSection>();
370 Add(InX::MipsGot);
371 } else {
372 InX::Got = make<GotSection>();
373 Add(InX::Got);
374 }
375
376 InX::GotPlt = make<GotPltSection>();
377 Add(InX::GotPlt);
378 InX::IgotPlt = make<IgotPltSection>();
379 Add(InX::IgotPlt);
380
381 if (Config->GdbIndex) {
382 InX::GdbIndex = createGdbIndex<ELFT>();
383 Add(InX::GdbIndex);
384 }
385
386 // We always need to add rel[a].plt to output if it has entries.
387 // Even for static linking it can contain R_[*]_IRELATIVE relocations.
388 In<ELFT>::RelaPlt = make<RelocationSection<ELFT>>(
389 Config->IsRela ? ".rela.plt" : ".rel.plt", false /*Sort*/);
390 Add(In<ELFT>::RelaPlt);
391
392 // The RelaIplt immediately follows .rel.plt (.rel.dyn for ARM) to ensure
393 // that the IRelative relocations are processed last by the dynamic loader
394 In<ELFT>::RelaIplt = make<RelocationSection<ELFT>>(
395 (Config->EMachine == EM_ARM) ? ".rel.dyn" : In<ELFT>::RelaPlt->Name,
396 false /*Sort*/);
397 Add(In<ELFT>::RelaIplt);
398
399 InX::Plt = make<PltSection>(Target->PltHeaderSize);
400 Add(InX::Plt);
401 InX::Iplt = make<PltSection>(0);
402 Add(InX::Iplt);
403
404 if (!Config->Relocatable) {
405 if (Config->EhFrameHdr) {
406 In<ELFT>::EhFrameHdr = make<EhFrameHeader<ELFT>>();
407 Add(In<ELFT>::EhFrameHdr);
408 }
409 In<ELFT>::EhFrame = make<EhFrameSection<ELFT>>();
410 Add(In<ELFT>::EhFrame);
411 }
412
413 if (InX::SymTab)
414 Add(InX::SymTab);
415 Add(InX::ShStrTab);
416 if (InX::StrTab)
417 Add(InX::StrTab);
418}
419
420static bool shouldKeepInSymtab(SectionBase *Sec, StringRef SymName,
421 const SymbolBody &B) {
422 if (B.isFile() || B.isSection())
423 return false;
424
425 // If sym references a section in a discarded group, don't keep it.
426 if (Sec == &InputSection::Discarded)
427 return false;
428
429 if (Config->Discard == DiscardPolicy::None)
430 return true;
431
432 // In ELF assembly .L symbols are normally discarded by the assembler.
433 // If the assembler fails to do so, the linker discards them if
434 // * --discard-locals is used.
435 // * The symbol is in a SHF_MERGE section, which is normally the reason for
436 // the assembler keeping the .L symbol.
437 if (!SymName.startswith(".L") && !SymName.empty())
438 return true;
439
440 if (Config->Discard == DiscardPolicy::Locals)
441 return false;
442
443 return !Sec || !(Sec->Flags & SHF_MERGE);
444}
445
446static bool includeInSymtab(const SymbolBody &B) {
447 if (!B.isLocal() && !B.symbol()->IsUsedInRegularObj)
448 return false;
449
450 if (auto *D = dyn_cast<DefinedRegular>(&B)) {
451 // Always include absolute symbols.
452 SectionBase *Sec = D->Section;
453 if (!Sec)
454 return true;
455 if (auto *IS = dyn_cast<InputSectionBase>(Sec)) {
456 Sec = IS->Repl;
457 IS = cast<InputSectionBase>(Sec);
458 // Exclude symbols pointing to garbage-collected sections.
459 if (!IS->Live)
460 return false;
461 }
462 if (auto *S = dyn_cast<MergeInputSection>(Sec))
463 if (!S->getSectionPiece(D->Value)->Live)
464 return false;
465 }
466 return true;
467}
468
469// Local symbols are not in the linker's symbol table. This function scans
470// each object file's symbol table to copy local symbols to the output.
471template <class ELFT> void Writer<ELFT>::copyLocalSymbols() {
472 if (!InX::SymTab)
473 return;
474 for (elf::ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles()) {
475 for (SymbolBody *B : F->getLocalSymbols()) {
476 if (!B->IsLocal)
477 fatal(toString(F) +
478 ": broken object: getLocalSymbols returns a non-local symbol");
479 auto *DR = dyn_cast<DefinedRegular>(B);
480
481 // No reason to keep local undefined symbol in symtab.
482 if (!DR)
483 continue;
484 if (!includeInSymtab(*B))
485 continue;
486
487 SectionBase *Sec = DR->Section;
488 if (!shouldKeepInSymtab(Sec, B->getName(), *B))
489 continue;
490 InX::SymTab->addSymbol(B);
491 }
492 }
493}
494
495template <class ELFT> void Writer<ELFT>::addSectionSymbols() {
496 // Create one STT_SECTION symbol for each output section we might
497 // have a relocation with.
498 for (BaseCommand *Base : Script->Opt.Commands) {
499 auto *Cmd = dyn_cast<OutputSectionCommand>(Base);
500 if (!Cmd)
501 continue;
502 auto I = llvm::find_if(Cmd->Commands, [](BaseCommand *Base) {
503 if (auto *ISD = dyn_cast<InputSectionDescription>(Base))
504 return !ISD->Sections.empty();
505 return false;
506 });
507 if (I == Cmd->Commands.end())
508 continue;
509 InputSection *IS = cast<InputSectionDescription>(*I)->Sections[0];
510 if (isa<SyntheticSection>(IS) || IS->Type == SHT_REL ||
511 IS->Type == SHT_RELA)
512 continue;
513
514 auto *Sym =
515 make<DefinedRegular>("", /*IsLocal=*/true, /*StOther=*/0, STT_SECTION,
516 /*Value=*/0, /*Size=*/0, IS, nullptr);
517 InX::SymTab->addSymbol(Sym);
518 }
519}
520
521// Today's loaders have a feature to make segments read-only after
522// processing dynamic relocations to enhance security. PT_GNU_RELRO
523// is defined for that.
524//
525// This function returns true if a section needs to be put into a
526// PT_GNU_RELRO segment.
527bool elf::isRelroSection(const OutputSection *Sec) {
528 if (!Config->ZRelro)
529 return false;
530
531 uint64_t Flags = Sec->Flags;
532
533 // Non-allocatable or non-writable sections don't need RELRO because
534 // they are not writable or not even mapped to memory in the first place.
535 // RELRO is for sections that are essentially read-only but need to
536 // be writable only at process startup to allow dynamic linker to
537 // apply relocations.
538 if (!(Flags & SHF_ALLOC) || !(Flags & SHF_WRITE))
539 return false;
540
541 // Once initialized, TLS data segments are used as data templates
542 // for a thread-local storage. For each new thread, runtime
543 // allocates memory for a TLS and copy templates there. No thread
544 // are supposed to use templates directly. Thus, it can be in RELRO.
545 if (Flags & SHF_TLS)
546 return true;
547
548 // .init_array, .preinit_array and .fini_array contain pointers to
549 // functions that are executed on process startup or exit. These
550 // pointers are set by the static linker, and they are not expected
551 // to change at runtime. But if you are an attacker, you could do
552 // interesting things by manipulating pointers in .fini_array, for
553 // example. So they are put into RELRO.
554 uint32_t Type = Sec->Type;
555 if (Type == SHT_INIT_ARRAY || Type == SHT_FINI_ARRAY ||
556 Type == SHT_PREINIT_ARRAY)
557 return true;
558
559 // .got contains pointers to external symbols. They are resolved by
560 // the dynamic linker when a module is loaded into memory, and after
561 // that they are not expected to change. So, it can be in RELRO.
562 if (InX::Got && Sec == InX::Got->getParent())
563 return true;
564
565 // .got.plt contains pointers to external function symbols. They are
566 // by default resolved lazily, so we usually cannot put it into RELRO.
567 // However, if "-z now" is given, the lazy symbol resolution is
568 // disabled, which enables us to put it into RELRO.
569 if (Sec == InX::GotPlt->getParent())
570 return Config->ZNow;
571
572 // .dynamic section contains data for the dynamic linker, and
573 // there's no need to write to it at runtime, so it's better to put
574 // it into RELRO.
575 if (Sec == InX::Dynamic->getParent())
576 return true;
577
578 // .bss.rel.ro is used for copy relocations for read-only symbols.
579 // Since the dynamic linker needs to process copy relocations, the
580 // section cannot be read-only, but once initialized, they shouldn't
581 // change.
582 if (Sec == InX::BssRelRo->getParent())
583 return true;
584
585 // Sections with some special names are put into RELRO. This is a
586 // bit unfortunate because section names shouldn't be significant in
587 // ELF in spirit. But in reality many linker features depend on
588 // magic section names.
589 StringRef S = Sec->Name;
590 return S == ".data.rel.ro" || S == ".ctors" || S == ".dtors" || S == ".jcr" ||
591 S == ".eh_frame" || S == ".openbsd.randomdata";
592}
593
594// We compute a rank for each section. The rank indicates where the
595// section should be placed in the file. Instead of using simple
596// numbers (0,1,2...), we use a series of flags. One for each decision
597// point when placing the section.
598// Using flags has two key properties:
599// * It is easy to check if a give branch was taken.
600// * It is easy two see how similar two ranks are (see getRankProximity).
601enum RankFlags {
602 RF_NOT_ADDR_SET = 1 << 16,
603 RF_NOT_INTERP = 1 << 15,
604 RF_NOT_ALLOC = 1 << 14,
605 RF_WRITE = 1 << 13,
606 RF_EXEC_WRITE = 1 << 12,
607 RF_EXEC = 1 << 11,
608 RF_NON_TLS_BSS = 1 << 10,
609 RF_NON_TLS_BSS_RO = 1 << 9,
610 RF_NOT_TLS = 1 << 8,
611 RF_BSS = 1 << 7,
612 RF_PPC_NOT_TOCBSS = 1 << 6,
613 RF_PPC_OPD = 1 << 5,
614 RF_PPC_TOCL = 1 << 4,
615 RF_PPC_TOC = 1 << 3,
616 RF_PPC_BRANCH_LT = 1 << 2,
617 RF_MIPS_GPREL = 1 << 1,
618 RF_MIPS_NOT_GOT = 1 << 0
619};
620
621static unsigned getSectionRank(const OutputSection *Sec) {
622 unsigned Rank = 0;
623
624 // We want to put section specified by -T option first, so we
625 // can start assigning VA starting from them later.
626 if (Config->SectionStartMap.count(Sec->Name))
627 return Rank;
628 Rank |= RF_NOT_ADDR_SET;
629
630 // Put .interp first because some loaders want to see that section
631 // on the first page of the executable file when loaded into memory.
632 if (Sec->Name == ".interp")
633 return Rank;
634 Rank |= RF_NOT_INTERP;
635
636 // Allocatable sections go first to reduce the total PT_LOAD size and
637 // so debug info doesn't change addresses in actual code.
638 if (!(Sec->Flags & SHF_ALLOC))
639 return Rank | RF_NOT_ALLOC;
640
641 // Sort sections based on their access permission in the following
642 // order: R, RX, RWX, RW. This order is based on the following
643 // considerations:
644 // * Read-only sections come first such that they go in the
645 // PT_LOAD covering the program headers at the start of the file.
646 // * Read-only, executable sections come next, unless the
647 // -no-rosegment option is used.
648 // * Writable, executable sections follow such that .plt on
649 // architectures where it needs to be writable will be placed
650 // between .text and .data.
651 // * Writable sections come last, such that .bss lands at the very
652 // end of the last PT_LOAD.
653 bool IsExec = Sec->Flags & SHF_EXECINSTR;
654 bool IsWrite = Sec->Flags & SHF_WRITE;
655
656 if (IsExec) {
657 if (IsWrite)
658 Rank |= RF_EXEC_WRITE;
659 else if (!Config->SingleRoRx)
660 Rank |= RF_EXEC;
661 } else {
662 if (IsWrite)
663 Rank |= RF_WRITE;
664 }
665
666 // If we got here we know that both A and B are in the same PT_LOAD.
667
668 bool IsTls = Sec->Flags & SHF_TLS;
669 bool IsNoBits = Sec->Type == SHT_NOBITS;
670
671 // The first requirement we have is to put (non-TLS) nobits sections last. The
672 // reason is that the only thing the dynamic linker will see about them is a
673 // p_memsz that is larger than p_filesz. Seeing that it zeros the end of the
674 // PT_LOAD, so that has to correspond to the nobits sections.
675 bool IsNonTlsNoBits = IsNoBits && !IsTls;
676 if (IsNonTlsNoBits)
677 Rank |= RF_NON_TLS_BSS;
678
679 // We place nobits RelRo sections before plain r/w ones, and non-nobits RelRo
680 // sections after r/w ones, so that the RelRo sections are contiguous.
681 bool IsRelRo = isRelroSection(Sec);
682 if (IsNonTlsNoBits && !IsRelRo)
683 Rank |= RF_NON_TLS_BSS_RO;
684 if (!IsNonTlsNoBits && IsRelRo)
685 Rank |= RF_NON_TLS_BSS_RO;
686
687 // The TLS initialization block needs to be a single contiguous block in a R/W
688 // PT_LOAD, so stick TLS sections directly before the other RelRo R/W
689 // sections. The TLS NOBITS sections are placed here as they don't take up
690 // virtual address space in the PT_LOAD.
691 if (!IsTls)
692 Rank |= RF_NOT_TLS;
693
694 // Within the TLS initialization block, the non-nobits sections need to appear
695 // first.
696 if (IsNoBits)
697 Rank |= RF_BSS;
698
699 // // Some architectures have additional ordering restrictions for sections
700 // // within the same PT_LOAD.
701 if (Config->EMachine == EM_PPC64) {
702 // PPC64 has a number of special SHT_PROGBITS+SHF_ALLOC+SHF_WRITE sections
703 // that we would like to make sure appear is a specific order to maximize
704 // their coverage by a single signed 16-bit offset from the TOC base
705 // pointer. Conversely, the special .tocbss section should be first among
706 // all SHT_NOBITS sections. This will put it next to the loaded special
707 // PPC64 sections (and, thus, within reach of the TOC base pointer).
708 StringRef Name = Sec->Name;
709 if (Name != ".tocbss")
710 Rank |= RF_PPC_NOT_TOCBSS;
711
712 if (Name == ".opd")
713 Rank |= RF_PPC_OPD;
714
715 if (Name == ".toc1")
716 Rank |= RF_PPC_TOCL;
717
718 if (Name == ".toc")
719 Rank |= RF_PPC_TOC;
720
721 if (Name == ".branch_lt")
722 Rank |= RF_PPC_BRANCH_LT;
723 }
724 if (Config->EMachine == EM_MIPS) {
725 // All sections with SHF_MIPS_GPREL flag should be grouped together
726 // because data in these sections is addressable with a gp relative address.
727 if (Sec->Flags & SHF_MIPS_GPREL)
728 Rank |= RF_MIPS_GPREL;
729
730 if (Sec->Name != ".got")
731 Rank |= RF_MIPS_NOT_GOT;
732 }
733
734 return Rank;
735}
736
737static bool compareSections(const BaseCommand *ACmd, const BaseCommand *BCmd) {
738 const OutputSection *A = cast<OutputSectionCommand>(ACmd)->Sec;
739 const OutputSection *B = cast<OutputSectionCommand>(BCmd)->Sec;
740 if (A->SortRank != B->SortRank)
741 return A->SortRank < B->SortRank;
742 if (!(A->SortRank & RF_NOT_ADDR_SET))
743 return Config->SectionStartMap.lookup(A->Name) <
744 Config->SectionStartMap.lookup(B->Name);
745 return false;
746}
747
748void PhdrEntry::add(OutputSection *Sec) {
749 Last = Sec;
750 if (!First)
751 First = Sec;
752 p_align = std::max(p_align, Sec->Alignment);
753 if (p_type == PT_LOAD)
754 Sec->FirstInPtLoad = First;
755}
756
757template <class ELFT>
758static Symbol *addRegular(StringRef Name, SectionBase *Sec, uint64_t Value,
759 uint8_t StOther = STV_HIDDEN,
760 uint8_t Binding = STB_WEAK) {
761 // The linker generated symbols are added as STB_WEAK to allow user defined
762 // ones to override them.
763 return Symtab<ELFT>::X->addRegular(Name, StOther, STT_NOTYPE, Value,
764 /*Size=*/0, Binding, Sec,
765 /*File=*/nullptr);
766}
767
768template <class ELFT>
769static DefinedRegular *
770addOptionalRegular(StringRef Name, SectionBase *Sec, uint64_t Val,
771 uint8_t StOther = STV_HIDDEN, uint8_t Binding = STB_GLOBAL) {
772 SymbolBody *S = Symtab<ELFT>::X->find(Name);
773 if (!S)
774 return nullptr;
775 if (S->isInCurrentDSO())
776 return nullptr;
777 return cast<DefinedRegular>(
778 addRegular<ELFT>(Name, Sec, Val, StOther, Binding)->body());
779}
780
781// The beginning and the ending of .rel[a].plt section are marked
782// with __rel[a]_iplt_{start,end} symbols if it is a statically linked
783// executable. The runtime needs these symbols in order to resolve
784// all IRELATIVE relocs on startup. For dynamic executables, we don't
785// need these symbols, since IRELATIVE relocs are resolved through GOT
786// and PLT. For details, see http://www.airs.com/blog/archives/403.
787template <class ELFT> void Writer<ELFT>::addRelIpltSymbols() {
788 if (InX::DynSymTab)
789 return;
790 StringRef S = Config->IsRela ? "__rela_iplt_start" : "__rel_iplt_start";
791 addOptionalRegular<ELFT>(S, In<ELFT>::RelaIplt, 0, STV_HIDDEN, STB_WEAK);
792
793 S = Config->IsRela ? "__rela_iplt_end" : "__rel_iplt_end";
794 addOptionalRegular<ELFT>(S, In<ELFT>::RelaIplt, -1, STV_HIDDEN, STB_WEAK);
795}
796
797// The linker is expected to define some symbols depending on
798// the linking result. This function defines such symbols.
799template <class ELFT> void Writer<ELFT>::addReservedSymbols() {
800 if (Config->EMachine == EM_MIPS) {
801 // Define _gp for MIPS. st_value of _gp symbol will be updated by Writer
802 // so that it points to an absolute address which by default is relative
803 // to GOT. Default offset is 0x7ff0.
804 // See "Global Data Symbols" in Chapter 6 in the following document:
805 // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
806 ElfSym::MipsGp = Symtab<ELFT>::X->addAbsolute("_gp", STV_HIDDEN, STB_LOCAL);
807
808 // On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between
809 // start of function and 'gp' pointer into GOT.
810 if (Symtab<ELFT>::X->find("_gp_disp"))
811 ElfSym::MipsGpDisp =
812 Symtab<ELFT>::X->addAbsolute("_gp_disp", STV_HIDDEN, STB_LOCAL);
813
814 // The __gnu_local_gp is a magic symbol equal to the current value of 'gp'
815 // pointer. This symbol is used in the code generated by .cpload pseudo-op
816 // in case of using -mno-shared option.
817 // https://sourceware.org/ml/binutils/2004-12/msg00094.html
818 if (Symtab<ELFT>::X->find("__gnu_local_gp"))
819 ElfSym::MipsLocalGp =
820 Symtab<ELFT>::X->addAbsolute("__gnu_local_gp", STV_HIDDEN, STB_LOCAL);
821 }
822
823 // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to
824 // be at some offset from the base of the .got section, usually 0 or the end
825 // of the .got
826 InputSection *GotSection = InX::MipsGot ? cast<InputSection>(InX::MipsGot)
827 : cast<InputSection>(InX::Got);
828 ElfSym::GlobalOffsetTable = addOptionalRegular<ELFT>(
829 "_GLOBAL_OFFSET_TABLE_", GotSection, Target->GotBaseSymOff);
830
831 // __tls_get_addr is defined by the dynamic linker for dynamic ELFs. For
832 // static linking the linker is required to optimize away any references to
833 // __tls_get_addr, so it's not defined anywhere. Create a hidden definition
834 // to avoid the undefined symbol error.
835 if (!InX::DynSymTab)
836 Symtab<ELFT>::X->addIgnored("__tls_get_addr");
837
838 // __ehdr_start is the location of ELF file headers. Note that we define
839 // this symbol unconditionally even when using a linker script, which
840 // differs from the behavior implemented by GNU linker which only define
841 // this symbol if ELF headers are in the memory mapped segment.
842 // __executable_start is not documented, but the expectation of at
843 // least the android libc is that it points to the elf header too.
844 // __dso_handle symbol is passed to cxa_finalize as a marker to identify
845 // each DSO. The address of the symbol doesn't matter as long as they are
846 // different in different DSOs, so we chose the start address of the DSO.
847 for (const char *Name :
848 {"__ehdr_start", "__executable_start", "__dso_handle"})
849 addOptionalRegular<ELFT>(Name, Out::ElfHeader, 0, STV_HIDDEN);
850
851 // If linker script do layout we do not need to create any standart symbols.
852 if (Script->Opt.HasSections)
853 return;
854
855 auto Add = [](StringRef S) {
856 return addOptionalRegular<ELFT>(S, Out::ElfHeader, 0, STV_DEFAULT);
857 };
858
859 ElfSym::Bss = Add("__bss_start");
860 ElfSym::End1 = Add("end");
861 ElfSym::End2 = Add("_end");
862 ElfSym::Etext1 = Add("etext");
863 ElfSym::Etext2 = Add("_etext");
864 ElfSym::Edata1 = Add("edata");
865 ElfSym::Edata2 = Add("_edata");
866}
867
868// Sort input sections by section name suffixes for
869// __attribute__((init_priority(N))).
870static void sortInitFini(OutputSectionCommand *Cmd) {
871 if (Cmd)
872 Cmd->sortInitFini();
873}
874
875// Sort input sections by the special rule for .ctors and .dtors.
876static void sortCtorsDtors(OutputSectionCommand *Cmd) {
877 if (Cmd)
878 Cmd->sortCtorsDtors();
879}
880
881// Sort input sections using the list provided by --symbol-ordering-file.
882template <class ELFT> static void sortBySymbolsOrder() {
883 if (Config->SymbolOrderingFile.empty())
884 return;
885
886 // Build a map from symbols to their priorities. Symbols that didn't
887 // appear in the symbol ordering file have the lowest priority 0.
888 // All explicitly mentioned symbols have negative (higher) priorities.
889 DenseMap<StringRef, int> SymbolOrder;
890 int Priority = -Config->SymbolOrderingFile.size();
891 for (StringRef S : Config->SymbolOrderingFile)
892 SymbolOrder.insert({S, Priority++});
893
894 // Build a map from sections to their priorities.
895 DenseMap<SectionBase *, int> SectionOrder;
896 for (elf::ObjectFile<ELFT> *File : Symtab<ELFT>::X->getObjectFiles()) {
897 for (SymbolBody *Body : File->getSymbols()) {
898 auto *D = dyn_cast<DefinedRegular>(Body);
899 if (!D || !D->Section)
900 continue;
901 int &Priority = SectionOrder[D->Section];
902 Priority = std::min(Priority, SymbolOrder.lookup(D->getName()));
903 }
904 }
905
906 // Sort sections by priority.
907 for (BaseCommand *Base : Script->Opt.Commands)
908 if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
909 Cmd->sort([&](InputSectionBase *S) { return SectionOrder.lookup(S); });
910}
911
912template <class ELFT>
913void Writer<ELFT>::forEachRelSec(std::function<void(InputSectionBase &)> Fn) {
914 for (InputSectionBase *IS : InputSections) {
915 if (!IS->Live)
916 continue;
917 // Scan all relocations. Each relocation goes through a series
918 // of tests to determine if it needs special treatment, such as
919 // creating GOT, PLT, copy relocations, etc.
920 // Note that relocations for non-alloc sections are directly
921 // processed by InputSection::relocateNonAlloc.
922 if (!(IS->Flags & SHF_ALLOC))
923 continue;
924 if (isa<InputSection>(IS) || isa<EhInputSection>(IS))
925 Fn(*IS);
926 }
927
928 if (!Config->Relocatable) {
929 for (EhInputSection *ES : In<ELFT>::EhFrame->Sections)
930 Fn(*ES);
931 }
932}
933
934template <class ELFT> void Writer<ELFT>::createSections() {
935 for (InputSectionBase *IS : InputSections)
936 if (IS)
937 Factory.addInputSec(IS, getOutputSectionName(IS->Name));
938
939 Script->fabricateDefaultCommands();
940 sortBySymbolsOrder<ELFT>();
941 sortInitFini(findSectionCommand(".init_array"));
942 sortInitFini(findSectionCommand(".fini_array"));
943 sortCtorsDtors(findSectionCommand(".ctors"));
944 sortCtorsDtors(findSectionCommand(".dtors"));
945}
946
947// We want to find how similar two ranks are.
948// The more branches in getSectionRank that match, the more similar they are.
949// Since each branch corresponds to a bit flag, we can just use
950// countLeadingZeros.
951static int getRankProximity(OutputSection *A, OutputSection *B) {
952 return countLeadingZeros(A->SortRank ^ B->SortRank);
953}
954
955static int getRankProximity(OutputSection *A, BaseCommand *B) {
956 if (auto *Cmd = dyn_cast<OutputSectionCommand>(B))
957 if (Cmd->Sec)
958 return getRankProximity(A, Cmd->Sec);
959 return -1;
960}
961
962// When placing orphan sections, we want to place them after symbol assignments
963// so that an orphan after
964// begin_foo = .;
965// foo : { *(foo) }
966// end_foo = .;
967// doesn't break the intended meaning of the begin/end symbols.
968// We don't want to go over sections since findOrphanPos is the
969// one in charge of deciding the order of the sections.
970// We don't want to go over changes to '.', since doing so in
971// rx_sec : { *(rx_sec) }
972// . = ALIGN(0x1000);
973// /* The RW PT_LOAD starts here*/
974// rw_sec : { *(rw_sec) }
975// would mean that the RW PT_LOAD would become unaligned.
976static bool shouldSkip(BaseCommand *Cmd) {
977 if (isa<OutputSectionCommand>(Cmd))
978 return false;
979 if (auto *Assign = dyn_cast<SymbolAssignment>(Cmd))
980 return Assign->Name != ".";
981 return true;
982}
983
984// We want to place orphan sections so that they share as much
985// characteristics with their neighbors as possible. For example, if
986// both are rw, or both are tls.
987template <typename ELFT>
988static std::vector<BaseCommand *>::iterator
989findOrphanPos(std::vector<BaseCommand *>::iterator B,
990 std::vector<BaseCommand *>::iterator E) {
991 OutputSection *Sec = cast<OutputSectionCommand>(*E)->Sec;
992
993 // Find the first element that has as close a rank as possible.
994 auto I = std::max_element(B, E, [=](BaseCommand *A, BaseCommand *B) {
995 return getRankProximity(Sec, A) < getRankProximity(Sec, B);
996 });
997 if (I == E)
998 return E;
999
1000 // Consider all existing sections with the same proximity.
1001 int Proximity = getRankProximity(Sec, *I);
1002 for (; I != E; ++I) {
1003 auto *Cmd = dyn_cast<OutputSectionCommand>(*I);
1004 if (!Cmd || !Cmd->Sec)
1005 continue;
1006 if (getRankProximity(Sec, Cmd->Sec) != Proximity ||
1007 Sec->SortRank < Cmd->Sec->SortRank)
1008 break;
1009 }
1010 auto J = std::find_if(
1011 llvm::make_reverse_iterator(I), llvm::make_reverse_iterator(B),
1012 [](BaseCommand *Cmd) { return isa<OutputSectionCommand>(Cmd); });
1013 I = J.base();
1014 while (I != E && shouldSkip(*I))
1015 ++I;
1016 return I;
1017}
1018
1019template <class ELFT> void Writer<ELFT>::sortSections() {
1020 if (Script->Opt.HasSections)
1021 Script->adjustSectionsBeforeSorting();
1022
1023 // Don't sort if using -r. It is not necessary and we want to preserve the
1024 // relative order for SHF_LINK_ORDER sections.
1025 if (Config->Relocatable)
1026 return;
1027
1028 for (BaseCommand *Base : Script->Opt.Commands)
1029 if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
1030 if (OutputSection *Sec = Cmd->Sec)
1031 Sec->SortRank = getSectionRank(Sec);
1032
1033 if (!Script->Opt.HasSections) {
1034 // We know that all the OutputSectionCommands are contiguous in
1035 // this case.
1036 auto E = Script->Opt.Commands.end();
1037 auto I = Script->Opt.Commands.begin();
1038 auto IsSection = [](BaseCommand *Base) {
1039 return isa<OutputSectionCommand>(Base);
1040 };
1041 I = std::find_if(I, E, IsSection);
1042 E = std::find_if(llvm::make_reverse_iterator(E),
1043 llvm::make_reverse_iterator(I), IsSection)
1044 .base();
1045 std::stable_sort(I, E, compareSections);
1046 return;
1047 }
1048
1049 // Orphan sections are sections present in the input files which are
1050 // not explicitly placed into the output file by the linker script.
1051 //
1052 // The sections in the linker script are already in the correct
1053 // order. We have to figuere out where to insert the orphan
1054 // sections.
1055 //
1056 // The order of the sections in the script is arbitrary and may not agree with
1057 // compareSections. This means that we cannot easily define a strict weak
1058 // ordering. To see why, consider a comparison of a section in the script and
1059 // one not in the script. We have a two simple options:
1060 // * Make them equivalent (a is not less than b, and b is not less than a).
1061 // The problem is then that equivalence has to be transitive and we can
1062 // have sections a, b and c with only b in a script and a less than c
1063 // which breaks this property.
1064 // * Use compareSectionsNonScript. Given that the script order doesn't have
1065 // to match, we can end up with sections a, b, c, d where b and c are in the
1066 // script and c is compareSectionsNonScript less than b. In which case d
1067 // can be equivalent to c, a to b and d < a. As a concrete example:
1068 // .a (rx) # not in script
1069 // .b (rx) # in script
1070 // .c (ro) # in script
1071 // .d (ro) # not in script
1072 //
1073 // The way we define an order then is:
1074 // * Sort only the orphan sections. They are in the end right now.
1075 // * Move each orphan section to its preferred position. We try
1076 // to put each section in the last position where it it can share
1077 // a PT_LOAD.
1078 //
1079 // There is some ambiguity as to where exactly a new entry should be
1080 // inserted, because Opt.Commands contains not only output section
1081 // commands but also other types of commands such as symbol assignment
1082 // expressions. There's no correct answer here due to the lack of the
1083 // formal specification of the linker script. We use heuristics to
1084 // determine whether a new output command should be added before or
1085 // after another commands. For the details, look at shouldSkip
1086 // function.
1087
1088 auto I = Script->Opt.Commands.begin();
1089 auto E = Script->Opt.Commands.end();
1090 auto NonScriptI = std::find_if(I, E, [](BaseCommand *Base) {
1091 if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
1092 return Cmd->Sec && Cmd->Sec->SectionIndex == INT_MAX;
1093 return false;
1094 });
1095
1096 // Sort the orphan sections.
1097 std::stable_sort(NonScriptI, E, compareSections);
1098
1099 // As a horrible special case, skip the first . assignment if it is before any
1100 // section. We do this because it is common to set a load address by starting
1101 // the script with ". = 0xabcd" and the expectation is that every section is
1102 // after that.
1103 auto FirstSectionOrDotAssignment =
1104 std::find_if(I, E, [](BaseCommand *Cmd) { return !shouldSkip(Cmd); });
1105 if (FirstSectionOrDotAssignment != E &&
1106 isa<SymbolAssignment>(**FirstSectionOrDotAssignment))
1107 ++FirstSectionOrDotAssignment;
1108 I = FirstSectionOrDotAssignment;
1109
1110 while (NonScriptI != E) {
1111 auto Pos = findOrphanPos<ELFT>(I, NonScriptI);
1112 OutputSection *Orphan = cast<OutputSectionCommand>(*NonScriptI)->Sec;
1113
1114 // As an optimization, find all sections with the same sort rank
1115 // and insert them with one rotate.
1116 unsigned Rank = Orphan->SortRank;
1117 auto End = std::find_if(NonScriptI + 1, E, [=](BaseCommand *Cmd) {
1118 return cast<OutputSectionCommand>(Cmd)->Sec->SortRank != Rank;
1119 });
1120 std::rotate(Pos, NonScriptI, End);
1121 NonScriptI = End;
1122 }
1123
1124 Script->adjustSectionsAfterSorting();
1125}
1126
1127static void applySynthetic(const std::vector<SyntheticSection *> &Sections,
1128 std::function<void(SyntheticSection *)> Fn) {
1129 for (SyntheticSection *SS : Sections)
1130 if (SS && SS->getParent() && !SS->empty())
1131 Fn(SS);
1132}
1133
1134// We need to add input synthetic sections early in createSyntheticSections()
1135// to make them visible from linkescript side. But not all sections are always
1136// required to be in output. For example we don't need dynamic section content
1137// sometimes. This function filters out such unused sections from the output.
1138static void removeUnusedSyntheticSections() {
1139 // All input synthetic sections that can be empty are placed after
1140 // all regular ones. We iterate over them all and exit at first
1141 // non-synthetic.
1142 for (InputSectionBase *S : llvm::reverse(InputSections)) {
1143 SyntheticSection *SS = dyn_cast<SyntheticSection>(S);
1144 if (!SS)
1145 return;
1146 OutputSection *OS = SS->getParent();
1147 if (!SS->empty() || !OS)
1148 continue;
1149 if ((SS == InX::Got || SS == InX::MipsGot) && ElfSym::GlobalOffsetTable)
1150 continue;
1151
1152 OutputSectionCommand *Cmd = Script->getCmd(OS);
1153 std::vector<BaseCommand *>::iterator Empty = Cmd->Commands.end();
1154 for (auto I = Cmd->Commands.begin(), E = Cmd->Commands.end(); I != E; ++I) {
1155 BaseCommand *B = *I;
1156 if (auto *ISD = dyn_cast<InputSectionDescription>(B)) {
1157 auto P = std::find(ISD->Sections.begin(), ISD->Sections.end(), SS);
1158 if (P != ISD->Sections.end())
1159 ISD->Sections.erase(P);
1160 if (ISD->Sections.empty())
1161 Empty = I;
1162 }
1163 }
1164 if (Empty != Cmd->Commands.end())
1165 Cmd->Commands.erase(Empty);
1166
1167 // If there are no other sections in the output section, remove it from the
1168 // output.
1169 if (Cmd->Commands.empty()) {
1170 // Also remove script commands matching the output section.
1171 auto &Cmds = Script->Opt.Commands;
1172 auto I = std::remove_if(Cmds.begin(), Cmds.end(), [&](BaseCommand *Cmd) {
1173 if (auto *OSCmd = dyn_cast<OutputSectionCommand>(Cmd))
1174 return OSCmd->Sec == OS;
1175 return false;
1176 });
1177 Cmds.erase(I, Cmds.end());
1178 }
1179 }
1180}
1181
1182// Create output section objects and add them to OutputSections.
1183template <class ELFT> void Writer<ELFT>::finalizeSections() {
1184 Out::DebugInfo = findSectionInScript(".debug_info");
1185 Out::PreinitArray = findSectionInScript(".preinit_array");
1186 Out::InitArray = findSectionInScript(".init_array");
1187 Out::FiniArray = findSectionInScript(".fini_array");
1188
1189 // The linker needs to define SECNAME_start, SECNAME_end and SECNAME_stop
1190 // symbols for sections, so that the runtime can get the start and end
1191 // addresses of each section by section name. Add such symbols.
1192 if (!Config->Relocatable) {
1193 addStartEndSymbols();
1194 for (BaseCommand *Base : Script->Opt.Commands)
1195 if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
1196 if (Cmd->Sec)
1197 addStartStopSymbols(Cmd->Sec);
1198 }
1199
1200 // Add _DYNAMIC symbol. Unlike GNU gold, our _DYNAMIC symbol has no type.
1201 // It should be okay as no one seems to care about the type.
1202 // Even the author of gold doesn't remember why gold behaves that way.
1203 // https://sourceware.org/ml/binutils/2002-03/msg00360.html
1204 if (InX::DynSymTab)
1205 addRegular<ELFT>("_DYNAMIC", InX::Dynamic, 0);
1206
1207 // Define __rel[a]_iplt_{start,end} symbols if needed.
1208 addRelIpltSymbols();
1209
1210 // This responsible for splitting up .eh_frame section into
1211 // pieces. The relocation scan uses those pieces, so this has to be
1212 // earlier.
1213 applySynthetic({In<ELFT>::EhFrame},
1214 [](SyntheticSection *SS) { SS->finalizeContents(); });
1215
1216 // Scan relocations. This must be done after every symbol is declared so that
1217 // we can correctly decide if a dynamic relocation is needed.
1218 forEachRelSec(scanRelocations<ELFT>);
1219
1220 if (InX::Plt && !InX::Plt->empty())
1221 InX::Plt->addSymbols();
1222 if (InX::Iplt && !InX::Iplt->empty())
1223 InX::Iplt->addSymbols();
1224
1225 // Now that we have defined all possible global symbols including linker-
1226 // synthesized ones. Visit all symbols to give the finishing touches.
1227 for (Symbol *S : Symtab<ELFT>::X->getSymbols()) {
1228 SymbolBody *Body = S->body();
1229
1230 if (!includeInSymtab(*Body))
1231 continue;
1232 if (InX::SymTab)
1233 InX::SymTab->addSymbol(Body);
1234
1235 if (InX::DynSymTab && S->includeInDynsym()) {
1236 InX::DynSymTab->addSymbol(Body);
1237 if (auto *SS = dyn_cast<SharedSymbol>(Body))
1238 if (cast<SharedFile<ELFT>>(SS->File)->isNeeded())
1239 In<ELFT>::VerNeed->addSymbol(SS);
1240 }
1241 }
1242
1243 // Do not proceed if there was an undefined symbol.
1244 if (ErrorCount)
1245 return;
1246
1247 addPredefinedSections();
1248 removeUnusedSyntheticSections();
1249
1250 sortSections();
1251
1252 // Now that we have the final list, create a list of all the
1253 // OutputSectionCommands for convenience.
1254 for (BaseCommand *Base : Script->Opt.Commands)
1255 if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
1256 OutputSectionCommands.push_back(Cmd);
1257
1258 // Prefer command line supplied address over other constraints.
1259 for (OutputSectionCommand *Cmd : OutputSectionCommands) {
1260 auto I = Config->SectionStartMap.find(Cmd->Name);
1261 if (I != Config->SectionStartMap.end())
1262 Cmd->AddrExpr = [=] { return I->second; };
1263 }
1264
1265 // This is a bit of a hack. A value of 0 means undef, so we set it
1266 // to 1 t make __ehdr_start defined. The section number is not
1267 // particularly relevant.
1268 Out::ElfHeader->SectionIndex = 1;
1269
1270 unsigned I = 1;
1271 for (OutputSectionCommand *Cmd : OutputSectionCommands) {
1272 OutputSection *Sec = Cmd->Sec;
1273 Sec->SectionIndex = I++;
1274 Sec->ShName = InX::ShStrTab->addString(Sec->Name);
1275 }
1276
1277 // Binary and relocatable output does not have PHDRS.
1278 // The headers have to be created before finalize as that can influence the
1279 // image base and the dynamic section on mips includes the image base.
1280 if (!Config->Relocatable && !Config->OFormatBinary) {
1281 Phdrs = Script->hasPhdrsCommands() ? Script->createPhdrs() : createPhdrs();
1282 addPtArmExid(Phdrs);
1283 Out::ProgramHeaders->Size = sizeof(Elf_Phdr) * Phdrs.size();
1284 }
1285
1286 // Dynamic section must be the last one in this list and dynamic
1287 // symbol table section (DynSymTab) must be the first one.
1288 applySynthetic({InX::DynSymTab, InX::Bss, InX::BssRelRo,
1289 InX::GnuHashTab, In<ELFT>::HashTab, InX::SymTab,
1290 InX::ShStrTab, InX::StrTab, In<ELFT>::VerDef,
1291 InX::DynStrTab, InX::GdbIndex, InX::Got,
1292 InX::MipsGot, InX::IgotPlt, InX::GotPlt,
1293 In<ELFT>::RelaDyn, In<ELFT>::RelaIplt, In<ELFT>::RelaPlt,
1294 InX::Plt, InX::Iplt, In<ELFT>::EhFrameHdr,
1295 In<ELFT>::VerSym, In<ELFT>::VerNeed, InX::Dynamic},
1296 [](SyntheticSection *SS) { SS->finalizeContents(); });
1297
1298 // Some architectures use small displacements for jump instructions.
1299 // It is linker's responsibility to create thunks containing long
1300 // jump instructions if jump targets are too far. Create thunks.
1301 if (Target->NeedsThunks) {
1302 // FIXME: only ARM Interworking and Mips LA25 Thunks are implemented,
1303 // these
1304 // do not require address information. To support range extension Thunks
1305 // we need to assign addresses so that we can tell if jump instructions
1306 // are out of range. This will need to turn into a loop that converges
1307 // when no more Thunks are added
1308 ThunkCreator TC;
1309 Script->assignAddresses();
1310 if (TC.createThunks(OutputSectionCommands)) {
1311 applySynthetic({InX::MipsGot},
1312 [](SyntheticSection *SS) { SS->updateAllocSize(); });
1313 if (TC.createThunks(OutputSectionCommands))
1314 fatal("All non-range thunks should be created in first call");
1315 }
1316 }
1317
1318 // Fill other section headers. The dynamic table is finalized
1319 // at the end because some tags like RELSZ depend on result
1320 // of finalizing other sections.
1321 for (OutputSectionCommand *Cmd : OutputSectionCommands)
1322 Cmd->finalize<ELFT>();
1323
1324 // createThunks may have added local symbols to the static symbol table
1325 applySynthetic({InX::SymTab, InX::ShStrTab, InX::StrTab},
1326 [](SyntheticSection *SS) { SS->postThunkContents(); });
1327}
1328
1329template <class ELFT> void Writer<ELFT>::addPredefinedSections() {
1330 // ARM ABI requires .ARM.exidx to be terminated by some piece of data.
1331 // We have the terminater synthetic section class. Add that at the end.
1332 OutputSectionCommand *Cmd = findSectionCommand(".ARM.exidx");
1333 if (!Cmd || !Cmd->Sec || Config->Relocatable)
1334 return;
1335
1336 auto *Sentinel = make<ARMExidxSentinelSection>();
1337 Cmd->Sec->addSection(Sentinel);
1338 // Add the sentinel to the last of these too.
1339 auto ISD = std::find_if(Cmd->Commands.rbegin(), Cmd->Commands.rend(),
1340 [](const BaseCommand *Base) {
1341 return isa<InputSectionDescription>(Base);
1342 });
1343 cast<InputSectionDescription>(*ISD)->Sections.push_back(Sentinel);
1344}
1345
1346// The linker is expected to define SECNAME_start and SECNAME_end
1347// symbols for a few sections. This function defines them.
1348template <class ELFT> void Writer<ELFT>::addStartEndSymbols() {
1349 auto Define = [&](StringRef Start, StringRef End, OutputSection *OS) {
1350 // These symbols resolve to the image base if the section does not exist.
1351 // A special value -1 indicates end of the section.
1352 if (OS) {
1353 addOptionalRegular<ELFT>(Start, OS, 0);
1354 addOptionalRegular<ELFT>(End, OS, -1);
1355 } else {
1356 if (Config->Pic)
1357 OS = Out::ElfHeader;
1358 addOptionalRegular<ELFT>(Start, OS, 0);
1359 addOptionalRegular<ELFT>(End, OS, 0);
1360 }
1361 };
1362
1363 Define("__preinit_array_start", "__preinit_array_end", Out::PreinitArray);
1364 Define("__init_array_start", "__init_array_end", Out::InitArray);
1365 Define("__fini_array_start", "__fini_array_end", Out::FiniArray);
1366
1367 if (OutputSection *Sec = findSectionInScript(".ARM.exidx"))
1368 Define("__exidx_start", "__exidx_end", Sec);
1369}
1370
1371// If a section name is valid as a C identifier (which is rare because of
1372// the leading '.'), linkers are expected to define __start_<secname> and
1373// __stop_<secname> symbols. They are at beginning and end of the section,
1374// respectively. This is not requested by the ELF standard, but GNU ld and
1375// gold provide the feature, and used by many programs.
1376template <class ELFT>
1377void Writer<ELFT>::addStartStopSymbols(OutputSection *Sec) {
1378 StringRef S = Sec->Name;
1379 if (!isValidCIdentifier(S))
1380 return;
1381 addOptionalRegular<ELFT>(Saver.save("__start_" + S), Sec, 0, STV_DEFAULT);
1382 addOptionalRegular<ELFT>(Saver.save("__stop_" + S), Sec, -1, STV_DEFAULT);
1383}
1384
1385template <class ELFT>
1386OutputSectionCommand *Writer<ELFT>::findSectionCommand(StringRef Name) {
1387 for (BaseCommand *Base : Script->Opt.Commands)
1388 if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
1389 if (Cmd->Name == Name)
1390 return Cmd;
1391 return nullptr;
1392}
1393
1394template <class ELFT>
1395OutputSection *Writer<ELFT>::findSectionInScript(StringRef Name) {
1396 if (OutputSectionCommand *Cmd = findSectionCommand(Name))
1397 return Cmd->Sec;
1398 return nullptr;
1399}
1400
1401static bool needsPtLoad(OutputSection *Sec) {
1402 if (!(Sec->Flags & SHF_ALLOC))
1403 return false;
1404
1405 // Don't allocate VA space for TLS NOBITS sections. The PT_TLS PHDR is
1406 // responsible for allocating space for them, not the PT_LOAD that
1407 // contains the TLS initialization image.
1408 if (Sec->Flags & SHF_TLS && Sec->Type == SHT_NOBITS)
1409 return false;
1410 return true;
1411}
1412
1413// Linker scripts are responsible for aligning addresses. Unfortunately, most
1414// linker scripts are designed for creating two PT_LOADs only, one RX and one
1415// RW. This means that there is no alignment in the RO to RX transition and we
1416// cannot create a PT_LOAD there.
1417static uint64_t computeFlags(uint64_t Flags) {
1418 if (Config->Omagic)
1419 return PF_R | PF_W | PF_X;
1420 if (Config->SingleRoRx && !(Flags & PF_W))
1421 return Flags | PF_X;
1422 return Flags;
1423}
1424
1425// Decide which program headers to create and which sections to include in each
1426// one.
1427template <class ELFT> std::vector<PhdrEntry> Writer<ELFT>::createPhdrs() {
1428 std::vector<PhdrEntry> Ret;
1429 auto AddHdr = [&](unsigned Type, unsigned Flags) -> PhdrEntry * {
1430 Ret.emplace_back(Type, Flags);
1431 return &Ret.back();
1432 };
1433
1434 // The first phdr entry is PT_PHDR which describes the program header itself.
1435 AddHdr(PT_PHDR, PF_R)->add(Out::ProgramHeaders);
1436
1437 // PT_INTERP must be the second entry if exists.
1438 if (OutputSection *Sec = findSectionInScript(".interp"))
1439 AddHdr(PT_INTERP, Sec->getPhdrFlags())->add(Sec);
1440
1441 // Add the first PT_LOAD segment for regular output sections.
1442 uint64_t Flags = computeFlags(PF_R);
1443 PhdrEntry *Load = AddHdr(PT_LOAD, Flags);
1444
1445 // Add the headers. We will remove them if they don't fit.
1446 Load->add(Out::ElfHeader);
1447 Load->add(Out::ProgramHeaders);
1448
1449 for (OutputSectionCommand *Cmd : OutputSectionCommands) {
1450 OutputSection *Sec = Cmd->Sec;
1451 if (!(Sec->Flags & SHF_ALLOC))
1452 break;
1453 if (!needsPtLoad(Sec))
1454 continue;
1455
1456 // Segments are contiguous memory regions that has the same attributes
1457 // (e.g. executable or writable). There is one phdr for each segment.
1458 // Therefore, we need to create a new phdr when the next section has
1459 // different flags or is loaded at a discontiguous address using AT linker
1460 // script command.
1461 uint64_t NewFlags = computeFlags(Sec->getPhdrFlags());
1462 if (Cmd->LMAExpr || Flags != NewFlags) {
1463 Load = AddHdr(PT_LOAD, NewFlags);
1464 Flags = NewFlags;
1465 }
1466
1467 Load->add(Sec);
1468 }
1469
1470 // Add a TLS segment if any.
1471 PhdrEntry TlsHdr(PT_TLS, PF_R);
1472 for (OutputSectionCommand *Cmd : OutputSectionCommands) {
1473 OutputSection *Sec = Cmd->Sec;
1474 if (Sec->Flags & SHF_TLS)
1475 TlsHdr.add(Sec);
1476 }
1477 if (TlsHdr.First)
1478 Ret.push_back(std::move(TlsHdr));
1479
1480 // Add an entry for .dynamic.
1481 if (InX::DynSymTab)
1482 AddHdr(PT_DYNAMIC, InX::Dynamic->getParent()->getPhdrFlags())
1483 ->add(InX::Dynamic->getParent());
1484
1485 // PT_GNU_RELRO includes all sections that should be marked as
1486 // read-only by dynamic linker after proccessing relocations.
1487 PhdrEntry RelRo(PT_GNU_RELRO, PF_R);
1488 for (OutputSectionCommand *Cmd : OutputSectionCommands) {
1489 OutputSection *Sec = Cmd->Sec;
1490 if (needsPtLoad(Sec) && isRelroSection(Sec))
1491 RelRo.add(Sec);
1492 }
1493 if (RelRo.First)
1494 Ret.push_back(std::move(RelRo));
1495
1496 // PT_GNU_EH_FRAME is a special section pointing on .eh_frame_hdr.
1497 if (!In<ELFT>::EhFrame->empty() && In<ELFT>::EhFrameHdr &&
1498 In<ELFT>::EhFrame->getParent() && In<ELFT>::EhFrameHdr->getParent())
1499 AddHdr(PT_GNU_EH_FRAME, In<ELFT>::EhFrameHdr->getParent()->getPhdrFlags())
1500 ->add(In<ELFT>::EhFrameHdr->getParent());
1501
1502 // PT_OPENBSD_RANDOMIZE is an OpenBSD-specific feature. That makes
1503 // the dynamic linker fill the segment with random data.
1504 if (OutputSection *Sec = findSectionInScript(".openbsd.randomdata"))
1505 AddHdr(PT_OPENBSD_RANDOMIZE, Sec->getPhdrFlags())->add(Sec);
1506
1507 // PT_GNU_STACK is a special section to tell the loader to make the
1508 // pages for the stack non-executable. If you really want an executable
1509 // stack, you can pass -z execstack, but that's not recommended for
1510 // security reasons.
1511 unsigned Perm;
1512 if (Config->ZExecstack)
1513 Perm = PF_R | PF_W | PF_X;
1514 else
1515 Perm = PF_R | PF_W;
1516 AddHdr(PT_GNU_STACK, Perm)->p_memsz = Config->ZStackSize;
1517
1518 // PT_OPENBSD_WXNEEDED is a OpenBSD-specific header to mark the executable
1519 // is expected to perform W^X violations, such as calling mprotect(2) or
1520 // mmap(2) with PROT_WRITE | PROT_EXEC, which is prohibited by default on
1521 // OpenBSD.
1522 if (Config->ZWxneeded)
1523 AddHdr(PT_OPENBSD_WXNEEDED, PF_X);
1524
1525 // Create one PT_NOTE per a group of contiguous .note sections.
1526 PhdrEntry *Note = nullptr;
1527 for (OutputSectionCommand *Cmd : OutputSectionCommands) {
1528 OutputSection *Sec = Cmd->Sec;
1529 if (Sec->Type == SHT_NOTE) {
1530 if (!Note || Cmd->LMAExpr)
1531 Note = AddHdr(PT_NOTE, PF_R);
1532 Note->add(Sec);
1533 } else {
1534 Note = nullptr;
1535 }
1536 }
1537 return Ret;
1538}
1539
1540template <class ELFT>
1541void Writer<ELFT>::addPtArmExid(std::vector<PhdrEntry> &Phdrs) {
1542 if (Config->EMachine != EM_ARM)
1543 return;
1544 auto I = llvm::find_if(OutputSectionCommands, [](OutputSectionCommand *Cmd) {
1545 return Cmd->Sec->Type == SHT_ARM_EXIDX;
1546 });
1547 if (I == OutputSectionCommands.end())
1548 return;
1549
1550 // PT_ARM_EXIDX is the ARM EHABI equivalent of PT_GNU_EH_FRAME
1551 PhdrEntry ARMExidx(PT_ARM_EXIDX, PF_R);
1552 ARMExidx.add((*I)->Sec);
1553 Phdrs.push_back(ARMExidx);
1554}
1555
1556// The first section of each PT_LOAD, the first section in PT_GNU_RELRO and the
1557// first section after PT_GNU_RELRO have to be page aligned so that the dynamic
1558// linker can set the permissions.
1559template <class ELFT> void Writer<ELFT>::fixSectionAlignments() {
1560 auto PageAlign = [](OutputSection *Sec) {
1561 OutputSectionCommand *Cmd = Script->getCmd(Sec);
1562 if (Cmd && !Cmd->AddrExpr)
1563 Cmd->AddrExpr = [=] {
1564 return alignTo(Script->getDot(), Config->MaxPageSize);
1565 };
1566 };
1567
1568 for (const PhdrEntry &P : Phdrs)
1569 if (P.p_type == PT_LOAD && P.First)
1570 PageAlign(P.First);
1571
1572 for (const PhdrEntry &P : Phdrs) {
1573 if (P.p_type != PT_GNU_RELRO)
1574 continue;
1575 if (P.First)
1576 PageAlign(P.First);
1577 // Find the first section after PT_GNU_RELRO. If it is in a PT_LOAD we
1578 // have to align it to a page.
1579 auto End = OutputSectionCommands.end();
1580 auto I =
1581 std::find(OutputSectionCommands.begin(), End, Script->getCmd(P.Last));
1582 if (I == End || (I + 1) == End)
1583 continue;
1584 OutputSection *Sec = (*(I + 1))->Sec;
1585 if (needsPtLoad(Sec))
1586 PageAlign(Sec);
1587 }
1588}
1589
1590// Adjusts the file alignment for a given output section and returns
1591// its new file offset. The file offset must be the same with its
1592// virtual address (modulo the page size) so that the loader can load
1593// executables without any address adjustment.
1594static uint64_t getFileAlignment(uint64_t Off, OutputSection *Sec) {
1595 OutputSection *First = Sec->FirstInPtLoad;
1596 // If the section is not in a PT_LOAD, we just have to align it.
1597 if (!First)
1598 return alignTo(Off, Sec->Alignment);
1599
1600 // The first section in a PT_LOAD has to have congruent offset and address
1601 // module the page size.
1602 if (Sec == First)
1603 return alignTo(Off, Config->MaxPageSize, Sec->Addr);
1604
1605 // If two sections share the same PT_LOAD the file offset is calculated
1606 // using this formula: Off2 = Off1 + (VA2 - VA1).
1607 return First->Offset + Sec->Addr - First->Addr;
1608}
1609
1610static uint64_t setOffset(OutputSection *Sec, uint64_t Off) {
1611 if (Sec->Type == SHT_NOBITS) {
1612 Sec->Offset = Off;
1613 return Off;
1614 }
1615
1616 Off = getFileAlignment(Off, Sec);
1617 Sec->Offset = Off;
1618 return Off + Sec->Size;
1619}
1620
1621template <class ELFT> void Writer<ELFT>::assignFileOffsetsBinary() {
1622 uint64_t Off = 0;
1623 for (OutputSectionCommand *Cmd : OutputSectionCommands) {
1624 OutputSection *Sec = Cmd->Sec;
1625 if (Sec->Flags & SHF_ALLOC)
1626 Off = setOffset(Sec, Off);
1627 }
1628 FileSize = alignTo(Off, Config->Wordsize);
1629}
1630
1631// Assign file offsets to output sections.
1632template <class ELFT> void Writer<ELFT>::assignFileOffsets() {
1633 uint64_t Off = 0;
1634 Off = setOffset(Out::ElfHeader, Off);
1635 Off = setOffset(Out::ProgramHeaders, Off);
1636
1637 for (OutputSectionCommand *Cmd : OutputSectionCommands)
1638 Off = setOffset(Cmd->Sec, Off);
1639
1640 SectionHeaderOff = alignTo(Off, Config->Wordsize);
1641 FileSize =
1642 SectionHeaderOff + (OutputSectionCommands.size() + 1) * sizeof(Elf_Shdr);
1643}
1644
1645// Finalize the program headers. We call this function after we assign
1646// file offsets and VAs to all sections.
1647template <class ELFT> void Writer<ELFT>::setPhdrs() {
1648 for (PhdrEntry &P : Phdrs) {
1649 OutputSection *First = P.First;
1650 OutputSection *Last = P.Last;
1651 if (First) {
1652 P.p_filesz = Last->Offset - First->Offset;
1653 if (Last->Type != SHT_NOBITS)
1654 P.p_filesz += Last->Size;
1655 P.p_memsz = Last->Addr + Last->Size - First->Addr;
1656 P.p_offset = First->Offset;
1657 P.p_vaddr = First->Addr;
1658 if (!P.HasLMA)
1659 P.p_paddr = First->getLMA();
1660 }
1661 if (P.p_type == PT_LOAD)
1662 P.p_align = Config->MaxPageSize;
1663 else if (P.p_type == PT_GNU_RELRO) {
1664 P.p_align = 1;
1665 // The glibc dynamic loader rounds the size down, so we need to round up
1666 // to protect the last page. This is a no-op on FreeBSD which always
1667 // rounds up.
1668 P.p_memsz = alignTo(P.p_memsz, Target->PageSize);
1669 }
1670
1671 // The TLS pointer goes after PT_TLS. At least glibc will align it,
1672 // so round up the size to make sure the offsets are correct.
1673 if (P.p_type == PT_TLS) {
1674 Out::TlsPhdr = &P;
1675 if (P.p_memsz)
1676 P.p_memsz = alignTo(P.p_memsz, P.p_align);
1677 }
1678 }
1679}
1680
1681// The entry point address is chosen in the following ways.
1682//
1683// 1. the '-e' entry command-line option;
1684// 2. the ENTRY(symbol) command in a linker control script;
1685// 3. the value of the symbol start, if present;
1686// 4. the address of the first byte of the .text section, if present;
1687// 5. the address 0.
1688template <class ELFT> uint64_t Writer<ELFT>::getEntryAddr() {
1689 // Case 1, 2 or 3. As a special case, if the symbol is actually
1690 // a number, we'll use that number as an address.
1691 if (SymbolBody *B = Symtab<ELFT>::X->find(Config->Entry))
1692 return B->getVA();
1693 uint64_t Addr;
1694 if (to_integer(Config->Entry, Addr))
1695 return Addr;
1696
1697 // Case 4
1698 if (OutputSection *Sec = findSectionInScript(".text")) {
1699 if (Config->WarnMissingEntry)
1700 warn("cannot find entry symbol " + Config->Entry + "; defaulting to 0x" +
1701 utohexstr(Sec->Addr));
1702 return Sec->Addr;
1703 }
1704
1705 // Case 5
1706 if (Config->WarnMissingEntry)
1707 warn("cannot find entry symbol " + Config->Entry +
1708 "; not setting start address");
1709 return 0;
1710}
1711
1712static uint16_t getELFType() {
1713 if (Config->Pic)
1714 return ET_DYN;
1715 if (Config->Relocatable)
1716 return ET_REL;
1717 return ET_EXEC;
1718}
1719
1720// This function is called after we have assigned address and size
1721// to each section. This function fixes some predefined
1722// symbol values that depend on section address and size.
1723template <class ELFT> void Writer<ELFT>::fixPredefinedSymbols() {
1724 // _etext is the first location after the last read-only loadable segment.
1725 // _edata is the first location after the last read-write loadable segment.
1726 // _end is the first location after the uninitialized data region.
1727 PhdrEntry *Last = nullptr;
1728 PhdrEntry *LastRO = nullptr;
1729 PhdrEntry *LastRW = nullptr;
1730 for (PhdrEntry &P : Phdrs) {
1731 if (P.p_type != PT_LOAD)
1732 continue;
1733 Last = &P;
1734 if (P.p_flags & PF_W)
1735 LastRW = &P;
1736 else
1737 LastRO = &P;
1738 }
1739
1740 auto Set = [](DefinedRegular *S, OutputSection *Sec, uint64_t Value) {
1741 if (S) {
1742 S->Section = Sec;
1743 S->Value = Value;
1744 }
1745 };
1746
1747 if (Last) {
1748 Set(ElfSym::End1, Last->First, Last->p_memsz);
1749 Set(ElfSym::End2, Last->First, Last->p_memsz);
1750 }
1751 if (LastRO) {
1752 Set(ElfSym::Etext1, LastRO->First, LastRO->p_filesz);
1753 Set(ElfSym::Etext2, LastRO->First, LastRO->p_filesz);
1754 }
1755 if (LastRW) {
1756 Set(ElfSym::Edata1, LastRW->First, LastRW->p_filesz);
1757 Set(ElfSym::Edata2, LastRW->First, LastRW->p_filesz);
1758 }
1759
1760 if (ElfSym::Bss)
1761 ElfSym::Bss->Section = findSectionInScript(".bss");
1762
1763 // Setup MIPS _gp_disp/__gnu_local_gp symbols which should
1764 // be equal to the _gp symbol's value.
1765 if (Config->EMachine == EM_MIPS && !ElfSym::MipsGp->Value) {
1766 // Find GP-relative section with the lowest address
1767 // and use this address to calculate default _gp value.
1768 for (const OutputSectionCommand *Cmd : OutputSectionCommands) {
1769 OutputSection *OS = Cmd->Sec;
1770 if (OS->Flags & SHF_MIPS_GPREL) {
1771 ElfSym::MipsGp->Value = OS->Addr + 0x7ff0;
1772 break;
1773 }
1774 }
1775 }
1776}
1777
1778template <class ELFT> void Writer<ELFT>::writeHeader() {
1779 uint8_t *Buf = Buffer->getBufferStart();
1780 memcpy(Buf, "\177ELF", 4);
1781
1782 // Write the ELF header.
1783 auto *EHdr = reinterpret_cast<Elf_Ehdr *>(Buf);
1784 EHdr->e_ident[EI_CLASS] = Config->Is64 ? ELFCLASS64 : ELFCLASS32;
1785 EHdr->e_ident[EI_DATA] = Config->IsLE ? ELFDATA2LSB : ELFDATA2MSB;
1786 EHdr->e_ident[EI_VERSION] = EV_CURRENT;
1787 EHdr->e_ident[EI_OSABI] = Config->OSABI;
1788 EHdr->e_type = getELFType();
1789 EHdr->e_machine = Config->EMachine;
1790 EHdr->e_version = EV_CURRENT;
1791 EHdr->e_entry = getEntryAddr();
1792 EHdr->e_shoff = SectionHeaderOff;
1793 EHdr->e_ehsize = sizeof(Elf_Ehdr);
1794 EHdr->e_phnum = Phdrs.size();
1795 EHdr->e_shentsize = sizeof(Elf_Shdr);
1796 EHdr->e_shnum = OutputSectionCommands.size() + 1;
1797 EHdr->e_shstrndx = InX::ShStrTab->getParent()->SectionIndex;
1798
1799 if (Config->EMachine == EM_ARM)
1800 // We don't currently use any features incompatible with EF_ARM_EABI_VER5,
1801 // but we don't have any firm guarantees of conformance. Linux AArch64
1802 // kernels (as of 2016) require an EABI version to be set.
1803 EHdr->e_flags = EF_ARM_EABI_VER5;
1804 else if (Config->EMachine == EM_MIPS)
1805 EHdr->e_flags = getMipsEFlags<ELFT>();
1806
1807 if (!Config->Relocatable) {
1808 EHdr->e_phoff = sizeof(Elf_Ehdr);
1809 EHdr->e_phentsize = sizeof(Elf_Phdr);
1810 }
1811
1812 // Write the program header table.
1813 auto *HBuf = reinterpret_cast<Elf_Phdr *>(Buf + EHdr->e_phoff);
1814 for (PhdrEntry &P : Phdrs) {
1815 HBuf->p_type = P.p_type;
1816 HBuf->p_flags = P.p_flags;
1817 HBuf->p_offset = P.p_offset;
1818 HBuf->p_vaddr = P.p_vaddr;
1819 HBuf->p_paddr = P.p_paddr;
1820 HBuf->p_filesz = P.p_filesz;
1821 HBuf->p_memsz = P.p_memsz;
1822 HBuf->p_align = P.p_align;
1823 ++HBuf;
1824 }
1825
1826 // Write the section header table. Note that the first table entry is null.
1827 auto *SHdrs = reinterpret_cast<Elf_Shdr *>(Buf + EHdr->e_shoff);
1828 for (OutputSectionCommand *Cmd : OutputSectionCommands)
1829 Cmd->Sec->writeHeaderTo<ELFT>(++SHdrs);
1830}
1831
1832// Open a result file.
1833template <class ELFT> void Writer<ELFT>::openFile() {
1834 if (!Config->Is64 && FileSize > UINT32_MAX) {
1835 error("output file too large: " + Twine(FileSize) + " bytes");
1836 return;
1837 }
1838
1839 unlinkAsync(Config->OutputFile);
1840 ErrorOr<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
1841 FileOutputBuffer::create(Config->OutputFile, FileSize,
1842 FileOutputBuffer::F_executable);
1843
1844 if (auto EC = BufferOrErr.getError())
1845 error("failed to open " + Config->OutputFile + ": " + EC.message());
1846 else
1847 Buffer = std::move(*BufferOrErr);
1848}
1849
1850template <class ELFT> void Writer<ELFT>::writeSectionsBinary() {
1851 uint8_t *Buf = Buffer->getBufferStart();
1852 for (OutputSectionCommand *Cmd : OutputSectionCommands) {
1853 OutputSection *Sec = Cmd->Sec;
1854 if (Sec->Flags & SHF_ALLOC)
1855 Cmd->writeTo<ELFT>(Buf + Sec->Offset);
1856 }
1857}
1858
1859// Write section contents to a mmap'ed file.
1860template <class ELFT> void Writer<ELFT>::writeSections() {
1861 uint8_t *Buf = Buffer->getBufferStart();
1862
1863 // PPC64 needs to process relocations in the .opd section
1864 // before processing relocations in code-containing sections.
1865 if (auto *OpdCmd = findSectionCommand(".opd")) {
1866 Out::Opd = OpdCmd->Sec;
1867 Out::OpdBuf = Buf + Out::Opd->Offset;
1868 OpdCmd->template writeTo<ELFT>(Buf + Out::Opd->Offset);
1869 }
1870
1871 OutputSection *EhFrameHdr =
1872 (In<ELFT>::EhFrameHdr && !In<ELFT>::EhFrameHdr->empty())
1873 ? In<ELFT>::EhFrameHdr->getParent()
1874 : nullptr;
1875
1876 // In -r or -emit-relocs mode, write the relocation sections first as in
1877 // ELf_Rel targets we might find out that we need to modify the relocated
1878 // section while doing it.
1879 for (OutputSectionCommand *Cmd : OutputSectionCommands) {
1880 OutputSection *Sec = Cmd->Sec;
1881 if (Sec->Type == SHT_REL || Sec->Type == SHT_RELA)
1882 Cmd->writeTo<ELFT>(Buf + Sec->Offset);
1883 }
1884
1885 for (OutputSectionCommand *Cmd : OutputSectionCommands) {
1886 OutputSection *Sec = Cmd->Sec;
1887 if (Sec != Out::Opd && Sec != EhFrameHdr && Sec->Type != SHT_REL &&
1888 Sec->Type != SHT_RELA)
1889 Cmd->writeTo<ELFT>(Buf + Sec->Offset);
1890 }
1891
1892 // The .eh_frame_hdr depends on .eh_frame section contents, therefore
1893 // it should be written after .eh_frame is written.
1894 if (EhFrameHdr) {
1895 OutputSectionCommand *Cmd = Script->getCmd(EhFrameHdr);
1896 Cmd->writeTo<ELFT>(Buf + EhFrameHdr->Offset);
1897 }
1898}
1899
1900template <class ELFT> void Writer<ELFT>::writeBuildId() {
1901 if (!InX::BuildId || !InX::BuildId->getParent())
1902 return;
1903
1904 // Compute a hash of all sections of the output file.
1905 uint8_t *Start = Buffer->getBufferStart();
1906 uint8_t *End = Start + FileSize;
1907 InX::BuildId->writeBuildId({Start, End});
1908}
1909
1910template void elf::writeResult<ELF32LE>();
1911template void elf::writeResult<ELF32BE>();
1912template void elf::writeResult<ELF64LE>();
1913template void elf::writeResult<ELF64BE>();
deps/lld/ELF/Writer.h created+61
......@@ -0,0 +1,61 @@
1//===- Writer.h -------------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_ELF_WRITER_H
11#define LLD_ELF_WRITER_H
12
13#include "llvm/ADT/ArrayRef.h"
14#include "llvm/ADT/StringRef.h"
15#include <cstdint>
16#include <memory>
17
18namespace lld {
19namespace elf {
20class InputFile;
21class OutputSection;
22class InputSectionBase;
23template <class ELFT> class ObjectFile;
24template <class ELFT> class SymbolTable;
25template <class ELFT> void writeResult();
26template <class ELFT> void markLive();
27bool isRelroSection(const OutputSection *Sec);
28
29// This describes a program header entry.
30// Each contains type, access flags and range of output sections that will be
31// placed in it.
32struct PhdrEntry {
33 PhdrEntry(unsigned Type, unsigned Flags) : p_type(Type), p_flags(Flags) {}
34 void add(OutputSection *Sec);
35
36 uint64_t p_paddr = 0;
37 uint64_t p_vaddr = 0;
38 uint64_t p_memsz = 0;
39 uint64_t p_filesz = 0;
40 uint64_t p_offset = 0;
41 uint32_t p_align = 0;
42 uint32_t p_type = 0;
43 uint32_t p_flags = 0;
44
45 OutputSection *First = nullptr;
46 OutputSection *Last = nullptr;
47 bool HasLMA = false;
48};
49
50llvm::StringRef getOutputSectionName(llvm::StringRef Name);
51
52template <class ELFT> uint32_t getMipsEFlags();
53
54uint8_t getMipsFpAbiFlag(uint8_t OldFlag, uint8_t NewFlag,
55 llvm::StringRef FileName);
56
57bool isMipsN32Abi(const InputFile *F);
58} // namespace elf
59} // namespace lld
60
61#endif
deps/lld/LICENSE.TXT created+62
......@@ -0,0 +1,62 @@
1==============================================================================
2lld License
3==============================================================================
4University of Illinois/NCSA
5Open Source License
6
7Copyright (c) 2011-2016 by the contributors listed in CREDITS.TXT
8All rights reserved.
9
10Developed by:
11
12 LLVM Team
13
14 University of Illinois at Urbana-Champaign
15
16 http://llvm.org
17
18Permission is hereby granted, free of charge, to any person obtaining a copy of
19this software and associated documentation files (the "Software"), to deal with
20the Software without restriction, including without limitation the rights to
21use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
22of the Software, and to permit persons to whom the Software is furnished to do
23so, subject to the following conditions:
24
25 * Redistributions of source code must retain the above copyright notice,
26 this list of conditions and the following disclaimers.
27
28 * Redistributions in binary form must reproduce the above copyright notice,
29 this list of conditions and the following disclaimers in the
30 documentation and/or other materials provided with the distribution.
31
32 * Neither the names of the LLVM Team, University of Illinois at
33 Urbana-Champaign, nor the names of its contributors may be used to
34 endorse or promote products derived from this Software without specific
35 prior written permission.
36
37THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
38IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
39FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
40CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
41LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
42OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
43SOFTWARE.
44
45==============================================================================
46The lld software contains code written by third parties. Such software will
47have its own individual LICENSE.TXT file in the directory in which it appears.
48This file will describe the copyrights, license, and restrictions which apply
49to that code.
50
51The disclaimer of warranty in the University of Illinois Open Source License
52applies to all code in the lld Distribution, and nothing in any of the
53other licenses gives permission to use the names of the LLVM Team or the
54University of Illinois to endorse or promote products derived from this
55Software.
56
57The following pieces of software have additional or alternate copyrights,
58licenses, and/or restrictions:
59
60Program Directory
61------- ---------
62<none yet>
deps/lld/README.md created+11
......@@ -0,0 +1,11 @@
1
2LLVM Linker (lld)
3==============================
4
5This directory and its subdirectories contain source code for the LLVM Linker, a
6modular cross platform linker which is built as part of the LLVM compiler
7infrastructure project.
8
9lld is open source software. You may freely distribute it under the terms of
10the license agreement found in LICENSE.txt.
11
deps/lld/cmake/modules/AddLLD.cmake created+77
......@@ -0,0 +1,77 @@
1macro(add_lld_library name)
2 cmake_parse_arguments(ARG
3 "SHARED"
4 ""
5 ""
6 ${ARGN})
7 if(ARG_SHARED)
8 set(ARG_ENABLE_SHARED SHARED)
9 endif()
10 llvm_add_library(${name} ${ARG_ENABLE_SHARED} ${ARG_UNPARSED_ARGUMENTS})
11 set_target_properties(${name} PROPERTIES FOLDER "lld libraries")
12
13 if (LLD_BUILD_TOOLS)
14 if(${name} IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR
15 NOT LLVM_DISTRIBUTION_COMPONENTS)
16 set(export_to_lldtargets EXPORT lldTargets)
17 set_property(GLOBAL PROPERTY LLD_HAS_EXPORTS True)
18 endif()
19
20 install(TARGETS ${name}
21 COMPONENT ${name}
22 ${export_to_lldtargets}
23 LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
24 ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX}
25 RUNTIME DESTINATION bin)
26
27 if (${ARG_SHARED} AND NOT CMAKE_CONFIGURATION_TYPES)
28 add_custom_target(install-${name}
29 DEPENDS ${name}
30 COMMAND "${CMAKE_COMMAND}"
31 -DCMAKE_INSTALL_COMPONENT=${name}
32 -P "${CMAKE_BINARY_DIR}/cmake_install.cmake")
33 endif()
34 set_property(GLOBAL APPEND PROPERTY LLD_EXPORTS ${name})
35 endif()
36endmacro(add_lld_library)
37
38macro(add_lld_executable name)
39 add_llvm_executable(${name} ${ARGN})
40 set_target_properties(${name} PROPERTIES FOLDER "lld executables")
41endmacro(add_lld_executable)
42
43macro(add_lld_tool name)
44 if (NOT LLD_BUILD_TOOLS)
45 set(EXCLUDE_FROM_ALL ON)
46 endif()
47
48 add_lld_executable(${name} ${ARGN})
49
50 if (LLD_BUILD_TOOLS)
51 if(${name} IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR
52 NOT LLVM_DISTRIBUTION_COMPONENTS)
53 set(export_to_lldtargets EXPORT lldTargets)
54 set_property(GLOBAL PROPERTY LLD_HAS_EXPORTS True)
55 endif()
56
57 install(TARGETS ${name}
58 ${export_to_lldtargets}
59 RUNTIME DESTINATION bin
60 COMPONENT ${name})
61
62 if(NOT CMAKE_CONFIGURATION_TYPES)
63 add_custom_target(install-${name}
64 DEPENDS ${name}
65 COMMAND "${CMAKE_COMMAND}"
66 -DCMAKE_INSTALL_COMPONENT=${name}
67 -P "${CMAKE_BINARY_DIR}/cmake_install.cmake")
68 endif()
69 set_property(GLOBAL APPEND PROPERTY LLD_EXPORTS ${name})
70 endif()
71endmacro()
72
73macro(add_lld_symlink name dest)
74 add_llvm_tool_symlink(${name} ${dest} ALWAYS_GENERATE)
75 # Always generate install targets
76 llvm_install_symlink(${name} ${dest} ALWAYS_GENERATE)
77endmacro()
deps/lld/cmake/modules/FindVTune.cmake created+31
......@@ -0,0 +1,31 @@
1# - Find VTune ittnotify.
2# Defines:
3# VTune_FOUND
4# VTune_INCLUDE_DIRS
5# VTune_LIBRARIES
6
7set(dirs
8 "$ENV{VTUNE_AMPLIFIER_XE_2013_DIR}/"
9 "C:/Program Files (x86)/Intel/VTune Amplifier XE 2013/"
10 "$ENV{VTUNE_AMPLIFIER_XE_2011_DIR}/"
11 "C:/Program Files (x86)/Intel/VTune Amplifier XE 2011/"
12 )
13
14find_path(VTune_INCLUDE_DIRS ittnotify.h
15 PATHS ${dirs}
16 PATH_SUFFIXES include)
17
18if (CMAKE_SIZEOF_VOID_P MATCHES "8")
19 set(vtune_lib_dir lib64)
20else()
21 set(vtune_lib_dir lib32)
22endif()
23
24find_library(VTune_LIBRARIES libittnotify
25 HINTS "${VTune_INCLUDE_DIRS}/.."
26 PATHS ${dirs}
27 PATH_SUFFIXES ${vtune_lib_dir})
28
29include(FindPackageHandleStandardArgs)
30find_package_handle_standard_args(
31 VTune DEFAULT_MSG VTune_LIBRARIES VTune_INCLUDE_DIRS)
deps/lld/docs/AtomLLD.rst created+62
......@@ -0,0 +1,62 @@
1ATOM-based lld
2==============
3
4Note: this document discuss Mach-O port of LLD. For ELF and COFF,
5see :doc:`index`.
6
7ATOM-based lld is a new set of modular code for creating linker tools.
8Currently it supports Mach-O.
9
10* End-User Features:
11
12 * Compatible with existing linker options
13 * Reads standard Object Files
14 * Writes standard Executable Files
15 * Remove clang's reliance on "the system linker"
16 * Uses the LLVM `"UIUC" BSD-Style license`__.
17
18* Applications:
19
20 * Modular design
21 * Support cross linking
22 * Easy to add new CPU support
23 * Can be built as static tool or library
24
25* Design and Implementation:
26
27 * Extensive unit tests
28 * Internal linker model can be dumped/read to textual format
29 * Additional linking features can be plugged in as "passes"
30 * OS specific and CPU specific code factored out
31
32Why a new linker?
33-----------------
34
35The fact that clang relies on whatever linker tool you happen to have installed
36means that clang has been very conservative adopting features which require a
37recent linker.
38
39In the same way that the MC layer of LLVM has removed clang's reliance on the
40system assembler tool, the lld project will remove clang's reliance on the
41system linker tool.
42
43
44Contents
45--------
46
47.. toctree::
48 :maxdepth: 2
49
50 design
51 getting_started
52 development
53 open_projects
54 sphinx_intro
55
56Indices and tables
57------------------
58
59* :ref:`genindex`
60* :ref:`search`
61
62__ http://llvm.org/docs/DeveloperPolicy.html#license
deps/lld/docs/CMakeLists.txt created+8
......@@ -0,0 +1,8 @@
1if (LLVM_ENABLE_SPHINX)
2 include(AddSphinxTarget)
3 if (SPHINX_FOUND)
4 if (${SPHINX_OUTPUT_HTML})
5 add_sphinx_target(html lld)
6 endif()
7 endif()
8endif()
deps/lld/docs/Driver.rst created+82
......@@ -0,0 +1,82 @@
1======
2Driver
3======
4
5Note: this document discuss Mach-O port of LLD. For ELF and COFF,
6see :doc:`index`.
7
8.. contents::
9 :local:
10
11Introduction
12============
13
14This document describes the lld driver. The purpose of this document is to
15describe both the motivation and design goals for the driver, as well as details
16of the internal implementation.
17
18Overview
19========
20
21The lld driver is designed to support a number of different command line
22interfaces. The main interfaces we plan to support are binutils' ld, Apple's
23ld, and Microsoft's link.exe.
24
25Flavors
26-------
27
28Each of these different interfaces is referred to as a flavor. There is also an
29extra flavor "core" which is used to exercise the core functionality of the
30linker it the test suite.
31
32* gnu
33* darwin
34* link
35* core
36
37Selecting a Flavor
38^^^^^^^^^^^^^^^^^^
39
40There are two different ways to tell lld which flavor to be. They are checked in
41order, so the second overrides the first. The first is to symlink :program:`lld`
42as :program:`lld-{flavor}` or just :program:`{flavor}`. You can also specify
43it as the first command line argument using ``-flavor``::
44
45 $ lld -flavor gnu
46
47There is a shortcut for ``-flavor core`` as ``-core``.
48
49
50Adding an Option to an existing Flavor
51======================================
52
53#. Add the option to the desired :file:`lib/Driver/{flavor}Options.td`.
54
55#. Add to :cpp:class:`lld::FlavorLinkingContext` a getter and setter method
56 for the option.
57
58#. Modify :cpp:func:`lld::FlavorDriver::parse` in :file:
59 `lib/Driver/{Flavor}Driver.cpp` to call the targetInfo setter
60 for corresponding to the option.
61
62#. Modify {Flavor}Reader and {Flavor}Writer to use the new targtInfo option.
63
64
65Adding a Flavor
66===============
67
68#. Add an entry for the flavor in :file:`include/lld/Driver/Driver.h` to
69 :cpp:class:`lld::UniversalDriver::Flavor`.
70
71#. Add an entry in :file:`lib/Driver/UniversalDriver.cpp` to
72 :cpp:func:`lld::Driver::strToFlavor` and
73 :cpp:func:`lld::UniversalDriver::link`.
74 This allows the flavor to be selected via symlink and `-flavor`.
75
76#. Add a tablegen file called :file:`lib/Driver/{flavor}Options.td` that
77 describes the options. If the options are a superset of another driver, that
78 driver's td file can simply be included. The :file:`{flavor}Options.td` file
79 must also be added to :file:`lib/Driver/CMakeLists.txt`.
80
81#. Add a ``{flavor}Driver`` as a subclass of :cpp:class:`lld::Driver`
82 in :file:`lib/Driver/{flavor}Driver.cpp`.
deps/lld/docs/NewLLD.rst created+314
......@@ -0,0 +1,314 @@
1The ELF and COFF Linkers
2========================
3
4The ELF Linker as a Library
5---------------------------
6
7You can embed LLD to your program by linking against it and calling the linker's
8entry point function lld::elf::link.
9
10The current policy is that it is your reponsibility to give trustworthy object
11files. The function is guaranteed to return as long as you do not pass corrupted
12or malicious object files. A corrupted file could cause a fatal error or SEGV.
13That being said, you don't need to worry too much about it if you create object
14files in the usual way and give them to the linker. It is naturally expected to
15work, or otherwise it's a linker's bug.
16
17Design
18======
19
20We will describe the design of the linkers in the rest of the document.
21
22Key Concepts
23------------
24
25Linkers are fairly large pieces of software.
26There are many design choices you have to make to create a complete linker.
27
28This is a list of design choices we've made for ELF and COFF LLD.
29We believe that these high-level design choices achieved a right balance
30between speed, simplicity and extensibility.
31
32* Implement as native linkers
33
34 We implemented the linkers as native linkers for each file format.
35
36 The two linkers share the same design but do not share code.
37 Sharing code makes sense if the benefit is worth its cost.
38 In our case, ELF and COFF are different enough that we thought the layer to
39 abstract the differences wouldn't worth its complexity and run-time cost.
40 Elimination of the abstract layer has greatly simplified the implementation.
41
42* Speed by design
43
44 One of the most important things in archiving high performance is to
45 do less rather than do it efficiently.
46 Therefore, the high-level design matters more than local optimizations.
47 Since we are trying to create a high-performance linker,
48 it is very important to keep the design as efficient as possible.
49
50 Broadly speaking, we do not do anything until we have to do it.
51 For example, we do not read section contents or relocations
52 until we need them to continue linking.
53 When we need to do some costly operation (such as looking up
54 a hash table for each symbol), we do it only once.
55 We obtain a handler (which is typically just a pointer to actual data)
56 on the first operation and use it throughout the process.
57
58* Efficient archive file handling
59
60 LLD's handling of archive files (the files with ".a" file extension) is different
61 from the traditional Unix linkers and similar to Windows linkers.
62 We'll describe how the traditional Unix linker handles archive files,
63 what the problem is, and how LLD approached the problem.
64
65 The traditional Unix linker maintains a set of undefined symbols during linking.
66 The linker visits each file in the order as they appeared in the command line
67 until the set becomes empty. What the linker would do depends on file type.
68
69 - If the linker visits an object file, the linker links object files to the result,
70 and undefined symbols in the object file are added to the set.
71
72 - If the linker visits an archive file, it checks for the archive file's symbol table
73 and extracts all object files that have definitions for any symbols in the set.
74
75 This algorithm sometimes leads to a counter-intuitive behavior.
76 If you give archive files before object files, nothing will happen
77 because when the linker visits archives, there is no undefined symbols in the set.
78 As a result, no files are extracted from the first archive file,
79 and the link is done at that point because the set is empty after it visits one file.
80
81 You can fix the problem by reordering the files,
82 but that cannot fix the issue of mutually-dependent archive files.
83
84 Linking mutually-dependent archive files is tricky.
85 You may specify the same archive file multiple times to
86 let the linker visit it more than once.
87 Or, you may use the special command line options, `--start-group` and `--end-group`,
88 to let the linker loop over the files between the options until
89 no new symbols are added to the set.
90
91 Visiting the same archive files multiple makes the linker slower.
92
93 Here is how LLD approaches the problem. Instead of memorizing only undefined symbols,
94 we program LLD so that it memorizes all symbols.
95 When it sees an undefined symbol that can be resolved by extracting an object file
96 from an archive file it previously visited, it immediately extracts the file and link it.
97 It is doable because LLD does not forget symbols it have seen in archive files.
98
99 We believe that the LLD's way is efficient and easy to justify.
100
101 The semantics of LLD's archive handling is different from the traditional Unix's.
102 You can observe it if you carefully craft archive files to exploit it.
103 However, in reality, we don't know any program that cannot link
104 with our algorithm so far, so it's not going to cause trouble.
105
106Numbers You Want to Know
107------------------------
108
109To give you intuition about what kinds of data the linker is mainly working on,
110I'll give you the list of objects and their numbers LLD has to read and process
111in order to link a very large executable. In order to link Chrome with debug info,
112which is roughly 2 GB in output size, LLD reads
113
114- 17,000 files,
115- 1,800,000 sections,
116- 6,300,000 symbols, and
117- 13,000,000 relocations.
118
119LLD produces the 2 GB executable in 15 seconds.
120
121These numbers vary depending on your program, but in general,
122you have a lot of relocations and symbols for each file.
123If your program is written in C++, symbol names are likely to be
124pretty long because of name mangling.
125
126It is important to not waste time on relocations and symbols.
127
128In the above case, the total amount of symbol strings is 450 MB,
129and inserting all of them to a hash table takes 1.5 seconds.
130Therefore, if you causally add a hash table lookup for each symbol,
131it would slow down the linker by 10%. So, don't do that.
132
133On the other hand, you don't have to pursue efficiency
134when handling files.
135
136Important Data Structures
137-------------------------
138
139We will describe the key data structures in LLD in this section.
140The linker can be understood as the interactions between them.
141Once you understand their functions, the code of the linker should look obvious to you.
142
143* SymbolBody
144
145 SymbolBody is a class to represent symbols.
146 They are created for symbols in object files or archive files.
147 The linker creates linker-defined symbols as well.
148
149 There are basically three types of SymbolBodies: Defined, Undefined, or Lazy.
150
151 - Defined symbols are for all symbols that are considered as "resolved",
152 including real defined symbols, COMDAT symbols, common symbols,
153 absolute symbols, linker-created symbols, etc.
154 - Undefined symbols represent undefined symbols, which need to be replaced by
155 Defined symbols by the resolver until the link is complete.
156 - Lazy symbols represent symbols we found in archive file headers
157 which can turn into Defined if we read archieve members.
158
159* Symbol
160
161 A Symbol is a container for a SymbolBody. There's only one Symbol for each
162 unique symbol name (this uniqueness is guaranteed by the symbol table).
163 Each global symbol has only one SymbolBody at any one time, which is
164 the SymbolBody stored within a memory region of the Symbol large enough
165 to store any SymbolBody.
166
167 As the resolver reads symbols from input files, it replaces the Symbol's
168 SymbolBody with the "best" SymbolBody for its symbol name by constructing
169 the new SymbolBody in place on top of the existing SymbolBody. For example,
170 if the resolver is given a defined symbol, and the SymbolBody with its name
171 is undefined, it will construct a Defined SymbolBody over the Undefined
172 SymbolBody.
173
174 This means that each SymbolBody pointer always points to the best SymbolBody,
175 and it is possible to get from a SymbolBody to a Symbol, or vice versa,
176 by adding or subtracting a fixed offset. This memory layout helps reduce
177 the cache miss rate through high locality and a small number of required
178 pointer indirections.
179
180* SymbolTable
181
182 SymbolTable is basically a hash table from strings to Symbols
183 with logic to resolve symbol conflicts. It resolves conflicts by symbol type.
184
185 - If we add Defined and Undefined symbols, the symbol table will keep the former.
186 - If we add Defined and Lazy symbols, it will keep the former.
187 - If we add Lazy and Undefined, it will keep the former,
188 but it will also trigger the Lazy symbol to load the archive member
189 to actually resolve the symbol.
190
191* Chunk (COFF specific)
192
193 Chunk represents a chunk of data that will occupy space in an output.
194 Each regular section becomes a chunk.
195 Chunks created for common or BSS symbols are not backed by sections.
196 The linker may create chunks to append additional data to an output as well.
197
198 Chunks know about their size, how to copy their data to mmap'ed outputs,
199 and how to apply relocations to them.
200 Specifically, section-based chunks know how to read relocation tables
201 and how to apply them.
202
203* InputSection (ELF specific)
204
205 Since we have less synthesized data for ELF, we don't abstract slices of
206 input files as Chunks for ELF. Instead, we directly use the input section
207 as an internal data type.
208
209 InputSection knows about their size and how to copy themselves to
210 mmap'ed outputs, just like COFF Chunks.
211
212* OutputSection
213
214 OutputSection is a container of InputSections (ELF) or Chunks (COFF).
215 An InputSection or Chunk belongs to at most one OutputSection.
216
217There are mainly three actors in this linker.
218
219* InputFile
220
221 InputFile is a superclass of file readers.
222 We have a different subclass for each input file type,
223 such as regular object file, archive file, etc.
224 They are responsible for creating and owning SymbolBodies and
225 InputSections/Chunks.
226
227* Writer
228
229 The writer is responsible for writing file headers and InputSections/Chunks to a file.
230 It creates OutputSections, put all InputSections/Chunks into them,
231 assign unique, non-overlapping addresses and file offsets to them,
232 and then write them down to a file.
233
234* Driver
235
236 The linking process is driven by the driver. The driver:
237
238 - processes command line options,
239 - creates a symbol table,
240 - creates an InputFile for each input file and puts all symbols within into the symbol table,
241 - checks if there's no remaining undefined symbols,
242 - creates a writer,
243 - and passes the symbol table to the writer to write the result to a file.
244
245Link-Time Optimization
246----------------------
247
248LTO is implemented by handling LLVM bitcode files as object files.
249The linker resolves symbols in bitcode files normally. If all symbols
250are successfully resolved, it then runs LLVM passes
251with all bitcode files to convert them to one big regular ELF/COFF file.
252Finally, the linker replaces bitcode symbols with ELF/COFF symbols,
253so that they are linked as if they were in the native format from the beginning.
254
255The details are described in this document.
256http://llvm.org/docs/LinkTimeOptimization.html
257
258Glossary
259--------
260
261* RVA (COFF)
262
263 Short for Relative Virtual Address.
264
265 Windows executables or DLLs are not position-independent; they are
266 linked against a fixed address called an image base. RVAs are
267 offsets from an image base.
268
269 Default image bases are 0x140000000 for executables and 0x18000000
270 for DLLs. For example, when we are creating an executable, we assume
271 that the executable will be loaded at address 0x140000000 by the
272 loader, so we apply relocations accordingly. Result texts and data
273 will contain raw absolute addresses.
274
275* VA
276
277 Short for Virtual Address. For COFF, it is equivalent to RVA + image base.
278
279* Base relocations (COFF)
280
281 Relocation information for the loader. If the loader decides to map
282 an executable or a DLL to a different address than their image
283 bases, it fixes up binaries using information contained in the base
284 relocation table. A base relocation table consists of a list of
285 locations containing addresses. The loader adds a difference between
286 RVA and actual load address to all locations listed there.
287
288 Note that this run-time relocation mechanism is much simpler than ELF.
289 There's no PLT or GOT. Images are relocated as a whole just
290 by shifting entire images in memory by some offsets. Although doing
291 this breaks text sharing, I think this mechanism is not actually bad
292 on today's computers.
293
294* ICF
295
296 Short for Identical COMDAT Folding (COFF) or Identical Code Folding (ELF).
297
298 ICF is an optimization to reduce output size by merging read-only sections
299 by not only their names but by their contents. If two read-only sections
300 happen to have the same metadata, actual contents and relocations,
301 they are merged by ICF. It is known as an effective technique,
302 and it usually reduces C++ program's size by a few percent or more.
303
304 Note that this is not entirely sound optimization. C/C++ require
305 different functions have different addresses. If a program depends on
306 that property, it would fail at runtime.
307
308 On Windows, that's not really an issue because MSVC link.exe enabled
309 the optimization by default. As long as your program works
310 with the linker's default settings, your program should be safe with ICF.
311
312 On Unix, your program is generally not guaranteed to be safe with ICF,
313 although large programs happen to work correctly.
314 LLD works fine with ICF for example.
deps/lld/docs/README.txt created+12
......@@ -0,0 +1,12 @@
1lld Documentation
2=================
3
4The lld documentation is written using the Sphinx documentation generator. It is
5currently tested with Sphinx 1.1.3.
6
7We currently use the 'nature' theme and a Beaker inspired structure.
8
9To rebuild documents into html:
10
11 [/lld/docs]> make html
12
deps/lld/docs/Readers.rst created+174
......@@ -0,0 +1,174 @@
1.. _Readers:
2
3Developing lld Readers
4======================
5
6Note: this document discuss Mach-O port of LLD. For ELF and COFF,
7see :doc:`index`.
8
9Introduction
10------------
11
12The purpose of a "Reader" is to take an object file in a particular format
13and create an `lld::File`:cpp:class: (which is a graph of Atoms)
14representing the object file. A Reader inherits from
15`lld::Reader`:cpp:class: which lives in
16:file:`include/lld/Core/Reader.h` and
17:file:`lib/Core/Reader.cpp`.
18
19The Reader infrastructure for an object format ``Foo`` requires the
20following pieces in order to fit into lld:
21
22:file:`include/lld/ReaderWriter/ReaderFoo.h`
23
24 .. cpp:class:: ReaderOptionsFoo : public ReaderOptions
25
26 This Options class is the only way to configure how the Reader will
27 parse any file into an `lld::Reader`:cpp:class: object. This class
28 should be declared in the `lld`:cpp:class: namespace.
29
30 .. cpp:function:: Reader *createReaderFoo(ReaderOptionsFoo &reader)
31
32 This factory function configures and create the Reader. This function
33 should be declared in the `lld`:cpp:class: namespace.
34
35:file:`lib/ReaderWriter/Foo/ReaderFoo.cpp`
36
37 .. cpp:class:: ReaderFoo : public Reader
38
39 This is the concrete Reader class which can be called to parse
40 object files. It should be declared in an anonymous namespace or
41 if there is shared code with the `lld::WriterFoo`:cpp:class: you
42 can make a nested namespace (e.g. `lld::foo`:cpp:class:).
43
44You may have noticed that :cpp:class:`ReaderFoo` is not declared in the
45``.h`` file. An important design aspect of lld is that all Readers are
46created *only* through an object-format-specific
47:cpp:func:`createReaderFoo` factory function. The creation of the Reader is
48parametrized through a :cpp:class:`ReaderOptionsFoo` class. This options
49class is the one-and-only way to control how the Reader operates when
50parsing an input file into an Atom graph. For instance, you may want the
51Reader to only accept certain architectures. The options class can be
52instantiated from command line options or be programmatically configured.
53
54Where to start
55--------------
56
57The lld project already has a skeleton of source code for Readers for
58``ELF``, ``PECOFF``, ``MachO``, and lld's native ``YAML`` graph format.
59If your file format is a variant of one of those, you should modify the
60existing Reader to support your variant. This is done by customizing the Options
61class for the Reader and making appropriate changes to the ``.cpp`` file to
62interpret those options and act accordingly.
63
64If your object file format is not a variant of any existing Reader, you'll need
65to create a new Reader subclass with the organization described above.
66
67Readers are factories
68---------------------
69
70The linker will usually only instantiate your Reader once. That one Reader will
71have its loadFile() method called many times with different input files.
72To support multithreaded linking, the Reader may be parsing multiple input
73files in parallel. Therefore, there should be no parsing state in you Reader
74object. Any parsing state should be in ivars of your File subclass or in
75some temporary object.
76
77The key method to implement in a reader is::
78
79 virtual error_code loadFile(LinkerInput &input,
80 std::vector<std::unique_ptr<File>> &result);
81
82It takes a memory buffer (which contains the contents of the object file
83being read) and returns an instantiated lld::File object which is
84a collection of Atoms. The result is a vector of File pointers (instead of
85simple a File pointer) because some file formats allow multiple object
86"files" to be encoded in one file system file.
87
88
89Memory Ownership
90----------------
91
92Atoms are always owned by their File object. During core linking when Atoms
93are coalesced or stripped away, core linking does not delete them.
94Core linking just removes those unused Atoms from its internal list.
95The destructor of a File object is responsible for deleting all Atoms it
96owns, and if ownership of the MemoryBuffer was passed to it, the File
97destructor needs to delete that too.
98
99Making Atoms
100------------
101
102The internal model of lld is purely Atom based. But most object files do not
103have an explicit concept of Atoms, instead most have "sections". The way
104to think of this is that a section is just a list of Atoms with common
105attributes.
106
107The first step in parsing section-based object files is to cleave each
108section into a list of Atoms. The technique may vary by section type. For
109code sections (e.g. .text), there are usually symbols at the start of each
110function. Those symbol addresses are the points at which the section is
111cleaved into discrete Atoms. Some file formats (like ELF) also include the
112length of each symbol in the symbol table. Otherwise, the length of each
113Atom is calculated to run to the start of the next symbol or the end of the
114section.
115
116Other sections types can be implicitly cleaved. For instance c-string literals
117or unwind info (e.g. .eh_frame) can be cleaved by having the Reader look at
118the content of the section. It is important to cleave sections into Atoms
119to remove false dependencies. For instance the .eh_frame section often
120has no symbols, but contains "pointers" to the functions for which it
121has unwind info. If the .eh_frame section was not cleaved (but left as one
122big Atom), there would always be a reference (from the eh_frame Atom) to
123each function. So the linker would be unable to coalesce or dead stripped
124away the function atoms.
125
126The lld Atom model also requires that a reference to an undefined symbol be
127modeled as a Reference to an UndefinedAtom. So the Reader also needs to
128create an UndefinedAtom for each undefined symbol in the object file.
129
130Once all Atoms have been created, the second step is to create References
131(recall that Atoms are "nodes" and References are "edges"). Most References
132are created by looking at the "relocation records" in the object file. If
133a function contains a call to "malloc", there is usually a relocation record
134specifying the address in the section and the symbol table index. Your
135Reader will need to convert the address to an Atom and offset and the symbol
136table index into a target Atom. If "malloc" is not defined in the object file,
137the target Atom of the Reference will be an UndefinedAtom.
138
139
140Performance
141-----------
142Once you have the above working to parse an object file into Atoms and
143References, you'll want to look at performance. Some techniques that can
144help performance are:
145
146* Use llvm::BumpPtrAllocator or pre-allocate one big vector<Reference> and then
147 just have each atom point to its subrange of References in that vector.
148 This can be faster that allocating each Reference as separate object.
149* Pre-scan the symbol table and determine how many atoms are in each section
150 then allocate space for all the Atom objects at once.
151* Don't copy symbol names or section content to each Atom, instead use
152 StringRef and ArrayRef in each Atom to point to its name and content in the
153 MemoryBuffer.
154
155
156Testing
157-------
158
159We are still working on infrastructure to test Readers. The issue is that
160you don't want to check in binary files to the test suite. And the tools
161for creating your object file from assembly source may not be available on
162every OS.
163
164We are investigating a way to use YAML to describe the section, symbols,
165and content of a file. Then have some code which will write out an object
166file from that YAML description.
167
168Once that is in place, you can write test cases that contain section/symbols
169YAML and is run through the linker to produce Atom/References based YAML which
170is then run through FileCheck to verify the Atoms and References are as
171expected.
172
173
174
deps/lld/docs/ReleaseNotes.rst created+172
......@@ -0,0 +1,172 @@
1=======================
2lld 5.0.0 Release Notes
3=======================
4
5.. contents::
6 :local:
7
8Introduction
9============
10
11lld is a linker from the LLVM project. It supports ELF (Unix), COFF (Windows)
12and Mach-O (macOS), and it is generally faster than the GNU bfd or gold linkers
13or the MSVC linker.
14
15lld is designed to be a drop-in replacement for the system linkers, so that
16users don't need to change their build systems other than swapping the linker
17command.
18
19All lld releases may be downloaded from the `LLVM releases web site
20<http://llvm.org/releases/>`_.
21
22Non-comprehensive list of changes in this release
23=================================================
24
25ELF Improvements
26----------------
27
28* First and foremost, a lot of compatibility issues and bugs have been fixed.
29 Linker script support has significantly improved. As a result, we believe you
30 are very likely to be able to link your programs with lld without experiencing
31 any problem now.
32
33* Error message format has changed in order to improve readability.
34 Traditionally, linker's error messages are concise and arguably too terse.
35 This is an example of lld 4.0.0's error message (they are actually in one line)::
36
37 /ssd/clang/bin/ld.lld: error: /ssd/llvm-project/lld/ELF/Writer.cpp:207:
38 undefined symbol 'lld::elf::EhFrameSection::addSection()'
39
40 It is not easy to read because too much information is packed into a single line
41 and the embedded text, particularly a symbol name, is sometimes too long.
42 In lld 5.0.0, we use more vertical space to print out error messages in a more
43 structured manner like this::
44
45 bin/ld.lld: error: undefined symbol: lld::elf::EhFrameSection::addSection()
46 >>> Referenced by Writer.cpp:207 (/ssd/llvm-project/lld/ELF/Writer.cpp:207)
47 >>> Writer.cpp.o in archive lib/liblldELF.a
48
49 As a bonus, the new error message contains source code location of the error
50 if it is available from debug info.
51
52* ``./configure`` scripts generated by GNU autoconf determines whether a linker
53 supports modern GNU-compatible features or not by searching for "GNU" in the
54 ``--help`` message. To be compatible with the scripts, we decided to add a
55 string "(compatible with GNU linkers)" to our ``--help`` message. This is a
56 hack, but just like the web browser's User-Agent string (which everyone still
57 claim they are "Mozilla/5.0"), we had no choice other than doing this to claim
58 that we accept GNU-compatible options.
59
60* The ``-Map`` option is added. The option is to make the linker to print out how
61 input files are mapped to the output file. Here is an example::
62
63 Address Size Align Out In Symbol
64 00000000016d84d8 00000000008f8f50 8 .eh_frame
65 00000000016d84d8 00000000008f8f50 8 <internal>:(.eh_frame)
66 0000000001fd2000 00000000034b3bd0 16 .text
67 0000000001fd2000 000000000000002a 1 /usr/lib/x86_64-linux-gnu/crt1.o:(.text)
68 0000000001fd2000 0000000000000000 0 _start
69 0000000001fd202a 0000000000000000 1 /usr/lib/x86_64-linux-gnu/crti.o:(.text)
70 0000000001fd2030 00000000000000bd 16 /usr/lib/gcc/x86_64-linux-gnu/4.8/crtbegin.o:(.text)
71 0000000001fd2030 0000000000000000 0 deregister_tm_clones
72 0000000001fd2060 0000000000000000 0 register_tm_clones
73
74 This format is not the same as GNU linkers as our linker internal data
75 structure is different from them but contains the same amount of information
76 and should be more readable than their outputs.
77
78 As with other lld features, the ``-Map`` option is designed with speed in mind.
79 The option would generate a hundred megabyte text file if you link a large
80 program with it. lld can usually do that in a few seconds, and it is generally
81 a few times faster than the GNU gold's ``-Map`` option.
82
83* lld's ``--gdb-index`` option used to be slow, but we sped it up so that it is
84 at least as fast as the GNU gold.
85
86* Some nonstandard relocations, such as R_X86_64_8 or R_X86_64_16, are supported.
87 They are not used for 32/64-bit applications, but some 16-bit bootloaders need
88 them.
89
90* Paddings in executable text sections are now filled with trap instructions
91 (such as INT3) instead of being left as null bytes. This change improves
92 disassembler outputs because it now prints out trap instructions instead of
93 trying to decode 0x00 as an instruction. It also makes debugging of some type
94 of program easier because when the control reaches a padding, the program
95 immediately raises an error.
96
97* The following options are added: ``-M``, ``-Map``,
98 ``-compress-debug-sections``, ``-emit-relocs``,
99 ``-error-unresolved-symbols``, ``-exclude-libs``, ``-filter``,
100 ``-no-dynamic-linker``, ``-no-export-dynamic``, ``-no-fatal-warnings``,
101 ``-print-map``, ``-warn-unresolved-symbols``, ``-z nocopyreloc``,
102 ``-z notext``, ``-z rodynamic``
103
104
105Contributors to lld 5.0
106=======================
107
108We had 63 individuals contribute to lld 5.0. Thank you so much!
109
110- Adrian McCarthy
111- Alberto Magni
112- Alexander Richardson
113- Andre Vieira
114- Andrew Ng
115- Anton Korobeynikov
116- Bob Haarman
117- David Blaikie
118- Davide Italiano
119- David L. Jones
120- Dmitry Mikulin
121- Ed Maste
122- Ed Schouten
123- Eric Beckmann
124- Eric Fiselier
125- Eugene Leviant
126- Evgeniy Stepanov
127- Galina Kistanova
128- George Rimar
129- Hans Wennborg
130- Igor Kudrin
131- Ismail Donmez
132- Jake Ehrlich
133- James Henderson
134- Joel Jones
135- Jon Chesterfield
136- Kamil Rytarowski
137- Kevin Enderby
138- Konstantin Zhuravlyov
139- Kyungwoo Lee
140- Leslie Zhai
141- Mark Kettenis
142- Martell Malone
143- Martin Storsjo
144- Meador Inge
145- Mehdi Amini
146- Michal Gorny
147- NAKAMURA Takumi
148- Paul Robinson
149- Pavel Labath
150- Petar Jovanovic
151- Peter Collingbourne
152- Peter Smith
153- Petr Hosek
154- Rafael Espindola
155- Reid Kleckner
156- Richard Smith
157- Robert Clarke
158- Rui Ueyama
159- Saleem Abdulrasool
160- Sam Clegg
161- Sean Eveson
162- Sean Silva
163- Shankar Easwaran
164- Shoaib Meenai
165- Simon Atanasyan
166- Simon Dardis
167- Simon Tatham
168- Sylvestre Ledru
169- Tom Stellard
170- Vitaly Buka
171- Yuka Takahashi
172- Zachary Turner
deps/lld/docs/_static/favicon.ico created
Binary files /dev/null and b/deps/lld/docs/_static/favicon.ico differ
deps/lld/docs/_templates/indexsidebar.html created+4
......@@ -0,0 +1,4 @@
1<h3>Bugs</h3>
2
3<p>lld bugs should be reported at the
4 LLVM <a href="http://llvm.org/bugs">Bugzilla</a>.</p>
deps/lld/docs/_templates/layout.html created+12
......@@ -0,0 +1,12 @@
1{% extends "!layout.html" %}
2
3{% block extrahead %}
4<style type="text/css">
5 table.right { float: right; margin-left: 20px; }
6 table.right td { border: 1px solid #ccc; }
7</style>
8{% endblock %}
9
10{% block rootrellink %}
11 <li><a href="{{ pathto('index') }}">lld Home</a>&nbsp;|&nbsp;</li>
12{% endblock %}
deps/lld/docs/conf.py created+255
......@@ -0,0 +1,255 @@
1# -*- coding: utf-8 -*-
2#
3# lld documentation build configuration file.
4#
5# This file is execfile()d with the current directory set to its containing dir.
6#
7# Note that not all possible configuration values are present in this
8# autogenerated file.
9#
10# All configuration values have a default; values that are commented out
11# serve to show the default.
12
13import sys, os
14from datetime import date
15
16# If extensions (or modules to document with autodoc) are in another directory,
17# add these directories to sys.path here. If the directory is relative to the
18# documentation root, use os.path.abspath to make it absolute, like shown here.
19#sys.path.insert(0, os.path.abspath('.'))
20
21# -- General configuration -----------------------------------------------------
22
23# If your documentation needs a minimal Sphinx version, state it here.
24#needs_sphinx = '1.0'
25
26# Add any Sphinx extension module names here, as strings. They can be extensions
27# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
28extensions = ['sphinx.ext.intersphinx', 'sphinx.ext.todo']
29
30# Add any paths that contain templates here, relative to this directory.
31templates_path = ['_templates']
32
33# The suffix of source filenames.
34source_suffix = '.rst'
35
36# The encoding of source files.
37#source_encoding = 'utf-8-sig'
38
39# The master toctree document.
40master_doc = 'index'
41
42# General information about the project.
43project = u'lld'
44copyright = u'2011-%d, LLVM Project' % date.today().year
45
46# The version info for the project you're documenting, acts as replacement for
47# |version| and |release|, also used in various other places throughout the
48# built documents.
49#
50# The short version.
51version = '5'
52# The full version, including alpha/beta/rc tags.
53release = '5'
54
55# The language for content autogenerated by Sphinx. Refer to documentation
56# for a list of supported languages.
57#language = None
58
59# There are two options for replacing |today|: either, you set today to some
60# non-false value, then it is used:
61#today = ''
62# Else, today_fmt is used as the format for a strftime call.
63today_fmt = '%Y-%m-%d'
64
65# List of patterns, relative to source directory, that match files and
66# directories to ignore when looking for source files.
67exclude_patterns = ['_build']
68
69# The reST default role (used for this markup: `text`) to use for all documents.
70#default_role = None
71
72# If true, '()' will be appended to :func: etc. cross-reference text.
73#add_function_parentheses = True
74
75# If true, the current module name will be prepended to all description
76# unit titles (such as .. function::).
77#add_module_names = True
78
79# If true, sectionauthor and moduleauthor directives will be shown in the
80# output. They are ignored by default.
81show_authors = True
82
83# The name of the Pygments (syntax highlighting) style to use.
84pygments_style = 'friendly'
85
86# A list of ignored prefixes for module index sorting.
87#modindex_common_prefix = []
88
89
90# -- Options for HTML output ---------------------------------------------------
91
92# The theme to use for HTML and HTML Help pages. See the documentation for
93# a list of builtin themes.
94html_theme = 'llvm-theme'
95
96# Theme options are theme-specific and customize the look and feel of a theme
97# further. For a list of options available for each theme, see the
98# documentation.
99#html_theme_options = {}
100
101# Add any paths that contain custom themes here, relative to this directory.
102html_theme_path = ["."]
103
104# The name for this set of Sphinx documents. If None, it defaults to
105# "<project> v<release> documentation".
106#html_title = None
107
108# A shorter title for the navigation bar. Default is the same as html_title.
109#html_short_title = None
110
111# The name of an image file (relative to this directory) to place at the top
112# of the sidebar.
113#html_logo = None
114
115# If given, this must be the name of an image file (path relative to the
116# configuration directory) that is the favicon of the docs. Modern browsers use
117# this as icon for tabs, windows and bookmarks. It should be a Windows-style
118# icon file (.ico), which is 16x16 or 32x32 pixels large. Default: None. The
119# image file will be copied to the _static directory of the output HTML, but
120# only if the file does not already exist there.
121html_favicon = '_static/favicon.ico'
122
123# Add any paths that contain custom static files (such as style sheets) here,
124# relative to this directory. They are copied after the builtin static files,
125# so a file named "default.css" will overwrite the builtin "default.css".
126html_static_path = ['_static']
127
128# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
129# using the given strftime format.
130html_last_updated_fmt = '%Y-%m-%d'
131
132# If true, SmartyPants will be used to convert quotes and dashes to
133# typographically correct entities.
134#html_use_smartypants = True
135
136# Custom sidebar templates, maps document names to template names.
137html_sidebars = {'index': 'indexsidebar.html'}
138
139# Additional templates that should be rendered to pages, maps page names to
140# template names.
141# html_additional_pages = {'index': 'index.html'}
142
143# If false, no module index is generated.
144#html_domain_indices = True
145
146# If false, no index is generated.
147#html_use_index = True
148
149# If true, the index is split into individual pages for each letter.
150#html_split_index = False
151
152# If true, links to the reST sources are added to the pages.
153html_show_sourcelink = True
154
155# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
156#html_show_sphinx = True
157
158# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
159#html_show_copyright = True
160
161# If true, an OpenSearch description file will be output, and all pages will
162# contain a <link> tag referring to it. The value of this option must be the
163# base URL from which the finished HTML is served.
164#html_use_opensearch = ''
165
166# This is the file name suffix for HTML files (e.g. ".xhtml").
167#html_file_suffix = None
168
169# Output file base name for HTML help builder.
170htmlhelp_basename = 'llddoc'
171
172
173# -- Options for LaTeX output --------------------------------------------------
174
175latex_elements = {
176# The paper size ('letterpaper' or 'a4paper').
177#'papersize': 'letterpaper',
178
179# The font size ('10pt', '11pt' or '12pt').
180#'pointsize': '10pt',
181
182# Additional stuff for the LaTeX preamble.
183#'preamble': '',
184}
185
186# Grouping the document tree into LaTeX files. List of tuples
187# (source start file, target name, title, author, documentclass [howto/manual]).
188latex_documents = [
189 ('contents', 'lld.tex', u'lld Documentation',
190 u'LLVM project', 'manual'),
191]
192
193# The name of an image file (relative to this directory) to place at the top of
194# the title page.
195#latex_logo = None
196
197# For "manual" documents, if this is true, then toplevel headings are parts,
198# not chapters.
199#latex_use_parts = False
200
201# If true, show page references after internal links.
202#latex_show_pagerefs = False
203
204# If true, show URL addresses after external links.
205#latex_show_urls = False
206
207# Documents to append as an appendix to all manuals.
208#latex_appendices = []
209
210# If false, no module index is generated.
211#latex_domain_indices = True
212
213
214# -- Options for manual page output --------------------------------------------
215
216# One entry per manual page. List of tuples
217# (source start file, name, description, authors, manual section).
218man_pages = [
219 ('contents', 'lld', u'lld Documentation',
220 [u'LLVM project'], 1)
221]
222
223# If true, show URL addresses after external links.
224#man_show_urls = False
225
226
227# -- Options for Texinfo output ------------------------------------------------
228
229# Grouping the document tree into Texinfo files. List of tuples
230# (source start file, target name, title, author,
231# dir menu entry, description, category)
232texinfo_documents = [
233 ('contents', 'lld', u'lld Documentation',
234 u'LLVM project', 'lld', 'One line description of project.',
235 'Miscellaneous'),
236]
237
238# Documents to append as an appendix to all manuals.
239#texinfo_appendices = []
240
241# If false, no module index is generated.
242#texinfo_domain_indices = True
243
244# How to display URL addresses: 'footnote', 'no', or 'inline'.
245#texinfo_show_urls = 'footnote'
246
247
248# FIXME: Define intersphinx configration.
249intersphinx_mapping = {}
250
251
252# -- Options for extensions ----------------------------------------------------
253
254# Enable this if you want TODOs to show up in the generated documentation.
255todo_include_todos = True
deps/lld/docs/design.rst created+421
......@@ -0,0 +1,421 @@
1.. _design:
2
3Linker Design
4=============
5
6Note: this document discuss Mach-O port of LLD. For ELF and COFF,
7see :doc:`index`.
8
9Introduction
10------------
11
12lld is a new generation of linker. It is not "section" based like traditional
13linkers which mostly just interlace sections from multiple object files into the
14output file. Instead, lld is based on "Atoms". Traditional section based
15linking work well for simple linking, but their model makes advanced linking
16features difficult to implement. Features like dead code stripping, reordering
17functions for locality, and C++ coalescing require the linker to work at a finer
18grain.
19
20An atom is an indivisible chunk of code or data. An atom has a set of
21attributes, such as: name, scope, content-type, alignment, etc. An atom also
22has a list of References. A Reference contains: a kind, an optional offset, an
23optional addend, and an optional target atom.
24
25The Atom model allows the linker to use standard graph theory models for linking
26data structures. Each atom is a node, and each Reference is an edge. The
27feature of dead code stripping is implemented by following edges to mark all
28live atoms, and then delete the non-live atoms.
29
30
31Atom Model
32----------
33
34An atom is an indivisible chunk of code or data. Typically each user written
35function or global variable is an atom. In addition, the compiler may emit
36other atoms, such as for literal c-strings or floating point constants, or for
37runtime data structures like dwarf unwind info or pointers to initializers.
38
39A simple "hello world" object file would be modeled like this:
40
41.. image:: hello.png
42
43There are three atoms: main, a proxy for printf, and an anonymous atom
44containing the c-string literal "hello world". The Atom "main" has two
45references. One is the call site for the call to printf, and the other is a
46reference for the instruction that loads the address of the c-string literal.
47
48There are only four different types of atoms:
49
50 * DefinedAtom
51 95% of all atoms. This is a chunk of code or data
52
53 * UndefinedAtom
54 This is a place holder in object files for a reference to some atom
55 outside the translation unit.During core linking it is usually replaced
56 by (coalesced into) another Atom.
57
58 * SharedLibraryAtom
59 If a required symbol name turns out to be defined in a dynamic shared
60 library (and not some object file). A SharedLibraryAtom is the
61 placeholder Atom used to represent that fact.
62
63 It is similar to an UndefinedAtom, but it also tracks information
64 about the associated shared library.
65
66 * AbsoluteAtom
67 This is for embedded support where some stuff is implemented in ROM at
68 some fixed address. This atom has no content. It is just an address
69 that the Writer needs to fix up any references to point to.
70
71
72File Model
73----------
74
75The linker views the input files as basically containers of Atoms and
76References, and just a few attributes of their own. The linker works with three
77kinds of files: object files, static libraries, and dynamic shared libraries.
78Each kind of file has reader object which presents the file in the model
79expected by the linker.
80
81Object File
82~~~~~~~~~~~
83
84An object file is just a container of atoms. When linking an object file, a
85reader is instantiated which parses the object file and instantiates a set of
86atoms representing all content in the .o file. The linker adds all those atoms
87to a master graph.
88
89Static Library (Archive)
90~~~~~~~~~~~~~~~~~~~~~~~~
91
92This is the traditional unix static archive which is just a collection of object
93files with a "table of contents". When linking with a static library, by default
94nothing is added to the master graph of atoms. Instead, if after merging all
95atoms from object files into a master graph, if any "undefined" atoms are left
96remaining in the master graph, the linker reads the table of contents for each
97static library to see if any have the needed definitions. If so, the set of
98atoms from the specified object file in the static library is added to the
99master graph of atoms.
100
101Dynamic Library (Shared Object)
102~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
103
104Dynamic libraries are different than object files and static libraries in that
105they don't directly add any content. Their purpose is to check at build time
106that the remaining undefined references can be resolved at runtime, and provide
107a list of dynamic libraries (SO_NEEDED) that will be needed at runtime. The way
108this is modeled in the linker is that a dynamic library contributes no atoms to
109the initial graph of atoms. Instead, (like static libraries) if there are
110"undefined" atoms in the master graph of all atoms, then each dynamic library is
111checked to see if exports the required symbol. If so, a "shared library" atom is
112instantiated by the by the reader which the linker uses to replace the
113"undefined" atom.
114
115Linking Steps
116-------------
117
118Through the use of abstract Atoms, the core of linking is architecture
119independent and file format independent. All command line parsing is factored
120out into a separate "options" abstraction which enables the linker to be driven
121with different command line sets.
122
123The overall steps in linking are:
124
125 #. Command line processing
126
127 #. Parsing input files
128
129 #. Resolving
130
131 #. Passes/Optimizations
132
133 #. Generate output file
134
135The Resolving and Passes steps are done purely on the master graph of atoms, so
136they have no notion of file formats such as mach-o or ELF.
137
138
139Input Files
140~~~~~~~~~~~
141
142Existing developer tools using different file formats for object files.
143A goal of lld is to be file format independent. This is done
144through a plug-in model for reading object files. The lld::Reader is the base
145class for all object file readers. A Reader follows the factory method pattern.
146A Reader instantiates an lld::File object (which is a graph of Atoms) from a
147given object file (on disk or in-memory).
148
149Every Reader subclass defines its own "options" class (for instance the mach-o
150Reader defines the class ReaderOptionsMachO). This options class is the
151one-and-only way to control how the Reader operates when parsing an input file
152into an Atom graph. For instance, you may want the Reader to only accept
153certain architectures. The options class can be instantiated from command
154line options, or it can be subclassed and the ivars programmatically set.
155
156Resolving
157~~~~~~~~~
158
159The resolving step takes all the atoms' graphs from each object file and
160combines them into one master object graph. Unfortunately, it is not as simple
161as appending the atom list from each file into one big list. There are many
162cases where atoms need to be coalesced. That is, two or more atoms need to be
163coalesced into one atom. This is necessary to support: C language "tentative
164definitions", C++ weak symbols for templates and inlines defined in headers,
165replacing undefined atoms with actual definition atoms, and for merging copies
166of constants like c-strings and floating point constants.
167
168The linker support coalescing by-name and by-content. By-name is used for
169tentative definitions and weak symbols. By-content is used for constant data
170that can be merged.
171
172The resolving process maintains some global linking "state", including a "symbol
173table" which is a map from llvm::StringRef to lld::Atom*. With these data
174structures, the linker iterates all atoms in all input files. For each atom, it
175checks if the atom is named and has a global or hidden scope. If so, the atom
176is added to the symbol table map. If there already is a matching atom in that
177table, that means the current atom needs to be coalesced with the found atom, or
178it is a multiple definition error.
179
180When all initial input file atoms have been processed by the resolver, a scan is
181made to see if there are any undefined atoms in the graph. If there are, the
182linker scans all libraries (both static and dynamic) looking for definitions to
183replace the undefined atoms. It is an error if any undefined atoms are left
184remaining.
185
186Dead code stripping (if requested) is done at the end of resolving. The linker
187does a simple mark-and-sweep. It starts with "root" atoms (like "main" in a main
188executable) and follows each references and marks each Atom that it visits as
189"live". When done, all atoms not marked "live" are removed.
190
191The result of the Resolving phase is the creation of an lld::File object. The
192goal is that the lld::File model is **the** internal representation
193throughout the linker. The file readers parse (mach-o, ELF, COFF) into an
194lld::File. The file writers (mach-o, ELF, COFF) taken an lld::File and produce
195their file kind, and every Pass only operates on an lld::File. This is not only
196a simpler, consistent model, but it enables the state of the linker to be dumped
197at any point in the link for testing purposes.
198
199
200Passes
201~~~~~~
202
203The Passes step is an open ended set of routines that each get a change to
204modify or enhance the current lld::File object. Some example Passes are:
205
206 * stub (PLT) generation
207
208 * GOT instantiation
209
210 * order_file optimization
211
212 * branch island generation
213
214 * branch shim generation
215
216 * Objective-C optimizations (Darwin specific)
217
218 * TLV instantiation (Darwin specific)
219
220 * DTrace probe processing (Darwin specific)
221
222 * compact unwind encoding (Darwin specific)
223
224
225Some of these passes are specific to Darwin's runtime environments. But many of
226the passes are applicable to any OS (such as generating branch island for out of
227range branch instructions).
228
229The general structure of a pass is to iterate through the atoms in the current
230lld::File object, inspecting each atom and doing something. For instance, the
231stub pass, looks for call sites to shared library atoms (e.g. call to printf).
232It then instantiates a "stub" atom (PLT entry) and a "lazy pointer" atom for
233each proxy atom needed, and these new atoms are added to the current lld::File
234object. Next, all the noted call sites to shared library atoms have their
235References altered to point to the stub atom instead of the shared library atom.
236
237
238Generate Output File
239~~~~~~~~~~~~~~~~~~~~
240
241Once the passes are done, the output file writer is given current lld::File
242object. The writer's job is to create the executable content file wrapper and
243place the content of the atoms into it.
244
245lld uses a plug-in model for writing output files. All concrete writers (e.g.
246ELF, mach-o, etc) are subclasses of the lld::Writer class.
247
248Unlike the Reader class which has just one method to instantiate an lld::File,
249the Writer class has multiple methods. The crucial method is to generate the
250output file, but there are also methods which allow the Writer to contribute
251Atoms to the resolver and specify passes to run.
252
253An example of contributing
254atoms is that if the Writer knows a main executable is being linked and such
255an executable requires a specially named entry point (e.g. "_main"), the Writer
256can add an UndefinedAtom with that special name to the resolver. This will
257cause the resolver to issue an error if that symbol is not defined.
258
259Sometimes a Writer supports lazily created symbols, such as names for the start
260of sections. To support this, the Writer can create a File object which vends
261no initial atoms, but does lazily supply atoms by name as needed.
262
263Every Writer subclass defines its own "options" class (for instance the mach-o
264Writer defines the class WriterOptionsMachO). This options class is the
265one-and-only way to control how the Writer operates when producing an output
266file from an Atom graph. For instance, you may want the Writer to optimize
267the output for certain OS versions, or strip local symbols, etc. The options
268class can be instantiated from command line options, or it can be subclassed
269and the ivars programmatically set.
270
271
272lld::File representations
273-------------------------
274
275Just as LLVM has three representations of its IR model, lld has two
276representations of its File/Atom/Reference model:
277
278 * In memory, abstract C++ classes (lld::Atom, lld::Reference, and lld::File).
279
280 * textual (in YAML)
281
282
283Textual representations in YAML
284~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
285
286In designing a textual format we want something easy for humans to read and easy
287for the linker to parse. Since an atom has lots of attributes most of which are
288usually just the default, we should define default values for every attribute so
289that those can be omitted from the text representation. Here is the atoms for a
290simple hello world program expressed in YAML::
291
292 target-triple: x86_64-apple-darwin11
293
294 atoms:
295 - name: _main
296 scope: global
297 type: code
298 content: [ 55, 48, 89, e5, 48, 8d, 3d, 00, 00, 00, 00, 30, c0, e8, 00, 00,
299 00, 00, 31, c0, 5d, c3 ]
300 fixups:
301 - offset: 07
302 kind: pcrel32
303 target: 2
304 - offset: 0E
305 kind: call32
306 target: _fprintf
307
308 - type: c-string
309 content: [ 73, 5A, 00 ]
310
311 ...
312
313The biggest use for the textual format will be writing test cases. Writing test
314cases in C is problematic because the compiler may vary its output over time for
315its own optimization reasons which my inadvertently disable or break the linker
316feature trying to be tested. By writing test cases in the linkers own textual
317format, we can exactly specify every attribute of every atom and thus target
318specific linker logic.
319
320The textual/YAML format follows the ReaderWriter patterns used in lld. The lld
321library comes with the classes: ReaderYAML and WriterYAML.
322
323
324Testing
325-------
326
327The lld project contains a test suite which is being built up as new code is
328added to lld. All new lld functionality should have a tests added to the test
329suite. The test suite is `lit <http://llvm.org/cmds/lit.html/>`_ driven. Each
330test is a text file with comments telling lit how to run the test and check the
331result To facilitate testing, the lld project builds a tool called lld-core.
332This tool reads a YAML file (default from stdin), parses it into one or more
333lld::File objects in memory and then feeds those lld::File objects to the
334resolver phase.
335
336
337Resolver testing
338~~~~~~~~~~~~~~~~
339
340Basic testing is the "core linking" or resolving phase. That is where the
341linker merges object files. All test cases are written in YAML. One feature of
342YAML is that it allows multiple "documents" to be encoding in one YAML stream.
343That means one text file can appear to the linker as multiple .o files - the
344normal case for the linker.
345
346Here is a simple example of a core linking test case. It checks that an
347undefined atom from one file will be replaced by a definition from another
348file::
349
350 # RUN: lld-core %s | FileCheck %s
351
352 #
353 # Test that undefined atoms are replaced with defined atoms.
354 #
355
356 ---
357 atoms:
358 - name: foo
359 definition: undefined
360 ---
361 atoms:
362 - name: foo
363 scope: global
364 type: code
365 ...
366
367 # CHECK: name: foo
368 # CHECK: scope: global
369 # CHECK: type: code
370 # CHECK-NOT: name: foo
371 # CHECK: ...
372
373
374Passes testing
375~~~~~~~~~~~~~~
376
377Since Passes just operate on an lld::File object, the lld-core tool has the
378option to run a particular pass (after resolving). Thus, you can write a YAML
379test case with carefully crafted input to exercise areas of a Pass and the check
380the resulting lld::File object as represented in YAML.
381
382
383Design Issues
384-------------
385
386There are a number of open issues in the design of lld. The plan is to wait and
387make these design decisions when we need to.
388
389
390Debug Info
391~~~~~~~~~~
392
393Currently, the lld model says nothing about debug info. But the most popular
394debug format is DWARF and there is some impedance mismatch with the lld model
395and DWARF. In lld there are just Atoms and only Atoms that need to be in a
396special section at runtime have an associated section. Also, Atoms do not have
397addresses. The way DWARF is spec'ed different parts of DWARF are supposed to go
398into specially named sections and the DWARF references function code by address.
399
400CPU and OS specific functionality
401~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
402
403Currently, lld has an abstract "Platform" that deals with any CPU or OS specific
404differences in linking. We just keep adding virtual methods to the base
405Platform class as we find linking areas that might need customization. At some
406point we'll need to structure this better.
407
408
409File Attributes
410~~~~~~~~~~~~~~~
411
412Currently, lld::File just has a path and a way to iterate its atoms. We will
413need to add more attributes on a File. For example, some equivalent to the
414target triple. There is also a number of cached or computed attributes that
415could make various Passes more efficient. For instance, on Darwin there are a
416number of Objective-C optimizations that can be done by a Pass. But it would
417improve the plain C case if the Objective-C optimization Pass did not have to
418scan all atoms looking for any Objective-C data structures. This could be done
419if the lld::File object had an attribute that said if the file had any
420Objective-C data in it. The Resolving phase would then be required to "merge"
421that attribute as object files are added.
deps/lld/docs/development.rst created+45
......@@ -0,0 +1,45 @@
1.. _development:
2
3Development
4===========
5
6Note: this document discuss Mach-O port of LLD. For ELF and COFF,
7see :doc:`index`.
8
9lld is developed as part of the `LLVM <http://llvm.org>`_ project.
10
11Creating a Reader
12-----------------
13
14See the :ref:`Creating a Reader <Readers>` guide.
15
16
17Modifying the Driver
18--------------------
19
20See :doc:`Driver`.
21
22
23Debugging
24---------
25
26You can run lld with ``-mllvm -debug`` command line options to enable debugging
27printouts. If you want to enable debug information for some specific pass, you
28can run it with ``-mllvm '-debug-only=<pass>'``, where pass is a name used in
29the ``DEBUG_WITH_TYPE()`` macro.
30
31
32
33Documentation
34-------------
35
36The project documentation is written in reStructuredText and generated using the
37`Sphinx <http://sphinx.pocoo.org/>`_ documentation generator. For more
38information on writing documentation for the project, see the
39:ref:`sphinx_intro`.
40
41.. toctree::
42 :hidden:
43
44 Readers
45 Driver
deps/lld/docs/getting_started.rst created+106
......@@ -0,0 +1,106 @@
1.. _getting_started:
2
3Getting Started: Building and Running lld
4=========================================
5
6This page gives you the shortest path to checking out and building lld. If you
7run into problems, please file bugs in the `LLVM Bugzilla`__
8
9__ http://llvm.org/bugs/
10
11Building lld
12------------
13
14On Unix-like Systems
15~~~~~~~~~~~~~~~~~~~~
16
171. Get the required tools.
18
19 * `CMake 2.8`_\+.
20 * make (or any build system CMake supports).
21 * `Clang 3.1`_\+ or GCC 4.7+ (C++11 support is required).
22
23 * If using Clang, you will also need `libc++`_.
24 * `Python 2.4`_\+ (not 3.x) for running tests.
25
26.. _CMake 2.8: http://www.cmake.org/cmake/resources/software.html
27.. _Clang 3.1: http://clang.llvm.org/
28.. _libc++: http://libcxx.llvm.org/
29.. _Python 2.4: http://python.org/download/
30
312. Check out LLVM::
32
33 $ cd path/to/llvm-project
34 $ svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
35
363. Check out lld::
37
38 $ cd llvm/tools
39 $ svn co http://llvm.org/svn/llvm-project/lld/trunk lld
40
41 * lld can also be checked out to ``path/to/llvm-project`` and built as an external
42 project.
43
444. Build LLVM and lld::
45
46 $ cd path/to/llvm-build/llvm (out of source build required)
47 $ cmake -G "Unix Makefiles" path/to/llvm-project/llvm
48 $ make
49
50 * If you want to build with clang and it is not the default compiler or
51 it is installed in an alternate location, you'll need to tell the cmake tool
52 the location of the C and C++ compiler via CMAKE_C_COMPILER and
53 CMAKE_CXX_COMPILER. For example::
54
55 $ cmake -DCMAKE_CXX_COMPILER=/path/to/clang++ -DCMAKE_C_COMPILER=/path/to/clang ...
56
575. Test::
58
59 $ make check-lld
60
61Using Visual Studio
62~~~~~~~~~~~~~~~~~~~
63
64#. Get the required tools.
65
66 * `CMake 2.8`_\+.
67 * `Visual Studio 12 (2013) or later`_ (required for C++11 support)
68 * `Python 2.4`_\+ (not 3.x) for running tests.
69
70.. _CMake 2.8: http://www.cmake.org/cmake/resources/software.html
71.. _Visual Studio 12 (2013) or later: http://www.microsoft.com/visualstudio/11/en-us
72.. _Python 2.4: http://python.org/download/
73
74#. Check out LLVM::
75
76 $ cd path/to/llvm-project
77 $ svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
78
79#. Check out lld::
80
81 $ cd llvm/tools
82 $ svn co http://llvm.org/svn/llvm-project/lld/trunk lld
83
84 * lld can also be checked out to ``path/to/llvm-project`` and built as an external
85 project.
86
87#. Generate Visual Studio project files::
88
89 $ cd path/to/llvm-build/llvm (out of source build required)
90 $ cmake -G "Visual Studio 11" path/to/llvm-project/llvm
91
92#. Build
93
94 * Open LLVM.sln in Visual Studio.
95 * Build the ``ALL_BUILD`` target.
96
97#. Test
98
99 * Build the ``lld-test`` target.
100
101More Information
102~~~~~~~~~~~~~~~~
103
104For more information on using CMake see the `LLVM CMake guide`_.
105
106.. _LLVM CMake guide: http://llvm.org/docs/CMake.html
deps/lld/docs/hello.png created
Binary files /dev/null and b/deps/lld/docs/hello.png differ
deps/lld/docs/index.rst created+179
......@@ -0,0 +1,179 @@
1LLD - The LLVM Linker
2=====================
3
4LLD is a linker from the LLVM project. That is a drop-in replacement
5for system linkers and runs much faster than them. It also provides
6features that are useful for toolchain developers.
7
8The linker supports ELF (Unix), PE/COFF (Windows) and Mach-O (macOS)
9in descending order of completeness. Internally, LLD consists of three
10different linkers. The ELF port is the one that will be described in
11this document. The PE/COFF port is almost complete except the lack of
12the Windows debug info (PDB) support. The Mach-O port is built based
13on a different architecture than the ELF or COFF ports. For the
14details about Mach-O, please read :doc:`AtomLLD`.
15
16Features
17--------
18
19- LLD is a drop-in replacement for the GNU linkers. That accepts the
20 same command line arguments and linker scripts as GNU.
21
22 We are currently working closely with the FreeBSD project to make
23 LLD default system linker in future versions of the operating
24 system, so we are serious about addressing compatibility issues. As
25 of February 2017, LLD is able to link the entire FreeBSD/amd64 base
26 system including the kernel. With a few work-in-progress patches it
27 can link approximately 95% of the ports collection on AMD64. For the
28 details, see `FreeBSD quarterly status report
29 <https://www.freebsd.org/news/status/report-2016-10-2016-12.html#Using-LLVM%27s-LLD-Linker-as-FreeBSD%27s-System-Linker>`_.
30
31- LLD is very fast. When you link a large program on a multicore
32 machine, you can expect that LLD runs more than twice as fast as GNU
33 gold linker. Your milage may vary, though.
34
35- It supports various CPUs/ABIs including x86-64, x86, x32, AArch64,
36 ARM, MIPS 32/64 big/little-endian, PowerPC, PowerPC 64 and AMDGPU.
37 Among these, x86-64 is the most well-supported target and have
38 reached production quality. AArch64 and MIPS seem decent too. x86
39 should be OK but not well tested yet. ARM support is being developed
40 actively.
41
42- It is always a cross-linker, meaning that it always supports all the
43 above targets however it was built. In fact, we don't provide a
44 build-time option to enable/disable each target. This should make it
45 easy to use our linker as part of a cross-compile toolchain.
46
47- You can embed LLD to your program to eliminate dependency to
48 external linkers. All you have to do is to construct object files
49 and command line arguments just like you would do to invoke an
50 external linker and then call the linker's main function,
51 ``lld::elf::link``, from your code.
52
53- It is small. We are using LLVM libObject library to read from object
54 files, so it is not completely a fair comparison, but as of February
55 2017, LLD/ELF consists only of 21k lines of C++ code while GNU gold
56 consists of 198k lines of C++ code.
57
58- Link-time optimization (LTO) is supported by default. Essentially,
59 all you have to do to do LTO is to pass the ``-flto`` option to clang.
60 Then clang creates object files not in the native object file format
61 but in LLVM bitcode format. LLD reads bitcode object files, compile
62 them using LLVM and emit an output file. Because in this way LLD can
63 see the entire program, it can do the whole program optimization.
64
65- Some very old features for ancient Unix systems (pre-90s or even
66 before that) have been removed. Some default settings have been
67 tuned for the 21st century. For example, the stack is marked as
68 non-executable by default to tighten security.
69
70Performance
71-----------
72
73This is a link time comparison on a 2-socket 20-core 40-thread Xeon
74E5-2680 2.80 GHz machine with an SSD drive.
75
76LLD is much faster than the GNU linkers for large programs. That's
77fast for small programs too, but because the link time is short
78anyway, the difference is not very noticeable in that case.
79
80Note that this is just a benchmark result of our environment.
81Depending on number of available cores, available amount of memory or
82disk latency/throughput, your results may vary.
83
84============ =========== ============ ============= ======
85Program Output size GNU ld GNU gold [1]_ LLD
86ffmpeg dbg 91 MiB 1.59s 1.15s 0.78s
87mysqld dbg 157 MiB 7.09s 2.49s 1.31s
88clang dbg 1.45 GiB 86.76s 21.93s 8.38s
89chromium dbg 1.52 GiB 142.30s [2]_ 40.86s 12.69s
90============ =========== ============ ============= ======
91
92.. [1] With the ``--threads`` option to enable multi-threading support.
93
94.. [2] Since GNU ld doesn't support the ``-icf=all`` option, we
95 removed that from the command line for GNU ld. GNU ld would be
96 slower than this if it had that option support. For gold and
97 LLD, we use ``-icf=all``.
98
99Build
100-----
101
102If you have already checked out LLVM using SVN, you can check out LLD
103under ``tools`` directory just like you probably did for clang. For the
104details, see `Getting Started with the LLVM System
105<http://llvm.org/docs/GettingStarted.html>`_.
106
107If you haven't checkout out LLVM, the easiest way to build LLD is to
108checkout the entire LLVM projects/sub-projects from a git mirror and
109build that tree. You need `cmake` and of course a C++ compiler.
110
111.. code-block:: console
112
113 $ git clone https://github.com/llvm-project/llvm-project/
114 $ mkdir build
115 $ cd build
116 $ cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS=lld -DCMAKE_INSTALL_PREFIX=/usr/local ../llvm-project/llvm
117 $ make install
118
119Using LLD
120---------
121
122LLD is installed as ``ld.lld``. On Unix, linkers are invoked by
123compiler drivers, so you are not expected to use that command
124directly. There are a few ways to tell compiler drivers to use ld.lld
125instead of the default linker.
126
127The easiest way to do that is to overwrite the default linker. After
128installing LLD to somewhere on your disk, you can create a symbolic
129link by doing ``ln -s /path/to/ld.lld /usr/bin/ld`` so that
130``/usr/bin/ld`` is resolved to LLD.
131
132If you don't want to change the system setting, you can use clang's
133``-fuse-ld`` option. In this way, you want to set ``-fuse-ld=lld`` to
134LDFLAGS when building your programs.
135
136LLD leaves its name and version number to a ``.comment`` section in an
137output. If you are in doubt whether you are successfully using LLD or
138not, run ``readelf --string-dump .comment <output-file>`` and examine the
139output. If the string "Linker: LLD" is included in the output, you are
140using LLD.
141
142History
143-------
144
145Here is a brief project history of the ELF and COFF ports.
146
147- May 2015: We decided to rewrite the COFF linker and did that.
148 Noticed that the new linker is much faster than the MSVC linker.
149
150- July 2015: The new ELF port was developed based on the COFF linker
151 architecture.
152
153- September 2015: The first patches to support MIPS and AArch64 landed.
154
155- October 2015: Succeeded to self-host the ELF port. We have noticed
156 that the linker was faster than the GNU linkers, but we weren't sure
157 at the time if we would be able to keep the gap as we would add more
158 features to the linker.
159
160- July 2016: Started working on improving the linker script support.
161
162- December 2016: Succeeded to build the entire FreeBSD base system
163 including the kernel. We had widen the performance gap against the
164 GNU linkers.
165
166Internals
167---------
168
169For the internals of the linker, please read :doc:`NewLLD`. It is a bit
170outdated but the fundamental concepts remain valid. We'll update the
171document soon.
172
173.. toctree::
174 :maxdepth: 1
175
176 NewLLD
177 AtomLLD
178 windows_support
179 ReleaseNotes
deps/lld/docs/llvm-theme/layout.html created+22
......@@ -0,0 +1,22 @@
1{#
2 sphinxdoc/layout.html
3 ~~~~~~~~~~~~~~~~~~~~~
4
5 Sphinx layout template for the sphinxdoc theme.
6
7 :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS.
8 :license: BSD, see LICENSE for details.
9#}
10{% extends "basic/layout.html" %}
11
12{% block relbar1 %}
13<div class="logo">
14<a href="{{ pathto('index') }}"><img src="{{
15pathto("_static/logo.png", 1) }}" alt="LLVM Documentation"/></a>
16</div>
17{{ super() }}
18{% endblock %}
19
20{# put the sidebar before the body #}
21{% block sidebar1 %}{{ sidebar() }}{% endblock %}
22{% block sidebar2 %}{% endblock %}
deps/lld/docs/llvm-theme/static/contents.png created
Binary files /dev/null and b/deps/lld/docs/llvm-theme/static/contents.png differ
deps/lld/docs/llvm-theme/static/llvm.css created+345
......@@ -0,0 +1,345 @@
1/*
2 * sphinxdoc.css_t
3 * ~~~~~~~~~~~~~~~
4 *
5 * Sphinx stylesheet -- sphinxdoc theme. Originally created by
6 * Armin Ronacher for Werkzeug.
7 *
8 * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS.
9 * :license: BSD, see LICENSE for details.
10 *
11 */
12
13@import url("basic.css");
14
15/* -- page layout ----------------------------------------------------------- */
16
17body {
18 font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva',
19 'Verdana', sans-serif;
20 font-size: 14px;
21 letter-spacing: -0.01em;
22 line-height: 150%;
23 text-align: center;
24 background-color: #BFD1D4;
25 color: black;
26 padding: 0;
27 border: 1px solid #aaa;
28
29 margin: 0px 80px 0px 80px;
30 min-width: 740px;
31}
32
33div.logo {
34 background-color: white;
35 text-align: left;
36 padding: 10px 10px 15px 15px;
37}
38
39div.document {
40 background-color: white;
41 text-align: left;
42 background-image: url(contents.png);
43 background-repeat: repeat-x;
44}
45
46div.bodywrapper {
47 margin: 0 240px 0 0;
48 border-right: 1px solid #ccc;
49}
50
51div.body {
52 margin: 0;
53 padding: 0.5em 20px 20px 20px;
54}
55
56div.related {
57 font-size: 1em;
58}
59
60div.related ul {
61 background-image: url(navigation.png);
62 height: 2em;
63 border-top: 1px solid #ddd;
64 border-bottom: 1px solid #ddd;
65}
66
67div.related ul li {
68 margin: 0;
69 padding: 0;
70 height: 2em;
71 float: left;
72}
73
74div.related ul li.right {
75 float: right;
76 margin-right: 5px;
77}
78
79div.related ul li a {
80 margin: 0;
81 padding: 0 5px 0 5px;
82 line-height: 1.75em;
83 color: #EE9816;
84}
85
86div.related ul li a:hover {
87 color: #3CA8E7;
88}
89
90div.sphinxsidebarwrapper {
91 padding: 0;
92}
93
94div.sphinxsidebar {
95 margin: 0;
96 padding: 0.5em 15px 15px 0;
97 width: 210px;
98 float: right;
99 font-size: 1em;
100 text-align: left;
101}
102
103div.sphinxsidebar h3, div.sphinxsidebar h4 {
104 margin: 1em 0 0.5em 0;
105 font-size: 1em;
106 padding: 0.1em 0 0.1em 0.5em;
107 color: white;
108 border: 1px solid #86989B;
109 background-color: #AFC1C4;
110}
111
112div.sphinxsidebar h3 a {
113 color: white;
114}
115
116div.sphinxsidebar ul {
117 padding-left: 1.5em;
118 margin-top: 7px;
119 padding: 0;
120 line-height: 130%;
121}
122
123div.sphinxsidebar ul ul {
124 margin-left: 20px;
125}
126
127div.footer {
128 background-color: #E3EFF1;
129 color: #86989B;
130 padding: 3px 8px 3px 0;
131 clear: both;
132 font-size: 0.8em;
133 text-align: right;
134}
135
136div.footer a {
137 color: #86989B;
138 text-decoration: underline;
139}
140
141/* -- body styles ----------------------------------------------------------- */
142
143p {
144 margin: 0.8em 0 0.5em 0;
145}
146
147a {
148 color: #CA7900;
149 text-decoration: none;
150}
151
152a:hover {
153 color: #2491CF;
154}
155
156div.body a {
157 text-decoration: underline;
158}
159
160h1 {
161 margin: 0;
162 padding: 0.7em 0 0.3em 0;
163 font-size: 1.5em;
164 color: #11557C;
165}
166
167h2 {
168 margin: 1.3em 0 0.2em 0;
169 font-size: 1.35em;
170 padding: 0;
171}
172
173h3 {
174 margin: 1em 0 -0.3em 0;
175 font-size: 1.2em;
176}
177
178div.body h1 a, div.body h2 a, div.body h3 a, div.body h4 a, div.body h5 a, div.body h6 a {
179 color: black!important;
180}
181
182h1 a.anchor, h2 a.anchor, h3 a.anchor, h4 a.anchor, h5 a.anchor, h6 a.anchor {
183 display: none;
184 margin: 0 0 0 0.3em;
185 padding: 0 0.2em 0 0.2em;
186 color: #aaa!important;
187}
188
189h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor,
190h5:hover a.anchor, h6:hover a.anchor {
191 display: inline;
192}
193
194h1 a.anchor:hover, h2 a.anchor:hover, h3 a.anchor:hover, h4 a.anchor:hover,
195h5 a.anchor:hover, h6 a.anchor:hover {
196 color: #777;
197 background-color: #eee;
198}
199
200a.headerlink {
201 color: #c60f0f!important;
202 font-size: 1em;
203 margin-left: 6px;
204 padding: 0 4px 0 4px;
205 text-decoration: none!important;
206}
207
208a.headerlink:hover {
209 background-color: #ccc;
210 color: white!important;
211}
212
213cite, code, tt {
214 font-family: 'Consolas', 'Deja Vu Sans Mono',
215 'Bitstream Vera Sans Mono', monospace;
216 font-size: 0.95em;
217 letter-spacing: 0.01em;
218}
219
220tt {
221 background-color: #f2f2f2;
222 border-bottom: 1px solid #ddd;
223 color: #333;
224}
225
226tt.descname, tt.descclassname, tt.xref {
227 border: 0;
228}
229
230hr {
231 border: 1px solid #abc;
232 margin: 2em;
233}
234
235a tt {
236 border: 0;
237 color: #CA7900;
238}
239
240a tt:hover {
241 color: #2491CF;
242}
243
244pre {
245 font-family: 'Consolas', 'Deja Vu Sans Mono',
246 'Bitstream Vera Sans Mono', monospace;
247 font-size: 0.95em;
248 letter-spacing: 0.015em;
249 line-height: 120%;
250 padding: 0.5em;
251 border: 1px solid #ccc;
252 background-color: #f8f8f8;
253}
254
255pre a {
256 color: inherit;
257 text-decoration: underline;
258}
259
260td.linenos pre {
261 padding: 0.5em 0;
262}
263
264div.quotebar {
265 background-color: #f8f8f8;
266 max-width: 250px;
267 float: right;
268 padding: 2px 7px;
269 border: 1px solid #ccc;
270}
271
272div.topic {
273 background-color: #f8f8f8;
274}
275
276table {
277 border-collapse: collapse;
278 margin: 0 -0.5em 0 -0.5em;
279}
280
281table td, table th {
282 padding: 0.2em 0.5em 0.2em 0.5em;
283}
284
285div.admonition, div.warning {
286 font-size: 0.9em;
287 margin: 1em 0 1em 0;
288 border: 1px solid #86989B;
289 background-color: #f7f7f7;
290 padding: 0;
291}
292
293div.admonition p, div.warning p {
294 margin: 0.5em 1em 0.5em 1em;
295 padding: 0;
296}
297
298div.admonition pre, div.warning pre {
299 margin: 0.4em 1em 0.4em 1em;
300}
301
302div.admonition p.admonition-title,
303div.warning p.admonition-title {
304 margin: 0;
305 padding: 0.1em 0 0.1em 0.5em;
306 color: white;
307 border-bottom: 1px solid #86989B;
308 font-weight: bold;
309 background-color: #AFC1C4;
310}
311
312div.warning {
313 border: 1px solid #940000;
314}
315
316div.warning p.admonition-title {
317 background-color: #CF0000;
318 border-bottom-color: #940000;
319}
320
321div.admonition ul, div.admonition ol,
322div.warning ul, div.warning ol {
323 margin: 0.1em 0.5em 0.5em 3em;
324 padding: 0;
325}
326
327div.versioninfo {
328 margin: 1em 0 0 0;
329 border: 1px solid #ccc;
330 background-color: #DDEAF0;
331 padding: 8px;
332 line-height: 1.3em;
333 font-size: 0.9em;
334}
335
336.viewcode-back {
337 font-family: 'Lucida Grande', 'Lucida Sans Unicode', 'Geneva',
338 'Verdana', sans-serif;
339}
340
341div.viewcode-block:target {
342 background-color: #f4debf;
343 border-top: 1px solid #ac9;
344 border-bottom: 1px solid #ac9;
345}
deps/lld/docs/llvm-theme/static/logo.png created
Binary files /dev/null and b/deps/lld/docs/llvm-theme/static/logo.png differ
deps/lld/docs/llvm-theme/static/navigation.png created
Binary files /dev/null and b/deps/lld/docs/llvm-theme/static/navigation.png differ
deps/lld/docs/llvm-theme/theme.conf created+4
......@@ -0,0 +1,4 @@
1[theme]
2inherit = basic
3stylesheet = llvm.css
4pygments_style = friendly
deps/lld/docs/make.bat created+190
......@@ -0,0 +1,190 @@
1@ECHO OFF
2
3REM Command file for Sphinx documentation
4
5if "%SPHINXBUILD%" == "" (
6 set SPHINXBUILD=sphinx-build
7)
8set BUILDDIR=_build
9set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
10set I18NSPHINXOPTS=%SPHINXOPTS% .
11if NOT "%PAPER%" == "" (
12 set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
13 set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
14)
15
16if "%1" == "" goto help
17
18if "%1" == "help" (
19 :help
20 echo.Please use `make ^<target^>` where ^<target^> is one of
21 echo. html to make standalone HTML files
22 echo. dirhtml to make HTML files named index.html in directories
23 echo. singlehtml to make a single large HTML file
24 echo. pickle to make pickle files
25 echo. json to make JSON files
26 echo. htmlhelp to make HTML files and a HTML help project
27 echo. qthelp to make HTML files and a qthelp project
28 echo. devhelp to make HTML files and a Devhelp project
29 echo. epub to make an epub
30 echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
31 echo. text to make text files
32 echo. man to make manual pages
33 echo. texinfo to make Texinfo files
34 echo. gettext to make PO message catalogs
35 echo. changes to make an overview over all changed/added/deprecated items
36 echo. linkcheck to check all external links for integrity
37 echo. doctest to run all doctests embedded in the documentation if enabled
38 goto end
39)
40
41if "%1" == "clean" (
42 for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
43 del /q /s %BUILDDIR%\*
44 goto end
45)
46
47if "%1" == "html" (
48 %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
49 if errorlevel 1 exit /b 1
50 echo.
51 echo.Build finished. The HTML pages are in %BUILDDIR%/html.
52 goto end
53)
54
55if "%1" == "dirhtml" (
56 %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
57 if errorlevel 1 exit /b 1
58 echo.
59 echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
60 goto end
61)
62
63if "%1" == "singlehtml" (
64 %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
65 if errorlevel 1 exit /b 1
66 echo.
67 echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
68 goto end
69)
70
71if "%1" == "pickle" (
72 %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
73 if errorlevel 1 exit /b 1
74 echo.
75 echo.Build finished; now you can process the pickle files.
76 goto end
77)
78
79if "%1" == "json" (
80 %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
81 if errorlevel 1 exit /b 1
82 echo.
83 echo.Build finished; now you can process the JSON files.
84 goto end
85)
86
87if "%1" == "htmlhelp" (
88 %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
89 if errorlevel 1 exit /b 1
90 echo.
91 echo.Build finished; now you can run HTML Help Workshop with the ^
92.hhp project file in %BUILDDIR%/htmlhelp.
93 goto end
94)
95
96if "%1" == "qthelp" (
97 %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
98 if errorlevel 1 exit /b 1
99 echo.
100 echo.Build finished; now you can run "qcollectiongenerator" with the ^
101.qhcp project file in %BUILDDIR%/qthelp, like this:
102 echo.^> qcollectiongenerator %BUILDDIR%\qthelp\lld.qhcp
103 echo.To view the help file:
104 echo.^> assistant -collectionFile %BUILDDIR%\qthelp\lld.ghc
105 goto end
106)
107
108if "%1" == "devhelp" (
109 %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
110 if errorlevel 1 exit /b 1
111 echo.
112 echo.Build finished.
113 goto end
114)
115
116if "%1" == "epub" (
117 %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
118 if errorlevel 1 exit /b 1
119 echo.
120 echo.Build finished. The epub file is in %BUILDDIR%/epub.
121 goto end
122)
123
124if "%1" == "latex" (
125 %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
126 if errorlevel 1 exit /b 1
127 echo.
128 echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
129 goto end
130)
131
132if "%1" == "text" (
133 %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
134 if errorlevel 1 exit /b 1
135 echo.
136 echo.Build finished. The text files are in %BUILDDIR%/text.
137 goto end
138)
139
140if "%1" == "man" (
141 %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
142 if errorlevel 1 exit /b 1
143 echo.
144 echo.Build finished. The manual pages are in %BUILDDIR%/man.
145 goto end
146)
147
148if "%1" == "texinfo" (
149 %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
150 if errorlevel 1 exit /b 1
151 echo.
152 echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
153 goto end
154)
155
156if "%1" == "gettext" (
157 %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
158 if errorlevel 1 exit /b 1
159 echo.
160 echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
161 goto end
162)
163
164if "%1" == "changes" (
165 %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
166 if errorlevel 1 exit /b 1
167 echo.
168 echo.The overview file is in %BUILDDIR%/changes.
169 goto end
170)
171
172if "%1" == "linkcheck" (
173 %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
174 if errorlevel 1 exit /b 1
175 echo.
176 echo.Link check complete; look for any errors in the above output ^
177or in %BUILDDIR%/linkcheck/output.txt.
178 goto end
179)
180
181if "%1" == "doctest" (
182 %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
183 if errorlevel 1 exit /b 1
184 echo.
185 echo.Testing of doctests in the sources finished, look at the ^
186results in %BUILDDIR%/doctest/output.txt.
187 goto end
188)
189
190:end
deps/lld/docs/open_projects.rst created+11
......@@ -0,0 +1,11 @@
1.. _open_projects:
2
3Open Projects
4=============
5
6.. include:: ../include/lld/Core/TODO.txt
7
8Documentation TODOs
9~~~~~~~~~~~~~~~~~~~
10
11.. todolist::
deps/lld/docs/sphinx_intro.rst created+147
......@@ -0,0 +1,147 @@
1.. _sphinx_intro:
2
3Sphinx Introduction for LLVM Developers
4=======================================
5
6This document is intended as a short and simple introduction to the Sphinx
7documentation generation system for LLVM developers.
8
9Quickstart
10----------
11
12To get started writing documentation, you will need to:
13
14 1. Have the Sphinx tools :ref:`installed <installing_sphinx>`.
15
16 2. Understand how to :ref:`build the documentation
17 <building_the_documentation>`.
18
19 3. Start :ref:`writing documentation <writing_documentation>`!
20
21.. _installing_sphinx:
22
23Installing Sphinx
24~~~~~~~~~~~~~~~~~
25
26You should be able to install Sphinx using the standard Python package
27installation tool ``easy_install``, as follows::
28
29 $ sudo easy_install sphinx
30 Searching for sphinx
31 Reading http://pypi.python.org/simple/sphinx/
32 Reading http://sphinx.pocoo.org/
33 Best match: Sphinx 1.1.3
34 ... more lines here ..
35
36If you do not have root access (or otherwise want to avoid installing Sphinx in
37system directories) see the section on :ref:`installing_sphinx_in_a_venv` .
38
39If you do not have the ``easy_install`` tool on your system, you should be able
40to install it using:
41
42 Linux
43 Use your distribution's standard package management tool to install it,
44 i.e., ``apt-get install easy_install`` or ``yum install easy_install``.
45
46 Mac OS X
47 All modern Mac OS X systems come with ``easy_install`` as part of the base
48 system.
49
50 Windows
51 See the `setuptools <http://pypi.python.org/pypi/setuptools>`_ package web
52 page for instructions.
53
54
55.. _building_the_documentation:
56
57Building the documentation
58~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
59
60In order to build the documentation, all you should need to do is change to the
61``docs`` directory and invoke make as follows::
62
63 $ cd path/to/project/docs
64 $ make html
65
66Note that on Windows there is a ``make.bat`` command in the docs directory which
67supplies the same interface as the ``Makefile``.
68
69That command will invoke ``sphinx-build`` with the appropriate options for the
70project, and generate the HTML documentation in a ``_build`` subdirectory. You
71can browse it starting from the index page by visiting
72``_build/html/index.html``.
73
74Sphinx supports a wide variety of generation formats (including LaTeX, man
75pages, and plain text). The ``Makefile`` includes a number of convenience
76targets for invoking ``sphinx-build`` appropriately, the common ones are:
77
78 make html
79 Generate the HTML output.
80
81 make latexpdf
82 Generate LaTeX documentation and convert to a PDF.
83
84 make man
85 Generate man pages.
86
87
88.. _writing_documentation:
89
90Writing documentation
91~~~~~~~~~~~~~~~~~~~~~
92
93The documentation itself is written in the reStructuredText (ReST) format, and Sphinx
94defines additional tags to support features like cross-referencing.
95
96The ReST format itself is organized around documents mostly being readable
97plaintext documents. You should generally be able to write new documentation
98easily just by following the style of the existing documentation.
99
100If you want to understand the formatting of the documents more, the best place
101to start is Sphinx's own `ReST Primer <http://sphinx.pocoo.org/rest.html>`_.
102
103
104Learning More
105-------------
106
107If you want to learn more about the Sphinx system, the best place to start is
108the Sphinx documentation itself, available `here
109<http://sphinx.pocoo.org/contents.html>`_.
110
111
112.. _installing_sphinx_in_a_venv:
113
114Installing Sphinx in a Virtual Environment
115------------------------------------------
116
117Most Python developers prefer to work with tools inside a *virtualenv* (virtual
118environment) instance, which functions as an application sandbox. This avoids
119polluting your system installation with different packages used by various
120projects (and ensures that dependencies for different packages don't conflict
121with one another). Of course, you need to first have the virtualenv software
122itself which generally would be installed at the system level::
123
124 $ sudo easy_install virtualenv
125
126but after that you no longer need to install additional packages in the system
127directories.
128
129Once you have the *virtualenv* tool itself installed, you can create a
130virtualenv for Sphinx using::
131
132 $ virtualenv ~/my-sphinx-install
133 New python executable in /Users/dummy/my-sphinx-install/bin/python
134 Installing setuptools............done.
135 Installing pip...............done.
136
137 $ ~/my-sphinx-install/bin/easy_install sphinx
138 ... install messages here ...
139
140and from now on you can "activate" the *virtualenv* using::
141
142 $ source ~/my-sphinx-install/bin/activate
143
144which will change your PATH to ensure the sphinx-build tool from inside the
145virtual environment will be used. See the `virtualenv website
146<http://www.virtualenv.org/en/latest/index.html>`_ for more information on using
147virtual environments.
deps/lld/docs/windows_support.rst created+91
......@@ -0,0 +1,91 @@
1.. raw:: html
2
3 <style type="text/css">
4 .none { background-color: #FFCCCC }
5 .partial { background-color: #FFFF99 }
6 .good { background-color: #CCFF99 }
7 </style>
8
9.. role:: none
10.. role:: partial
11.. role:: good
12
13===============
14Windows support
15===============
16
17LLD supports Windows operating system. When invoked as ``lld-link.exe`` or with
18``-flavor link``, the driver for Windows operating system is used to parse
19command line options, and it drives further linking processes. LLD accepts
20almost all command line options that the linker shipped with Microsoft Visual
21C++ (link.exe) supports.
22
23The current status is that LLD can link itself on Windows x86/x64
24using Visual C++ 2013 as the compiler.
25
26Development status
27==================
28
29Driver
30 :good:`Mostly done`. Some exotic command line options that are not usually
31 used for application develompent, such as ``/DRIVER``, are not supported.
32
33Linking against DLL
34 :good:`Done`. LLD can read import libraries needed to link against DLL. Both
35 export-by-name and export-by-ordinal are supported.
36
37Linking against static library
38 :good:`Done`. The format of static library (.lib) on Windows is actually the
39 same as on Unix (.a). LLD can read it.
40
41Creating DLL
42 :good:`Done`. LLD creates a DLL if ``/DLL`` option is given. Exported
43 functions can be specified either via command line (``/EXPORT``) or via
44 module-definition file (.def). Both export-by-name and export-by-ordinal are
45 supported.
46
47Windows resource files support
48 :good:`Done`. If an ``.res`` file is given, LLD converts the file to a COFF
49 file using LLVM's Object library.
50
51Safe Structured Exception Handler (SEH)
52 :good:`Done` for both x86 and x64.
53
54Module-definition file
55 :partial:`Partially done`. LLD currently recognizes these directives:
56 ``EXPORTS``, ``HEAPSIZE``, ``STACKSIZE``, ``NAME``, and ``VERSION``.
57
58Debug info
59 :none:`No progress has been made`. Microsoft linker can interpret the CodeGen
60 debug info (old-style debug info) and PDB to emit an .pdb file. LLD doesn't
61 support neither.
62
63
64Building LLD
65============
66
67Using Visual Studio IDE/MSBuild
68-------------------------------
69
701. Check out LLVM and LLD from the LLVM SVN repository (or Git mirror),
71#. run ``cmake -G "Visual Studio 12" <llvm-source-dir>`` from VS command prompt,
72#. open LLVM.sln with Visual Studio, and
73#. build ``lld`` target in ``lld executables`` folder
74
75Alternatively, you can use msbuild if you don't like to work in an IDE::
76
77 msbuild LLVM.sln /m /target:"lld executables\lld"
78
79MSBuild.exe had been shipped as a component of the .NET framework, but since
802013 it's part of Visual Studio. You can find it at "C:\\Program Files
81(x86)\\msbuild".
82
83You can build LLD as a 64 bit application. To do that, open VS2013 x64 command
84prompt and run cmake for "Visual Studio 12 Win64" target.
85
86Using Ninja
87-----------
88
891. Check out LLVM and LLD from the LLVM SVN repository (or Git mirror),
90#. run ``cmake -G ninja <llvm-source-dir>`` from VS command prompt,
91#. run ``ninja lld``
deps/lld/include/lld/Config/Version.h created+25
......@@ -0,0 +1,25 @@
1//===- lld/Config/Version.h - LLD Version Number ----------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Defines a version-related utility function.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLD_VERSION_H
15#define LLD_VERSION_H
16
17#include "lld/Config/Version.inc"
18#include "llvm/ADT/StringRef.h"
19
20namespace lld {
21/// \brief Retrieves a string representing the complete lld version.
22std::string getLLDVersion();
23}
24
25#endif // LLD_VERSION_H
deps/lld/include/lld/Config/Version.inc.in created+6
......@@ -0,0 +1,6 @@
1#define LLD_VERSION @LLD_VERSION@
2#define LLD_VERSION_STRING "@LLD_VERSION@"
3#define LLD_VERSION_MAJOR @LLD_VERSION_MAJOR@
4#define LLD_VERSION_MINOR @LLD_VERSION_MINOR@
5#define LLD_REVISION_STRING "@LLD_REVISION@"
6#define LLD_REPOSITORY_STRING "@LLD_REPOSITORY@"
deps/lld/include/lld/Core/AbsoluteAtom.h created+43
......@@ -0,0 +1,43 @@
1//===- Core/AbsoluteAtom.h - An absolute Atom -----------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_CORE_ABSOLUTE_ATOM_H
11#define LLD_CORE_ABSOLUTE_ATOM_H
12
13#include "lld/Core/Atom.h"
14
15namespace lld {
16
17/// An AbsoluteAtom has no content.
18/// It exists to represent content at fixed addresses in memory.
19class AbsoluteAtom : public Atom {
20public:
21
22 virtual uint64_t value() const = 0;
23
24 /// scope - The visibility of this atom to other atoms. C static functions
25 /// have scope scopeTranslationUnit. Regular C functions have scope
26 /// scopeGlobal. Functions compiled with visibility=hidden have scope
27 /// scopeLinkageUnit so they can be see by other atoms being linked but not
28 /// by the OS loader.
29 virtual Scope scope() const = 0;
30
31 static bool classof(const Atom *a) {
32 return a->definition() == definitionAbsolute;
33 }
34
35 static bool classof(const AbsoluteAtom *) { return true; }
36
37protected:
38 AbsoluteAtom() : Atom(definitionAbsolute) {}
39};
40
41} // namespace lld
42
43#endif // LLD_CORE_ABSOLUTE_ATOM_H
deps/lld/include/lld/Core/ArchiveLibraryFile.h created+47
......@@ -0,0 +1,47 @@
1//===- Core/ArchiveLibraryFile.h - Models static library ------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_CORE_ARCHIVE_LIBRARY_FILE_H
11#define LLD_CORE_ARCHIVE_LIBRARY_FILE_H
12
13#include "lld/Core/File.h"
14#include <set>
15
16namespace lld {
17
18///
19/// The ArchiveLibraryFile subclass of File is used to represent unix
20/// static library archives. These libraries provide no atoms to the
21/// initial set of atoms linked. Instead, when the Resolver will query
22/// ArchiveLibraryFile instances for specific symbols names using the
23/// find() method. If the archive contains an object file which has a
24/// DefinedAtom whose scope is not translationUnit, then that entire
25/// object file File is returned.
26///
27class ArchiveLibraryFile : public File {
28public:
29 static bool classof(const File *f) {
30 return f->kind() == kindArchiveLibrary;
31 }
32
33 /// Check if any member of the archive contains an Atom with the
34 /// specified name and return the File object for that member, or nullptr.
35 virtual File *find(StringRef name) = 0;
36
37 virtual std::error_code
38 parseAllMembers(std::vector<std::unique_ptr<File>> &result) = 0;
39
40protected:
41 /// only subclasses of ArchiveLibraryFile can be instantiated
42 ArchiveLibraryFile(StringRef path) : File(path, kindArchiveLibrary) {}
43};
44
45} // namespace lld
46
47#endif // LLD_CORE_ARCHIVE_LIBRARY_FILE_H
deps/lld/include/lld/Core/Atom.h created+131
......@@ -0,0 +1,131 @@
1//===- Core/Atom.h - A node in linking graph --------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_CORE_ATOM_H
11#define LLD_CORE_ATOM_H
12
13#include "lld/Core/LLVM.h"
14#include "llvm/ADT/StringRef.h"
15
16namespace lld {
17
18class File;
19
20template<typename T>
21class OwningAtomPtr;
22
23///
24/// The linker has a Graph Theory model of linking. An object file is seen
25/// as a set of Atoms with References to other Atoms. Each Atom is a node
26/// and each Reference is an edge. An Atom can be a DefinedAtom which has
27/// content or a UndefinedAtom which is a placeholder and represents an
28/// undefined symbol (extern declaration).
29///
30class Atom {
31 template<typename T> friend class OwningAtomPtr;
32
33public:
34 /// Whether this atom is defined or a proxy for an undefined symbol
35 enum Definition {
36 definitionRegular, ///< Normal C/C++ function or global variable.
37 definitionAbsolute, ///< Asm-only (foo = 10). Not tied to any content.
38 definitionUndefined, ///< Only in .o files to model reference to undef.
39 definitionSharedLibrary ///< Only in shared libraries to model export.
40 };
41
42 /// The scope in which this atom is acessible to other atoms.
43 enum Scope {
44 scopeTranslationUnit, ///< Accessible only to atoms in the same translation
45 /// unit (e.g. a C static).
46 scopeLinkageUnit, ///< Accessible to atoms being linked but not visible
47 /// to runtime loader (e.g. visibility=hidden).
48 scopeGlobal ///< Accessible to all atoms and visible to runtime
49 /// loader (e.g. visibility=default).
50 };
51
52 /// file - returns the File that produced/owns this Atom
53 virtual const File& file() const = 0;
54
55 /// name - The name of the atom. For a function atom, it is the (mangled)
56 /// name of the function.
57 virtual StringRef name() const = 0;
58
59 /// definition - Whether this atom is a definition or represents an undefined
60 /// symbol.
61 Definition definition() const { return _definition; }
62
63 static bool classof(const Atom *a) { return true; }
64
65protected:
66 /// Atom is an abstract base class. Only subclasses can access constructor.
67 explicit Atom(Definition def) : _definition(def) {}
68
69 /// The memory for Atom objects is always managed by the owning File
70 /// object. Therefore, no one but the owning File object should call
71 /// delete on an Atom. In fact, some File objects may bulk allocate
72 /// an array of Atoms, so they cannot be individually deleted by anyone.
73 virtual ~Atom() = default;
74
75private:
76 Definition _definition;
77};
78
79/// Class which owns an atom pointer and runs the atom destructor when the
80/// owning pointer goes out of scope.
81template<typename T>
82class OwningAtomPtr {
83private:
84 OwningAtomPtr(const OwningAtomPtr &) = delete;
85 void operator=(const OwningAtomPtr &) = delete;
86
87public:
88 OwningAtomPtr() = default;
89 OwningAtomPtr(T *atom) : atom(atom) { }
90
91 ~OwningAtomPtr() {
92 if (atom)
93 runDestructor(atom);
94 }
95
96 void runDestructor(Atom *atom) {
97 atom->~Atom();
98 }
99
100 OwningAtomPtr(OwningAtomPtr &&ptr) : atom(ptr.atom) {
101 ptr.atom = nullptr;
102 }
103
104 void operator=(OwningAtomPtr&& ptr) {
105 if (atom)
106 runDestructor(atom);
107 atom = ptr.atom;
108 ptr.atom = nullptr;
109 }
110
111 T *const &get() const {
112 return atom;
113 }
114
115 T *&get() {
116 return atom;
117 }
118
119 T *release() {
120 auto *v = atom;
121 atom = nullptr;
122 return v;
123 }
124
125private:
126 T *atom = nullptr;
127};
128
129} // end namespace lld
130
131#endif // LLD_CORE_ATOM_H
deps/lld/include/lld/Core/DefinedAtom.h created+374
......@@ -0,0 +1,374 @@
1//===- Core/DefinedAtom.h - An Atom with content --------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_CORE_DEFINED_ATOM_H
11#define LLD_CORE_DEFINED_ATOM_H
12
13#include "lld/Core/Atom.h"
14#include "lld/Core/Reference.h"
15#include "lld/Core/LLVM.h"
16#include "llvm/Support/ErrorHandling.h"
17
18namespace lld {
19class File;
20
21/// \brief The fundamental unit of linking.
22///
23/// A C function or global variable is an atom. An atom has content and
24/// attributes. The content of a function atom is the instructions that
25/// implement the function. The content of a global variable atom is its
26/// initial bytes.
27///
28/// Here are some example attribute sets for common atoms. If a particular
29/// attribute is not listed, the default values are: definition=regular,
30/// sectionChoice=basedOnContent, scope=translationUnit, merge=no,
31/// deadStrip=normal, interposable=no
32///
33/// C function: void foo() {} <br>
34/// name=foo, type=code, perm=r_x, scope=global
35///
36/// C static function: staic void func() {} <br>
37/// name=func, type=code, perm=r_x
38///
39/// C global variable: int count = 1; <br>
40/// name=count, type=data, perm=rw_, scope=global
41///
42/// C tentative definition: int bar; <br>
43/// name=bar, type=zerofill, perm=rw_, scope=global,
44/// merge=asTentative, interposable=yesAndRuntimeWeak
45///
46/// Uninitialized C static variable: static int stuff; <br>
47/// name=stuff, type=zerofill, perm=rw_
48///
49/// Weak C function: __attribute__((weak)) void foo() {} <br>
50/// name=foo, type=code, perm=r_x, scope=global, merge=asWeak
51///
52/// Hidden C function: __attribute__((visibility("hidden"))) void foo() {}<br>
53/// name=foo, type=code, perm=r_x, scope=linkageUnit
54///
55/// No-dead-strip function: __attribute__((used)) void foo() {} <br>
56/// name=foo, type=code, perm=r_x, scope=global, deadStrip=never
57///
58/// Non-inlined C++ inline method: inline void Foo::doit() {} <br>
59/// name=_ZN3Foo4doitEv, type=code, perm=r_x, scope=global,
60/// mergeDupes=asWeak
61///
62/// Non-inlined C++ inline method whose address is taken:
63/// inline void Foo::doit() {} <br>
64/// name=_ZN3Foo4doitEv, type=code, perm=r_x, scope=global,
65/// mergeDupes=asAddressedWeak
66///
67/// literal c-string: "hello" <br>
68/// name="" type=cstring, perm=r__, scope=linkageUnit
69///
70/// literal double: 1.234 <br>
71/// name="" type=literal8, perm=r__, scope=linkageUnit
72///
73/// constant: { 1,2,3 } <br>
74/// name="" type=constant, perm=r__, scope=linkageUnit
75///
76/// Pointer to initializer function: <br>
77/// name="" type=initializer, perm=rw_l,
78/// sectionChoice=customRequired
79///
80/// C function place in custom section: __attribute__((section("__foo")))
81/// void foo() {} <br>
82/// name=foo, type=code, perm=r_x, scope=global,
83/// sectionChoice=customRequired, customSectionName=__foo
84///
85class DefinedAtom : public Atom {
86public:
87 enum Interposable {
88 interposeNo, // linker can directly bind uses of this atom
89 interposeYes, // linker must indirect (through GOT) uses
90 interposeYesAndRuntimeWeak // must indirect and mark symbol weak in final
91 // linked image
92 };
93
94 enum Merge {
95 mergeNo, // Another atom with same name is error
96 mergeAsTentative, // Is ANSI C tentative definition, can be coalesced
97 mergeAsWeak, // Is C++ inline definition that was not inlined,
98 // but address was not taken, so atom can be hidden
99 // by linker
100 mergeAsWeakAndAddressUsed, // Is C++ definition inline definition whose
101 // address was taken.
102 mergeSameNameAndSize, // Another atom with different size is error
103 mergeByLargestSection, // Choose an atom whose section is the largest.
104 mergeByContent, // Merge with other constants with same content.
105 };
106
107 enum ContentType {
108 typeUnknown, // for use with definitionUndefined
109 typeMachHeader, // atom representing mach_header [Darwin]
110 typeCode, // executable code
111 typeResolver, // function which returns address of target
112 typeBranchIsland, // linker created for large binaries
113 typeBranchShim, // linker created to switch thumb mode
114 typeStub, // linker created for calling external function
115 typeStubHelper, // linker created for initial stub binding
116 typeConstant, // a read-only constant
117 typeCString, // a zero terminated UTF8 C string
118 typeUTF16String, // a zero terminated UTF16 string
119 typeCFI, // a FDE or CIE from dwarf unwind info
120 typeLSDA, // extra unwinding info
121 typeLiteral4, // a four-btye read-only constant
122 typeLiteral8, // an eight-btye read-only constant
123 typeLiteral16, // a sixteen-btye read-only constant
124 typeData, // read-write data
125 typeDataFast, // allow data to be quickly accessed
126 typeZeroFill, // zero-fill data
127 typeZeroFillFast, // allow zero-fill data to be quicky accessed
128 typeConstData, // read-only data after dynamic linker is done
129 typeObjC1Class, // ObjC1 class [Darwin]
130 typeLazyPointer, // pointer through which a stub jumps
131 typeLazyDylibPointer, // pointer through which a stub jumps [Darwin]
132 typeNonLazyPointer, // pointer to external symbol
133 typeCFString, // NS/CFString object [Darwin]
134 typeGOT, // pointer to external symbol
135 typeInitializerPtr, // pointer to initializer function
136 typeTerminatorPtr, // pointer to terminator function
137 typeCStringPtr, // pointer to UTF8 C string [Darwin]
138 typeObjCClassPtr, // pointer to ObjC class [Darwin]
139 typeObjC2CategoryList, // pointers to ObjC category [Darwin]
140 typeObjCImageInfo, // pointer to ObjC class [Darwin]
141 typeObjCMethodList, // pointer to ObjC method list [Darwin]
142 typeDTraceDOF, // runtime data for Dtrace [Darwin]
143 typeInterposingTuples, // tuples of interposing info for dyld [Darwin]
144 typeTempLTO, // temporary atom for bitcode reader
145 typeCompactUnwindInfo, // runtime data for unwinder [Darwin]
146 typeProcessedUnwindInfo,// compressed compact unwind info [Darwin]
147 typeThunkTLV, // thunk used to access a TLV [Darwin]
148 typeTLVInitialData, // initial data for a TLV [Darwin]
149 typeTLVInitialZeroFill, // TLV initial zero fill data [Darwin]
150 typeTLVInitializerPtr, // pointer to thread local initializer [Darwin]
151 typeDSOHandle, // atom representing DSO handle [Darwin]
152 typeSectCreate, // Created via the -sectcreate option [Darwin]
153 };
154
155 // Permission bits for atoms and segments. The order of these values are
156 // important, because the layout pass may sort atoms by permission if other
157 // attributes are the same.
158 enum ContentPermissions {
159 perm___ = 0, // mapped as unaccessible
160 permR__ = 8, // mapped read-only
161 permRW_ = 8 + 2, // mapped readable and writable
162 permRW_L = 8 + 2 + 1, // initially mapped r/w, then made read-only
163 // loader writable
164 permR_X = 8 + 4, // mapped readable and executable
165 permRWX = 8 + 2 + 4, // mapped readable and writable and executable
166 permUnknown = 16 // unknown or invalid permissions
167 };
168
169 enum SectionChoice {
170 sectionBasedOnContent, // linker infers final section based on content
171 sectionCustomPreferred, // linker may place in specific section
172 sectionCustomRequired // linker must place in specific section
173 };
174
175 enum DeadStripKind {
176 deadStripNormal, // linker may dead strip this atom
177 deadStripNever, // linker must never dead strip this atom
178 deadStripAlways // linker must remove this atom if unused
179 };
180
181 enum DynamicExport {
182 /// \brief The linker may or may not export this atom dynamically depending
183 /// on the output type and other context of the link.
184 dynamicExportNormal,
185 /// \brief The linker will always export this atom dynamically.
186 dynamicExportAlways,
187 };
188
189 // Attributes describe a code model used by the atom.
190 enum CodeModel {
191 codeNA, // no specific code model
192 // MIPS code models
193 codeMipsPIC, // PIC function in a PIC / non-PIC mixed file
194 codeMipsMicro, // microMIPS instruction encoding
195 codeMipsMicroPIC, // microMIPS instruction encoding + PIC
196 codeMips16, // MIPS-16 instruction encoding
197 // ARM code models
198 codeARMThumb, // ARM Thumb instruction set
199 codeARM_a, // $a-like mapping symbol (for ARM code)
200 codeARM_d, // $d-like mapping symbol (for data)
201 codeARM_t, // $t-like mapping symbol (for Thumb code)
202 };
203
204 struct Alignment {
205 Alignment(int v, int m = 0) : value(v), modulus(m) {}
206
207 uint16_t value;
208 uint16_t modulus;
209
210 bool operator==(const Alignment &rhs) const {
211 return (value == rhs.value) && (modulus == rhs.modulus);
212 }
213 };
214
215 /// \brief returns a value for the order of this Atom within its file.
216 ///
217 /// This is used by the linker to order the layout of Atoms so that the
218 /// resulting image is stable and reproducible.
219 virtual uint64_t ordinal() const = 0;
220
221 /// \brief the number of bytes of space this atom's content will occupy in the
222 /// final linked image.
223 ///
224 /// For a function atom, it is the number of bytes of code in the function.
225 virtual uint64_t size() const = 0;
226
227 /// \brief The size of the section from which the atom is instantiated.
228 ///
229 /// Merge::mergeByLargestSection is defined in terms of section size
230 /// and not in terms of atom size, so we need this function separate
231 /// from size().
232 virtual uint64_t sectionSize() const { return 0; }
233
234 /// \brief The visibility of this atom to other atoms.
235 ///
236 /// C static functions have scope scopeTranslationUnit. Regular C functions
237 /// have scope scopeGlobal. Functions compiled with visibility=hidden have
238 /// scope scopeLinkageUnit so they can be see by other atoms being linked but
239 /// not by the OS loader.
240 virtual Scope scope() const = 0;
241
242 /// \brief Whether the linker should use direct or indirect access to this
243 /// atom.
244 virtual Interposable interposable() const = 0;
245
246 /// \brief how the linker should handle if multiple atoms have the same name.
247 virtual Merge merge() const = 0;
248
249 /// \brief The type of this atom, such as code or data.
250 virtual ContentType contentType() const = 0;
251
252 /// \brief The alignment constraints on how this atom must be laid out in the
253 /// final linked image (e.g. 16-byte aligned).
254 virtual Alignment alignment() const = 0;
255
256 /// \brief Whether this atom must be in a specially named section in the final
257 /// linked image, or if the linker can infer the section based on the
258 /// contentType().
259 virtual SectionChoice sectionChoice() const = 0;
260
261 /// \brief If sectionChoice() != sectionBasedOnContent, then this return the
262 /// name of the section the atom should be placed into.
263 virtual StringRef customSectionName() const = 0;
264
265 /// \brief constraints on whether the linker may dead strip away this atom.
266 virtual DeadStripKind deadStrip() const = 0;
267
268 /// \brief Under which conditions should this atom be dynamically exported.
269 virtual DynamicExport dynamicExport() const {
270 return dynamicExportNormal;
271 }
272
273 /// \brief Code model used by the atom.
274 virtual CodeModel codeModel() const { return codeNA; }
275
276 /// \brief Returns the OS memory protections required for this atom's content
277 /// at runtime.
278 ///
279 /// A function atom is R_X, a global variable is RW_, and a read-only constant
280 /// is R__.
281 virtual ContentPermissions permissions() const;
282
283 /// \brief returns a reference to the raw (unrelocated) bytes of this Atom's
284 /// content.
285 virtual ArrayRef<uint8_t> rawContent() const = 0;
286
287 /// This class abstracts iterating over the sequence of References
288 /// in an Atom. Concrete instances of DefinedAtom must implement
289 /// the derefIterator() and incrementIterator() methods.
290 class reference_iterator {
291 public:
292 reference_iterator(const DefinedAtom &a, const void *it)
293 : _atom(a), _it(it) { }
294
295 const Reference *operator*() const {
296 return _atom.derefIterator(_it);
297 }
298
299 const Reference *operator->() const {
300 return _atom.derefIterator(_it);
301 }
302
303 bool operator==(const reference_iterator &other) const {
304 return _it == other._it;
305 }
306
307 bool operator!=(const reference_iterator &other) const {
308 return !(*this == other);
309 }
310
311 reference_iterator &operator++() {
312 _atom.incrementIterator(_it);
313 return *this;
314 }
315 private:
316 const DefinedAtom &_atom;
317 const void *_it;
318 };
319
320 /// \brief Returns an iterator to the beginning of this Atom's References.
321 virtual reference_iterator begin() const = 0;
322
323 /// \brief Returns an iterator to the end of this Atom's References.
324 virtual reference_iterator end() const = 0;
325
326 /// Adds a reference to this atom.
327 virtual void addReference(Reference::KindNamespace ns,
328 Reference::KindArch arch,
329 Reference::KindValue kindValue, uint64_t off,
330 const Atom *target, Reference::Addend a) {
331 llvm_unreachable("Subclass does not permit adding references");
332 }
333
334 static bool classof(const Atom *a) {
335 return a->definition() == definitionRegular;
336 }
337
338 /// Utility for deriving permissions from content type
339 static ContentPermissions permissions(ContentType type);
340
341 /// Utility function to check if the atom occupies file space
342 bool occupiesDiskSpace() const {
343 ContentType atomContentType = contentType();
344 return !(atomContentType == DefinedAtom::typeZeroFill ||
345 atomContentType == DefinedAtom::typeZeroFillFast ||
346 atomContentType == DefinedAtom::typeTLVInitialZeroFill);
347 }
348
349 /// Utility function to check if relocations in this atom to other defined
350 /// atoms can be implicitly generated, and so we don't need to explicitly
351 /// emit those relocations.
352 bool relocsToDefinedCanBeImplicit() const {
353 ContentType atomContentType = contentType();
354 return atomContentType == typeCFI;
355 }
356
357protected:
358 // DefinedAtom is an abstract base class. Only subclasses can access
359 // constructor.
360 DefinedAtom() : Atom(definitionRegular) { }
361
362 ~DefinedAtom() override = default;
363
364 /// \brief Returns a pointer to the Reference object that the abstract
365 /// iterator "points" to.
366 virtual const Reference *derefIterator(const void *iter) const = 0;
367
368 /// \brief Adjusts the abstract iterator to "point" to the next Reference
369 /// object for this Atom.
370 virtual void incrementIterator(const void *&iter) const = 0;
371};
372} // end namespace lld
373
374#endif
deps/lld/include/lld/Core/Error.h created+68
......@@ -0,0 +1,68 @@
1//===- Error.h - system_error extensions for lld ----------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This declares a new error_category for the lld library.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLD_CORE_ERROR_H
15#define LLD_CORE_ERROR_H
16
17#include "lld/Core/LLVM.h"
18#include "llvm/ADT/Twine.h"
19#include "llvm/Support/Error.h"
20#include <system_error>
21
22namespace lld {
23
24const std::error_category &YamlReaderCategory();
25
26enum class YamlReaderError {
27 unknown_keyword,
28 illegal_value
29};
30
31inline std::error_code make_error_code(YamlReaderError e) {
32 return std::error_code(static_cast<int>(e), YamlReaderCategory());
33}
34
35/// Creates an error_code object that has associated with it an arbitrary
36/// error messsage. The value() of the error_code will always be non-zero
37/// but its value is meaningless. The messsage() will be (a copy of) the
38/// supplied error string.
39/// Note: Once ErrorOr<> is updated to work with errors other than error_code,
40/// this can be updated to return some other kind of error.
41std::error_code make_dynamic_error_code(StringRef msg);
42
43/// Generic error.
44///
45/// For errors that don't require their own specific sub-error (most errors)
46/// this class can be used to describe the error via a string message.
47class GenericError : public llvm::ErrorInfo<GenericError> {
48public:
49 static char ID;
50 GenericError(Twine Msg);
51 const std::string &getMessage() const { return Msg; }
52 void log(llvm::raw_ostream &OS) const override;
53
54 std::error_code convertToErrorCode() const override {
55 return make_dynamic_error_code(getMessage());
56 }
57
58private:
59 std::string Msg;
60};
61
62} // end namespace lld
63
64namespace std {
65template <> struct is_error_code_enum<lld::YamlReaderError> : std::true_type {};
66}
67
68#endif
deps/lld/include/lld/Core/File.h created+278
......@@ -0,0 +1,278 @@
1//===- Core/File.h - A Container of Atoms ---------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_CORE_FILE_H
11#define LLD_CORE_FILE_H
12
13#include "lld/Core/AbsoluteAtom.h"
14#include "lld/Core/DefinedAtom.h"
15#include "lld/Core/SharedLibraryAtom.h"
16#include "lld/Core/UndefinedAtom.h"
17#include "llvm/ADT/Optional.h"
18#include "llvm/ADT/STLExtras.h"
19#include "llvm/ADT/Twine.h"
20#include "llvm/Support/ErrorHandling.h"
21#include <functional>
22#include <memory>
23#include <mutex>
24#include <vector>
25
26namespace lld {
27
28class LinkingContext;
29
30/// Every Atom is owned by some File. A common scenario is for a single
31/// object file (.o) to be parsed by some reader and produce a single
32/// File object that represents the content of that object file.
33///
34/// To iterate through the Atoms in a File there are four methods that
35/// return collections. For instance to iterate through all the DefinedAtoms
36/// in a File object use:
37/// for (const DefinedAtoms *atom : file->defined()) {
38/// }
39///
40/// The Atom objects in a File are owned by the File object. The Atom objects
41/// are destroyed when the File object is destroyed.
42class File {
43public:
44 virtual ~File();
45
46 /// \brief Kinds of files that are supported.
47 enum Kind {
48 kindErrorObject, ///< a error object file (.o)
49 kindNormalizedObject, ///< a normalized file (.o)
50 kindMachObject, ///< a MachO object file (.o)
51 kindCEntryObject, ///< a file for CEntries
52 kindHeaderObject, ///< a file for file headers
53 kindEntryObject, ///< a file for the entry
54 kindUndefinedSymsObject, ///< a file for undefined symbols
55 kindStubHelperObject, ///< a file for stub helpers
56 kindResolverMergedObject, ///< the resolver merged file.
57 kindSectCreateObject, ///< a sect create object file (.o)
58 kindSharedLibrary, ///< shared library (.so)
59 kindArchiveLibrary ///< archive (.a)
60 };
61
62 /// \brief Returns file kind. Need for dyn_cast<> on File objects.
63 Kind kind() const {
64 return _kind;
65 }
66
67 /// This returns the path to the file which was used to create this object
68 /// (e.g. "/tmp/foo.o"). If the file is a member of an archive file, the
69 /// returned string includes the archive file name.
70 StringRef path() const {
71 if (_archivePath.empty())
72 return _path;
73 if (_archiveMemberPath.empty())
74 _archiveMemberPath = (_archivePath + "(" + _path + ")").str();
75 return _archiveMemberPath;
76 }
77
78 /// Returns the path of the archive file name if this file is instantiated
79 /// from an archive file. Otherwise returns the empty string.
80 StringRef archivePath() const { return _archivePath; }
81 void setArchivePath(StringRef path) { _archivePath = path; }
82
83 /// Returns the path name of this file. It doesn't include archive file name.
84 StringRef memberPath() const { return _path; }
85
86 /// Returns the command line order of the file.
87 uint64_t ordinal() const {
88 assert(_ordinal != UINT64_MAX);
89 return _ordinal;
90 }
91
92 /// Returns true/false depending on whether an ordinal has been set.
93 bool hasOrdinal() const { return (_ordinal != UINT64_MAX); }
94
95 /// Sets the command line order of the file.
96 void setOrdinal(uint64_t ordinal) const { _ordinal = ordinal; }
97
98 /// Returns the ordinal for the next atom to be defined in this file.
99 uint64_t getNextAtomOrdinalAndIncrement() const {
100 return _nextAtomOrdinal++;
101 }
102
103 /// For allocating any objects owned by this File.
104 llvm::BumpPtrAllocator &allocator() const {
105 return _allocator;
106 }
107
108 /// The type of atom mutable container.
109 template <typename T> using AtomVector = std::vector<OwningAtomPtr<T>>;
110
111 /// The range type for the atoms.
112 template <typename T> class AtomRange {
113 public:
114 AtomRange(AtomVector<T> &v) : _v(v) {}
115 AtomRange(const AtomVector<T> &v) : _v(const_cast<AtomVector<T> &>(v)) {}
116
117 typedef std::pointer_to_unary_function<const OwningAtomPtr<T>&,
118 const T*> ConstDerefFn;
119
120 typedef std::pointer_to_unary_function<OwningAtomPtr<T>&, T*> DerefFn;
121
122 typedef llvm::mapped_iterator<typename AtomVector<T>::const_iterator,
123 ConstDerefFn> ConstItTy;
124 typedef llvm::mapped_iterator<typename AtomVector<T>::iterator,
125 DerefFn> ItTy;
126
127 static const T* DerefConst(const OwningAtomPtr<T> &p) {
128 return p.get();
129 }
130
131 static T* Deref(OwningAtomPtr<T> &p) {
132 return p.get();
133 }
134
135 ConstItTy begin() const {
136 return ConstItTy(_v.begin(), ConstDerefFn(DerefConst));
137 }
138 ConstItTy end() const {
139 return ConstItTy(_v.end(), ConstDerefFn(DerefConst));
140 }
141
142 ItTy begin() {
143 return ItTy(_v.begin(), DerefFn(Deref));
144 }
145 ItTy end() {
146 return ItTy(_v.end(), DerefFn(Deref));
147 }
148
149 llvm::iterator_range<typename AtomVector<T>::iterator> owning_ptrs() {
150 return llvm::make_range(_v.begin(), _v.end());
151 }
152
153 llvm::iterator_range<typename AtomVector<T>::iterator> owning_ptrs() const {
154 return llvm::make_range(_v.begin(), _v.end());
155 }
156
157 bool empty() const {
158 return _v.empty();
159 }
160
161 size_t size() const {
162 return _v.size();
163 }
164
165 const OwningAtomPtr<T> &operator[](size_t idx) const {
166 return _v[idx];
167 }
168
169 OwningAtomPtr<T> &operator[](size_t idx) {
170 return _v[idx];
171 }
172
173 private:
174 AtomVector<T> &_v;
175 };
176
177 /// \brief Must be implemented to return the AtomVector object for
178 /// all DefinedAtoms in this File.
179 virtual const AtomRange<DefinedAtom> defined() const = 0;
180
181 /// \brief Must be implemented to return the AtomVector object for
182 /// all UndefinedAtomw in this File.
183 virtual const AtomRange<UndefinedAtom> undefined() const = 0;
184
185 /// \brief Must be implemented to return the AtomVector object for
186 /// all SharedLibraryAtoms in this File.
187 virtual const AtomRange<SharedLibraryAtom> sharedLibrary() const = 0;
188
189 /// \brief Must be implemented to return the AtomVector object for
190 /// all AbsoluteAtoms in this File.
191 virtual const AtomRange<AbsoluteAtom> absolute() const = 0;
192
193 /// Drop all of the atoms owned by this file. This will result in all of
194 /// the atoms running their destructors.
195 /// This is required because atoms may be allocated on a BumpPtrAllocator
196 /// of a different file. We need to destruct all atoms before any files.
197 virtual void clearAtoms() = 0;
198
199 /// \brief If a file is parsed using a different method than doParse(),
200 /// one must use this method to set the last error status, so that
201 /// doParse will not be called twice. Only YAML reader uses this
202 /// (because YAML reader does not read blobs but structured data).
203 void setLastError(std::error_code err) { _lastError = err; }
204
205 std::error_code parse();
206
207 // Usually each file owns a std::unique_ptr<MemoryBuffer>.
208 // However, there's one special case. If a file is an archive file,
209 // the archive file and its children all shares the same memory buffer.
210 // This method is used by the ArchiveFile to give its children
211 // co-ownership of the buffer.
212 void setSharedMemoryBuffer(std::shared_ptr<MemoryBuffer> mb) {
213 _sharedMemoryBuffer = mb;
214 }
215
216protected:
217 /// \brief only subclasses of File can be instantiated
218 File(StringRef p, Kind kind)
219 : _path(p), _kind(kind), _ordinal(UINT64_MAX),
220 _nextAtomOrdinal(0) {}
221
222 /// \brief Subclasses should override this method to parse the
223 /// memory buffer passed to this file's constructor.
224 virtual std::error_code doParse() { return std::error_code(); }
225
226 static AtomVector<DefinedAtom> _noDefinedAtoms;
227 static AtomVector<UndefinedAtom> _noUndefinedAtoms;
228 static AtomVector<SharedLibraryAtom> _noSharedLibraryAtoms;
229 static AtomVector<AbsoluteAtom> _noAbsoluteAtoms;
230 mutable llvm::BumpPtrAllocator _allocator;
231
232private:
233 StringRef _path;
234 std::string _archivePath;
235 mutable std::string _archiveMemberPath;
236 Kind _kind;
237 mutable uint64_t _ordinal;
238 mutable uint64_t _nextAtomOrdinal;
239 std::shared_ptr<MemoryBuffer> _sharedMemoryBuffer;
240 llvm::Optional<std::error_code> _lastError;
241 std::mutex _parseMutex;
242};
243
244/// An ErrorFile represents a file that doesn't exist.
245/// If you try to parse a file which doesn't exist, an instance of this
246/// class will be returned. That's parse method always returns an error.
247/// This is useful to delay erroring on non-existent files, so that we
248/// can do unit testing a driver using non-existing file paths.
249class ErrorFile : public File {
250public:
251 ErrorFile(StringRef path, std::error_code ec)
252 : File(path, kindErrorObject), _ec(ec) {}
253
254 std::error_code doParse() override { return _ec; }
255
256 const AtomRange<DefinedAtom> defined() const override {
257 llvm_unreachable("internal error");
258 }
259 const AtomRange<UndefinedAtom> undefined() const override {
260 llvm_unreachable("internal error");
261 }
262 const AtomRange<SharedLibraryAtom> sharedLibrary() const override {
263 llvm_unreachable("internal error");
264 }
265 const AtomRange<AbsoluteAtom> absolute() const override {
266 llvm_unreachable("internal error");
267 }
268
269 void clearAtoms() override {
270 }
271
272private:
273 std::error_code _ec;
274};
275
276} // end namespace lld
277
278#endif
deps/lld/include/lld/Core/Instrumentation.h created+132
......@@ -0,0 +1,132 @@
1//===- include/Core/Instrumentation.h - Instrumentation API ---------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11/// \brief Provide an Instrumentation API that optionally uses VTune interfaces.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLD_CORE_INSTRUMENTATION_H
16#define LLD_CORE_INSTRUMENTATION_H
17
18#include "llvm/Support/Compiler.h"
19#include <utility>
20
21#ifdef LLD_HAS_VTUNE
22# include <ittnotify.h>
23#endif
24
25namespace lld {
26#ifdef LLD_HAS_VTUNE
27/// \brief A unique global scope for instrumentation data.
28///
29/// Domains last for the lifetime of the application and cannot be destroyed.
30/// Multiple Domains created with the same name represent the same domain.
31class Domain {
32 __itt_domain *_domain;
33
34public:
35 explicit Domain(const char *name) : _domain(__itt_domain_createA(name)) {}
36
37 operator __itt_domain *() const { return _domain; }
38 __itt_domain *operator->() const { return _domain; }
39};
40
41/// \brief A global reference to a string constant.
42///
43/// These are uniqued by the ITT runtime and cannot be deleted. They are not
44/// specific to a domain.
45///
46/// Prefer reusing a single StringHandle over passing a ntbs when the same
47/// string will be used often.
48class StringHandle {
49 __itt_string_handle *_handle;
50
51public:
52 StringHandle(const char *name) : _handle(__itt_string_handle_createA(name)) {}
53
54 operator __itt_string_handle *() const { return _handle; }
55};
56
57/// \brief A task on a single thread. Nests within other tasks.
58///
59/// Each thread has its own task stack and tasks nest recursively on that stack.
60/// A task cannot transfer threads.
61///
62/// SBRM is used to ensure task starts and ends are ballanced. The lifetime of
63/// a task is either the lifetime of this object, or until end is called.
64class ScopedTask {
65 __itt_domain *_domain;
66
67 ScopedTask(const ScopedTask &) = delete;
68 ScopedTask &operator=(const ScopedTask &) = delete;
69
70public:
71 /// \brief Create a task in Domain \p d named \p s.
72 ScopedTask(const Domain &d, const StringHandle &s) : _domain(d) {
73 __itt_task_begin(d, __itt_null, __itt_null, s);
74 }
75
76 ScopedTask(ScopedTask &&other) {
77 *this = std::move(other);
78 }
79
80 ScopedTask &operator=(ScopedTask &&other) {
81 _domain = other._domain;
82 other._domain = nullptr;
83 return *this;
84 }
85
86 /// \brief Prematurely end this task.
87 void end() {
88 if (_domain)
89 __itt_task_end(_domain);
90 _domain = nullptr;
91 }
92
93 ~ScopedTask() { end(); }
94};
95
96/// \brief A specific point in time. Allows metadata to be associated.
97class Marker {
98public:
99 Marker(const Domain &d, const StringHandle &s) {
100 __itt_marker(d, __itt_null, s, __itt_scope_global);
101 }
102};
103#else
104class Domain {
105public:
106 Domain(const char *name) {}
107};
108
109class StringHandle {
110public:
111 StringHandle(const char *name) {}
112};
113
114class ScopedTask {
115public:
116 ScopedTask(const Domain &d, const StringHandle &s) {}
117 void end() {}
118};
119
120class Marker {
121public:
122 Marker(const Domain &d, const StringHandle &s) {}
123};
124#endif
125
126inline const Domain &getDefaultDomain() {
127 static Domain domain("org.llvm.lld");
128 return domain;
129}
130} // end namespace lld.
131
132#endif
deps/lld/include/lld/Core/LLVM.h created+83
......@@ -0,0 +1,83 @@
1//===--- LLVM.h - Import various common LLVM datatypes ----------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file forward declares and imports various common LLVM datatypes that
11// lld wants to use unqualified.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLD_CORE_LLVM_H
16#define LLD_CORE_LLVM_H
17
18// This should be the only #include, force #includes of all the others on
19// clients.
20#include "llvm/ADT/Hashing.h"
21#include "llvm/Support/Casting.h"
22#include <utility>
23
24namespace llvm {
25 // ADT's.
26 class Error;
27 class StringRef;
28 class Twine;
29 class MemoryBuffer;
30 class MemoryBufferRef;
31 template<typename T> class ArrayRef;
32 template<unsigned InternalLen> class SmallString;
33 template<typename T, unsigned N> class SmallVector;
34 template<typename T> class SmallVectorImpl;
35
36 template<typename T>
37 struct SaveAndRestore;
38
39 template<typename T>
40 class ErrorOr;
41
42 template<typename T>
43 class Expected;
44
45 class raw_ostream;
46 // TODO: DenseMap, ...
47}
48
49namespace lld {
50 // Casting operators.
51 using llvm::isa;
52 using llvm::cast;
53 using llvm::dyn_cast;
54 using llvm::dyn_cast_or_null;
55 using llvm::cast_or_null;
56
57 // ADT's.
58 using llvm::Error;
59 using llvm::StringRef;
60 using llvm::Twine;
61 using llvm::MemoryBuffer;
62 using llvm::MemoryBufferRef;
63 using llvm::ArrayRef;
64 using llvm::SmallString;
65 using llvm::SmallVector;
66 using llvm::SmallVectorImpl;
67 using llvm::SaveAndRestore;
68 using llvm::ErrorOr;
69 using llvm::Expected;
70
71 using llvm::raw_ostream;
72} // end namespace lld.
73
74namespace std {
75template <> struct hash<llvm::StringRef> {
76public:
77 size_t operator()(const llvm::StringRef &s) const {
78 return llvm::hash_value(s);
79 }
80};
81}
82
83#endif
deps/lld/include/lld/Core/LinkingContext.h created+258
......@@ -0,0 +1,258 @@
1//===- lld/Core/LinkingContext.h - Linker Target Info Interface -*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_CORE_LINKING_CONTEXT_H
11#define LLD_CORE_LINKING_CONTEXT_H
12
13#include "lld/Core/Node.h"
14#include "lld/Core/Reader.h"
15#include "llvm/ADT/ArrayRef.h"
16#include "llvm/ADT/StringRef.h"
17#include "llvm/Support/Allocator.h"
18#include "llvm/Support/Error.h"
19#include "llvm/Support/raw_ostream.h"
20#include <cassert>
21#include <cstdint>
22#include <memory>
23#include <string>
24#include <vector>
25
26namespace lld {
27
28class PassManager;
29class File;
30class Writer;
31class Node;
32class SharedLibraryFile;
33
34/// \brief The LinkingContext class encapsulates "what and how" to link.
35///
36/// The base class LinkingContext contains the options needed by core linking.
37/// Subclasses of LinkingContext have additional options needed by specific
38/// Writers.
39class LinkingContext {
40public:
41 virtual ~LinkingContext();
42
43 /// \name Methods needed by core linking
44 /// @{
45
46 /// Name of symbol linker should use as "entry point" to program,
47 /// usually "main" or "start".
48 virtual StringRef entrySymbolName() const { return _entrySymbolName; }
49
50 /// Whether core linking should remove Atoms not reachable by following
51 /// References from the entry point Atom or from all global scope Atoms
52 /// if globalsAreDeadStripRoots() is true.
53 bool deadStrip() const { return _deadStrip; }
54
55 /// Only used if deadStrip() returns true. Means all global scope Atoms
56 /// should be marked live (along with all Atoms they reference). Usually
57 /// this method returns false for main executables, but true for dynamic
58 /// shared libraries.
59 bool globalsAreDeadStripRoots() const { return _globalsAreDeadStripRoots; }
60
61 /// Only used if deadStrip() returns true. This method returns the names
62 /// of DefinedAtoms that should be marked live (along with all Atoms they
63 /// reference). Only Atoms with scope scopeLinkageUnit or scopeGlobal can
64 /// be kept live using this method.
65 const std::vector<StringRef> &deadStripRoots() const {
66 return _deadStripRoots;
67 }
68
69 /// Add the given symbol name to the dead strip root set. Only used if
70 /// deadStrip() returns true.
71 void addDeadStripRoot(StringRef symbolName) {
72 assert(!symbolName.empty() && "Empty symbol cannot be a dead strip root");
73 _deadStripRoots.push_back(symbolName);
74 }
75
76 /// Normally, every UndefinedAtom must be replaced by a DefinedAtom or a
77 /// SharedLibraryAtom for the link to be successful. This method controls
78 /// whether core linking prints out a list of remaining UndefinedAtoms.
79 ///
80 /// \todo This should be a method core linking calls with a list of the
81 /// UndefinedAtoms so that different drivers can format the error message
82 /// as needed.
83 bool printRemainingUndefines() const { return _printRemainingUndefines; }
84
85 /// Normally, every UndefinedAtom must be replaced by a DefinedAtom or a
86 /// SharedLibraryAtom for the link to be successful. This method controls
87 /// whether core linking considers remaining undefines to be an error.
88 bool allowRemainingUndefines() const { return _allowRemainingUndefines; }
89
90 /// Normally, every UndefinedAtom must be replaced by a DefinedAtom or a
91 /// SharedLibraryAtom for the link to be successful. This method controls
92 /// whether core linking considers remaining undefines from the shared library
93 /// to be an error.
94 bool allowShlibUndefines() const { return _allowShlibUndefines; }
95
96 /// If true, core linking will write the path to each input file to stdout
97 /// (i.e. llvm::outs()) as it is used. This is used to implement the -t
98 /// linker option.
99 ///
100 /// \todo This should be a method core linking calls so that drivers can
101 /// format the line as needed.
102 bool logInputFiles() const { return _logInputFiles; }
103
104 /// Parts of LLVM use global variables which are bound to command line
105 /// options (see llvm::cl::Options). This method returns "command line"
106 /// options which are used to configure LLVM's command line settings.
107 /// For instance the -debug-only XXX option can be used to dynamically
108 /// trace different parts of LLVM and lld.
109 const std::vector<const char *> &llvmOptions() const { return _llvmOptions; }
110
111 /// \name Methods used by Drivers to configure TargetInfo
112 /// @{
113 void setOutputPath(StringRef str) { _outputPath = str; }
114
115 // Set the entry symbol name. You may also need to call addDeadStripRoot() for
116 // the symbol if your platform supports dead-stripping, so that the symbol
117 // will not be removed from the output.
118 void setEntrySymbolName(StringRef name) {
119 _entrySymbolName = name;
120 }
121
122 void setDeadStripping(bool enable) { _deadStrip = enable; }
123 void setGlobalsAreDeadStripRoots(bool v) { _globalsAreDeadStripRoots = v; }
124
125 void setPrintRemainingUndefines(bool print) {
126 _printRemainingUndefines = print;
127 }
128
129 void setAllowRemainingUndefines(bool allow) {
130 _allowRemainingUndefines = allow;
131 }
132
133 void setAllowShlibUndefines(bool allow) { _allowShlibUndefines = allow; }
134 void setLogInputFiles(bool log) { _logInputFiles = log; }
135
136 void appendLLVMOption(const char *opt) { _llvmOptions.push_back(opt); }
137
138 std::vector<std::unique_ptr<Node>> &getNodes() { return _nodes; }
139 const std::vector<std::unique_ptr<Node>> &getNodes() const { return _nodes; }
140
141 /// This method adds undefined symbols specified by the -u option to the to
142 /// the list of undefined symbols known to the linker. This option essentially
143 /// forces an undefined symbol to be created. You may also need to call
144 /// addDeadStripRoot() for the symbol if your platform supports dead
145 /// stripping, so that the symbol will not be removed from the output.
146 void addInitialUndefinedSymbol(StringRef symbolName) {
147 _initialUndefinedSymbols.push_back(symbolName);
148 }
149
150 /// Iterators for symbols that appear on the command line.
151 typedef std::vector<StringRef> StringRefVector;
152 typedef StringRefVector::iterator StringRefVectorIter;
153 typedef StringRefVector::const_iterator StringRefVectorConstIter;
154
155 /// Create linker internal files containing atoms for the linker to include
156 /// during link. Flavors can override this function in their LinkingContext
157 /// to add more internal files. These internal files are positioned before
158 /// the actual input files.
159 virtual void createInternalFiles(std::vector<std::unique_ptr<File>> &) const;
160
161 /// Return the list of undefined symbols that are specified in the
162 /// linker command line, using the -u option.
163 ArrayRef<StringRef> initialUndefinedSymbols() const {
164 return _initialUndefinedSymbols;
165 }
166
167 /// After all set* methods are called, the Driver calls this method
168 /// to validate that there are no missing options or invalid combinations
169 /// of options. If there is a problem, a description of the problem
170 /// is written to the supplied stream.
171 ///
172 /// \returns true if there is an error with the current settings.
173 bool validate(raw_ostream &diagnostics);
174
175 /// Formats symbol name for use in error messages.
176 virtual std::string demangle(StringRef symbolName) const = 0;
177
178 /// @}
179 /// \name Methods used by Driver::link()
180 /// @{
181
182 /// Returns the file system path to which the linked output should be written.
183 ///
184 /// \todo To support in-memory linking, we need an abstraction that allows
185 /// the linker to write to an in-memory buffer.
186 StringRef outputPath() const { return _outputPath; }
187
188 /// Accessor for Register object embedded in LinkingContext.
189 const Registry &registry() const { return _registry; }
190 Registry &registry() { return _registry; }
191
192 /// This method is called by core linking to give the Writer a chance
193 /// to add file format specific "files" to set of files to be linked. This is
194 /// how file format specific atoms can be added to the link.
195 virtual void createImplicitFiles(std::vector<std::unique_ptr<File>> &) = 0;
196
197 /// This method is called by core linking to build the list of Passes to be
198 /// run on the merged/linked graph of all input files.
199 virtual void addPasses(PassManager &pm) = 0;
200
201 /// Calls through to the writeFile() method on the specified Writer.
202 ///
203 /// \param linkedFile This is the merged/linked graph of all input file Atoms.
204 virtual llvm::Error writeFile(const File &linkedFile) const;
205
206 /// Return the next ordinal and Increment it.
207 virtual uint64_t getNextOrdinalAndIncrement() const { return _nextOrdinal++; }
208
209 // This function is called just before the Resolver kicks in.
210 // Derived classes may use it to change the list of input files.
211 virtual void finalizeInputFiles() = 0;
212
213 /// Callback invoked for each file the Resolver decides we are going to load.
214 /// This can be used to update context state based on the file, and emit
215 /// errors for any differences between the context state and a loaded file.
216 /// For example, we can error if we try to load a file which is a different
217 /// arch from that being linked.
218 virtual llvm::Error handleLoadedFile(File &file) = 0;
219
220 /// @}
221protected:
222 LinkingContext(); // Must be subclassed
223
224 /// Abstract method to lazily instantiate the Writer.
225 virtual Writer &writer() const = 0;
226
227 /// Method to create an internal file for the entry symbol
228 virtual std::unique_ptr<File> createEntrySymbolFile() const;
229 std::unique_ptr<File> createEntrySymbolFile(StringRef filename) const;
230
231 /// Method to create an internal file for an undefined symbol
232 virtual std::unique_ptr<File> createUndefinedSymbolFile() const;
233 std::unique_ptr<File> createUndefinedSymbolFile(StringRef filename) const;
234
235 StringRef _outputPath;
236 StringRef _entrySymbolName;
237 bool _deadStrip = false;
238 bool _globalsAreDeadStripRoots = false;
239 bool _printRemainingUndefines = true;
240 bool _allowRemainingUndefines = false;
241 bool _logInputFiles = false;
242 bool _allowShlibUndefines = false;
243 std::vector<StringRef> _deadStripRoots;
244 std::vector<const char *> _llvmOptions;
245 StringRefVector _initialUndefinedSymbols;
246 std::vector<std::unique_ptr<Node>> _nodes;
247 mutable llvm::BumpPtrAllocator _allocator;
248 mutable uint64_t _nextOrdinal = 0;
249 Registry _registry;
250
251private:
252 /// Validate the subclass bits. Only called by validate.
253 virtual bool validateImpl(raw_ostream &diagnostics) = 0;
254};
255
256} // end namespace lld
257
258#endif // LLD_CORE_LINKING_CONTEXT_H
deps/lld/include/lld/Core/Node.h created+75
......@@ -0,0 +1,75 @@
1//===- lld/Core/Node.h - Input file class -----------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11///
12/// The classes in this file represents inputs to the linker.
13///
14//===----------------------------------------------------------------------===//
15
16#ifndef LLD_CORE_NODE_H
17#define LLD_CORE_NODE_H
18
19#include "lld/Core/File.h"
20#include <algorithm>
21#include <memory>
22
23namespace lld {
24
25// A Node represents a FileNode or other type of Node. In the latter case,
26// the node contains meta information about the input file list.
27// Currently only GroupEnd node is defined as a meta node.
28class Node {
29public:
30 enum class Kind { File, GroupEnd };
31
32 explicit Node(Kind type) : _kind(type) {}
33 virtual ~Node() = default;
34
35 virtual Kind kind() const { return _kind; }
36
37private:
38 Kind _kind;
39};
40
41// This is a marker for --end-group. getSize() returns the number of
42// files between the corresponding --start-group and this marker.
43class GroupEnd : public Node {
44public:
45 explicit GroupEnd(int size) : Node(Kind::GroupEnd), _size(size) {}
46
47 int getSize() const { return _size; }
48
49 static bool classof(const Node *a) {
50 return a->kind() == Kind::GroupEnd;
51 }
52
53private:
54 int _size;
55};
56
57// A container of File.
58class FileNode : public Node {
59public:
60 explicit FileNode(std::unique_ptr<File> f)
61 : Node(Node::Kind::File), _file(std::move(f)) {}
62
63 static bool classof(const Node *a) {
64 return a->kind() == Node::Kind::File;
65 }
66
67 File *getFile() { return _file.get(); }
68
69protected:
70 std::unique_ptr<File> _file;
71};
72
73} // end namespace lld
74
75#endif // LLD_CORE_NODE_H
deps/lld/include/lld/Core/Pass.h created+43
......@@ -0,0 +1,43 @@
1//===------ Core/Pass.h - Base class for linker passes ----------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_CORE_PASS_H
11#define LLD_CORE_PASS_H
12
13#include "llvm/Support/Error.h"
14
15namespace lld {
16
17class SimpleFile;
18
19/// Once the core linking is done (which resolves references, coalesces atoms
20/// and produces a complete Atom graph), the linker runs a series of passes
21/// on the Atom graph. The graph is modeled as a File, which means the pass
22/// has access to all the atoms and to File level attributes. Each pass does
23/// a particular transformation to the Atom graph or to the File attributes.
24///
25/// This is the abstract base class for all passes. A Pass does its
26/// actual work in it perform() method. It can iterator over Atoms in the
27/// graph using the *begin()/*end() atom iterator of the File. It can add
28/// new Atoms to the graph using the File's addAtom() method.
29class Pass {
30public:
31 virtual ~Pass() = default;
32
33 /// Do the actual work of the Pass.
34 virtual llvm::Error perform(SimpleFile &mergedFile) = 0;
35
36protected:
37 // Only subclassess can be instantiated.
38 Pass() = default;
39};
40
41} // end namespace lld
42
43#endif // LLD_CORE_PASS_H
deps/lld/include/lld/Core/PassManager.h created+48
......@@ -0,0 +1,48 @@
1//===- lld/Core/PassManager.h - Manage linker passes ----------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_CORE_PASS_MANAGER_H
11#define LLD_CORE_PASS_MANAGER_H
12
13#include "lld/Core/LLVM.h"
14#include "lld/Core/Pass.h"
15#include "llvm/Support/Error.h"
16#include <memory>
17#include <vector>
18
19namespace lld {
20class SimpleFile;
21class Pass;
22
23/// \brief Owns and runs a collection of passes.
24///
25/// This class is currently just a container for passes and a way to run them.
26///
27/// In the future this should handle timing pass runs, running parallel passes,
28/// and validate/satisfy pass dependencies.
29class PassManager {
30public:
31 void add(std::unique_ptr<Pass> pass) {
32 _passes.push_back(std::move(pass));
33 }
34
35 llvm::Error runOnFile(SimpleFile &file) {
36 for (std::unique_ptr<Pass> &pass : _passes)
37 if (llvm::Error EC = pass->perform(file))
38 return EC;
39 return llvm::Error::success();
40 }
41
42private:
43 /// \brief Passes in the order they should run.
44 std::vector<std::unique_ptr<Pass>> _passes;
45};
46} // end namespace lld
47
48#endif
deps/lld/include/lld/Core/Reader.h created+155
......@@ -0,0 +1,155 @@
1//===- lld/Core/Reader.h - Abstract File Format Reading Interface ---------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_CORE_READER_H
11#define LLD_CORE_READER_H
12
13#include "lld/Core/LLVM.h"
14#include "lld/Core/Reference.h"
15#include "llvm/ADT/StringRef.h"
16#include "llvm/BinaryFormat/Magic.h"
17#include "llvm/Support/ErrorOr.h"
18#include "llvm/Support/FileSystem.h"
19#include "llvm/Support/MemoryBuffer.h"
20#include <memory>
21#include <vector>
22
23namespace llvm {
24namespace yaml {
25class IO;
26} // end namespace yaml
27} // end namespace llvm
28
29namespace lld {
30
31class File;
32class LinkingContext;
33class MachOLinkingContext;
34
35/// \brief An abstract class for reading object files, library files, and
36/// executable files.
37///
38/// Each file format (e.g. mach-o, etc) has a concrete subclass of Reader.
39class Reader {
40public:
41 virtual ~Reader() = default;
42
43 /// Sniffs the file to determine if this Reader can parse it.
44 /// The method is called with:
45 /// 1) the file_magic enumeration returned by identify_magic()
46 /// 2) the whole file content buffer if the above is not enough.
47 virtual bool canParse(llvm::file_magic magic, MemoryBufferRef mb) const = 0;
48
49 /// \brief Parse a supplied buffer (already filled with the contents of a
50 /// file) and create a File object.
51 /// The resulting File object takes ownership of the MemoryBuffer.
52 virtual ErrorOr<std::unique_ptr<File>>
53 loadFile(std::unique_ptr<MemoryBuffer> mb, const class Registry &) const = 0;
54};
55
56/// \brief An abstract class for handling alternate yaml representations
57/// of object files.
58///
59/// The YAML syntax allows "tags" which are used to specify the type of
60/// the YAML node. In lld, top level YAML documents can be in many YAML
61/// representations (e.g mach-o encoded as yaml, etc). A tag is used to
62/// specify which representation is used in the following YAML document.
63/// To work, there must be a YamlIOTaggedDocumentHandler registered that
64/// handles each tag type.
65class YamlIOTaggedDocumentHandler {
66public:
67 virtual ~YamlIOTaggedDocumentHandler();
68
69 /// This method is called on each registered YamlIOTaggedDocumentHandler
70 /// until one returns true. If the subclass handles tag type !xyz, then
71 /// this method should call io.mapTag("!xzy") to see if that is the current
72 /// document type, and if so, process the rest of the document using
73 /// YAML I/O, then convert the result into an lld::File* and return it.
74 virtual bool handledDocTag(llvm::yaml::IO &io, const lld::File *&f) const = 0;
75};
76
77/// A registry to hold the list of currently registered Readers and
78/// tables which map Reference kind values to strings.
79/// The linker does not directly invoke Readers. Instead, it registers
80/// Readers based on it configuration and command line options, then calls
81/// the Registry object to parse files.
82class Registry {
83public:
84 Registry();
85
86 /// Walk the list of registered Readers and find one that can parse the
87 /// supplied file and parse it.
88 ErrorOr<std::unique_ptr<File>>
89 loadFile(std::unique_ptr<MemoryBuffer> mb) const;
90
91 /// Walk the list of registered kind tables to convert a Reference Kind
92 /// name to a value.
93 bool referenceKindFromString(StringRef inputStr, Reference::KindNamespace &ns,
94 Reference::KindArch &a,
95 Reference::KindValue &value) const;
96
97 /// Walk the list of registered kind tables to convert a Reference Kind
98 /// value to a string.
99 bool referenceKindToString(Reference::KindNamespace ns, Reference::KindArch a,
100 Reference::KindValue value, StringRef &) const;
101
102 /// Walk the list of registered tag handlers and have the one that handles
103 /// the current document type process the yaml into an lld::File*.
104 bool handleTaggedDoc(llvm::yaml::IO &io, const lld::File *&file) const;
105
106 // These methods are called to dynamically add support for various file
107 // formats. The methods are also implemented in the appropriate lib*.a
108 // library, so that the code for handling a format is only linked in, if this
109 // method is used. Any options that a Reader might need must be passed
110 // as parameters to the addSupport*() method.
111 void addSupportArchives(bool logLoading);
112 void addSupportYamlFiles();
113 void addSupportMachOObjects(MachOLinkingContext &);
114
115 /// To convert between kind values and names, the registry walks the list
116 /// of registered kind tables. Each table is a zero terminated array of
117 /// KindStrings elements.
118 struct KindStrings {
119 Reference::KindValue value;
120 StringRef name;
121 };
122
123 /// A Reference Kind value is a tuple of <namespace, arch, value>. All
124 /// entries in a conversion table have the same <namespace, arch>. The
125 /// array then contains the value/name pairs.
126 void addKindTable(Reference::KindNamespace ns, Reference::KindArch arch,
127 const KindStrings array[]);
128
129private:
130 struct KindEntry {
131 Reference::KindNamespace ns;
132 Reference::KindArch arch;
133 const KindStrings *array;
134 };
135
136 void add(std::unique_ptr<Reader>);
137 void add(std::unique_ptr<YamlIOTaggedDocumentHandler>);
138
139 std::vector<std::unique_ptr<Reader>> _readers;
140 std::vector<std::unique_ptr<YamlIOTaggedDocumentHandler>> _yamlHandlers;
141 std::vector<KindEntry> _kindEntries;
142};
143
144// Utilities for building a KindString table. For instance:
145// static const Registry::KindStrings table[] = {
146// LLD_KIND_STRING_ENTRY(R_VAX_ADDR16),
147// LLD_KIND_STRING_ENTRY(R_VAX_DATA16),
148// LLD_KIND_STRING_END
149// };
150#define LLD_KIND_STRING_ENTRY(name) { name, #name }
151#define LLD_KIND_STRING_END { 0, "" }
152
153} // end namespace lld
154
155#endif // LLD_CORE_READER_H
deps/lld/include/lld/Core/Reference.h created+119
......@@ -0,0 +1,119 @@
1//===- Core/References.h - A Reference to Another Atom ----------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_CORE_REFERENCES_H
11#define LLD_CORE_REFERENCES_H
12
13#include <cstdint>
14
15namespace lld {
16
17class Atom;
18
19///
20/// The linker has a Graph Theory model of linking. An object file is seen
21/// as a set of Atoms with References to other Atoms. Each Atom is a node
22/// and each Reference is an edge.
23///
24/// For example if a function contains a call site to "malloc" 40 bytes into
25/// the Atom, then the function Atom will have a Reference of: offsetInAtom=40,
26/// kind=callsite, target=malloc, addend=0.
27///
28/// Besides supporting traditional "relocations", references are also used
29/// forcing layout (one atom must follow another), marking data-in-code
30/// (jump tables or ARM constants), etc.
31///
32/// The "kind" of a reference is a tuple of <namespace, arch, value>. This
33/// enable us to re-use existing relocation types definded for various
34/// file formats and architectures.
35///
36/// References and atoms form a directed graph. The dead-stripping pass
37/// traverses them starting from dead-strip root atoms to garbage collect
38/// unreachable ones.
39///
40/// References of any kind are considered as directed edges. In addition to
41/// that, references of some kind is considered as bidirected edges.
42class Reference {
43public:
44 /// Which universe defines the kindValue().
45 enum class KindNamespace {
46 all = 0,
47 testing = 1,
48 mach_o = 2,
49 };
50
51 KindNamespace kindNamespace() const { return (KindNamespace)_kindNamespace; }
52 void setKindNamespace(KindNamespace ns) { _kindNamespace = (uint8_t)ns; }
53
54 // Which architecture the kind value is for.
55 enum class KindArch { all, AArch64, ARM, x86, x86_64};
56
57 KindArch kindArch() const { return (KindArch)_kindArch; }
58 void setKindArch(KindArch a) { _kindArch = (uint8_t)a; }
59
60 typedef uint16_t KindValue;
61
62 KindValue kindValue() const { return _kindValue; }
63
64 /// setKindValue() is needed because during linking, some optimizations may
65 /// change the codegen and hence the reference kind.
66 void setKindValue(KindValue value) {
67 _kindValue = value;
68 }
69
70 /// KindValues used with KindNamespace::all and KindArch::all.
71 enum {
72 // kindLayoutAfter is treated as a bidirected edge by the dead-stripping
73 // pass.
74 kindLayoutAfter = 1,
75 kindAssociate,
76 };
77
78 // A value to be added to the value of a target
79 typedef int64_t Addend;
80
81 /// If the reference is a fixup in the Atom, then this returns the
82 /// byte offset into the Atom's content to do the fix up.
83 virtual uint64_t offsetInAtom() const = 0;
84
85 /// Returns the atom this reference refers to.
86 virtual const Atom *target() const = 0;
87
88 /// During linking, the linker may merge graphs which coalesces some nodes
89 /// (i.e. Atoms). To switch the target of a reference, this method is called.
90 virtual void setTarget(const Atom *) = 0;
91
92 /// Some relocations require a symbol and a value (e.g. foo + 4).
93 virtual Addend addend() const = 0;
94
95 /// During linking, some optimzations may change addend value.
96 virtual void setAddend(Addend) = 0;
97
98 /// Returns target specific attributes of the reference.
99 virtual uint32_t tag() const { return 0; }
100
101protected:
102 /// Reference is an abstract base class. Only subclasses can use constructor.
103 Reference(KindNamespace ns, KindArch a, KindValue value)
104 : _kindValue(value), _kindNamespace((uint8_t)ns), _kindArch((uint8_t)a) {}
105
106 /// The memory for Reference objects is always managed by the owning File
107 /// object. Therefore, no one but the owning File object should call
108 /// delete on an Reference. In fact, some File objects may bulk allocate
109 /// an array of References, so they cannot be individually deleted by anyone.
110 virtual ~Reference() = default;
111
112 KindValue _kindValue;
113 uint8_t _kindNamespace;
114 uint8_t _kindArch;
115};
116
117} // end namespace lld
118
119#endif // LLD_CORE_REFERENCES_H
deps/lld/include/lld/Core/Reproduce.h created+39
......@@ -0,0 +1,39 @@
1//===- Reproduce.h - Utilities for creating reproducers ---------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_CORE_REPRODUCE_H
11#define LLD_CORE_REPRODUCE_H
12
13#include "lld/Core/LLVM.h"
14#include "llvm/ADT/StringRef.h"
15#include "llvm/Support/Error.h"
16
17namespace llvm {
18namespace opt { class Arg; }
19}
20
21namespace lld {
22
23// Makes a given pathname an absolute path first, and then remove
24// beginning /. For example, "../foo.o" is converted to "home/john/foo.o",
25// assuming that the current directory is "/home/john/bar".
26std::string relativeToRoot(StringRef Path);
27
28// Quote a given string if it contains a space character.
29std::string quote(StringRef S);
30
31// Rewrite the given path if a file exists with that pathname, otherwise
32// returns the original path.
33std::string rewritePath(StringRef S);
34
35// Returns the string form of the given argument.
36std::string toString(llvm::opt::Arg *Arg);
37}
38
39#endif
deps/lld/include/lld/Core/Resolver.h created+106
......@@ -0,0 +1,106 @@
1//===- Core/Resolver.h - Resolves Atom References -------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_CORE_RESOLVER_H
11#define LLD_CORE_RESOLVER_H
12
13#include "lld/Core/ArchiveLibraryFile.h"
14#include "lld/Core/File.h"
15#include "lld/Core/SharedLibraryFile.h"
16#include "lld/Core/Simple.h"
17#include "lld/Core/SymbolTable.h"
18#include "llvm/ADT/DenseMap.h"
19#include "llvm/ADT/DenseSet.h"
20#include "llvm/Support/ErrorOr.h"
21#include <set>
22#include <unordered_map>
23#include <unordered_set>
24#include <vector>
25
26namespace lld {
27
28class Atom;
29class LinkingContext;
30
31/// \brief The Resolver is responsible for merging all input object files
32/// and producing a merged graph.
33class Resolver {
34public:
35 Resolver(LinkingContext &ctx) : _ctx(ctx), _result(new MergedFile()) {}
36
37 // InputFiles::Handler methods
38 void doDefinedAtom(OwningAtomPtr<DefinedAtom> atom);
39 bool doUndefinedAtom(OwningAtomPtr<UndefinedAtom> atom);
40 void doSharedLibraryAtom(OwningAtomPtr<SharedLibraryAtom> atom);
41 void doAbsoluteAtom(OwningAtomPtr<AbsoluteAtom> atom);
42
43 // Handle files, this adds atoms from the current file thats
44 // being processed by the resolver
45 llvm::Expected<bool> handleFile(File &);
46
47 // Handle an archive library file.
48 llvm::Expected<bool> handleArchiveFile(File &);
49
50 // Handle a shared library file.
51 llvm::Error handleSharedLibrary(File &);
52
53 /// @brief do work of merging and resolving and return list
54 bool resolve();
55
56 std::unique_ptr<SimpleFile> resultFile() { return std::move(_result); }
57
58private:
59 typedef std::function<llvm::Expected<bool>(StringRef)> UndefCallback;
60
61 bool undefinesAdded(int begin, int end);
62 File *getFile(int &index);
63
64 /// \brief The main function that iterates over the files to resolve
65 bool resolveUndefines();
66 void updateReferences();
67 void deadStripOptimize();
68 bool checkUndefines();
69 void removeCoalescedAwayAtoms();
70 llvm::Expected<bool> forEachUndefines(File &file, UndefCallback callback);
71
72 void markLive(const Atom *atom);
73
74 class MergedFile : public SimpleFile {
75 public:
76 MergedFile() : SimpleFile("<linker-internal>", kindResolverMergedObject) {}
77 void addAtoms(llvm::MutableArrayRef<OwningAtomPtr<Atom>> atoms);
78 };
79
80 LinkingContext &_ctx;
81 SymbolTable _symbolTable;
82 std::vector<OwningAtomPtr<Atom>> _atoms;
83 std::set<const Atom *> _deadStripRoots;
84 llvm::DenseSet<const Atom *> _liveAtoms;
85 llvm::DenseSet<const Atom *> _deadAtoms;
86 std::unique_ptr<MergedFile> _result;
87 std::unordered_multimap<const Atom *, const Atom *> _reverseRef;
88
89 // --start-group and --end-group
90 std::vector<File *> _files;
91 std::map<File *, bool> _newUndefinesAdded;
92
93 // List of undefined symbols.
94 std::vector<StringRef> _undefines;
95
96 // Start position in _undefines for each archive/shared library file.
97 // Symbols from index 0 to the start position are already searched before.
98 // Searching them again would never succeed. When we look for undefined
99 // symbols from an archive/shared library file, start from its start
100 // position to save time.
101 std::map<File *, size_t> _undefineIndex;
102};
103
104} // namespace lld
105
106#endif // LLD_CORE_RESOLVER_H
deps/lld/include/lld/Core/SharedLibraryAtom.h created+53
......@@ -0,0 +1,53 @@
1//===- Core/SharedLibraryAtom.h - A Shared Library Atom -------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_CORE_SHARED_LIBRARY_ATOM_H
11#define LLD_CORE_SHARED_LIBRARY_ATOM_H
12
13#include "lld/Core/Atom.h"
14
15namespace lld {
16
17/// A SharedLibraryAtom has no content.
18/// It exists to represent a symbol which will be bound at runtime.
19class SharedLibraryAtom : public Atom {
20public:
21 enum class Type : uint32_t {
22 Unknown,
23 Code,
24 Data,
25 };
26
27 /// Returns shared library name used to load it at runtime.
28 /// On Darwin it is the LC_DYLIB_LOAD dylib name.
29 virtual StringRef loadName() const = 0;
30
31 /// Returns if shared library symbol can be missing at runtime and if
32 /// so the loader should silently resolve address of symbol to be nullptr.
33 virtual bool canBeNullAtRuntime() const = 0;
34
35 virtual Type type() const = 0;
36
37 virtual uint64_t size() const = 0;
38
39 static bool classof(const Atom *a) {
40 return a->definition() == definitionSharedLibrary;
41 }
42
43 static inline bool classof(const SharedLibraryAtom *) { return true; }
44
45protected:
46 SharedLibraryAtom() : Atom(definitionSharedLibrary) {}
47
48 ~SharedLibraryAtom() override = default;
49};
50
51} // namespace lld
52
53#endif // LLD_CORE_SHARED_LIBRARY_ATOM_H
deps/lld/include/lld/Core/SharedLibraryFile.h created+70
......@@ -0,0 +1,70 @@
1//===- Core/SharedLibraryFile.h - Models shared libraries as Atoms --------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_CORE_SHARED_LIBRARY_FILE_H
11#define LLD_CORE_SHARED_LIBRARY_FILE_H
12
13#include "lld/Core/File.h"
14
15namespace lld {
16
17///
18/// The SharedLibraryFile subclass of File is used to represent dynamic
19/// shared libraries being linked against.
20///
21class SharedLibraryFile : public File {
22public:
23 static bool classof(const File *f) {
24 return f->kind() == kindSharedLibrary;
25 }
26
27 /// Check if the shared library exports a symbol with the specified name.
28 /// If so, return a SharedLibraryAtom which represents that exported
29 /// symbol. Otherwise return nullptr.
30 virtual OwningAtomPtr<SharedLibraryAtom> exports(StringRef name) const = 0;
31
32 // Returns the install name.
33 virtual StringRef getDSOName() const = 0;
34
35 const AtomRange<DefinedAtom> defined() const override {
36 return _definedAtoms;
37 }
38
39 const AtomRange<UndefinedAtom> undefined() const override {
40 return _undefinedAtoms;
41 }
42
43 const AtomRange<SharedLibraryAtom> sharedLibrary() const override {
44 return _sharedLibraryAtoms;
45 }
46
47 const AtomRange<AbsoluteAtom> absolute() const override {
48 return _absoluteAtoms;
49 }
50
51 void clearAtoms() override {
52 _definedAtoms.clear();
53 _undefinedAtoms.clear();
54 _sharedLibraryAtoms.clear();
55 _absoluteAtoms.clear();
56 }
57
58protected:
59 /// only subclasses of SharedLibraryFile can be instantiated
60 explicit SharedLibraryFile(StringRef path) : File(path, kindSharedLibrary) {}
61
62 AtomVector<DefinedAtom> _definedAtoms;
63 AtomVector<UndefinedAtom> _undefinedAtoms;
64 AtomVector<SharedLibraryAtom> _sharedLibraryAtoms;
65 AtomVector<AbsoluteAtom> _absoluteAtoms;
66};
67
68} // namespace lld
69
70#endif // LLD_CORE_SHARED_LIBRARY_FILE_H
deps/lld/include/lld/Core/Simple.h created+271
......@@ -0,0 +1,271 @@
1//===- lld/Core/Simple.h - Simple implementations of Atom and File --------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11/// \brief Provide simple implementations for Atoms and File.
12///
13//===----------------------------------------------------------------------===//
14
15#ifndef LLD_CORE_SIMPLE_H
16#define LLD_CORE_SIMPLE_H
17
18#include "lld/Core/AbsoluteAtom.h"
19#include "lld/Core/Atom.h"
20#include "lld/Core/DefinedAtom.h"
21#include "lld/Core/File.h"
22#include "lld/Core/Reference.h"
23#include "lld/Core/SharedLibraryAtom.h"
24#include "lld/Core/UndefinedAtom.h"
25#include "llvm/ADT/SmallVector.h"
26#include "llvm/ADT/StringRef.h"
27#include "llvm/ADT/ilist.h"
28#include "llvm/ADT/ilist_node.h"
29#include "llvm/Support/Allocator.h"
30#include "llvm/Support/Casting.h"
31#include "llvm/Support/ErrorHandling.h"
32#include <algorithm>
33#include <cassert>
34#include <cstdint>
35#include <functional>
36
37namespace lld {
38
39class SimpleFile : public File {
40public:
41 SimpleFile(StringRef path, File::Kind kind)
42 : File(path, kind) {}
43
44 ~SimpleFile() override {
45 _defined.clear();
46 _undefined.clear();
47 _shared.clear();
48 _absolute.clear();
49 }
50
51 void addAtom(DefinedAtom &a) {
52 _defined.push_back(OwningAtomPtr<DefinedAtom>(&a));
53 }
54 void addAtom(UndefinedAtom &a) {
55 _undefined.push_back(OwningAtomPtr<UndefinedAtom>(&a));
56 }
57 void addAtom(SharedLibraryAtom &a) {
58 _shared.push_back(OwningAtomPtr<SharedLibraryAtom>(&a));
59 }
60 void addAtom(AbsoluteAtom &a) {
61 _absolute.push_back(OwningAtomPtr<AbsoluteAtom>(&a));
62 }
63
64 void addAtom(const Atom &atom) {
65 if (auto *p = dyn_cast<DefinedAtom>(&atom)) {
66 addAtom(const_cast<DefinedAtom &>(*p));
67 } else if (auto *p = dyn_cast<UndefinedAtom>(&atom)) {
68 addAtom(const_cast<UndefinedAtom &>(*p));
69 } else if (auto *p = dyn_cast<SharedLibraryAtom>(&atom)) {
70 addAtom(const_cast<SharedLibraryAtom &>(*p));
71 } else if (auto *p = dyn_cast<AbsoluteAtom>(&atom)) {
72 addAtom(const_cast<AbsoluteAtom &>(*p));
73 } else {
74 llvm_unreachable("atom has unknown definition kind");
75 }
76 }
77
78 void removeDefinedAtomsIf(std::function<bool(const DefinedAtom *)> pred) {
79 auto &atoms = _defined;
80 auto newEnd = std::remove_if(atoms.begin(), atoms.end(),
81 [&pred](OwningAtomPtr<DefinedAtom> &p) {
82 return pred(p.get());
83 });
84 atoms.erase(newEnd, atoms.end());
85 }
86
87 const AtomRange<DefinedAtom> defined() const override { return _defined; }
88
89 const AtomRange<UndefinedAtom> undefined() const override {
90 return _undefined;
91 }
92
93 const AtomRange<SharedLibraryAtom> sharedLibrary() const override {
94 return _shared;
95 }
96
97 const AtomRange<AbsoluteAtom> absolute() const override {
98 return _absolute;
99 }
100
101 void clearAtoms() override {
102 _defined.clear();
103 _undefined.clear();
104 _shared.clear();
105 _absolute.clear();
106 }
107
108private:
109 AtomVector<DefinedAtom> _defined;
110 AtomVector<UndefinedAtom> _undefined;
111 AtomVector<SharedLibraryAtom> _shared;
112 AtomVector<AbsoluteAtom> _absolute;
113};
114
115class SimpleReference : public Reference,
116 public llvm::ilist_node<SimpleReference> {
117public:
118 SimpleReference(Reference::KindNamespace ns, Reference::KindArch arch,
119 Reference::KindValue value, uint64_t off, const Atom *t,
120 Reference::Addend a)
121 : Reference(ns, arch, value), _target(t), _offsetInAtom(off), _addend(a) {
122 }
123 SimpleReference()
124 : Reference(Reference::KindNamespace::all, Reference::KindArch::all, 0),
125 _target(nullptr), _offsetInAtom(0), _addend(0) {}
126
127 uint64_t offsetInAtom() const override { return _offsetInAtom; }
128
129 const Atom *target() const override {
130 assert(_target);
131 return _target;
132 }
133
134 Addend addend() const override { return _addend; }
135 void setAddend(Addend a) override { _addend = a; }
136 void setTarget(const Atom *newAtom) override { _target = newAtom; }
137
138private:
139 const Atom *_target;
140 uint64_t _offsetInAtom;
141 Addend _addend;
142};
143
144class SimpleDefinedAtom : public DefinedAtom {
145public:
146 explicit SimpleDefinedAtom(const File &f)
147 : _file(f), _ordinal(f.getNextAtomOrdinalAndIncrement()) {}
148
149 ~SimpleDefinedAtom() override {
150 _references.clearAndLeakNodesUnsafely();
151 }
152
153 const File &file() const override { return _file; }
154
155 StringRef name() const override { return StringRef(); }
156
157 uint64_t ordinal() const override { return _ordinal; }
158
159 Scope scope() const override { return DefinedAtom::scopeLinkageUnit; }
160
161 Interposable interposable() const override {
162 return DefinedAtom::interposeNo;
163 }
164
165 Merge merge() const override { return DefinedAtom::mergeNo; }
166
167 Alignment alignment() const override { return 1; }
168
169 SectionChoice sectionChoice() const override {
170 return DefinedAtom::sectionBasedOnContent;
171 }
172
173 StringRef customSectionName() const override { return StringRef(); }
174 DeadStripKind deadStrip() const override {
175 return DefinedAtom::deadStripNormal;
176 }
177
178 DefinedAtom::reference_iterator begin() const override {
179 const void *it =
180 reinterpret_cast<const void *>(_references.begin().getNodePtr());
181 return reference_iterator(*this, it);
182 }
183
184 DefinedAtom::reference_iterator end() const override {
185 const void *it =
186 reinterpret_cast<const void *>(_references.end().getNodePtr());
187 return reference_iterator(*this, it);
188 }
189
190 const Reference *derefIterator(const void *it) const override {
191 return &*RefList::const_iterator(
192 *reinterpret_cast<const llvm::ilist_node<SimpleReference> *>(it));
193 }
194
195 void incrementIterator(const void *&it) const override {
196 RefList::const_iterator ref(
197 *reinterpret_cast<const llvm::ilist_node<SimpleReference> *>(it));
198 it = reinterpret_cast<const void *>(std::next(ref).getNodePtr());
199 }
200
201 void addReference(Reference::KindNamespace ns,
202 Reference::KindArch arch,
203 Reference::KindValue kindValue, uint64_t off,
204 const Atom *target, Reference::Addend a) override {
205 assert(target && "trying to create reference to nothing");
206 auto node = new (_file.allocator())
207 SimpleReference(ns, arch, kindValue, off, target, a);
208 _references.push_back(node);
209 }
210
211 /// Sort references in a canonical order (by offset, then by kind).
212 void sortReferences() const {
213 // Cannot sort a linked list, so move elements into a temporary vector,
214 // sort the vector, then reconstruct the list.
215 llvm::SmallVector<SimpleReference *, 16> elements;
216 for (SimpleReference &node : _references) {
217 elements.push_back(&node);
218 }
219 std::sort(elements.begin(), elements.end(),
220 [] (const SimpleReference *lhs, const SimpleReference *rhs) -> bool {
221 uint64_t lhsOffset = lhs->offsetInAtom();
222 uint64_t rhsOffset = rhs->offsetInAtom();
223 if (rhsOffset != lhsOffset)
224 return (lhsOffset < rhsOffset);
225 if (rhs->kindNamespace() != lhs->kindNamespace())
226 return (lhs->kindNamespace() < rhs->kindNamespace());
227 if (rhs->kindArch() != lhs->kindArch())
228 return (lhs->kindArch() < rhs->kindArch());
229 return (lhs->kindValue() < rhs->kindValue());
230 });
231 _references.clearAndLeakNodesUnsafely();
232 for (SimpleReference *node : elements) {
233 _references.push_back(node);
234 }
235 }
236
237 void setOrdinal(uint64_t ord) { _ordinal = ord; }
238
239private:
240 typedef llvm::ilist<SimpleReference> RefList;
241
242 const File &_file;
243 uint64_t _ordinal;
244 mutable RefList _references;
245};
246
247class SimpleUndefinedAtom : public UndefinedAtom {
248public:
249 SimpleUndefinedAtom(const File &f, StringRef name) : _file(f), _name(name) {
250 assert(!name.empty() && "UndefinedAtoms must have a name");
251 }
252
253 ~SimpleUndefinedAtom() override = default;
254
255 /// file - returns the File that produced/owns this Atom
256 const File &file() const override { return _file; }
257
258 /// name - The name of the atom. For a function atom, it is the (mangled)
259 /// name of the function.
260 StringRef name() const override { return _name; }
261
262 CanBeNull canBeNull() const override { return UndefinedAtom::canBeNullNever; }
263
264private:
265 const File &_file;
266 StringRef _name;
267};
268
269} // end namespace lld
270
271#endif // LLD_CORE_SIMPLE_H
deps/lld/include/lld/Core/SymbolTable.h created+96
......@@ -0,0 +1,96 @@
1//===- Core/SymbolTable.h - Main Symbol Table -----------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_CORE_SYMBOL_TABLE_H
11#define LLD_CORE_SYMBOL_TABLE_H
12
13#include "lld/Core/LLVM.h"
14#include "llvm/ADT/DenseSet.h"
15#include "llvm/ADT/StringExtras.h"
16#include <cstring>
17#include <map>
18#include <vector>
19
20namespace lld {
21
22class AbsoluteAtom;
23class Atom;
24class DefinedAtom;
25class LinkingContext;
26class ResolverOptions;
27class SharedLibraryAtom;
28class UndefinedAtom;
29
30/// \brief The SymbolTable class is responsible for coalescing atoms.
31///
32/// All atoms coalescable by-name or by-content should be added.
33/// The method replacement() can be used to find the replacement atom
34/// if an atom has been coalesced away.
35class SymbolTable {
36public:
37 /// @brief add atom to symbol table
38 bool add(const DefinedAtom &);
39
40 /// @brief add atom to symbol table
41 bool add(const UndefinedAtom &);
42
43 /// @brief add atom to symbol table
44 bool add(const SharedLibraryAtom &);
45
46 /// @brief add atom to symbol table
47 bool add(const AbsoluteAtom &);
48
49 /// @brief returns atom in symbol table for specified name (or nullptr)
50 const Atom *findByName(StringRef sym);
51
52 /// @brief returns vector of remaining UndefinedAtoms
53 std::vector<const UndefinedAtom *> undefines();
54
55 /// @brief if atom has been coalesced away, return replacement, else return atom
56 const Atom *replacement(const Atom *);
57
58 /// @brief if atom has been coalesced away, return true
59 bool isCoalescedAway(const Atom *);
60
61private:
62 typedef llvm::DenseMap<const Atom *, const Atom *> AtomToAtom;
63
64 struct StringRefMappingInfo {
65 static StringRef getEmptyKey() { return StringRef(); }
66 static StringRef getTombstoneKey() { return StringRef(" ", 1); }
67 static unsigned getHashValue(StringRef const val) {
68 return llvm::HashString(val);
69 }
70 static bool isEqual(StringRef const lhs, StringRef const rhs) {
71 return lhs.equals(rhs);
72 }
73 };
74 typedef llvm::DenseMap<StringRef, const Atom *,
75 StringRefMappingInfo> NameToAtom;
76
77 struct AtomMappingInfo {
78 static const DefinedAtom * getEmptyKey() { return nullptr; }
79 static const DefinedAtom * getTombstoneKey() { return (DefinedAtom*)(-1); }
80 static unsigned getHashValue(const DefinedAtom * const Val);
81 static bool isEqual(const DefinedAtom * const LHS,
82 const DefinedAtom * const RHS);
83 };
84 typedef llvm::DenseSet<const DefinedAtom*, AtomMappingInfo> AtomContentSet;
85
86 bool addByName(const Atom &);
87 bool addByContent(const DefinedAtom &);
88
89 AtomToAtom _replacedAtoms;
90 NameToAtom _nameTable;
91 AtomContentSet _contentTable;
92};
93
94} // namespace lld
95
96#endif // LLD_CORE_SYMBOL_TABLE_H
deps/lld/include/lld/Core/TODO.txt created+17
......@@ -0,0 +1,17 @@
1include/lld/Core
2~~~~~~~~~~~~~~~~
3
4* The yaml reader/writer interfaces should be changed to return
5 an explanatory string if there is an error. The existing error_code
6 abstraction only works for returning low level OS errors. It does not
7 work for describing formatting issues.
8
9* We need to design a diagnostics interface. It would be nice to share code
10 with Clang_ where possible.
11
12* We need to add more attributes to File. In particular, we need cpu
13 and OS information (like target triples). We should also provide explicit
14 support for `LLVM IR module flags metadata`__.
15
16.. __: http://llvm.org/docs/LangRef.html#module_flags
17.. _Clang: http://clang.llvm.org/docs/InternalsManual.html#Diagnostics
deps/lld/include/lld/Core/TargetOptionsCommandFlags.h created+20
......@@ -0,0 +1,20 @@
1//===-- TargetOptionsCommandFlags.h ----------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Helper to create TargetOptions from command line flags.
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/Support/CodeGen.h"
15#include "llvm/Target/TargetOptions.h"
16
17namespace lld {
18llvm::TargetOptions InitTargetOptionsFromCodeGenFlags();
19llvm::CodeModel::Model GetCodeModelFromCMModel();
20}
deps/lld/include/lld/Core/UndefinedAtom.h created+68
......@@ -0,0 +1,68 @@
1//===- Core/UndefinedAtom.h - An Undefined Atom ---------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_CORE_UNDEFINED_ATOM_H
11#define LLD_CORE_UNDEFINED_ATOM_H
12
13#include "lld/Core/Atom.h"
14
15namespace lld {
16
17/// An UndefinedAtom has no content.
18/// It exists as a placeholder for a future atom.
19class UndefinedAtom : public Atom {
20public:
21 /// Whether this undefined symbol needs to be resolved,
22 /// or whether it can just evaluate to nullptr.
23 /// This concept is often called "weak", but that term
24 /// is overloaded to mean other things too.
25 enum CanBeNull {
26 /// Normal symbols must be resolved at build time
27 canBeNullNever,
28
29 /// This symbol can be missing at runtime and will evalute to nullptr.
30 /// That is, the static linker still must find a definition (usually
31 /// is some shared library), but at runtime, the dynamic loader
32 /// will allow the symbol to be missing and resolved to nullptr.
33 ///
34 /// On Darwin this is generated using a function prototype with
35 /// __attribute__((weak_import)).
36 /// On linux this is generated using a function prototype with
37 /// __attribute__((weak)).
38 /// On Windows this feature is not supported.
39 canBeNullAtRuntime,
40
41 /// This symbol can be missing at build time.
42 /// That is, the static linker will not error if a definition for
43 /// this symbol is not found at build time. Instead, the linker
44 /// will build an executable that lets the dynamic loader find the
45 /// symbol at runtime.
46 /// This feature is not supported on Darwin nor Windows.
47 /// On linux this is generated using a function prototype with
48 /// __attribute__((weak)).
49 canBeNullAtBuildtime
50 };
51
52 virtual CanBeNull canBeNull() const = 0;
53
54 static bool classof(const Atom *a) {
55 return a->definition() == definitionUndefined;
56 }
57
58 static bool classof(const UndefinedAtom *) { return true; }
59
60protected:
61 UndefinedAtom() : Atom(definitionUndefined) {}
62
63 ~UndefinedAtom() override = default;
64};
65
66} // namespace lld
67
68#endif // LLD_CORE_UNDEFINED_ATOM_H
deps/lld/include/lld/Core/Writer.h created+47
......@@ -0,0 +1,47 @@
1//===- lld/Core/Writer.h - Abstract File Format Interface -----------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_CORE_WRITER_H
11#define LLD_CORE_WRITER_H
12
13#include "lld/Core/LLVM.h"
14#include "llvm/Support/Error.h"
15#include <memory>
16#include <vector>
17
18namespace lld {
19class File;
20class LinkingContext;
21class MachOLinkingContext;
22
23/// \brief The Writer is an abstract class for writing object files, shared
24/// library files, and executable files. Each file format (e.g. mach-o, etc)
25/// has a concrete subclass of Writer.
26class Writer {
27public:
28 virtual ~Writer();
29
30 /// \brief Write a file from the supplied File object
31 virtual llvm::Error writeFile(const File &linkedFile, StringRef path) = 0;
32
33 /// \brief This method is called by Core Linking to give the Writer a chance
34 /// to add file format specific "files" to set of files to be linked. This is
35 /// how file format specific atoms can be added to the link.
36 virtual void createImplicitFiles(std::vector<std::unique_ptr<File>> &) {}
37
38protected:
39 // only concrete subclasses can be instantiated
40 Writer();
41};
42
43std::unique_ptr<Writer> createWriterMachO(const MachOLinkingContext &);
44std::unique_ptr<Writer> createWriterYAML(const LinkingContext &);
45} // end namespace lld
46
47#endif
deps/lld/include/lld/Driver/Driver.h created+33
......@@ -0,0 +1,33 @@
1//===- lld/Driver/Driver.h - Linker Driver Emulator -----------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_DRIVER_DRIVER_H
11#define LLD_DRIVER_DRIVER_H
12
13#include "llvm/ADT/ArrayRef.h"
14#include "llvm/Support/raw_ostream.h"
15
16namespace lld {
17namespace coff {
18bool link(llvm::ArrayRef<const char *> Args,
19 llvm::raw_ostream &Diag = llvm::errs());
20}
21
22namespace elf {
23bool link(llvm::ArrayRef<const char *> Args, bool CanExitEarly,
24 llvm::raw_ostream &Diag = llvm::errs());
25}
26
27namespace mach_o {
28bool link(llvm::ArrayRef<const char *> Args,
29 llvm::raw_ostream &Diag = llvm::errs());
30}
31}
32
33#endif
deps/lld/include/lld/ReaderWriter/MachOLinkingContext.h created+508
......@@ -0,0 +1,508 @@
1//===- lld/ReaderWriter/MachOLinkingContext.h -----------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_READER_WRITER_MACHO_LINKING_CONTEXT_H
11#define LLD_READER_WRITER_MACHO_LINKING_CONTEXT_H
12
13#include "lld/Core/LinkingContext.h"
14#include "lld/Core/Reader.h"
15#include "lld/Core/Writer.h"
16#include "llvm/ADT/STLExtras.h"
17#include "llvm/ADT/StringMap.h"
18#include "llvm/ADT/StringSet.h"
19#include "llvm/BinaryFormat/MachO.h"
20#include "llvm/Support/ErrorHandling.h"
21#include <set>
22
23using llvm::MachO::HeaderFileType;
24
25namespace lld {
26
27namespace mach_o {
28class ArchHandler;
29class MachODylibFile;
30class MachOFile;
31class SectCreateFile;
32}
33
34class MachOLinkingContext : public LinkingContext {
35public:
36 MachOLinkingContext();
37 ~MachOLinkingContext() override;
38
39 enum Arch {
40 arch_unknown,
41 arch_ppc,
42 arch_x86,
43 arch_x86_64,
44 arch_armv6,
45 arch_armv7,
46 arch_armv7s,
47 arch_arm64,
48 };
49
50 enum class OS {
51 unknown,
52 macOSX,
53 iOS,
54 iOS_simulator
55 };
56
57 enum class ExportMode {
58 globals, // Default, all global symbols exported.
59 whiteList, // -exported_symbol[s_list], only listed symbols exported.
60 blackList // -unexported_symbol[s_list], no listed symbol exported.
61 };
62
63 enum class DebugInfoMode {
64 addDebugMap, // Default
65 noDebugMap // -S option
66 };
67
68 enum class UndefinedMode {
69 error,
70 warning,
71 suppress,
72 dynamicLookup
73 };
74
75 enum ObjCConstraint {
76 objc_unknown = 0,
77 objc_supports_gc = 2,
78 objc_gc_only = 4,
79 // Image optimized by dyld = 8
80 // GC compaction = 16
81 objc_retainReleaseForSimulator = 32,
82 objc_retainRelease
83 };
84
85 /// Initializes the context to sane default values given the specified output
86 /// file type, arch, os, and minimum os version. This should be called before
87 /// other setXXX() methods.
88 void configure(HeaderFileType type, Arch arch, OS os, uint32_t minOSVersion,
89 bool exportDynamicSymbols);
90
91 void addPasses(PassManager &pm) override;
92 bool validateImpl(raw_ostream &diagnostics) override;
93 std::string demangle(StringRef symbolName) const override;
94
95 void createImplicitFiles(std::vector<std::unique_ptr<File>> &) override;
96
97 /// Creates a new file which is owned by the context. Returns a pointer to
98 /// the new file.
99 template <class T, class... Args>
100 typename std::enable_if<!std::is_array<T>::value, T *>::type
101 make_file(Args &&... args) const {
102 auto file = std::unique_ptr<T>(new T(std::forward<Args>(args)...));
103 auto *filePtr = file.get();
104 auto *ctx = const_cast<MachOLinkingContext *>(this);
105 ctx->getNodes().push_back(llvm::make_unique<FileNode>(std::move(file)));
106 return filePtr;
107 }
108
109 uint32_t getCPUType() const;
110 uint32_t getCPUSubType() const;
111
112 bool addEntryPointLoadCommand() const;
113 bool addUnixThreadLoadCommand() const;
114 bool outputTypeHasEntry() const;
115 bool is64Bit() const;
116
117 virtual uint64_t pageZeroSize() const { return _pageZeroSize; }
118 virtual uint64_t pageSize() const { return _pageSize; }
119
120 mach_o::ArchHandler &archHandler() const;
121
122 HeaderFileType outputMachOType() const { return _outputMachOType; }
123
124 Arch arch() const { return _arch; }
125 StringRef archName() const { return nameFromArch(_arch); }
126 OS os() const { return _os; }
127
128 ExportMode exportMode() const { return _exportMode; }
129 void setExportMode(ExportMode mode) { _exportMode = mode; }
130 void addExportSymbol(StringRef sym);
131 bool exportRestrictMode() const { return _exportMode != ExportMode::globals; }
132 bool exportSymbolNamed(StringRef sym) const;
133
134 DebugInfoMode debugInfoMode() const { return _debugInfoMode; }
135 void setDebugInfoMode(DebugInfoMode mode) {
136 _debugInfoMode = mode;
137 }
138
139 void appendOrderedSymbol(StringRef symbol, StringRef filename);
140
141 bool keepPrivateExterns() const { return _keepPrivateExterns; }
142 void setKeepPrivateExterns(bool v) { _keepPrivateExterns = v; }
143 bool demangleSymbols() const { return _demangle; }
144 void setDemangleSymbols(bool d) { _demangle = d; }
145 bool mergeObjCCategories() const { return _mergeObjCCategories; }
146 void setMergeObjCCategories(bool v) { _mergeObjCCategories = v; }
147 /// Create file at specified path which will contain a binary encoding
148 /// of all input and output file paths.
149 std::error_code createDependencyFile(StringRef path);
150 void addInputFileDependency(StringRef path) const;
151 void addInputFileNotFound(StringRef path) const;
152 void addOutputFileDependency(StringRef path) const;
153
154 bool minOS(StringRef mac, StringRef iOS) const;
155 void setDoNothing(bool value) { _doNothing = value; }
156 bool doNothing() const { return _doNothing; }
157 bool printAtoms() const { return _printAtoms; }
158 bool testingFileUsage() const { return _testingFileUsage; }
159 const StringRefVector &searchDirs() const { return _searchDirs; }
160 const StringRefVector &frameworkDirs() const { return _frameworkDirs; }
161 void setSysLibRoots(const StringRefVector &paths);
162 const StringRefVector &sysLibRoots() const { return _syslibRoots; }
163 bool PIE() const { return _pie; }
164 void setPIE(bool pie) { _pie = pie; }
165 bool generateVersionLoadCommand() const {
166 return _generateVersionLoadCommand;
167 }
168 void setGenerateVersionLoadCommand(bool v) {
169 _generateVersionLoadCommand = v;
170 }
171
172 bool generateFunctionStartsLoadCommand() const {
173 return _generateFunctionStartsLoadCommand;
174 }
175 void setGenerateFunctionStartsLoadCommand(bool v) {
176 _generateFunctionStartsLoadCommand = v;
177 }
178
179 bool generateDataInCodeLoadCommand() const {
180 return _generateDataInCodeLoadCommand;
181 }
182 void setGenerateDataInCodeLoadCommand(bool v) {
183 _generateDataInCodeLoadCommand = v;
184 }
185
186 uint64_t stackSize() const { return _stackSize; }
187 void setStackSize(uint64_t stackSize) { _stackSize = stackSize; }
188
189 uint64_t baseAddress() const { return _baseAddress; }
190 void setBaseAddress(uint64_t baseAddress) { _baseAddress = baseAddress; }
191
192 ObjCConstraint objcConstraint() const { return _objcConstraint; }
193
194 uint32_t osMinVersion() const { return _osMinVersion; }
195
196 uint32_t sdkVersion() const { return _sdkVersion; }
197 void setSdkVersion(uint64_t v) { _sdkVersion = v; }
198
199 uint64_t sourceVersion() const { return _sourceVersion; }
200 void setSourceVersion(uint64_t v) { _sourceVersion = v; }
201
202 uint32_t swiftVersion() const { return _swiftVersion; }
203
204 /// \brief Checks whether a given path on the filesystem exists.
205 ///
206 /// When running in -test_file_usage mode, this method consults an
207 /// internally maintained list of files that exist (provided by -path_exists)
208 /// instead of the actual filesystem.
209 bool pathExists(StringRef path) const;
210
211 /// Like pathExists() but only used on files - not directories.
212 bool fileExists(StringRef path) const;
213
214 /// \brief Adds any library search paths derived from the given base, possibly
215 /// modified by -syslibroots.
216 ///
217 /// The set of paths added consists of approximately all syslibroot-prepended
218 /// versions of libPath that exist, or the original libPath if there are none
219 /// for whatever reason. With various edge-cases for compatibility.
220 void addModifiedSearchDir(StringRef libPath, bool isSystemPath = false);
221
222 /// \brief Determine whether -lFoo can be resolve within the given path, and
223 /// return the filename if so.
224 ///
225 /// The -lFoo option is documented to search for libFoo.dylib and libFoo.a in
226 /// that order, unless Foo ends in ".o", in which case only the exact file
227 /// matches (e.g. -lfoo.o would only find foo.o).
228 llvm::Optional<StringRef> searchDirForLibrary(StringRef path,
229 StringRef libName) const;
230
231 /// \brief Iterates through all search path entries looking for libName (as
232 /// specified by -lFoo).
233 llvm::Optional<StringRef> searchLibrary(StringRef libName) const;
234
235 /// Add a framework search path. Internally, this method may be prepended
236 /// the path with syslibroot.
237 void addFrameworkSearchDir(StringRef fwPath, bool isSystemPath = false);
238
239 /// \brief Iterates through all framework directories looking for
240 /// Foo.framework/Foo (when fwName = "Foo").
241 llvm::Optional<StringRef> findPathForFramework(StringRef fwName) const;
242
243 /// \brief The dylib's binary compatibility version, in the raw uint32 format.
244 ///
245 /// When building a dynamic library, this is the compatibility version that
246 /// gets embedded into the result. Other Mach-O binaries that link against
247 /// this library will store the compatibility version in its load command. At
248 /// runtime, the loader will verify that the binary is compatible with the
249 /// installed dynamic library.
250 uint32_t compatibilityVersion() const { return _compatibilityVersion; }
251
252 /// \brief The dylib's current version, in the the raw uint32 format.
253 ///
254 /// When building a dynamic library, this is the current version that gets
255 /// embedded into the result. Other Mach-O binaries that link against
256 /// this library will store the compatibility version in its load command.
257 uint32_t currentVersion() const { return _currentVersion; }
258
259 /// \brief The dylib's install name.
260 ///
261 /// Binaries that link against the dylib will embed this path into the dylib
262 /// load command. When loading the binaries at runtime, this is the location
263 /// on disk that the loader will look for the dylib.
264 StringRef installName() const { return _installName; }
265
266 /// \brief Whether or not the dylib has side effects during initialization.
267 ///
268 /// Dylibs marked as being dead strippable provide the guarantee that loading
269 /// the dylib has no side effects, allowing the linker to strip out the dylib
270 /// when linking a binary that does not use any of its symbols.
271 bool deadStrippableDylib() const { return _deadStrippableDylib; }
272
273 /// \brief Whether or not to use flat namespace.
274 ///
275 /// MachO usually uses a two-level namespace, where each external symbol
276 /// referenced by the target is associated with the dylib that will provide
277 /// the symbol's definition at runtime. Using flat namespace overrides this
278 /// behavior: the linker searches all dylibs on the command line and all
279 /// dylibs those original dylibs depend on, but does not record which dylib
280 /// an external symbol came from. At runtime dyld again searches all images
281 /// and uses the first definition it finds. In addition, any undefines in
282 /// loaded flat_namespace dylibs must be resolvable at build time.
283 bool useFlatNamespace() const { return _flatNamespace; }
284
285 /// \brief How to handle undefined symbols.
286 ///
287 /// Options are:
288 /// * error: Report an error and terminate linking.
289 /// * warning: Report a warning, but continue linking.
290 /// * suppress: Ignore and continue linking.
291 /// * dynamic_lookup: For use with -twolevel namespace: Records source dylibs
292 /// for symbols that are defined in a linked dylib at static link time.
293 /// Undefined symbols are handled by searching all loaded images at
294 /// runtime.
295 UndefinedMode undefinedMode() const { return _undefinedMode; }
296
297 /// \brief The path to the executable that will load the bundle at runtime.
298 ///
299 /// When building a Mach-O bundle, this executable will be examined if there
300 /// are undefined symbols after the main link phase. It is expected that this
301 /// binary will be loading the bundle at runtime and will provide the symbols
302 /// at that point.
303 StringRef bundleLoader() const { return _bundleLoader; }
304
305 void setCompatibilityVersion(uint32_t vers) { _compatibilityVersion = vers; }
306 void setCurrentVersion(uint32_t vers) { _currentVersion = vers; }
307 void setInstallName(StringRef name) { _installName = name; }
308 void setDeadStrippableDylib(bool deadStrippable) {
309 _deadStrippableDylib = deadStrippable;
310 }
311 void setUseFlatNamespace(bool flatNamespace) {
312 _flatNamespace = flatNamespace;
313 }
314
315 void setUndefinedMode(UndefinedMode undefinedMode) {
316 _undefinedMode = undefinedMode;
317 }
318
319 void setBundleLoader(StringRef loader) { _bundleLoader = loader; }
320 void setPrintAtoms(bool value=true) { _printAtoms = value; }
321 void setTestingFileUsage(bool value = true) {
322 _testingFileUsage = value;
323 }
324 void addExistingPathForDebug(StringRef path) {
325 _existingPaths.insert(path);
326 }
327
328 void addRpath(StringRef rpath);
329 const StringRefVector &rpaths() const { return _rpaths; }
330
331 /// Add section alignment constraint on final layout.
332 void addSectionAlignment(StringRef seg, StringRef sect, uint16_t align);
333
334 /// \brief Add a section based on a command-line sectcreate option.
335 void addSectCreateSection(StringRef seg, StringRef sect,
336 std::unique_ptr<MemoryBuffer> content);
337
338 /// Returns true if specified section had alignment constraints.
339 bool sectionAligned(StringRef seg, StringRef sect, uint16_t &align) const;
340
341 StringRef dyldPath() const { return "/usr/lib/dyld"; }
342
343 /// Stub creation Pass should be run.
344 bool needsStubsPass() const;
345
346 // GOT creation Pass should be run.
347 bool needsGOTPass() const;
348
349 /// Pass to add TLV sections.
350 bool needsTLVPass() const;
351
352 /// Pass to transform __compact_unwind into __unwind_info should be run.
353 bool needsCompactUnwindPass() const;
354
355 /// Pass to add shims switching between thumb and arm mode.
356 bool needsShimPass() const;
357
358 /// Pass to add objc image info and optimized objc data.
359 bool needsObjCPass() const;
360
361 /// Magic symbol name stubs will need to help lazy bind.
362 StringRef binderSymbolName() const;
363
364 /// Used to keep track of direct and indirect dylibs.
365 void registerDylib(mach_o::MachODylibFile *dylib, bool upward) const;
366
367 // Reads a file from disk to memory. Returns only a needed chunk
368 // if a fat binary.
369 ErrorOr<std::unique_ptr<MemoryBuffer>> getMemoryBuffer(StringRef path);
370
371 /// Used to find indirect dylibs. Instantiates a MachODylibFile if one
372 /// has not already been made for the requested dylib. Uses -L and -F
373 /// search paths to allow indirect dylibs to be overridden.
374 mach_o::MachODylibFile* findIndirectDylib(StringRef path);
375
376 uint32_t dylibCurrentVersion(StringRef installName) const;
377
378 uint32_t dylibCompatVersion(StringRef installName) const;
379
380 ArrayRef<mach_o::MachODylibFile*> allDylibs() const {
381 return _allDylibs;
382 }
383
384 /// Creates a copy (owned by this MachOLinkingContext) of a string.
385 StringRef copy(StringRef str) { return str.copy(_allocator); }
386
387 /// If the memoryBuffer is a fat file with a slice for the current arch,
388 /// this method will return the offset and size of that slice.
389 bool sliceFromFatFile(MemoryBufferRef mb, uint32_t &offset, uint32_t &size);
390
391 /// Returns if a command line option specified dylib is an upward link.
392 bool isUpwardDylib(StringRef installName) const;
393
394 static bool isThinObjectFile(StringRef path, Arch &arch);
395 static Arch archFromCpuType(uint32_t cputype, uint32_t cpusubtype);
396 static Arch archFromName(StringRef archName);
397 static StringRef nameFromArch(Arch arch);
398 static uint32_t cpuTypeFromArch(Arch arch);
399 static uint32_t cpuSubtypeFromArch(Arch arch);
400 static bool is64Bit(Arch arch);
401 static bool isHostEndian(Arch arch);
402 static bool isBigEndian(Arch arch);
403
404 /// Construct 32-bit value from string "X.Y.Z" where
405 /// bits are xxxx.yy.zz. Largest number is 65535.255.255
406 static bool parsePackedVersion(StringRef str, uint32_t &result);
407
408 /// Construct 64-bit value from string "A.B.C.D.E" where
409 /// bits are aaaa.bb.cc.dd.ee. Largest number is 16777215.1023.1023.1023.1023
410 static bool parsePackedVersion(StringRef str, uint64_t &result);
411
412 void finalizeInputFiles() override;
413
414 llvm::Error handleLoadedFile(File &file) override;
415
416 bool customAtomOrderer(const DefinedAtom *left, const DefinedAtom *right,
417 bool &leftBeforeRight) const;
418
419 /// Return the 'flat namespace' file. This is the file that supplies
420 /// atoms for otherwise undefined symbols when the -flat_namespace or
421 /// -undefined dynamic_lookup options are used.
422 File* flatNamespaceFile() const { return _flatNamespaceFile; }
423
424private:
425 Writer &writer() const override;
426 mach_o::MachODylibFile* loadIndirectDylib(StringRef path);
427 void checkExportWhiteList(const DefinedAtom *atom) const;
428 void checkExportBlackList(const DefinedAtom *atom) const;
429 struct ArchInfo {
430 StringRef archName;
431 MachOLinkingContext::Arch arch;
432 bool littleEndian;
433 uint32_t cputype;
434 uint32_t cpusubtype;
435 };
436
437 struct SectionAlign {
438 StringRef segmentName;
439 StringRef sectionName;
440 uint16_t align;
441 };
442
443 struct OrderFileNode {
444 StringRef fileFilter;
445 unsigned order;
446 };
447
448 static bool findOrderOrdinal(const std::vector<OrderFileNode> &nodes,
449 const DefinedAtom *atom, unsigned &ordinal);
450
451 static ArchInfo _s_archInfos[];
452
453 std::set<StringRef> _existingPaths; // For testing only.
454 StringRefVector _searchDirs;
455 StringRefVector _syslibRoots;
456 StringRefVector _frameworkDirs;
457 HeaderFileType _outputMachOType = llvm::MachO::MH_EXECUTE;
458 bool _outputMachOTypeStatic = false; // Disambiguate static vs dynamic prog
459 bool _doNothing = false; // for -help and -v which just print info
460 bool _pie = false;
461 Arch _arch = arch_unknown;
462 OS _os = OS::macOSX;
463 uint32_t _osMinVersion = 0;
464 uint32_t _sdkVersion = 0;
465 uint64_t _sourceVersion = 0;
466 uint64_t _pageZeroSize = 0;
467 uint64_t _pageSize = 4096;
468 uint64_t _baseAddress = 0;
469 uint64_t _stackSize = 0;
470 uint32_t _compatibilityVersion = 0;
471 uint32_t _currentVersion = 0;
472 ObjCConstraint _objcConstraint = objc_unknown;
473 uint32_t _swiftVersion = 0;
474 StringRef _installName;
475 StringRefVector _rpaths;
476 bool _flatNamespace = false;
477 UndefinedMode _undefinedMode = UndefinedMode::error;
478 bool _deadStrippableDylib = false;
479 bool _printAtoms = false;
480 bool _testingFileUsage = false;
481 bool _keepPrivateExterns = false;
482 bool _demangle = false;
483 bool _mergeObjCCategories = true;
484 bool _generateVersionLoadCommand = false;
485 bool _generateFunctionStartsLoadCommand = false;
486 bool _generateDataInCodeLoadCommand = false;
487 StringRef _bundleLoader;
488 mutable std::unique_ptr<mach_o::ArchHandler> _archHandler;
489 mutable std::unique_ptr<Writer> _writer;
490 std::vector<SectionAlign> _sectAligns;
491 mutable llvm::StringMap<mach_o::MachODylibFile*> _pathToDylibMap;
492 mutable std::vector<mach_o::MachODylibFile*> _allDylibs;
493 mutable std::set<mach_o::MachODylibFile*> _upwardDylibs;
494 mutable std::vector<std::unique_ptr<File>> _indirectDylibs;
495 mutable std::mutex _dylibsMutex;
496 ExportMode _exportMode = ExportMode::globals;
497 llvm::StringSet<> _exportedSymbols;
498 DebugInfoMode _debugInfoMode = DebugInfoMode::addDebugMap;
499 std::unique_ptr<llvm::raw_fd_ostream> _dependencyInfo;
500 llvm::StringMap<std::vector<OrderFileNode>> _orderFiles;
501 unsigned _orderFileEntries = 0;
502 File *_flatNamespaceFile = nullptr;
503 mach_o::SectCreateFile *_sectCreateFile = nullptr;
504};
505
506} // end namespace lld
507
508#endif // LLD_READER_WRITER_MACHO_LINKING_CONTEXT_H
deps/lld/include/lld/ReaderWriter/YamlContext.h created+42
......@@ -0,0 +1,42 @@
1//===- lld/ReaderWriter/YamlContext.h - object used in YAML I/O context ---===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_READER_WRITER_YAML_CONTEXT_H
11#define LLD_READER_WRITER_YAML_CONTEXT_H
12
13#include "lld/Core/LLVM.h"
14#include <functional>
15#include <memory>
16#include <vector>
17
18namespace lld {
19class File;
20class LinkingContext;
21namespace mach_o {
22namespace normalized {
23struct NormalizedFile;
24}
25}
26
27using lld::mach_o::normalized::NormalizedFile;
28
29/// When YAML I/O is used in lld, the yaml context always holds a YamlContext
30/// object. We need to support hetergenous yaml documents which each require
31/// different context info. This struct supports all clients.
32struct YamlContext {
33 const LinkingContext *_ctx = nullptr;
34 const Registry *_registry = nullptr;
35 File *_file = nullptr;
36 NormalizedFile *_normalizeMachOFile = nullptr;
37 StringRef _path;
38};
39
40} // end namespace lld
41
42#endif // LLD_READER_WRITER_YAML_CONTEXT_H
deps/lld/lib/CMakeLists.txt created+4
......@@ -0,0 +1,4 @@
1add_subdirectory(Config)
2add_subdirectory(Core)
3add_subdirectory(Driver)
4add_subdirectory(ReaderWriter)
deps/lld/lib/Config/CMakeLists.txt created+9
......@@ -0,0 +1,9 @@
1add_lld_library(lldConfig
2 Version.cpp
3
4 ADDITIONAL_HEADER_DIRS
5 ${LLD_INCLUDE_DIR}/lld/Config
6
7 LINK_COMPONENTS
8 Support
9 )
deps/lld/lib/Config/Version.cpp created+43
......@@ -0,0 +1,43 @@
1//===- lib/Config/Version.cpp - LLD Version Number ---------------*- C++-=====//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines several version-related utility functions for LLD.
11//
12//===----------------------------------------------------------------------===//
13
14#include "lld/Config/Version.h"
15
16using namespace llvm;
17
18// Returns an SVN repository path, which is usually "trunk".
19static std::string getRepositoryPath() {
20 StringRef S = LLD_REPOSITORY_STRING;
21 size_t Pos = S.find("lld/");
22 if (Pos != StringRef::npos)
23 return S.substr(Pos + 4);
24 return S;
25}
26
27// Returns an SVN repository name, e.g., " (trunk 284614)"
28// or an empty string if no repository info is available.
29static std::string getRepository() {
30 std::string Repo = getRepositoryPath();
31 std::string Rev = LLD_REVISION_STRING;
32
33 if (Repo.empty() && Rev.empty())
34 return "";
35 if (!Repo.empty() && !Rev.empty())
36 return " (" + Repo + " " + Rev + ")";
37 return " (" + Repo + Rev + ")";
38}
39
40// Returns a version string, e.g., "LLD 4.0 (lld/trunk 284614)".
41std::string lld::getLLDVersion() {
42 return "LLD " + std::string(LLD_VERSION_STRING) + getRepository();
43}
deps/lld/lib/Core/CMakeLists.txt created+30
......@@ -0,0 +1,30 @@
1if(NOT LLD_BUILT_STANDALONE)
2 set(tablegen_deps intrinsics_gen)
3endif()
4
5add_lld_library(lldCore
6 DefinedAtom.cpp
7 Error.cpp
8 File.cpp
9 LinkingContext.cpp
10 Reader.cpp
11 Reproduce.cpp
12 Resolver.cpp
13 SymbolTable.cpp
14 TargetOptionsCommandFlags.cpp
15 Writer.cpp
16
17 ADDITIONAL_HEADER_DIRS
18 ${LLD_INCLUDE_DIR}/lld/Core
19
20 LINK_COMPONENTS
21 BinaryFormat
22 MC
23 Support
24
25 LINK_LIBS
26 ${LLVM_PTHREAD_LIB}
27
28 DEPENDS
29 ${tablegen_deps}
30 )
deps/lld/lib/Core/DefinedAtom.cpp created+82
......@@ -0,0 +1,82 @@
1//===- DefinedAtom.cpp ------------------------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "llvm/Support/ErrorHandling.h"
11#include "lld/Core/DefinedAtom.h"
12#include "lld/Core/File.h"
13
14namespace lld {
15
16DefinedAtom::ContentPermissions DefinedAtom::permissions() const {
17 // By default base permissions on content type.
18 return permissions(this->contentType());
19}
20
21// Utility function for deriving permissions from content type
22DefinedAtom::ContentPermissions DefinedAtom::permissions(ContentType type) {
23 switch (type) {
24 case typeCode:
25 case typeResolver:
26 case typeBranchIsland:
27 case typeBranchShim:
28 case typeStub:
29 case typeStubHelper:
30 case typeMachHeader:
31 return permR_X;
32
33 case typeConstant:
34 case typeCString:
35 case typeUTF16String:
36 case typeCFI:
37 case typeLSDA:
38 case typeLiteral4:
39 case typeLiteral8:
40 case typeLiteral16:
41 case typeDTraceDOF:
42 case typeCompactUnwindInfo:
43 case typeProcessedUnwindInfo:
44 case typeObjCImageInfo:
45 case typeObjCMethodList:
46 return permR__;
47
48 case typeData:
49 case typeDataFast:
50 case typeZeroFill:
51 case typeZeroFillFast:
52 case typeObjC1Class:
53 case typeLazyPointer:
54 case typeLazyDylibPointer:
55 case typeNonLazyPointer:
56 case typeThunkTLV:
57 return permRW_;
58
59 case typeGOT:
60 case typeConstData:
61 case typeCFString:
62 case typeInitializerPtr:
63 case typeTerminatorPtr:
64 case typeCStringPtr:
65 case typeObjCClassPtr:
66 case typeObjC2CategoryList:
67 case typeInterposingTuples:
68 case typeTLVInitialData:
69 case typeTLVInitialZeroFill:
70 case typeTLVInitializerPtr:
71 return permRW_L;
72
73 case typeUnknown:
74 case typeTempLTO:
75 case typeSectCreate:
76 case typeDSOHandle:
77 return permUnknown;
78 }
79 llvm_unreachable("unknown content type");
80}
81
82} // namespace
deps/lld/lib/Core/Error.cpp created+93
......@@ -0,0 +1,93 @@
1//===- Error.cpp - system_error extensions for lld --------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lld/Core/Error.h"
11#include "llvm/ADT/Twine.h"
12#include "llvm/Support/ErrorHandling.h"
13#include <mutex>
14#include <string>
15#include <vector>
16
17using namespace lld;
18
19namespace {
20class _YamlReaderErrorCategory : public std::error_category {
21public:
22 const char* name() const noexcept override {
23 return "lld.yaml.reader";
24 }
25
26 std::string message(int ev) const override {
27 switch (static_cast<YamlReaderError>(ev)) {
28 case YamlReaderError::unknown_keyword:
29 return "Unknown keyword found in yaml file";
30 case YamlReaderError::illegal_value:
31 return "Bad value found in yaml file";
32 }
33 llvm_unreachable("An enumerator of YamlReaderError does not have a "
34 "message defined.");
35 }
36};
37} // end anonymous namespace
38
39const std::error_category &lld::YamlReaderCategory() {
40 static _YamlReaderErrorCategory o;
41 return o;
42}
43
44namespace lld {
45
46/// Temporary class to enable make_dynamic_error_code() until
47/// llvm::ErrorOr<> is updated to work with error encapsulations
48/// other than error_code.
49class dynamic_error_category : public std::error_category {
50public:
51 ~dynamic_error_category() override = default;
52
53 const char *name() const noexcept override {
54 return "lld.dynamic_error";
55 }
56
57 std::string message(int ev) const override {
58 assert(ev >= 0);
59 assert(ev < (int)_messages.size());
60 // The value is an index into the string vector.
61 return _messages[ev];
62 }
63
64 int add(std::string msg) {
65 std::lock_guard<std::recursive_mutex> lock(_mutex);
66 // Value zero is always the successs value.
67 if (_messages.empty())
68 _messages.push_back("Success");
69 _messages.push_back(msg);
70 // Return the index of the string just appended.
71 return _messages.size() - 1;
72 }
73
74private:
75 std::vector<std::string> _messages;
76 std::recursive_mutex _mutex;
77};
78
79static dynamic_error_category categorySingleton;
80
81std::error_code make_dynamic_error_code(StringRef msg) {
82 return std::error_code(categorySingleton.add(msg), categorySingleton);
83}
84
85char GenericError::ID = 0;
86
87GenericError::GenericError(Twine Msg) : Msg(Msg.str()) { }
88
89void GenericError::log(raw_ostream &OS) const {
90 OS << Msg;
91}
92
93} // namespace lld
deps/lld/lib/Core/File.cpp created+29
......@@ -0,0 +1,29 @@
1//===- Core/File.cpp - A Container of Atoms -------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lld/Core/File.h"
11#include <mutex>
12
13namespace lld {
14
15File::~File() = default;
16
17File::AtomVector<DefinedAtom> File::_noDefinedAtoms;
18File::AtomVector<UndefinedAtom> File::_noUndefinedAtoms;
19File::AtomVector<SharedLibraryAtom> File::_noSharedLibraryAtoms;
20File::AtomVector<AbsoluteAtom> File::_noAbsoluteAtoms;
21
22std::error_code File::parse() {
23 std::lock_guard<std::mutex> lock(_parseMutex);
24 if (!_lastError.hasValue())
25 _lastError = doParse();
26 return _lastError.getValue();
27}
28
29} // end namespace lld
deps/lld/lib/Core/LinkingContext.cpp created+70
......@@ -0,0 +1,70 @@
1//===- lib/Core/LinkingContext.cpp - Linker Context Object Interface ------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lld/Core/LinkingContext.h"
11#include "lld/Core/File.h"
12#include "lld/Core/Node.h"
13#include "lld/Core/Simple.h"
14#include "lld/Core/Writer.h"
15#include <algorithm>
16
17namespace lld {
18
19LinkingContext::LinkingContext() = default;
20
21LinkingContext::~LinkingContext() = default;
22
23bool LinkingContext::validate(raw_ostream &diagnostics) {
24 return validateImpl(diagnostics);
25}
26
27llvm::Error LinkingContext::writeFile(const File &linkedFile) const {
28 return this->writer().writeFile(linkedFile, _outputPath);
29}
30
31std::unique_ptr<File> LinkingContext::createEntrySymbolFile() const {
32 return createEntrySymbolFile("<command line option -e>");
33}
34
35std::unique_ptr<File>
36LinkingContext::createEntrySymbolFile(StringRef filename) const {
37 if (entrySymbolName().empty())
38 return nullptr;
39 std::unique_ptr<SimpleFile> entryFile(new SimpleFile(filename,
40 File::kindEntryObject));
41 entryFile->addAtom(
42 *(new (_allocator) SimpleUndefinedAtom(*entryFile, entrySymbolName())));
43 return std::move(entryFile);
44}
45
46std::unique_ptr<File> LinkingContext::createUndefinedSymbolFile() const {
47 return createUndefinedSymbolFile("<command line option -u or --defsym>");
48}
49
50std::unique_ptr<File>
51LinkingContext::createUndefinedSymbolFile(StringRef filename) const {
52 if (_initialUndefinedSymbols.empty())
53 return nullptr;
54 std::unique_ptr<SimpleFile> undefinedSymFile(
55 new SimpleFile(filename, File::kindUndefinedSymsObject));
56 for (StringRef undefSym : _initialUndefinedSymbols)
57 undefinedSymFile->addAtom(*(new (_allocator) SimpleUndefinedAtom(
58 *undefinedSymFile, undefSym)));
59 return std::move(undefinedSymFile);
60}
61
62void LinkingContext::createInternalFiles(
63 std::vector<std::unique_ptr<File>> &result) const {
64 if (std::unique_ptr<File> file = createEntrySymbolFile())
65 result.push_back(std::move(file));
66 if (std::unique_ptr<File> file = createUndefinedSymbolFile())
67 result.push_back(std::move(file));
68}
69
70} // end namespace lld
deps/lld/lib/Core/Reader.cpp created+114
......@@ -0,0 +1,114 @@
1//===- lib/Core/Reader.cpp ------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lld/Core/Reader.h"
11#include "lld/Core/File.h"
12#include "lld/Core/Reference.h"
13#include "llvm/ADT/StringRef.h"
14#include "llvm/BinaryFormat/Magic.h"
15#include "llvm/Support/Errc.h"
16#include "llvm/Support/FileSystem.h"
17#include "llvm/Support/MemoryBuffer.h"
18#include <algorithm>
19#include <memory>
20
21using llvm::file_magic;
22using llvm::identify_magic;
23
24namespace lld {
25
26YamlIOTaggedDocumentHandler::~YamlIOTaggedDocumentHandler() = default;
27
28void Registry::add(std::unique_ptr<Reader> reader) {
29 _readers.push_back(std::move(reader));
30}
31
32void Registry::add(std::unique_ptr<YamlIOTaggedDocumentHandler> handler) {
33 _yamlHandlers.push_back(std::move(handler));
34}
35
36ErrorOr<std::unique_ptr<File>>
37Registry::loadFile(std::unique_ptr<MemoryBuffer> mb) const {
38 // Get file magic.
39 StringRef content(mb->getBufferStart(), mb->getBufferSize());
40 file_magic fileType = identify_magic(content);
41
42 // Ask each registered reader if it can handle this file type or extension.
43 for (const std::unique_ptr<Reader> &reader : _readers) {
44 if (!reader->canParse(fileType, mb->getMemBufferRef()))
45 continue;
46 return reader->loadFile(std::move(mb), *this);
47 }
48
49 // No Reader could parse this file.
50 return make_error_code(llvm::errc::executable_format_error);
51}
52
53static const Registry::KindStrings kindStrings[] = {
54 {Reference::kindLayoutAfter, "layout-after"},
55 {Reference::kindAssociate, "associate"},
56 LLD_KIND_STRING_END};
57
58Registry::Registry() {
59 addKindTable(Reference::KindNamespace::all, Reference::KindArch::all,
60 kindStrings);
61}
62
63bool Registry::handleTaggedDoc(llvm::yaml::IO &io,
64 const lld::File *&file) const {
65 for (const std::unique_ptr<YamlIOTaggedDocumentHandler> &h : _yamlHandlers)
66 if (h->handledDocTag(io, file))
67 return true;
68 return false;
69}
70
71void Registry::addKindTable(Reference::KindNamespace ns,
72 Reference::KindArch arch,
73 const KindStrings array[]) {
74 KindEntry entry = { ns, arch, array };
75 _kindEntries.push_back(entry);
76}
77
78bool Registry::referenceKindFromString(StringRef inputStr,
79 Reference::KindNamespace &ns,
80 Reference::KindArch &arch,
81 Reference::KindValue &value) const {
82 for (const KindEntry &entry : _kindEntries) {
83 for (const KindStrings *pair = entry.array; !pair->name.empty(); ++pair) {
84 if (!inputStr.equals(pair->name))
85 continue;
86 ns = entry.ns;
87 arch = entry.arch;
88 value = pair->value;
89 return true;
90 }
91 }
92 return false;
93}
94
95bool Registry::referenceKindToString(Reference::KindNamespace ns,
96 Reference::KindArch arch,
97 Reference::KindValue value,
98 StringRef &str) const {
99 for (const KindEntry &entry : _kindEntries) {
100 if (entry.ns != ns)
101 continue;
102 if (entry.arch != arch)
103 continue;
104 for (const KindStrings *pair = entry.array; !pair->name.empty(); ++pair) {
105 if (pair->value != value)
106 continue;
107 str = pair->name;
108 return true;
109 }
110 }
111 return false;
112}
113
114} // end namespace lld
deps/lld/lib/Core/Reproduce.cpp created+66
......@@ -0,0 +1,66 @@
1//===- Reproduce.cpp - Utilities for creating reproducers -----------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lld/Core/Reproduce.h"
11#include "llvm/Option/Arg.h"
12#include "llvm/Support/Error.h"
13#include "llvm/Support/FileSystem.h"
14#include "llvm/Support/Path.h"
15
16using namespace lld;
17using namespace llvm;
18using namespace llvm::sys;
19
20// Makes a given pathname an absolute path first, and then remove
21// beginning /. For example, "../foo.o" is converted to "home/john/foo.o",
22// assuming that the current directory is "/home/john/bar".
23// Returned string is a forward slash separated path even on Windows to avoid
24// a mess with backslash-as-escape and backslash-as-path-separator.
25std::string lld::relativeToRoot(StringRef Path) {
26 SmallString<128> Abs = Path;
27 if (fs::make_absolute(Abs))
28 return Path;
29 path::remove_dots(Abs, /*remove_dot_dot=*/true);
30
31 // This is Windows specific. root_name() returns a drive letter
32 // (e.g. "c:") or a UNC name (//net). We want to keep it as part
33 // of the result.
34 SmallString<128> Res;
35 StringRef Root = path::root_name(Abs);
36 if (Root.endswith(":"))
37 Res = Root.drop_back();
38 else if (Root.startswith("//"))
39 Res = Root.substr(2);
40
41 path::append(Res, path::relative_path(Abs));
42 return path::convert_to_slash(Res);
43}
44
45// Quote a given string if it contains a space character.
46std::string lld::quote(StringRef S) {
47 if (S.find(' ') == StringRef::npos)
48 return S;
49 return ("\"" + S + "\"").str();
50}
51
52std::string lld::rewritePath(StringRef S) {
53 if (fs::exists(S))
54 return relativeToRoot(S);
55 return S;
56}
57
58std::string lld::toString(opt::Arg *Arg) {
59 std::string K = Arg->getSpelling();
60 if (Arg->getNumValues() == 0)
61 return K;
62 std::string V = quote(Arg->getValue());
63 if (Arg->getOption().getRenderStyle() == opt::Option::RenderJoinedStyle)
64 return K + V;
65 return K + " " + V;
66}
deps/lld/lib/Core/Resolver.cpp created+505
......@@ -0,0 +1,505 @@
1//===- Core/Resolver.cpp - Resolves Atom References -----------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lld/Core/Atom.h"
11#include "lld/Core/ArchiveLibraryFile.h"
12#include "lld/Core/File.h"
13#include "lld/Core/Instrumentation.h"
14#include "lld/Core/LLVM.h"
15#include "lld/Core/LinkingContext.h"
16#include "lld/Core/Resolver.h"
17#include "lld/Core/SharedLibraryFile.h"
18#include "lld/Core/SymbolTable.h"
19#include "lld/Core/UndefinedAtom.h"
20#include "llvm/ADT/iterator_range.h"
21#include "llvm/Support/Debug.h"
22#include "llvm/Support/Error.h"
23#include "llvm/Support/ErrorHandling.h"
24#include "llvm/Support/Format.h"
25#include "llvm/Support/raw_ostream.h"
26#include <algorithm>
27#include <cassert>
28#include <utility>
29#include <vector>
30
31namespace lld {
32
33llvm::Expected<bool> Resolver::handleFile(File &file) {
34 if (auto ec = _ctx.handleLoadedFile(file))
35 return std::move(ec);
36 bool undefAdded = false;
37 for (auto &atom : file.defined().owning_ptrs())
38 doDefinedAtom(std::move(atom));
39 for (auto &atom : file.undefined().owning_ptrs()) {
40 if (doUndefinedAtom(std::move(atom)))
41 undefAdded = true;
42 }
43 for (auto &atom : file.sharedLibrary().owning_ptrs())
44 doSharedLibraryAtom(std::move(atom));
45 for (auto &atom : file.absolute().owning_ptrs())
46 doAbsoluteAtom(std::move(atom));
47 return undefAdded;
48}
49
50llvm::Expected<bool> Resolver::forEachUndefines(File &file,
51 UndefCallback callback) {
52 size_t i = _undefineIndex[&file];
53 bool undefAdded = false;
54 do {
55 for (; i < _undefines.size(); ++i) {
56 StringRef undefName = _undefines[i];
57 if (undefName.empty())
58 continue;
59 const Atom *atom = _symbolTable.findByName(undefName);
60 if (!isa<UndefinedAtom>(atom) || _symbolTable.isCoalescedAway(atom)) {
61 // The symbol was resolved by some other file. Cache the result.
62 _undefines[i] = "";
63 continue;
64 }
65 auto undefAddedOrError = callback(undefName);
66 if (auto ec = undefAddedOrError.takeError())
67 return std::move(ec);
68 undefAdded |= undefAddedOrError.get();
69 }
70 } while (i < _undefines.size());
71 _undefineIndex[&file] = i;
72 return undefAdded;
73}
74
75llvm::Expected<bool> Resolver::handleArchiveFile(File &file) {
76 ArchiveLibraryFile *archiveFile = cast<ArchiveLibraryFile>(&file);
77 return forEachUndefines(file,
78 [&](StringRef undefName) -> llvm::Expected<bool> {
79 if (File *member = archiveFile->find(undefName)) {
80 member->setOrdinal(_ctx.getNextOrdinalAndIncrement());
81 return handleFile(*member);
82 }
83 return false;
84 });
85}
86
87llvm::Error Resolver::handleSharedLibrary(File &file) {
88 // Add all the atoms from the shared library
89 SharedLibraryFile *sharedLibrary = cast<SharedLibraryFile>(&file);
90 auto undefAddedOrError = handleFile(*sharedLibrary);
91 if (auto ec = undefAddedOrError.takeError())
92 return ec;
93 undefAddedOrError =
94 forEachUndefines(file, [&](StringRef undefName) -> llvm::Expected<bool> {
95 auto atom = sharedLibrary->exports(undefName);
96 if (atom.get())
97 doSharedLibraryAtom(std::move(atom));
98 return false;
99 });
100
101 if (auto ec = undefAddedOrError.takeError())
102 return ec;
103 return llvm::Error::success();
104}
105
106bool Resolver::doUndefinedAtom(OwningAtomPtr<UndefinedAtom> atom) {
107 DEBUG_WITH_TYPE("resolver", llvm::dbgs()
108 << " UndefinedAtom: "
109 << llvm::format("0x%09lX", atom.get())
110 << ", name=" << atom.get()->name() << "\n");
111
112 // tell symbol table
113 bool newUndefAdded = _symbolTable.add(*atom.get());
114 if (newUndefAdded)
115 _undefines.push_back(atom.get()->name());
116
117 // add to list of known atoms
118 _atoms.push_back(OwningAtomPtr<Atom>(atom.release()));
119
120 return newUndefAdded;
121}
122
123// Called on each atom when a file is added. Returns true if a given
124// atom is added to the symbol table.
125void Resolver::doDefinedAtom(OwningAtomPtr<DefinedAtom> atom) {
126 DEBUG_WITH_TYPE("resolver", llvm::dbgs()
127 << " DefinedAtom: "
128 << llvm::format("0x%09lX", atom.get())
129 << ", file=#"
130 << atom.get()->file().ordinal()
131 << ", atom=#"
132 << atom.get()->ordinal()
133 << ", name="
134 << atom.get()->name()
135 << ", type="
136 << atom.get()->contentType()
137 << "\n");
138
139 // An atom that should never be dead-stripped is a dead-strip root.
140 if (_ctx.deadStrip() &&
141 atom.get()->deadStrip() == DefinedAtom::deadStripNever) {
142 _deadStripRoots.insert(atom.get());
143 }
144
145 // add to list of known atoms
146 _symbolTable.add(*atom.get());
147 _atoms.push_back(OwningAtomPtr<Atom>(atom.release()));
148}
149
150void Resolver::doSharedLibraryAtom(OwningAtomPtr<SharedLibraryAtom> atom) {
151 DEBUG_WITH_TYPE("resolver", llvm::dbgs()
152 << " SharedLibraryAtom: "
153 << llvm::format("0x%09lX", atom.get())
154 << ", name="
155 << atom.get()->name()
156 << "\n");
157
158 // tell symbol table
159 _symbolTable.add(*atom.get());
160
161 // add to list of known atoms
162 _atoms.push_back(OwningAtomPtr<Atom>(atom.release()));
163}
164
165void Resolver::doAbsoluteAtom(OwningAtomPtr<AbsoluteAtom> atom) {
166 DEBUG_WITH_TYPE("resolver", llvm::dbgs()
167 << " AbsoluteAtom: "
168 << llvm::format("0x%09lX", atom.get())
169 << ", name="
170 << atom.get()->name()
171 << "\n");
172
173 // tell symbol table
174 if (atom.get()->scope() != Atom::scopeTranslationUnit)
175 _symbolTable.add(*atom.get());
176
177 // add to list of known atoms
178 _atoms.push_back(OwningAtomPtr<Atom>(atom.release()));
179}
180
181// Returns true if at least one of N previous files has created an
182// undefined symbol.
183bool Resolver::undefinesAdded(int begin, int end) {
184 std::vector<std::unique_ptr<Node>> &inputs = _ctx.getNodes();
185 for (int i = begin; i < end; ++i)
186 if (FileNode *node = dyn_cast<FileNode>(inputs[i].get()))
187 if (_newUndefinesAdded[node->getFile()])
188 return true;
189 return false;
190}
191
192File *Resolver::getFile(int &index) {
193 std::vector<std::unique_ptr<Node>> &inputs = _ctx.getNodes();
194 if ((size_t)index >= inputs.size())
195 return nullptr;
196 if (GroupEnd *group = dyn_cast<GroupEnd>(inputs[index].get())) {
197 // We are at the end of the current group. If one or more new
198 // undefined atom has been added in the last groupSize files, we
199 // reiterate over the files.
200 int size = group->getSize();
201 if (undefinesAdded(index - size, index)) {
202 index -= size;
203 return getFile(index);
204 }
205 ++index;
206 return getFile(index);
207 }
208 return cast<FileNode>(inputs[index++].get())->getFile();
209}
210
211// Keep adding atoms until _ctx.getNextFile() returns an error. This
212// function is where undefined atoms are resolved.
213bool Resolver::resolveUndefines() {
214 DEBUG_WITH_TYPE("resolver",
215 llvm::dbgs() << "******** Resolving undefines:\n");
216 ScopedTask task(getDefaultDomain(), "resolveUndefines");
217 int index = 0;
218 std::set<File *> seen;
219 for (;;) {
220 bool undefAdded = false;
221 DEBUG_WITH_TYPE("resolver",
222 llvm::dbgs() << "Loading file #" << index << "\n");
223 File *file = getFile(index);
224 if (!file)
225 return true;
226 if (std::error_code ec = file->parse()) {
227 llvm::errs() << "Cannot open " + file->path()
228 << ": " << ec.message() << "\n";
229 return false;
230 }
231 DEBUG_WITH_TYPE("resolver",
232 llvm::dbgs() << "Loaded file: " << file->path() << "\n");
233 switch (file->kind()) {
234 case File::kindErrorObject:
235 case File::kindNormalizedObject:
236 case File::kindMachObject:
237 case File::kindCEntryObject:
238 case File::kindHeaderObject:
239 case File::kindEntryObject:
240 case File::kindUndefinedSymsObject:
241 case File::kindStubHelperObject:
242 case File::kindResolverMergedObject:
243 case File::kindSectCreateObject: {
244 // The same file may be visited more than once if the file is
245 // in --start-group and --end-group. Only library files should
246 // be processed more than once.
247 if (seen.count(file))
248 break;
249 seen.insert(file);
250 assert(!file->hasOrdinal());
251 file->setOrdinal(_ctx.getNextOrdinalAndIncrement());
252 auto undefAddedOrError = handleFile(*file);
253 if (auto EC = undefAddedOrError.takeError()) {
254 // FIXME: This should be passed to logAllUnhandledErrors but it needs
255 // to be passed a Twine instead of a string.
256 llvm::errs() << "Error in " + file->path() << ": ";
257 logAllUnhandledErrors(std::move(EC), llvm::errs(), std::string());
258 return false;
259 }
260 undefAdded = undefAddedOrError.get();
261 break;
262 }
263 case File::kindArchiveLibrary: {
264 if (!file->hasOrdinal())
265 file->setOrdinal(_ctx.getNextOrdinalAndIncrement());
266 auto undefAddedOrError = handleArchiveFile(*file);
267 if (auto EC = undefAddedOrError.takeError()) {
268 // FIXME: This should be passed to logAllUnhandledErrors but it needs
269 // to be passed a Twine instead of a string.
270 llvm::errs() << "Error in " + file->path() << ": ";
271 logAllUnhandledErrors(std::move(EC), llvm::errs(), std::string());
272 return false;
273 }
274 undefAdded = undefAddedOrError.get();
275 break;
276 }
277 case File::kindSharedLibrary:
278 if (!file->hasOrdinal())
279 file->setOrdinal(_ctx.getNextOrdinalAndIncrement());
280 if (auto EC = handleSharedLibrary(*file)) {
281 // FIXME: This should be passed to logAllUnhandledErrors but it needs
282 // to be passed a Twine instead of a string.
283 llvm::errs() << "Error in " + file->path() << ": ";
284 logAllUnhandledErrors(std::move(EC), llvm::errs(), std::string());
285 return false;
286 }
287 break;
288 }
289 _newUndefinesAdded[file] = undefAdded;
290 }
291}
292
293// switch all references to undefined or coalesced away atoms
294// to the new defined atom
295void Resolver::updateReferences() {
296 DEBUG_WITH_TYPE("resolver",
297 llvm::dbgs() << "******** Updating references:\n");
298 ScopedTask task(getDefaultDomain(), "updateReferences");
299 for (const OwningAtomPtr<Atom> &atom : _atoms) {
300 if (const DefinedAtom *defAtom = dyn_cast<DefinedAtom>(atom.get())) {
301 for (const Reference *ref : *defAtom) {
302 // A reference of type kindAssociate should't be updated.
303 // Instead, an atom having such reference will be removed
304 // if the target atom is coalesced away, so that they will
305 // go away as a group.
306 if (ref->kindNamespace() == lld::Reference::KindNamespace::all &&
307 ref->kindValue() == lld::Reference::kindAssociate) {
308 if (_symbolTable.isCoalescedAway(atom.get()))
309 _deadAtoms.insert(ref->target());
310 continue;
311 }
312 const Atom *newTarget = _symbolTable.replacement(ref->target());
313 const_cast<Reference *>(ref)->setTarget(newTarget);
314 }
315 }
316 }
317}
318
319// For dead code stripping, recursively mark atoms "live"
320void Resolver::markLive(const Atom *atom) {
321 // Mark the atom is live. If it's already marked live, then stop recursion.
322 auto exists = _liveAtoms.insert(atom);
323 if (!exists.second)
324 return;
325
326 // Mark all atoms it references as live
327 if (const DefinedAtom *defAtom = dyn_cast<DefinedAtom>(atom)) {
328 for (const Reference *ref : *defAtom)
329 markLive(ref->target());
330 for (auto &p : llvm::make_range(_reverseRef.equal_range(defAtom))) {
331 const Atom *target = p.second;
332 markLive(target);
333 }
334 }
335}
336
337static bool isBackref(const Reference *ref) {
338 if (ref->kindNamespace() != lld::Reference::KindNamespace::all)
339 return false;
340 return (ref->kindValue() == lld::Reference::kindLayoutAfter);
341}
342
343// remove all atoms not actually used
344void Resolver::deadStripOptimize() {
345 DEBUG_WITH_TYPE("resolver",
346 llvm::dbgs() << "******** Dead stripping unused atoms:\n");
347 ScopedTask task(getDefaultDomain(), "deadStripOptimize");
348 // only do this optimization with -dead_strip
349 if (!_ctx.deadStrip())
350 return;
351
352 // Some type of references prevent referring atoms to be dead-striped.
353 // Make a reverse map of such references before traversing the graph.
354 // While traversing the list of atoms, mark AbsoluteAtoms as live
355 // in order to avoid reclaim.
356 for (const OwningAtomPtr<Atom> &atom : _atoms) {
357 if (const DefinedAtom *defAtom = dyn_cast<DefinedAtom>(atom.get()))
358 for (const Reference *ref : *defAtom)
359 if (isBackref(ref))
360 _reverseRef.insert(std::make_pair(ref->target(), atom.get()));
361 if (const AbsoluteAtom *absAtom = dyn_cast<AbsoluteAtom>(atom.get()))
362 markLive(absAtom);
363 }
364
365 // By default, shared libraries are built with all globals as dead strip roots
366 if (_ctx.globalsAreDeadStripRoots())
367 for (const OwningAtomPtr<Atom> &atom : _atoms)
368 if (const DefinedAtom *defAtom = dyn_cast<DefinedAtom>(atom.get()))
369 if (defAtom->scope() == DefinedAtom::scopeGlobal)
370 _deadStripRoots.insert(defAtom);
371
372 // Or, use list of names that are dead strip roots.
373 for (const StringRef &name : _ctx.deadStripRoots()) {
374 const Atom *symAtom = _symbolTable.findByName(name);
375 assert(symAtom);
376 _deadStripRoots.insert(symAtom);
377 }
378
379 // mark all roots as live, and recursively all atoms they reference
380 for (const Atom *dsrAtom : _deadStripRoots)
381 markLive(dsrAtom);
382
383 // now remove all non-live atoms from _atoms
384 _atoms.erase(std::remove_if(_atoms.begin(), _atoms.end(),
385 [&](OwningAtomPtr<Atom> &a) {
386 return _liveAtoms.count(a.get()) == 0;
387 }),
388 _atoms.end());
389}
390
391// error out if some undefines remain
392bool Resolver::checkUndefines() {
393 DEBUG_WITH_TYPE("resolver",
394 llvm::dbgs() << "******** Checking for undefines:\n");
395
396 // build vector of remaining undefined symbols
397 std::vector<const UndefinedAtom *> undefinedAtoms = _symbolTable.undefines();
398 if (_ctx.deadStrip()) {
399 // When dead code stripping, we don't care if dead atoms are undefined.
400 undefinedAtoms.erase(
401 std::remove_if(undefinedAtoms.begin(), undefinedAtoms.end(),
402 [&](const Atom *a) { return _liveAtoms.count(a) == 0; }),
403 undefinedAtoms.end());
404 }
405
406 if (undefinedAtoms.empty())
407 return false;
408
409 // Warn about unresolved symbols.
410 bool foundUndefines = false;
411 for (const UndefinedAtom *undef : undefinedAtoms) {
412 // Skip over a weak symbol.
413 if (undef->canBeNull() != UndefinedAtom::canBeNullNever)
414 continue;
415
416 // If this is a library and undefined symbols are allowed on the
417 // target platform, skip over it.
418 if (isa<SharedLibraryFile>(undef->file()) && _ctx.allowShlibUndefines())
419 continue;
420
421 // If the undefine is coalesced away, skip over it.
422 if (_symbolTable.isCoalescedAway(undef))
423 continue;
424
425 // Seems like this symbol is undefined. Warn that.
426 foundUndefines = true;
427 if (_ctx.printRemainingUndefines()) {
428 llvm::errs() << "Undefined symbol: " << undef->file().path()
429 << ": " << _ctx.demangle(undef->name())
430 << "\n";
431 }
432 }
433 if (!foundUndefines)
434 return false;
435 if (_ctx.printRemainingUndefines())
436 llvm::errs() << "symbol(s) not found\n";
437 return true;
438}
439
440// remove from _atoms all coaleseced away atoms
441void Resolver::removeCoalescedAwayAtoms() {
442 DEBUG_WITH_TYPE("resolver",
443 llvm::dbgs() << "******** Removing coalesced away atoms:\n");
444 ScopedTask task(getDefaultDomain(), "removeCoalescedAwayAtoms");
445 _atoms.erase(std::remove_if(_atoms.begin(), _atoms.end(),
446 [&](OwningAtomPtr<Atom> &a) {
447 return _symbolTable.isCoalescedAway(a.get()) ||
448 _deadAtoms.count(a.get());
449 }),
450 _atoms.end());
451}
452
453bool Resolver::resolve() {
454 DEBUG_WITH_TYPE("resolver",
455 llvm::dbgs() << "******** Resolving atom references:\n");
456 if (!resolveUndefines())
457 return false;
458 updateReferences();
459 deadStripOptimize();
460 if (checkUndefines()) {
461 DEBUG_WITH_TYPE("resolver", llvm::dbgs() << "Found undefines... ");
462 if (!_ctx.allowRemainingUndefines()) {
463 DEBUG_WITH_TYPE("resolver", llvm::dbgs() << "which we don't allow\n");
464 return false;
465 }
466 DEBUG_WITH_TYPE("resolver", llvm::dbgs() << "which we are ok with\n");
467 }
468 removeCoalescedAwayAtoms();
469 _result->addAtoms(_atoms);
470 DEBUG_WITH_TYPE("resolver", llvm::dbgs() << "******** Finished resolver\n");
471 return true;
472}
473
474void Resolver::MergedFile::addAtoms(
475 llvm::MutableArrayRef<OwningAtomPtr<Atom>> all) {
476 ScopedTask task(getDefaultDomain(), "addAtoms");
477 DEBUG_WITH_TYPE("resolver", llvm::dbgs() << "Resolver final atom list:\n");
478
479 for (OwningAtomPtr<Atom> &atom : all) {
480#ifndef NDEBUG
481 if (auto *definedAtom = dyn_cast<DefinedAtom>(atom.get())) {
482 DEBUG_WITH_TYPE("resolver", llvm::dbgs()
483 << llvm::format(" 0x%09lX", definedAtom)
484 << ", file=#"
485 << definedAtom->file().ordinal()
486 << ", atom=#"
487 << definedAtom->ordinal()
488 << ", name="
489 << definedAtom->name()
490 << ", type="
491 << definedAtom->contentType()
492 << "\n");
493 } else {
494 DEBUG_WITH_TYPE("resolver", llvm::dbgs()
495 << llvm::format(" 0x%09lX", atom.get())
496 << ", name="
497 << atom.get()->name()
498 << "\n");
499 }
500#endif
501 addAtom(*atom.release());
502 }
503}
504
505} // namespace lld
deps/lld/lib/Core/SymbolTable.cpp created+291
......@@ -0,0 +1,291 @@
1//===- Core/SymbolTable.cpp - Main Symbol Table ---------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lld/Core/SymbolTable.h"
11#include "lld/Core/AbsoluteAtom.h"
12#include "lld/Core/Atom.h"
13#include "lld/Core/DefinedAtom.h"
14#include "lld/Core/File.h"
15#include "lld/Core/LLVM.h"
16#include "lld/Core/LinkingContext.h"
17#include "lld/Core/Resolver.h"
18#include "lld/Core/SharedLibraryAtom.h"
19#include "lld/Core/UndefinedAtom.h"
20#include "llvm/ADT/ArrayRef.h"
21#include "llvm/ADT/DenseMapInfo.h"
22#include "llvm/ADT/Hashing.h"
23#include "llvm/Support/ErrorHandling.h"
24#include "llvm/Support/raw_ostream.h"
25#include <algorithm>
26#include <cassert>
27#include <cstdlib>
28#include <vector>
29
30namespace lld {
31bool SymbolTable::add(const UndefinedAtom &atom) { return addByName(atom); }
32
33bool SymbolTable::add(const SharedLibraryAtom &atom) { return addByName(atom); }
34
35bool SymbolTable::add(const AbsoluteAtom &atom) { return addByName(atom); }
36
37bool SymbolTable::add(const DefinedAtom &atom) {
38 if (!atom.name().empty() &&
39 atom.scope() != DefinedAtom::scopeTranslationUnit) {
40 // Named atoms cannot be merged by content.
41 assert(atom.merge() != DefinedAtom::mergeByContent);
42 // Track named atoms that are not scoped to file (static).
43 return addByName(atom);
44 }
45 if (atom.merge() == DefinedAtom::mergeByContent) {
46 // Named atoms cannot be merged by content.
47 assert(atom.name().empty());
48 // Currently only read-only constants can be merged.
49 if (atom.permissions() == DefinedAtom::permR__)
50 return addByContent(atom);
51 // TODO: support mergeByContent of data atoms by comparing content & fixups.
52 }
53 return false;
54}
55
56enum NameCollisionResolution {
57 NCR_First,
58 NCR_Second,
59 NCR_DupDef,
60 NCR_DupUndef,
61 NCR_DupShLib,
62 NCR_Error
63};
64
65static NameCollisionResolution cases[4][4] = {
66 //regular absolute undef sharedLib
67 {
68 // first is regular
69 NCR_DupDef, NCR_Error, NCR_First, NCR_First
70 },
71 {
72 // first is absolute
73 NCR_Error, NCR_Error, NCR_First, NCR_First
74 },
75 {
76 // first is undef
77 NCR_Second, NCR_Second, NCR_DupUndef, NCR_Second
78 },
79 {
80 // first is sharedLib
81 NCR_Second, NCR_Second, NCR_First, NCR_DupShLib
82 }
83};
84
85static NameCollisionResolution collide(Atom::Definition first,
86 Atom::Definition second) {
87 return cases[first][second];
88}
89
90enum MergeResolution {
91 MCR_First,
92 MCR_Second,
93 MCR_Largest,
94 MCR_SameSize,
95 MCR_Error
96};
97
98static MergeResolution mergeCases[][6] = {
99 // no tentative weak weakAddress sameNameAndSize largest
100 {MCR_Error, MCR_First, MCR_First, MCR_First, MCR_SameSize, MCR_Largest}, // no
101 {MCR_Second, MCR_Largest, MCR_Second, MCR_Second, MCR_SameSize, MCR_Largest}, // tentative
102 {MCR_Second, MCR_First, MCR_First, MCR_Second, MCR_SameSize, MCR_Largest}, // weak
103 {MCR_Second, MCR_First, MCR_First, MCR_First, MCR_SameSize, MCR_Largest}, // weakAddress
104 {MCR_SameSize, MCR_SameSize, MCR_SameSize, MCR_SameSize, MCR_SameSize, MCR_SameSize}, // sameSize
105 {MCR_Largest, MCR_Largest, MCR_Largest, MCR_Largest, MCR_SameSize, MCR_Largest}, // largest
106};
107
108static MergeResolution mergeSelect(DefinedAtom::Merge first,
109 DefinedAtom::Merge second) {
110 assert(first != DefinedAtom::mergeByContent);
111 assert(second != DefinedAtom::mergeByContent);
112 return mergeCases[first][second];
113}
114
115bool SymbolTable::addByName(const Atom &newAtom) {
116 StringRef name = newAtom.name();
117 assert(!name.empty());
118 const Atom *existing = findByName(name);
119 if (existing == nullptr) {
120 // Name is not in symbol table yet, add it associate with this atom.
121 _nameTable[name] = &newAtom;
122 return true;
123 }
124
125 // Do nothing if the same object is added more than once.
126 if (existing == &newAtom)
127 return false;
128
129 // Name is already in symbol table and associated with another atom.
130 bool useNew = true;
131 switch (collide(existing->definition(), newAtom.definition())) {
132 case NCR_First:
133 useNew = false;
134 break;
135 case NCR_Second:
136 useNew = true;
137 break;
138 case NCR_DupDef: {
139 const auto *existingDef = cast<DefinedAtom>(existing);
140 const auto *newDef = cast<DefinedAtom>(&newAtom);
141 switch (mergeSelect(existingDef->merge(), newDef->merge())) {
142 case MCR_First:
143 useNew = false;
144 break;
145 case MCR_Second:
146 useNew = true;
147 break;
148 case MCR_Largest: {
149 uint64_t existingSize = existingDef->sectionSize();
150 uint64_t newSize = newDef->sectionSize();
151 useNew = (newSize >= existingSize);
152 break;
153 }
154 case MCR_SameSize: {
155 uint64_t existingSize = existingDef->sectionSize();
156 uint64_t newSize = newDef->sectionSize();
157 if (existingSize == newSize) {
158 useNew = true;
159 break;
160 }
161 llvm::errs() << "Size mismatch: "
162 << existing->name() << " (" << existingSize << ") "
163 << newAtom.name() << " (" << newSize << ")\n";
164 LLVM_FALLTHROUGH;
165 }
166 case MCR_Error:
167 llvm::errs() << "Duplicate symbols: "
168 << existing->name()
169 << ":"
170 << existing->file().path()
171 << " and "
172 << newAtom.name()
173 << ":"
174 << newAtom.file().path()
175 << "\n";
176 llvm::report_fatal_error("duplicate symbol error");
177 break;
178 }
179 break;
180 }
181 case NCR_DupUndef: {
182 const UndefinedAtom* existingUndef = cast<UndefinedAtom>(existing);
183 const UndefinedAtom* newUndef = cast<UndefinedAtom>(&newAtom);
184
185 bool sameCanBeNull = (existingUndef->canBeNull() == newUndef->canBeNull());
186 if (sameCanBeNull)
187 useNew = false;
188 else
189 useNew = (newUndef->canBeNull() < existingUndef->canBeNull());
190 break;
191 }
192 case NCR_DupShLib: {
193 useNew = false;
194 break;
195 }
196 case NCR_Error:
197 llvm::errs() << "SymbolTable: error while merging " << name << "\n";
198 llvm::report_fatal_error("duplicate symbol error");
199 break;
200 }
201
202 if (useNew) {
203 // Update name table to use new atom.
204 _nameTable[name] = &newAtom;
205 // Add existing atom to replacement table.
206 _replacedAtoms[existing] = &newAtom;
207 } else {
208 // New atom is not being used. Add it to replacement table.
209 _replacedAtoms[&newAtom] = existing;
210 }
211 return false;
212}
213
214unsigned SymbolTable::AtomMappingInfo::getHashValue(const DefinedAtom *atom) {
215 auto content = atom->rawContent();
216 return llvm::hash_combine(atom->size(),
217 atom->contentType(),
218 llvm::hash_combine_range(content.begin(),
219 content.end()));
220}
221
222bool SymbolTable::AtomMappingInfo::isEqual(const DefinedAtom * const l,
223 const DefinedAtom * const r) {
224 if (l == r)
225 return true;
226 if (l == getEmptyKey() || r == getEmptyKey())
227 return false;
228 if (l == getTombstoneKey() || r == getTombstoneKey())
229 return false;
230 if (l->contentType() != r->contentType())
231 return false;
232 if (l->size() != r->size())
233 return false;
234 if (l->sectionChoice() != r->sectionChoice())
235 return false;
236 if (l->sectionChoice() == DefinedAtom::sectionCustomRequired) {
237 if (!l->customSectionName().equals(r->customSectionName()))
238 return false;
239 }
240 ArrayRef<uint8_t> lc = l->rawContent();
241 ArrayRef<uint8_t> rc = r->rawContent();
242 return memcmp(lc.data(), rc.data(), lc.size()) == 0;
243}
244
245bool SymbolTable::addByContent(const DefinedAtom &newAtom) {
246 AtomContentSet::iterator pos = _contentTable.find(&newAtom);
247 if (pos == _contentTable.end()) {
248 _contentTable.insert(&newAtom);
249 return true;
250 }
251 const Atom* existing = *pos;
252 // New atom is not being used. Add it to replacement table.
253 _replacedAtoms[&newAtom] = existing;
254 return false;
255}
256
257const Atom *SymbolTable::findByName(StringRef sym) {
258 NameToAtom::iterator pos = _nameTable.find(sym);
259 if (pos == _nameTable.end())
260 return nullptr;
261 return pos->second;
262}
263
264const Atom *SymbolTable::replacement(const Atom *atom) {
265 // Find the replacement for a given atom. Atoms in _replacedAtoms
266 // may be chained, so find the last one.
267 for (;;) {
268 AtomToAtom::iterator pos = _replacedAtoms.find(atom);
269 if (pos == _replacedAtoms.end())
270 return atom;
271 atom = pos->second;
272 }
273}
274
275bool SymbolTable::isCoalescedAway(const Atom *atom) {
276 return _replacedAtoms.count(atom) > 0;
277}
278
279std::vector<const UndefinedAtom *> SymbolTable::undefines() {
280 std::vector<const UndefinedAtom *> ret;
281 for (auto it : _nameTable) {
282 const Atom *atom = it.second;
283 assert(atom != nullptr);
284 if (const auto *undef = dyn_cast<const UndefinedAtom>(atom))
285 if (_replacedAtoms.count(undef) == 0)
286 ret.push_back(undef);
287 }
288 return ret;
289}
290
291} // namespace lld
deps/lld/lib/Core/TargetOptionsCommandFlags.cpp created+32
......@@ -0,0 +1,32 @@
1//===-- TargetOptionsCommandFlags.cpp ---------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file exists as a place for global variables defined in LLVM's
11// CodeGen/CommandFlags.h. By putting the resulting object file in
12// an archive and linking with it, the definitions will automatically be
13// included when needed and skipped when already present.
14//
15//===----------------------------------------------------------------------===//
16
17#include "lld/Core/TargetOptionsCommandFlags.h"
18
19#include "llvm/CodeGen/CommandFlags.h"
20#include "llvm/Target/TargetOptions.h"
21
22// Define an externally visible version of
23// InitTargetOptionsFromCodeGenFlags, so that its functionality can be
24// used without having to include llvm/CodeGen/CommandFlags.h, which
25// would lead to multiple definitions of the command line flags.
26llvm::TargetOptions lld::InitTargetOptionsFromCodeGenFlags() {
27 return ::InitTargetOptionsFromCodeGenFlags();
28}
29
30llvm::CodeModel::Model lld::GetCodeModelFromCMModel() {
31 return CMModel;
32}
deps/lld/lib/Core/Writer.cpp created+18
......@@ -0,0 +1,18 @@
1//===- lib/Core/Writer.cpp ------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lld/Core/Writer.h"
11
12namespace lld {
13
14Writer::Writer() = default;
15
16Writer::~Writer() = default;
17
18} // end namespace lld
deps/lld/lib/Driver/CMakeLists.txt created+24
......@@ -0,0 +1,24 @@
1set(LLVM_TARGET_DEFINITIONS DarwinLdOptions.td)
2tablegen(LLVM DarwinLdOptions.inc -gen-opt-parser-defs)
3add_public_tablegen_target(DriverOptionsTableGen)
4
5add_lld_library(lldDriver
6 DarwinLdDriver.cpp
7
8 ADDITIONAL_HEADER_DIRS
9 ${LLD_INCLUDE_DIR}/lld/Driver
10
11 LINK_COMPONENTS
12 Object
13 Option
14 Support
15
16 LINK_LIBS
17 lldConfig
18 lldMachO
19 lldCore
20 lldReaderWriter
21 lldYAML
22 )
23
24add_dependencies(lldDriver DriverOptionsTableGen)
deps/lld/lib/Driver/DarwinLdDriver.cpp created+1239
......@@ -0,0 +1,1239 @@
1//===- lib/Driver/DarwinLdDriver.cpp --------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11///
12/// Concrete instance of the Driver for darwin's ld.
13///
14//===----------------------------------------------------------------------===//
15
16#include "lld/Core/ArchiveLibraryFile.h"
17#include "lld/Core/Error.h"
18#include "lld/Core/File.h"
19#include "lld/Core/Instrumentation.h"
20#include "lld/Core/LLVM.h"
21#include "lld/Core/LinkingContext.h"
22#include "lld/Core/Node.h"
23#include "lld/Core/PassManager.h"
24#include "lld/Core/Resolver.h"
25#include "lld/Core/SharedLibraryFile.h"
26#include "lld/Core/Simple.h"
27#include "lld/ReaderWriter/MachOLinkingContext.h"
28#include "llvm/ADT/ArrayRef.h"
29#include "llvm/ADT/Optional.h"
30#include "llvm/ADT/STLExtras.h"
31#include "llvm/ADT/SmallString.h"
32#include "llvm/ADT/StringExtras.h"
33#include "llvm/ADT/StringRef.h"
34#include "llvm/ADT/Twine.h"
35#include "llvm/BinaryFormat/MachO.h"
36#include "llvm/Option/Arg.h"
37#include "llvm/Option/ArgList.h"
38#include "llvm/Option/OptTable.h"
39#include "llvm/Option/Option.h"
40#include "llvm/Support/Casting.h"
41#include "llvm/Support/CommandLine.h"
42#include "llvm/Support/Error.h"
43#include "llvm/Support/ErrorOr.h"
44#include "llvm/Support/Format.h"
45#include "llvm/Support/MathExtras.h"
46#include "llvm/Support/MemoryBuffer.h"
47#include "llvm/Support/Path.h"
48#include "llvm/Support/raw_ostream.h"
49#include <algorithm>
50#include <cstdint>
51#include <memory>
52#include <string>
53#include <system_error>
54#include <utility>
55#include <vector>
56
57using namespace lld;
58
59namespace {
60
61// Create enum with OPT_xxx values for each option in DarwinLdOptions.td
62enum {
63 OPT_INVALID = 0,
64#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
65 HELP, META, VALUES) \
66 OPT_##ID,
67#include "DarwinLdOptions.inc"
68#undef OPTION
69};
70
71// Create prefix string literals used in DarwinLdOptions.td
72#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
73#include "DarwinLdOptions.inc"
74#undef PREFIX
75
76// Create table mapping all options defined in DarwinLdOptions.td
77static const llvm::opt::OptTable::Info infoTable[] = {
78#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
79 HELPTEXT, METAVAR, VALUES) \
80 {PREFIX, NAME, HELPTEXT, \
81 METAVAR, OPT_##ID, llvm::opt::Option::KIND##Class, \
82 PARAM, FLAGS, OPT_##GROUP, \
83 OPT_##ALIAS, ALIASARGS, VALUES},
84#include "DarwinLdOptions.inc"
85#undef OPTION
86};
87
88// Create OptTable class for parsing actual command line arguments
89class DarwinLdOptTable : public llvm::opt::OptTable {
90public:
91 DarwinLdOptTable() : OptTable(infoTable) {}
92};
93
94static std::vector<std::unique_ptr<File>>
95makeErrorFile(StringRef path, std::error_code ec) {
96 std::vector<std::unique_ptr<File>> result;
97 result.push_back(llvm::make_unique<ErrorFile>(path, ec));
98 return result;
99}
100
101static std::vector<std::unique_ptr<File>>
102parseMemberFiles(std::unique_ptr<File> file) {
103 std::vector<std::unique_ptr<File>> members;
104 if (auto *archive = dyn_cast<ArchiveLibraryFile>(file.get())) {
105 if (std::error_code ec = archive->parseAllMembers(members))
106 return makeErrorFile(file->path(), ec);
107 } else {
108 members.push_back(std::move(file));
109 }
110 return members;
111}
112
113std::vector<std::unique_ptr<File>>
114loadFile(MachOLinkingContext &ctx, StringRef path,
115 raw_ostream &diag, bool wholeArchive, bool upwardDylib) {
116 if (ctx.logInputFiles())
117 diag << path << "\n";
118
119 ErrorOr<std::unique_ptr<MemoryBuffer>> mbOrErr = ctx.getMemoryBuffer(path);
120 if (std::error_code ec = mbOrErr.getError())
121 return makeErrorFile(path, ec);
122 ErrorOr<std::unique_ptr<File>> fileOrErr =
123 ctx.registry().loadFile(std::move(mbOrErr.get()));
124 if (std::error_code ec = fileOrErr.getError())
125 return makeErrorFile(path, ec);
126 std::unique_ptr<File> &file = fileOrErr.get();
127
128 // If file is a dylib, inform LinkingContext about it.
129 if (SharedLibraryFile *shl = dyn_cast<SharedLibraryFile>(file.get())) {
130 if (std::error_code ec = shl->parse())
131 return makeErrorFile(path, ec);
132 ctx.registerDylib(reinterpret_cast<mach_o::MachODylibFile *>(shl),
133 upwardDylib);
134 }
135 if (wholeArchive)
136 return parseMemberFiles(std::move(file));
137 std::vector<std::unique_ptr<File>> files;
138 files.push_back(std::move(file));
139 return files;
140}
141
142} // end anonymous namespace
143
144// Test may be running on Windows. Canonicalize the path
145// separator to '/' to get consistent outputs for tests.
146static std::string canonicalizePath(StringRef path) {
147 char sep = llvm::sys::path::get_separator().front();
148 if (sep != '/') {
149 std::string fixedPath = path;
150 std::replace(fixedPath.begin(), fixedPath.end(), sep, '/');
151 return fixedPath;
152 } else {
153 return path;
154 }
155}
156
157static void addFile(StringRef path, MachOLinkingContext &ctx,
158 bool loadWholeArchive,
159 bool upwardDylib, raw_ostream &diag) {
160 std::vector<std::unique_ptr<File>> files =
161 loadFile(ctx, path, diag, loadWholeArchive, upwardDylib);
162 for (std::unique_ptr<File> &file : files)
163 ctx.getNodes().push_back(llvm::make_unique<FileNode>(std::move(file)));
164}
165
166// Export lists are one symbol per line. Blank lines are ignored.
167// Trailing comments start with #.
168static std::error_code parseExportsList(StringRef exportFilePath,
169 MachOLinkingContext &ctx,
170 raw_ostream &diagnostics) {
171 // Map in export list file.
172 ErrorOr<std::unique_ptr<MemoryBuffer>> mb =
173 MemoryBuffer::getFileOrSTDIN(exportFilePath);
174 if (std::error_code ec = mb.getError())
175 return ec;
176 ctx.addInputFileDependency(exportFilePath);
177 StringRef buffer = mb->get()->getBuffer();
178 while (!buffer.empty()) {
179 // Split off each line in the file.
180 std::pair<StringRef, StringRef> lineAndRest = buffer.split('\n');
181 StringRef line = lineAndRest.first;
182 // Ignore trailing # comments.
183 std::pair<StringRef, StringRef> symAndComment = line.split('#');
184 StringRef sym = symAndComment.first.trim();
185 if (!sym.empty())
186 ctx.addExportSymbol(sym);
187 buffer = lineAndRest.second;
188 }
189 return std::error_code();
190}
191
192/// Order files are one symbol per line. Blank lines are ignored.
193/// Trailing comments start with #. Symbol names can be prefixed with an
194/// architecture name and/or .o leaf name. Examples:
195/// _foo
196/// bar.o:_bar
197/// libfrob.a(bar.o):_bar
198/// x86_64:_foo64
199static std::error_code parseOrderFile(StringRef orderFilePath,
200 MachOLinkingContext &ctx,
201 raw_ostream &diagnostics) {
202 // Map in order file.
203 ErrorOr<std::unique_ptr<MemoryBuffer>> mb =
204 MemoryBuffer::getFileOrSTDIN(orderFilePath);
205 if (std::error_code ec = mb.getError())
206 return ec;
207 ctx.addInputFileDependency(orderFilePath);
208 StringRef buffer = mb->get()->getBuffer();
209 while (!buffer.empty()) {
210 // Split off each line in the file.
211 std::pair<StringRef, StringRef> lineAndRest = buffer.split('\n');
212 StringRef line = lineAndRest.first;
213 buffer = lineAndRest.second;
214 // Ignore trailing # comments.
215 std::pair<StringRef, StringRef> symAndComment = line.split('#');
216 if (symAndComment.first.empty())
217 continue;
218 StringRef sym = symAndComment.first.trim();
219 if (sym.empty())
220 continue;
221 // Check for prefix.
222 StringRef prefix;
223 std::pair<StringRef, StringRef> prefixAndSym = sym.split(':');
224 if (!prefixAndSym.second.empty()) {
225 sym = prefixAndSym.second;
226 prefix = prefixAndSym.first;
227 if (!prefix.endswith(".o") && !prefix.endswith(".o)")) {
228 // If arch name prefix does not match arch being linked, ignore symbol.
229 if (!ctx.archName().equals(prefix))
230 continue;
231 prefix = "";
232 }
233 } else
234 sym = prefixAndSym.first;
235 if (!sym.empty()) {
236 ctx.appendOrderedSymbol(sym, prefix);
237 //llvm::errs() << sym << ", prefix=" << prefix << "\n";
238 }
239 }
240 return std::error_code();
241}
242
243//
244// There are two variants of the -filelist option:
245//
246// -filelist <path>
247// In this variant, the path is to a text file which contains one file path
248// per line. There are no comments or trimming of whitespace.
249//
250// -fileList <path>,<dir>
251// In this variant, the path is to a text file which contains a partial path
252// per line. The <dir> prefix is prepended to each partial path.
253//
254static llvm::Error loadFileList(StringRef fileListPath,
255 MachOLinkingContext &ctx, bool forceLoad,
256 raw_ostream &diagnostics) {
257 // If there is a comma, split off <dir>.
258 std::pair<StringRef, StringRef> opt = fileListPath.split(',');
259 StringRef filePath = opt.first;
260 StringRef dirName = opt.second;
261 ctx.addInputFileDependency(filePath);
262 // Map in file list file.
263 ErrorOr<std::unique_ptr<MemoryBuffer>> mb =
264 MemoryBuffer::getFileOrSTDIN(filePath);
265 if (std::error_code ec = mb.getError())
266 return llvm::errorCodeToError(ec);
267 StringRef buffer = mb->get()->getBuffer();
268 while (!buffer.empty()) {
269 // Split off each line in the file.
270 std::pair<StringRef, StringRef> lineAndRest = buffer.split('\n');
271 StringRef line = lineAndRest.first;
272 StringRef path;
273 if (!dirName.empty()) {
274 // If there is a <dir> then prepend dir to each line.
275 SmallString<256> fullPath;
276 fullPath.assign(dirName);
277 llvm::sys::path::append(fullPath, Twine(line));
278 path = ctx.copy(fullPath.str());
279 } else {
280 // No <dir> use whole line as input file path.
281 path = ctx.copy(line);
282 }
283 if (!ctx.pathExists(path)) {
284 return llvm::make_error<GenericError>(Twine("File not found '")
285 + path
286 + "'");
287 }
288 if (ctx.testingFileUsage()) {
289 diagnostics << "Found filelist entry " << canonicalizePath(path) << '\n';
290 }
291 addFile(path, ctx, forceLoad, false, diagnostics);
292 buffer = lineAndRest.second;
293 }
294 return llvm::Error::success();
295}
296
297/// Parse number assuming it is base 16, but allow 0x prefix.
298static bool parseNumberBase16(StringRef numStr, uint64_t &baseAddress) {
299 if (numStr.startswith_lower("0x"))
300 numStr = numStr.drop_front(2);
301 return numStr.getAsInteger(16, baseAddress);
302}
303
304static void parseLLVMOptions(const LinkingContext &ctx) {
305 // Honor -mllvm
306 if (!ctx.llvmOptions().empty()) {
307 unsigned numArgs = ctx.llvmOptions().size();
308 auto **args = new const char *[numArgs + 2];
309 args[0] = "lld (LLVM option parsing)";
310 for (unsigned i = 0; i != numArgs; ++i)
311 args[i + 1] = ctx.llvmOptions()[i];
312 args[numArgs + 1] = nullptr;
313 llvm::cl::ParseCommandLineOptions(numArgs + 1, args);
314 }
315}
316
317namespace lld {
318namespace mach_o {
319
320bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx,
321 raw_ostream &diagnostics) {
322 // Parse command line options using DarwinLdOptions.td
323 DarwinLdOptTable table;
324 unsigned missingIndex;
325 unsigned missingCount;
326 llvm::opt::InputArgList parsedArgs =
327 table.ParseArgs(args.slice(1), missingIndex, missingCount);
328 if (missingCount) {
329 diagnostics << "error: missing arg value for '"
330 << parsedArgs.getArgString(missingIndex) << "' expected "
331 << missingCount << " argument(s).\n";
332 return false;
333 }
334
335 for (auto unknownArg : parsedArgs.filtered(OPT_UNKNOWN)) {
336 diagnostics << "warning: ignoring unknown argument: "
337 << unknownArg->getAsString(parsedArgs) << "\n";
338 }
339
340 // Figure out output kind ( -dylib, -r, -bundle, -preload, or -static )
341 llvm::MachO::HeaderFileType fileType = llvm::MachO::MH_EXECUTE;
342 bool isStaticExecutable = false;
343 if (llvm::opt::Arg *kind = parsedArgs.getLastArg(
344 OPT_dylib, OPT_relocatable, OPT_bundle, OPT_static, OPT_preload)) {
345 switch (kind->getOption().getID()) {
346 case OPT_dylib:
347 fileType = llvm::MachO::MH_DYLIB;
348 break;
349 case OPT_relocatable:
350 fileType = llvm::MachO::MH_OBJECT;
351 break;
352 case OPT_bundle:
353 fileType = llvm::MachO::MH_BUNDLE;
354 break;
355 case OPT_static:
356 fileType = llvm::MachO::MH_EXECUTE;
357 isStaticExecutable = true;
358 break;
359 case OPT_preload:
360 fileType = llvm::MachO::MH_PRELOAD;
361 break;
362 }
363 }
364
365 // Handle -arch xxx
366 MachOLinkingContext::Arch arch = MachOLinkingContext::arch_unknown;
367 if (llvm::opt::Arg *archStr = parsedArgs.getLastArg(OPT_arch)) {
368 arch = MachOLinkingContext::archFromName(archStr->getValue());
369 if (arch == MachOLinkingContext::arch_unknown) {
370 diagnostics << "error: unknown arch named '" << archStr->getValue()
371 << "'\n";
372 return false;
373 }
374 }
375 // If no -arch specified, scan input files to find first non-fat .o file.
376 if (arch == MachOLinkingContext::arch_unknown) {
377 for (auto &inFile : parsedArgs.filtered(OPT_INPUT)) {
378 // This is expensive because it opens and maps the file. But that is
379 // ok because no -arch is rare.
380 if (MachOLinkingContext::isThinObjectFile(inFile->getValue(), arch))
381 break;
382 }
383 if (arch == MachOLinkingContext::arch_unknown &&
384 !parsedArgs.getLastArg(OPT_test_file_usage)) {
385 // If no -arch and no options at all, print usage message.
386 if (parsedArgs.size() == 0)
387 table.PrintHelp(llvm::outs(), args[0], "LLVM Linker", false);
388 else
389 diagnostics << "error: -arch not specified and could not be inferred\n";
390 return false;
391 }
392 }
393
394 // Handle -macosx_version_min or -ios_version_min
395 MachOLinkingContext::OS os = MachOLinkingContext::OS::unknown;
396 uint32_t minOSVersion = 0;
397 if (llvm::opt::Arg *minOS =
398 parsedArgs.getLastArg(OPT_macosx_version_min, OPT_ios_version_min,
399 OPT_ios_simulator_version_min)) {
400 switch (minOS->getOption().getID()) {
401 case OPT_macosx_version_min:
402 os = MachOLinkingContext::OS::macOSX;
403 if (MachOLinkingContext::parsePackedVersion(minOS->getValue(),
404 minOSVersion)) {
405 diagnostics << "error: malformed macosx_version_min value\n";
406 return false;
407 }
408 break;
409 case OPT_ios_version_min:
410 os = MachOLinkingContext::OS::iOS;
411 if (MachOLinkingContext::parsePackedVersion(minOS->getValue(),
412 minOSVersion)) {
413 diagnostics << "error: malformed ios_version_min value\n";
414 return false;
415 }
416 break;
417 case OPT_ios_simulator_version_min:
418 os = MachOLinkingContext::OS::iOS_simulator;
419 if (MachOLinkingContext::parsePackedVersion(minOS->getValue(),
420 minOSVersion)) {
421 diagnostics << "error: malformed ios_simulator_version_min value\n";
422 return false;
423 }
424 break;
425 }
426 } else {
427 // No min-os version on command line, check environment variables
428 }
429
430 // Handle export_dynamic
431 // FIXME: Should we warn when this applies to something other than a static
432 // executable or dylib? Those are the only cases where this has an effect.
433 // Note, this has to come before ctx.configure() so that we get the correct
434 // value for _globalsAreDeadStripRoots.
435 bool exportDynamicSymbols = parsedArgs.hasArg(OPT_export_dynamic);
436
437 // Now that there's enough information parsed in, let the linking context
438 // set up default values.
439 ctx.configure(fileType, arch, os, minOSVersion, exportDynamicSymbols);
440
441 // Handle -e xxx
442 if (llvm::opt::Arg *entry = parsedArgs.getLastArg(OPT_entry))
443 ctx.setEntrySymbolName(entry->getValue());
444
445 // Handle -o xxx
446 if (llvm::opt::Arg *outpath = parsedArgs.getLastArg(OPT_output))
447 ctx.setOutputPath(outpath->getValue());
448 else
449 ctx.setOutputPath("a.out");
450
451 // Handle -image_base XXX and -seg1addr XXXX
452 if (llvm::opt::Arg *imageBase = parsedArgs.getLastArg(OPT_image_base)) {
453 uint64_t baseAddress;
454 if (parseNumberBase16(imageBase->getValue(), baseAddress)) {
455 diagnostics << "error: image_base expects a hex number\n";
456 return false;
457 } else if (baseAddress < ctx.pageZeroSize()) {
458 diagnostics << "error: image_base overlaps with __PAGEZERO\n";
459 return false;
460 } else if (baseAddress % ctx.pageSize()) {
461 diagnostics << "error: image_base must be a multiple of page size ("
462 << "0x" << llvm::utohexstr(ctx.pageSize()) << ")\n";
463 return false;
464 }
465
466 ctx.setBaseAddress(baseAddress);
467 }
468
469 // Handle -dead_strip
470 if (parsedArgs.getLastArg(OPT_dead_strip))
471 ctx.setDeadStripping(true);
472
473 bool globalWholeArchive = false;
474 // Handle -all_load
475 if (parsedArgs.getLastArg(OPT_all_load))
476 globalWholeArchive = true;
477
478 // Handle -install_name
479 if (llvm::opt::Arg *installName = parsedArgs.getLastArg(OPT_install_name))
480 ctx.setInstallName(installName->getValue());
481 else
482 ctx.setInstallName(ctx.outputPath());
483
484 // Handle -mark_dead_strippable_dylib
485 if (parsedArgs.getLastArg(OPT_mark_dead_strippable_dylib))
486 ctx.setDeadStrippableDylib(true);
487
488 // Handle -compatibility_version and -current_version
489 if (llvm::opt::Arg *vers = parsedArgs.getLastArg(OPT_compatibility_version)) {
490 if (ctx.outputMachOType() != llvm::MachO::MH_DYLIB) {
491 diagnostics
492 << "error: -compatibility_version can only be used with -dylib\n";
493 return false;
494 }
495 uint32_t parsedVers;
496 if (MachOLinkingContext::parsePackedVersion(vers->getValue(), parsedVers)) {
497 diagnostics << "error: -compatibility_version value is malformed\n";
498 return false;
499 }
500 ctx.setCompatibilityVersion(parsedVers);
501 }
502
503 if (llvm::opt::Arg *vers = parsedArgs.getLastArg(OPT_current_version)) {
504 if (ctx.outputMachOType() != llvm::MachO::MH_DYLIB) {
505 diagnostics << "-current_version can only be used with -dylib\n";
506 return false;
507 }
508 uint32_t parsedVers;
509 if (MachOLinkingContext::parsePackedVersion(vers->getValue(), parsedVers)) {
510 diagnostics << "error: -current_version value is malformed\n";
511 return false;
512 }
513 ctx.setCurrentVersion(parsedVers);
514 }
515
516 // Handle -bundle_loader
517 if (llvm::opt::Arg *loader = parsedArgs.getLastArg(OPT_bundle_loader))
518 ctx.setBundleLoader(loader->getValue());
519
520 // Handle -sectalign segname sectname align
521 for (auto &alignArg : parsedArgs.filtered(OPT_sectalign)) {
522 const char* segName = alignArg->getValue(0);
523 const char* sectName = alignArg->getValue(1);
524 const char* alignStr = alignArg->getValue(2);
525 if ((alignStr[0] == '0') && (alignStr[1] == 'x'))
526 alignStr += 2;
527 unsigned long long alignValue;
528 if (llvm::getAsUnsignedInteger(alignStr, 16, alignValue)) {
529 diagnostics << "error: -sectalign alignment value '"
530 << alignStr << "' not a valid number\n";
531 return false;
532 }
533 uint16_t align = 1 << llvm::countTrailingZeros(alignValue);
534 if (!llvm::isPowerOf2_64(alignValue)) {
535 diagnostics << "warning: alignment for '-sectalign "
536 << segName << " " << sectName
537 << llvm::format(" 0x%llX", alignValue)
538 << "' is not a power of two, using "
539 << llvm::format("0x%08X", align) << "\n";
540 }
541 ctx.addSectionAlignment(segName, sectName, align);
542 }
543
544 // Handle -mllvm
545 for (auto &llvmArg : parsedArgs.filtered(OPT_mllvm)) {
546 ctx.appendLLVMOption(llvmArg->getValue());
547 }
548
549 // Handle -print_atoms
550 if (parsedArgs.getLastArg(OPT_print_atoms))
551 ctx.setPrintAtoms();
552
553 // Handle -t (trace) option.
554 if (parsedArgs.getLastArg(OPT_t))
555 ctx.setLogInputFiles(true);
556
557 // Handle -demangle option.
558 if (parsedArgs.getLastArg(OPT_demangle))
559 ctx.setDemangleSymbols(true);
560
561 // Handle -keep_private_externs
562 if (parsedArgs.getLastArg(OPT_keep_private_externs)) {
563 ctx.setKeepPrivateExterns(true);
564 if (ctx.outputMachOType() != llvm::MachO::MH_OBJECT)
565 diagnostics << "warning: -keep_private_externs only used in -r mode\n";
566 }
567
568 // Handle -dependency_info <path> used by Xcode.
569 if (llvm::opt::Arg *depInfo = parsedArgs.getLastArg(OPT_dependency_info)) {
570 if (std::error_code ec = ctx.createDependencyFile(depInfo->getValue())) {
571 diagnostics << "warning: " << ec.message()
572 << ", processing '-dependency_info "
573 << depInfo->getValue()
574 << "'\n";
575 }
576 }
577
578 // In -test_file_usage mode, we'll be given an explicit list of paths that
579 // exist. We'll also be expected to print out information about how we located
580 // libraries and so on that the user specified, but not to actually do any
581 // linking.
582 if (parsedArgs.getLastArg(OPT_test_file_usage)) {
583 ctx.setTestingFileUsage();
584
585 // With paths existing by fiat, linking is not going to end well.
586 ctx.setDoNothing(true);
587
588 // Only bother looking for an existence override if we're going to use it.
589 for (auto existingPath : parsedArgs.filtered(OPT_path_exists)) {
590 ctx.addExistingPathForDebug(existingPath->getValue());
591 }
592 }
593
594 // Register possible input file parsers.
595 if (!ctx.doNothing()) {
596 ctx.registry().addSupportMachOObjects(ctx);
597 ctx.registry().addSupportArchives(ctx.logInputFiles());
598 ctx.registry().addSupportYamlFiles();
599 }
600
601 // Now construct the set of library search directories, following ld64's
602 // baroque set of accumulated hacks. Mostly, the algorithm constructs
603 // { syslibroots } x { libpaths }
604 //
605 // Unfortunately, there are numerous exceptions:
606 // 1. Only absolute paths get modified by syslibroot options.
607 // 2. If there is just 1 -syslibroot, system paths not found in it are
608 // skipped.
609 // 3. If the last -syslibroot is "/", all of them are ignored entirely.
610 // 4. If { syslibroots } x path == {}, the original path is kept.
611 std::vector<StringRef> sysLibRoots;
612 for (auto syslibRoot : parsedArgs.filtered(OPT_syslibroot)) {
613 sysLibRoots.push_back(syslibRoot->getValue());
614 }
615 if (!sysLibRoots.empty()) {
616 // Ignore all if last -syslibroot is "/".
617 if (sysLibRoots.back() != "/")
618 ctx.setSysLibRoots(sysLibRoots);
619 }
620
621 // Paths specified with -L come first, and are not considered system paths for
622 // the case where there is precisely 1 -syslibroot.
623 for (auto libPath : parsedArgs.filtered(OPT_L)) {
624 ctx.addModifiedSearchDir(libPath->getValue());
625 }
626
627 // Process -F directories (where to look for frameworks).
628 for (auto fwPath : parsedArgs.filtered(OPT_F)) {
629 ctx.addFrameworkSearchDir(fwPath->getValue());
630 }
631
632 // -Z suppresses the standard search paths.
633 if (!parsedArgs.hasArg(OPT_Z)) {
634 ctx.addModifiedSearchDir("/usr/lib", true);
635 ctx.addModifiedSearchDir("/usr/local/lib", true);
636 ctx.addFrameworkSearchDir("/Library/Frameworks", true);
637 ctx.addFrameworkSearchDir("/System/Library/Frameworks", true);
638 }
639
640 // Now that we've constructed the final set of search paths, print out those
641 // search paths in verbose mode.
642 if (parsedArgs.getLastArg(OPT_v)) {
643 diagnostics << "Library search paths:\n";
644 for (auto path : ctx.searchDirs()) {
645 diagnostics << " " << path << '\n';
646 }
647 diagnostics << "Framework search paths:\n";
648 for (auto path : ctx.frameworkDirs()) {
649 diagnostics << " " << path << '\n';
650 }
651 }
652
653 // Handle -exported_symbols_list <file>
654 for (auto expFile : parsedArgs.filtered(OPT_exported_symbols_list)) {
655 if (ctx.exportMode() == MachOLinkingContext::ExportMode::blackList) {
656 diagnostics << "error: -exported_symbols_list cannot be combined "
657 << "with -unexported_symbol[s_list]\n";
658 return false;
659 }
660 ctx.setExportMode(MachOLinkingContext::ExportMode::whiteList);
661 if (std::error_code ec = parseExportsList(expFile->getValue(), ctx,
662 diagnostics)) {
663 diagnostics << "error: " << ec.message()
664 << ", processing '-exported_symbols_list "
665 << expFile->getValue()
666 << "'\n";
667 return false;
668 }
669 }
670
671 // Handle -exported_symbol <symbol>
672 for (auto symbol : parsedArgs.filtered(OPT_exported_symbol)) {
673 if (ctx.exportMode() == MachOLinkingContext::ExportMode::blackList) {
674 diagnostics << "error: -exported_symbol cannot be combined "
675 << "with -unexported_symbol[s_list]\n";
676 return false;
677 }
678 ctx.setExportMode(MachOLinkingContext::ExportMode::whiteList);
679 ctx.addExportSymbol(symbol->getValue());
680 }
681
682 // Handle -unexported_symbols_list <file>
683 for (auto expFile : parsedArgs.filtered(OPT_unexported_symbols_list)) {
684 if (ctx.exportMode() == MachOLinkingContext::ExportMode::whiteList) {
685 diagnostics << "error: -unexported_symbols_list cannot be combined "
686 << "with -exported_symbol[s_list]\n";
687 return false;
688 }
689 ctx.setExportMode(MachOLinkingContext::ExportMode::blackList);
690 if (std::error_code ec = parseExportsList(expFile->getValue(), ctx,
691 diagnostics)) {
692 diagnostics << "error: " << ec.message()
693 << ", processing '-unexported_symbols_list "
694 << expFile->getValue()
695 << "'\n";
696 return false;
697 }
698 }
699
700 // Handle -unexported_symbol <symbol>
701 for (auto symbol : parsedArgs.filtered(OPT_unexported_symbol)) {
702 if (ctx.exportMode() == MachOLinkingContext::ExportMode::whiteList) {
703 diagnostics << "error: -unexported_symbol cannot be combined "
704 << "with -exported_symbol[s_list]\n";
705 return false;
706 }
707 ctx.setExportMode(MachOLinkingContext::ExportMode::blackList);
708 ctx.addExportSymbol(symbol->getValue());
709 }
710
711 // Handle obosolete -multi_module and -single_module
712 if (llvm::opt::Arg *mod =
713 parsedArgs.getLastArg(OPT_multi_module, OPT_single_module)) {
714 if (mod->getOption().getID() == OPT_multi_module) {
715 diagnostics << "warning: -multi_module is obsolete and being ignored\n";
716 }
717 else {
718 if (ctx.outputMachOType() != llvm::MachO::MH_DYLIB) {
719 diagnostics << "warning: -single_module being ignored. "
720 "It is only for use when producing a dylib\n";
721 }
722 }
723 }
724
725 // Handle obsolete ObjC options: -objc_gc_compaction, -objc_gc, -objc_gc_only
726 if (parsedArgs.getLastArg(OPT_objc_gc_compaction)) {
727 diagnostics << "error: -objc_gc_compaction is not supported\n";
728 return false;
729 }
730
731 if (parsedArgs.getLastArg(OPT_objc_gc)) {
732 diagnostics << "error: -objc_gc is not supported\n";
733 return false;
734 }
735
736 if (parsedArgs.getLastArg(OPT_objc_gc_only)) {
737 diagnostics << "error: -objc_gc_only is not supported\n";
738 return false;
739 }
740
741 // Handle -pie or -no_pie
742 if (llvm::opt::Arg *pie = parsedArgs.getLastArg(OPT_pie, OPT_no_pie)) {
743 switch (ctx.outputMachOType()) {
744 case llvm::MachO::MH_EXECUTE:
745 switch (ctx.os()) {
746 case MachOLinkingContext::OS::macOSX:
747 if ((minOSVersion < 0x000A0500) &&
748 (pie->getOption().getID() == OPT_pie)) {
749 diagnostics << "-pie can only be used when targeting "
750 "Mac OS X 10.5 or later\n";
751 return false;
752 }
753 break;
754 case MachOLinkingContext::OS::iOS:
755 if ((minOSVersion < 0x00040200) &&
756 (pie->getOption().getID() == OPT_pie)) {
757 diagnostics << "-pie can only be used when targeting "
758 "iOS 4.2 or later\n";
759 return false;
760 }
761 break;
762 case MachOLinkingContext::OS::iOS_simulator:
763 if (pie->getOption().getID() == OPT_no_pie) {
764 diagnostics << "iOS simulator programs must be built PIE\n";
765 return false;
766 }
767 break;
768 case MachOLinkingContext::OS::unknown:
769 break;
770 }
771 ctx.setPIE(pie->getOption().getID() == OPT_pie);
772 break;
773 case llvm::MachO::MH_PRELOAD:
774 break;
775 case llvm::MachO::MH_DYLIB:
776 case llvm::MachO::MH_BUNDLE:
777 diagnostics << "warning: " << pie->getSpelling() << " being ignored. "
778 << "It is only used when linking main executables\n";
779 break;
780 default:
781 diagnostics << pie->getSpelling()
782 << " can only used when linking main executables\n";
783 return false;
784 }
785 }
786
787 // Handle -version_load_command or -no_version_load_command
788 {
789 bool flagOn = false;
790 bool flagOff = false;
791 if (auto *arg = parsedArgs.getLastArg(OPT_version_load_command,
792 OPT_no_version_load_command)) {
793 flagOn = arg->getOption().getID() == OPT_version_load_command;
794 flagOff = arg->getOption().getID() == OPT_no_version_load_command;
795 }
796
797 // default to adding version load command for dynamic code,
798 // static code must opt-in
799 switch (ctx.outputMachOType()) {
800 case llvm::MachO::MH_OBJECT:
801 ctx.setGenerateVersionLoadCommand(false);
802 break;
803 case llvm::MachO::MH_EXECUTE:
804 // dynamic executables default to generating a version load command,
805 // while static exectuables only generate it if required.
806 if (isStaticExecutable) {
807 if (flagOn)
808 ctx.setGenerateVersionLoadCommand(true);
809 } else {
810 if (!flagOff)
811 ctx.setGenerateVersionLoadCommand(true);
812 }
813 break;
814 case llvm::MachO::MH_PRELOAD:
815 case llvm::MachO::MH_KEXT_BUNDLE:
816 if (flagOn)
817 ctx.setGenerateVersionLoadCommand(true);
818 break;
819 case llvm::MachO::MH_DYLINKER:
820 case llvm::MachO::MH_DYLIB:
821 case llvm::MachO::MH_BUNDLE:
822 if (!flagOff)
823 ctx.setGenerateVersionLoadCommand(true);
824 break;
825 case llvm::MachO::MH_FVMLIB:
826 case llvm::MachO::MH_DYLDLINK:
827 case llvm::MachO::MH_DYLIB_STUB:
828 case llvm::MachO::MH_DSYM:
829 // We don't generate load commands for these file types, even if
830 // forced on.
831 break;
832 }
833 }
834
835 // Handle -function_starts or -no_function_starts
836 {
837 bool flagOn = false;
838 bool flagOff = false;
839 if (auto *arg = parsedArgs.getLastArg(OPT_function_starts,
840 OPT_no_function_starts)) {
841 flagOn = arg->getOption().getID() == OPT_function_starts;
842 flagOff = arg->getOption().getID() == OPT_no_function_starts;
843 }
844
845 // default to adding functions start for dynamic code, static code must
846 // opt-in
847 switch (ctx.outputMachOType()) {
848 case llvm::MachO::MH_OBJECT:
849 ctx.setGenerateFunctionStartsLoadCommand(false);
850 break;
851 case llvm::MachO::MH_EXECUTE:
852 // dynamic executables default to generating a version load command,
853 // while static exectuables only generate it if required.
854 if (isStaticExecutable) {
855 if (flagOn)
856 ctx.setGenerateFunctionStartsLoadCommand(true);
857 } else {
858 if (!flagOff)
859 ctx.setGenerateFunctionStartsLoadCommand(true);
860 }
861 break;
862 case llvm::MachO::MH_PRELOAD:
863 case llvm::MachO::MH_KEXT_BUNDLE:
864 if (flagOn)
865 ctx.setGenerateFunctionStartsLoadCommand(true);
866 break;
867 case llvm::MachO::MH_DYLINKER:
868 case llvm::MachO::MH_DYLIB:
869 case llvm::MachO::MH_BUNDLE:
870 if (!flagOff)
871 ctx.setGenerateFunctionStartsLoadCommand(true);
872 break;
873 case llvm::MachO::MH_FVMLIB:
874 case llvm::MachO::MH_DYLDLINK:
875 case llvm::MachO::MH_DYLIB_STUB:
876 case llvm::MachO::MH_DSYM:
877 // We don't generate load commands for these file types, even if
878 // forced on.
879 break;
880 }
881 }
882
883 // Handle -data_in_code_info or -no_data_in_code_info
884 {
885 bool flagOn = false;
886 bool flagOff = false;
887 if (auto *arg = parsedArgs.getLastArg(OPT_data_in_code_info,
888 OPT_no_data_in_code_info)) {
889 flagOn = arg->getOption().getID() == OPT_data_in_code_info;
890 flagOff = arg->getOption().getID() == OPT_no_data_in_code_info;
891 }
892
893 // default to adding data in code for dynamic code, static code must
894 // opt-in
895 switch (ctx.outputMachOType()) {
896 case llvm::MachO::MH_OBJECT:
897 if (!flagOff)
898 ctx.setGenerateDataInCodeLoadCommand(true);
899 break;
900 case llvm::MachO::MH_EXECUTE:
901 // dynamic executables default to generating a version load command,
902 // while static exectuables only generate it if required.
903 if (isStaticExecutable) {
904 if (flagOn)
905 ctx.setGenerateDataInCodeLoadCommand(true);
906 } else {
907 if (!flagOff)
908 ctx.setGenerateDataInCodeLoadCommand(true);
909 }
910 break;
911 case llvm::MachO::MH_PRELOAD:
912 case llvm::MachO::MH_KEXT_BUNDLE:
913 if (flagOn)
914 ctx.setGenerateDataInCodeLoadCommand(true);
915 break;
916 case llvm::MachO::MH_DYLINKER:
917 case llvm::MachO::MH_DYLIB:
918 case llvm::MachO::MH_BUNDLE:
919 if (!flagOff)
920 ctx.setGenerateDataInCodeLoadCommand(true);
921 break;
922 case llvm::MachO::MH_FVMLIB:
923 case llvm::MachO::MH_DYLDLINK:
924 case llvm::MachO::MH_DYLIB_STUB:
925 case llvm::MachO::MH_DSYM:
926 // We don't generate load commands for these file types, even if
927 // forced on.
928 break;
929 }
930 }
931
932 // Handle sdk_version
933 if (llvm::opt::Arg *arg = parsedArgs.getLastArg(OPT_sdk_version)) {
934 uint32_t sdkVersion = 0;
935 if (MachOLinkingContext::parsePackedVersion(arg->getValue(),
936 sdkVersion)) {
937 diagnostics << "error: malformed sdkVersion value\n";
938 return false;
939 }
940 ctx.setSdkVersion(sdkVersion);
941 } else if (ctx.generateVersionLoadCommand()) {
942 // If we don't have an sdk version, but were going to emit a load command
943 // with min_version, then we need to give an warning as we have no sdk
944 // version to put in that command.
945 // FIXME: We need to decide whether to make this an error.
946 diagnostics << "warning: -sdk_version is required when emitting "
947 "min version load command. "
948 "Setting sdk version to match provided min version\n";
949 ctx.setSdkVersion(ctx.osMinVersion());
950 }
951
952 // Handle source_version
953 if (llvm::opt::Arg *arg = parsedArgs.getLastArg(OPT_source_version)) {
954 uint64_t version = 0;
955 if (MachOLinkingContext::parsePackedVersion(arg->getValue(),
956 version)) {
957 diagnostics << "error: malformed source_version value\n";
958 return false;
959 }
960 ctx.setSourceVersion(version);
961 }
962
963 // Handle stack_size
964 if (llvm::opt::Arg *stackSize = parsedArgs.getLastArg(OPT_stack_size)) {
965 uint64_t stackSizeVal;
966 if (parseNumberBase16(stackSize->getValue(), stackSizeVal)) {
967 diagnostics << "error: stack_size expects a hex number\n";
968 return false;
969 }
970 if ((stackSizeVal % ctx.pageSize()) != 0) {
971 diagnostics << "error: stack_size must be a multiple of page size ("
972 << "0x" << llvm::utohexstr(ctx.pageSize()) << ")\n";
973 return false;
974 }
975
976 ctx.setStackSize(stackSizeVal);
977 }
978
979 // Handle debug info handling options: -S
980 if (parsedArgs.hasArg(OPT_S))
981 ctx.setDebugInfoMode(MachOLinkingContext::DebugInfoMode::noDebugMap);
982
983 // Handle -order_file <file>
984 for (auto orderFile : parsedArgs.filtered(OPT_order_file)) {
985 if (std::error_code ec = parseOrderFile(orderFile->getValue(), ctx,
986 diagnostics)) {
987 diagnostics << "error: " << ec.message()
988 << ", processing '-order_file "
989 << orderFile->getValue()
990 << "'\n";
991 return false;
992 }
993 }
994
995 // Handle -flat_namespace.
996 if (llvm::opt::Arg *ns =
997 parsedArgs.getLastArg(OPT_flat_namespace, OPT_twolevel_namespace)) {
998 if (ns->getOption().getID() == OPT_flat_namespace)
999 ctx.setUseFlatNamespace(true);
1000 }
1001
1002 // Handle -undefined
1003 if (llvm::opt::Arg *undef = parsedArgs.getLastArg(OPT_undefined)) {
1004 MachOLinkingContext::UndefinedMode UndefMode;
1005 if (StringRef(undef->getValue()).equals("error"))
1006 UndefMode = MachOLinkingContext::UndefinedMode::error;
1007 else if (StringRef(undef->getValue()).equals("warning"))
1008 UndefMode = MachOLinkingContext::UndefinedMode::warning;
1009 else if (StringRef(undef->getValue()).equals("suppress"))
1010 UndefMode = MachOLinkingContext::UndefinedMode::suppress;
1011 else if (StringRef(undef->getValue()).equals("dynamic_lookup"))
1012 UndefMode = MachOLinkingContext::UndefinedMode::dynamicLookup;
1013 else {
1014 diagnostics << "error: invalid option to -undefined "
1015 "[ warning | error | suppress | dynamic_lookup ]\n";
1016 return false;
1017 }
1018
1019 if (ctx.useFlatNamespace()) {
1020 // If we're using -flat_namespace then 'warning', 'suppress' and
1021 // 'dynamic_lookup' are all equivalent, so map them to 'suppress'.
1022 if (UndefMode != MachOLinkingContext::UndefinedMode::error)
1023 UndefMode = MachOLinkingContext::UndefinedMode::suppress;
1024 } else {
1025 // If we're using -twolevel_namespace then 'warning' and 'suppress' are
1026 // illegal. Emit a diagnostic if they've been (mis)used.
1027 if (UndefMode == MachOLinkingContext::UndefinedMode::warning ||
1028 UndefMode == MachOLinkingContext::UndefinedMode::suppress) {
1029 diagnostics << "error: can't use -undefined warning or suppress with "
1030 "-twolevel_namespace\n";
1031 return false;
1032 }
1033 }
1034
1035 ctx.setUndefinedMode(UndefMode);
1036 }
1037
1038 // Handle -no_objc_category_merging.
1039 if (parsedArgs.getLastArg(OPT_no_objc_category_merging))
1040 ctx.setMergeObjCCategories(false);
1041
1042 // Handle -rpath <path>
1043 if (parsedArgs.hasArg(OPT_rpath)) {
1044 switch (ctx.outputMachOType()) {
1045 case llvm::MachO::MH_EXECUTE:
1046 case llvm::MachO::MH_DYLIB:
1047 case llvm::MachO::MH_BUNDLE:
1048 if (!ctx.minOS("10.5", "2.0")) {
1049 if (ctx.os() == MachOLinkingContext::OS::macOSX) {
1050 diagnostics << "error: -rpath can only be used when targeting "
1051 "OS X 10.5 or later\n";
1052 } else {
1053 diagnostics << "error: -rpath can only be used when targeting "
1054 "iOS 2.0 or later\n";
1055 }
1056 return false;
1057 }
1058 break;
1059 default:
1060 diagnostics << "error: -rpath can only be used when creating "
1061 "a dynamic final linked image\n";
1062 return false;
1063 }
1064
1065 for (auto rPath : parsedArgs.filtered(OPT_rpath)) {
1066 ctx.addRpath(rPath->getValue());
1067 }
1068 }
1069
1070 // Parse the LLVM options before we process files in case the file handling
1071 // makes use of things like DEBUG().
1072 parseLLVMOptions(ctx);
1073
1074 // Handle input files and sectcreate.
1075 for (auto &arg : parsedArgs) {
1076 bool upward;
1077 llvm::Optional<StringRef> resolvedPath;
1078 switch (arg->getOption().getID()) {
1079 default:
1080 continue;
1081 case OPT_INPUT:
1082 addFile(arg->getValue(), ctx, globalWholeArchive, false, diagnostics);
1083 break;
1084 case OPT_upward_library:
1085 addFile(arg->getValue(), ctx, false, true, diagnostics);
1086 break;
1087 case OPT_force_load:
1088 addFile(arg->getValue(), ctx, true, false, diagnostics);
1089 break;
1090 case OPT_l:
1091 case OPT_upward_l:
1092 upward = (arg->getOption().getID() == OPT_upward_l);
1093 resolvedPath = ctx.searchLibrary(arg->getValue());
1094 if (!resolvedPath) {
1095 diagnostics << "Unable to find library for " << arg->getSpelling()
1096 << arg->getValue() << "\n";
1097 return false;
1098 } else if (ctx.testingFileUsage()) {
1099 diagnostics << "Found " << (upward ? "upward " : " ") << "library "
1100 << canonicalizePath(resolvedPath.getValue()) << '\n';
1101 }
1102 addFile(resolvedPath.getValue(), ctx, globalWholeArchive,
1103 upward, diagnostics);
1104 break;
1105 case OPT_framework:
1106 case OPT_upward_framework:
1107 upward = (arg->getOption().getID() == OPT_upward_framework);
1108 resolvedPath = ctx.findPathForFramework(arg->getValue());
1109 if (!resolvedPath) {
1110 diagnostics << "Unable to find framework for "
1111 << arg->getSpelling() << " " << arg->getValue() << "\n";
1112 return false;
1113 } else if (ctx.testingFileUsage()) {
1114 diagnostics << "Found " << (upward ? "upward " : " ") << "framework "
1115 << canonicalizePath(resolvedPath.getValue()) << '\n';
1116 }
1117 addFile(resolvedPath.getValue(), ctx, globalWholeArchive,
1118 upward, diagnostics);
1119 break;
1120 case OPT_filelist:
1121 if (auto ec = loadFileList(arg->getValue(),
1122 ctx, globalWholeArchive,
1123 diagnostics)) {
1124 handleAllErrors(std::move(ec), [&](const llvm::ErrorInfoBase &EI) {
1125 diagnostics << "error: ";
1126 EI.log(diagnostics);
1127 diagnostics << ", processing '-filelist " << arg->getValue() << "'\n";
1128 });
1129 return false;
1130 }
1131 break;
1132 case OPT_sectcreate: {
1133 const char* seg = arg->getValue(0);
1134 const char* sect = arg->getValue(1);
1135 const char* fileName = arg->getValue(2);
1136
1137 ErrorOr<std::unique_ptr<MemoryBuffer>> contentOrErr =
1138 MemoryBuffer::getFile(fileName);
1139
1140 if (!contentOrErr) {
1141 diagnostics << "error: can't open -sectcreate file " << fileName << "\n";
1142 return false;
1143 }
1144
1145 ctx.addSectCreateSection(seg, sect, std::move(*contentOrErr));
1146 }
1147 break;
1148 }
1149 }
1150
1151 if (ctx.getNodes().empty()) {
1152 diagnostics << "No input files\n";
1153 return false;
1154 }
1155
1156 // Validate the combination of options used.
1157 return ctx.validate(diagnostics);
1158}
1159
1160static void createFiles(MachOLinkingContext &ctx, bool Implicit) {
1161 std::vector<std::unique_ptr<File>> Files;
1162 if (Implicit)
1163 ctx.createImplicitFiles(Files);
1164 else
1165 ctx.createInternalFiles(Files);
1166 for (auto i = Files.rbegin(), e = Files.rend(); i != e; ++i) {
1167 auto &members = ctx.getNodes();
1168 members.insert(members.begin(), llvm::make_unique<FileNode>(std::move(*i)));
1169 }
1170}
1171
1172/// This is where the link is actually performed.
1173bool link(llvm::ArrayRef<const char *> args, raw_ostream &diagnostics) {
1174 MachOLinkingContext ctx;
1175 if (!parse(args, ctx, diagnostics))
1176 return false;
1177 if (ctx.doNothing())
1178 return true;
1179 if (ctx.getNodes().empty())
1180 return false;
1181
1182 for (std::unique_ptr<Node> &ie : ctx.getNodes())
1183 if (FileNode *node = dyn_cast<FileNode>(ie.get()))
1184 node->getFile()->parse();
1185
1186 createFiles(ctx, false /* Implicit */);
1187
1188 // Give target a chance to add files
1189 createFiles(ctx, true /* Implicit */);
1190
1191 // Give target a chance to postprocess input files.
1192 // Mach-O uses this chance to move all object files before library files.
1193 ctx.finalizeInputFiles();
1194
1195 // Do core linking.
1196 ScopedTask resolveTask(getDefaultDomain(), "Resolve");
1197 Resolver resolver(ctx);
1198 if (!resolver.resolve())
1199 return false;
1200 SimpleFile *merged = nullptr;
1201 {
1202 std::unique_ptr<SimpleFile> mergedFile = resolver.resultFile();
1203 merged = mergedFile.get();
1204 auto &members = ctx.getNodes();
1205 members.insert(members.begin(),
1206 llvm::make_unique<FileNode>(std::move(mergedFile)));
1207 }
1208 resolveTask.end();
1209
1210 // Run passes on linked atoms.
1211 ScopedTask passTask(getDefaultDomain(), "Passes");
1212 PassManager pm;
1213 ctx.addPasses(pm);
1214 if (auto ec = pm.runOnFile(*merged)) {
1215 // FIXME: This should be passed to logAllUnhandledErrors but it needs
1216 // to be passed a Twine instead of a string.
1217 diagnostics << "Failed to run passes on file '" << ctx.outputPath()
1218 << "': ";
1219 logAllUnhandledErrors(std::move(ec), diagnostics, std::string());
1220 return false;
1221 }
1222
1223 passTask.end();
1224
1225 // Give linked atoms to Writer to generate output file.
1226 ScopedTask writeTask(getDefaultDomain(), "Write");
1227 if (auto ec = ctx.writeFile(*merged)) {
1228 // FIXME: This should be passed to logAllUnhandledErrors but it needs
1229 // to be passed a Twine instead of a string.
1230 diagnostics << "Failed to write file '" << ctx.outputPath() << "': ";
1231 logAllUnhandledErrors(std::move(ec), diagnostics, std::string());
1232 return false;
1233 }
1234
1235 return true;
1236}
1237
1238} // end namespace mach_o
1239} // end namespace lld
deps/lld/lib/Driver/DarwinLdOptions.td created+242
......@@ -0,0 +1,242 @@
1include "llvm/Option/OptParser.td"
2
3
4// output kinds
5def grp_kind : OptionGroup<"outs">, HelpText<"OUTPUT KIND">;
6def relocatable : Flag<["-"], "r">,
7 HelpText<"Create relocatable object file">, Group<grp_kind>;
8def static : Flag<["-"], "static">,
9 HelpText<"Create static executable">, Group<grp_kind>;
10def dynamic : Flag<["-"], "dynamic">,
11 HelpText<"Create dynamic executable (default)">,Group<grp_kind>;
12def dylib : Flag<["-"], "dylib">,
13 HelpText<"Create dynamic library">, Group<grp_kind>;
14def bundle : Flag<["-"], "bundle">,
15 HelpText<"Create dynamic bundle">, Group<grp_kind>;
16def execute : Flag<["-"], "execute">,
17 HelpText<"Create main executable (default)">, Group<grp_kind>;
18def preload : Flag<["-"], "preload">,
19 HelpText<"Create binary for use with embedded systems">, Group<grp_kind>;
20
21// optimizations
22def grp_opts : OptionGroup<"opts">, HelpText<"OPTIMIZATIONS">;
23def dead_strip : Flag<["-"], "dead_strip">,
24 HelpText<"Remove unreference code and data">, Group<grp_opts>;
25def macosx_version_min : Separate<["-"], "macosx_version_min">,
26 MetaVarName<"<version>">,
27 HelpText<"Minimum Mac OS X version">, Group<grp_opts>;
28def ios_version_min : Separate<["-"], "ios_version_min">,
29 MetaVarName<"<version>">,
30 HelpText<"Minimum iOS version">, Group<grp_opts>;
31def iphoneos_version_min : Separate<["-"], "iphoneos_version_min">,
32 Alias<ios_version_min>;
33def ios_simulator_version_min : Separate<["-"], "ios_simulator_version_min">,
34 MetaVarName<"<version>">,
35 HelpText<"Minimum iOS simulator version">, Group<grp_opts>;
36def sdk_version : Separate<["-"], "sdk_version">,
37 MetaVarName<"<version>">,
38 HelpText<"SDK version">, Group<grp_opts>;
39def source_version : Separate<["-"], "source_version">,
40 MetaVarName<"<version>">,
41 HelpText<"Source version">, Group<grp_opts>;
42def version_load_command : Flag<["-"], "version_load_command">,
43 HelpText<"Force generation of a version load command">, Group<grp_opts>;
44def no_version_load_command : Flag<["-"], "no_version_load_command">,
45 HelpText<"Disable generation of a version load command">, Group<grp_opts>;
46def function_starts : Flag<["-"], "function_starts">,
47 HelpText<"Force generation of a function starts load command">,
48 Group<grp_opts>;
49def no_function_starts : Flag<["-"], "no_function_starts">,
50 HelpText<"Disable generation of a function starts load command">,
51 Group<grp_opts>;
52def data_in_code_info : Flag<["-"], "data_in_code_info">,
53 HelpText<"Force generation of a data in code load command">,
54 Group<grp_opts>;
55def no_data_in_code_info : Flag<["-"], "no_data_in_code_info">,
56 HelpText<"Disable generation of a data in code load command">,
57 Group<grp_opts>;
58def mllvm : Separate<["-"], "mllvm">,
59 MetaVarName<"<option>">,
60 HelpText<"Options to pass to LLVM during LTO">, Group<grp_opts>;
61def exported_symbols_list : Separate<["-"], "exported_symbols_list">,
62 MetaVarName<"<file-path>">,
63 HelpText<"Restricts which symbols will be exported">, Group<grp_opts>;
64def exported_symbol : Separate<["-"], "exported_symbol">,
65 MetaVarName<"<symbol>">,
66 HelpText<"Restricts which symbols will be exported">, Group<grp_opts>;
67def unexported_symbols_list : Separate<["-"], "unexported_symbols_list">,
68 MetaVarName<"<file-path>">,
69 HelpText<"Lists symbols that should not be exported">, Group<grp_opts>;
70def unexported_symbol : Separate<["-"], "unexported_symbol">,
71 MetaVarName<"<symbol>">,
72 HelpText<"A symbol which should not be exported">, Group<grp_opts>;
73def keep_private_externs : Flag<["-"], "keep_private_externs">,
74 HelpText<"Private extern (hidden) symbols should not be transformed "
75 "into local symbols">, Group<grp_opts>;
76def order_file : Separate<["-"], "order_file">,
77 MetaVarName<"<file-path>">,
78 HelpText<"re-order and move specified symbols to start of their section">,
79 Group<grp_opts>;
80def flat_namespace : Flag<["-"], "flat_namespace">,
81 HelpText<"Resolves symbols in any (transitively) linked dynamic libraries. "
82 "Source libraries are not recorded: dyld will re-search all "
83 "images at runtime and use the first definition found.">,
84 Group<grp_opts>;
85def twolevel_namespace : Flag<["-"], "twolevel_namespace">,
86 HelpText<"Resolves symbols in listed libraries only. Source libraries are "
87 "recorded in the symbol table.">,
88 Group<grp_opts>;
89def undefined : Separate<["-"], "undefined">,
90 MetaVarName<"<undefined>">,
91 HelpText<"Determines how undefined symbols are handled.">,
92 Group<grp_opts>;
93def no_objc_category_merging : Flag<["-"], "no_objc_category_merging">,
94 HelpText<"Disables the optimisation which merges Objective-C categories "
95 "on a class in to the class itself.">,
96 Group<grp_opts>;
97
98// main executable options
99def grp_main : OptionGroup<"opts">, HelpText<"MAIN EXECUTABLE OPTIONS">;
100def entry : Separate<["-"], "e">,
101 MetaVarName<"<entry-name>">,
102 HelpText<"entry symbol name">,Group<grp_main>;
103def pie : Flag<["-"], "pie">,
104 HelpText<"Create Position Independent Executable (for ASLR)">,
105 Group<grp_main>;
106def no_pie : Flag<["-"], "no_pie">,
107 HelpText<"Do not create Position Independent Executable">,
108 Group<grp_main>;
109def stack_size : Separate<["-"], "stack_size">,
110 HelpText<"Specifies the maximum stack size for the main thread in a program. "
111 "Must be a page-size multiple. (default=8Mb)">,
112 Group<grp_main>;
113def export_dynamic : Flag<["-"], "export_dynamic">,
114 HelpText<"Preserves all global symbols in main executables during LTO">,
115 Group<grp_main>;
116
117// dylib executable options
118def grp_dylib : OptionGroup<"opts">, HelpText<"DYLIB EXECUTABLE OPTIONS">;
119def install_name : Separate<["-"], "install_name">,
120 MetaVarName<"<path>">,
121 HelpText<"The dylib's install name">, Group<grp_dylib>;
122def mark_dead_strippable_dylib : Flag<["-"], "mark_dead_strippable_dylib">,
123 HelpText<"Marks the dylib as having no side effects during initialization">,
124 Group<grp_dylib>;
125def compatibility_version : Separate<["-"], "compatibility_version">,
126 MetaVarName<"<version>">,
127 HelpText<"The dylib's compatibility version">, Group<grp_dylib>;
128def current_version : Separate<["-"], "current_version">,
129 MetaVarName<"<version>">,
130 HelpText<"The dylib's current version">, Group<grp_dylib>;
131
132// dylib executable options - compatibility aliases
133def dylib_install_name : Separate<["-"], "dylib_install_name">,
134 Alias<install_name>;
135def dylib_compatibility_version : Separate<["-"], "dylib_compatibility_version">,
136 MetaVarName<"<version>">, Alias<compatibility_version>;
137def dylib_current_version : Separate<["-"], "dylib_current_version">,
138 MetaVarName<"<version>">, Alias<current_version>;
139
140// bundle executable options
141def grp_bundle : OptionGroup<"opts">, HelpText<"BUNDLE EXECUTABLE OPTIONS">;
142def bundle_loader : Separate<["-"], "bundle_loader">,
143 MetaVarName<"<path>">,
144 HelpText<"The executable that will be loading this Mach-O bundle">,
145 Group<grp_bundle>;
146
147// library options
148def grp_libs : OptionGroup<"libs">, HelpText<"LIBRARY OPTIONS">;
149def L : JoinedOrSeparate<["-"], "L">,
150 MetaVarName<"<dir>">,
151 HelpText<"Add directory to library search path">, Group<grp_libs>;
152def F : JoinedOrSeparate<["-"], "F">,
153 MetaVarName<"<dir>">,
154 HelpText<"Add directory to framework search path">, Group<grp_libs>;
155def Z : Flag<["-"], "Z">,
156 HelpText<"Do not search standard directories for libraries or frameworks">;
157def all_load : Flag<["-"], "all_load">,
158 HelpText<"Forces all members of all static libraries to be loaded">,
159 Group<grp_libs>;
160def force_load : Separate<["-"], "force_load">,
161 MetaVarName<"<library-path>">,
162 HelpText<"Forces all members of specified static libraries to be loaded">,
163 Group<grp_libs>;
164def syslibroot : Separate<["-"], "syslibroot">, MetaVarName<"<dir>">,
165 HelpText<"Add path to SDK to all absolute library search paths">,
166 Group<grp_libs>;
167
168// Input options
169def l : Joined<["-"], "l">,
170 MetaVarName<"<libname>">,
171 HelpText<"Base name of library searched for in -L directories">;
172def upward_l : Joined<["-"], "upward-l">,
173 MetaVarName<"<libname>">,
174 HelpText<"Base name of upward library searched for in -L directories">;
175def framework : Separate<["-"], "framework">,
176 MetaVarName<"<name>">,
177 HelpText<"Base name of framework searched for in -F directories">;
178def upward_framework : Separate<["-"], "upward_framework">,
179 MetaVarName<"<name>">,
180 HelpText<"Base name of upward framework searched for in -F directories">;
181def upward_library : Separate<["-"], "upward_library">,
182 MetaVarName<"<path>">,
183 HelpText<"path to upward dylib to link with">;
184def filelist : Separate<["-"], "filelist">,
185 MetaVarName<"<path>">,
186 HelpText<"file containing paths to input files">;
187
188
189// test case options
190def print_atoms : Flag<["-"], "print_atoms">,
191 HelpText<"Emit output as yaml atoms">;
192def test_file_usage : Flag<["-"], "test_file_usage">,
193 HelpText<"Only files specified by -file_exists are considered to exist. "
194 "Print which files would be used">;
195def path_exists : Separate<["-"], "path_exists">,
196 MetaVarName<"<path>">,
197 HelpText<"Used with -test_file_usage to declare a path">;
198
199
200// general options
201def output : Separate<["-"], "o">,
202 MetaVarName<"<path>">,
203 HelpText<"Output file path">;
204def arch : Separate<["-"], "arch">,
205 MetaVarName<"<arch-name>">,
206 HelpText<"Architecture to link">;
207def sectalign : MultiArg<["-"], "sectalign", 3>,
208 MetaVarName<"<segname> <sectname> <alignment>">,
209 HelpText<"Alignment for segment/section">;
210def sectcreate : MultiArg<["-"], "sectcreate", 3>,
211 MetaVarName<"<segname> <sectname> <file>">,
212 HelpText<"Create section <segname>/<sectname> from contents of <file>">;
213def image_base : Separate<["-"], "image_base">;
214def seg1addr : Separate<["-"], "seg1addr">, Alias<image_base>;
215def demangle : Flag<["-"], "demangle">,
216 HelpText<"Demangles symbol names in errors and warnings">;
217def dependency_info : Separate<["-"], "dependency_info">,
218 MetaVarName<"<file>">,
219 HelpText<"Write binary list of files used during link">;
220def S : Flag<["-"], "S">,
221 HelpText<"Remove debug information (STABS or DWARF) from the output file">;
222def rpath : Separate<["-"], "rpath">,
223 MetaVarName<"<path>">,
224 HelpText<"Add path to the runpath search path list for image being created">;
225
226def t : Flag<["-"], "t">,
227 HelpText<"Print the names of the input files as ld processes them">;
228def v : Flag<["-"], "v">,
229 HelpText<"Print linker information">;
230
231// Obsolete options
232def grp_obsolete : OptionGroup<"obsolete">, HelpText<"OBSOLETE OPTIONS">;
233def single_module : Flag<["-"], "single_module">,
234 HelpText<"Default for dylibs">, Group<grp_obsolete>;
235def multi_module : Flag<["-"], "multi_module">,
236 HelpText<"Unsupported way to build dylibs">, Group<grp_obsolete>;
237def objc_gc_compaction : Flag<["-"], "objc_gc_compaction">,
238 HelpText<"Unsupported ObjC GC option">, Group<grp_obsolete>;
239def objc_gc : Flag<["-"], "objc_gc">,
240 HelpText<"Unsupported ObjC GC option">, Group<grp_obsolete>;
241def objc_gc_only : Flag<["-"], "objc_gc_only">,
242 HelpText<"Unsupported ObjC GC option">, Group<grp_obsolete>;
deps/lld/lib/ReaderWriter/CMakeLists.txt created+21
......@@ -0,0 +1,21 @@
1add_subdirectory(MachO)
2add_subdirectory(YAML)
3
4if (MSVC)
5 add_definitions(-wd4062) # Suppress 'warning C4062: Enumerator has no associated handler in a switch statement.'
6endif()
7
8add_lld_library(lldReaderWriter
9 FileArchive.cpp
10
11 ADDITIONAL_HEADER_DIRS
12 ${LLD_INCLUDE_DIR}/lld/ReaderWriter
13
14 LINK_COMPONENTS
15 Object
16 Support
17
18 LINK_LIBS
19 lldCore
20 lldYAML
21 )
deps/lld/lib/ReaderWriter/FileArchive.cpp created+228
......@@ -0,0 +1,228 @@
1//===- lib/ReaderWriter/FileArchive.cpp -----------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lld/Core/ArchiveLibraryFile.h"
11#include "lld/Core/File.h"
12#include "lld/Core/LLVM.h"
13#include "lld/Core/Reader.h"
14#include "llvm/ADT/STLExtras.h"
15#include "llvm/ADT/StringRef.h"
16#include "llvm/BinaryFormat/Magic.h"
17#include "llvm/Object/Archive.h"
18#include "llvm/Object/Error.h"
19#include "llvm/Support/Debug.h"
20#include "llvm/Support/ErrorOr.h"
21#include "llvm/Support/FileSystem.h"
22#include "llvm/Support/Format.h"
23#include "llvm/Support/MemoryBuffer.h"
24#include "llvm/Support/raw_ostream.h"
25#include <memory>
26#include <set>
27#include <string>
28#include <system_error>
29#include <unordered_map>
30#include <utility>
31#include <vector>
32
33using llvm::object::Archive;
34using llvm::file_magic;
35using llvm::identify_magic;
36
37namespace lld {
38
39namespace {
40
41/// \brief The FileArchive class represents an Archive Library file
42class FileArchive : public lld::ArchiveLibraryFile {
43public:
44 FileArchive(std::unique_ptr<MemoryBuffer> mb, const Registry &reg,
45 StringRef path, bool logLoading)
46 : ArchiveLibraryFile(path), _mb(std::shared_ptr<MemoryBuffer>(mb.release())),
47 _registry(reg), _logLoading(logLoading) {}
48
49 /// \brief Check if any member of the archive contains an Atom with the
50 /// specified name and return the File object for that member, or nullptr.
51 File *find(StringRef name) override {
52 auto member = _symbolMemberMap.find(name);
53 if (member == _symbolMemberMap.end())
54 return nullptr;
55 Archive::Child c = member->second;
56
57 // Don't return a member already returned
58 Expected<StringRef> buf = c.getBuffer();
59 if (!buf) {
60 // TODO: Actually report errors helpfully.
61 consumeError(buf.takeError());
62 return nullptr;
63 }
64 const char *memberStart = buf->data();
65 if (_membersInstantiated.count(memberStart))
66 return nullptr;
67 _membersInstantiated.insert(memberStart);
68
69 std::unique_ptr<File> result;
70 if (instantiateMember(c, result))
71 return nullptr;
72
73 File *file = result.get();
74 _filesReturned.push_back(std::move(result));
75
76 // Give up the file pointer. It was stored and will be destroyed with destruction of FileArchive
77 return file;
78 }
79
80 /// \brief parse each member
81 std::error_code
82 parseAllMembers(std::vector<std::unique_ptr<File>> &result) override {
83 if (std::error_code ec = parse())
84 return ec;
85 llvm::Error err = llvm::Error::success();
86 for (auto mf = _archive->child_begin(err), me = _archive->child_end();
87 mf != me; ++mf) {
88 std::unique_ptr<File> file;
89 if (std::error_code ec = instantiateMember(*mf, file)) {
90 // err is Success (or we wouldn't be in the loop body) but we can't
91 // return without testing or consuming it.
92 consumeError(std::move(err));
93 return ec;
94 }
95 result.push_back(std::move(file));
96 }
97 if (err)
98 return errorToErrorCode(std::move(err));
99 return std::error_code();
100 }
101
102 const AtomRange<DefinedAtom> defined() const override {
103 return _noDefinedAtoms;
104 }
105
106 const AtomRange<UndefinedAtom> undefined() const override {
107 return _noUndefinedAtoms;
108 }
109
110 const AtomRange<SharedLibraryAtom> sharedLibrary() const override {
111 return _noSharedLibraryAtoms;
112 }
113
114 const AtomRange<AbsoluteAtom> absolute() const override {
115 return _noAbsoluteAtoms;
116 }
117
118 void clearAtoms() override {
119 _noDefinedAtoms.clear();
120 _noUndefinedAtoms.clear();
121 _noSharedLibraryAtoms.clear();
122 _noAbsoluteAtoms.clear();
123 }
124
125protected:
126 std::error_code doParse() override {
127 // Make Archive object which will be owned by FileArchive object.
128 llvm::Error Err = llvm::Error::success();
129 _archive.reset(new Archive(_mb->getMemBufferRef(), Err));
130 if (Err)
131 return errorToErrorCode(std::move(Err));
132 std::error_code ec;
133 if ((ec = buildTableOfContents()))
134 return ec;
135 return std::error_code();
136 }
137
138private:
139 std::error_code instantiateMember(Archive::Child member,
140 std::unique_ptr<File> &result) const {
141 Expected<llvm::MemoryBufferRef> mbOrErr = member.getMemoryBufferRef();
142 if (!mbOrErr)
143 return errorToErrorCode(mbOrErr.takeError());
144 llvm::MemoryBufferRef mb = mbOrErr.get();
145 std::string memberPath = (_archive->getFileName() + "("
146 + mb.getBufferIdentifier() + ")").str();
147
148 if (_logLoading)
149 llvm::errs() << memberPath << "\n";
150
151 std::unique_ptr<MemoryBuffer> memberMB(MemoryBuffer::getMemBuffer(
152 mb.getBuffer(), mb.getBufferIdentifier(), false));
153
154 ErrorOr<std::unique_ptr<File>> fileOrErr =
155 _registry.loadFile(std::move(memberMB));
156 if (std::error_code ec = fileOrErr.getError())
157 return ec;
158 result = std::move(fileOrErr.get());
159 if (std::error_code ec = result->parse())
160 return ec;
161 result->setArchivePath(_archive->getFileName());
162
163 // The memory buffer is co-owned by the archive file and the children,
164 // so that the bufffer is deallocated when all the members are destructed.
165 result->setSharedMemoryBuffer(_mb);
166 return std::error_code();
167 }
168
169 std::error_code buildTableOfContents() {
170 DEBUG_WITH_TYPE("FileArchive", llvm::dbgs()
171 << "Table of contents for archive '"
172 << _archive->getFileName() << "':\n");
173 for (const Archive::Symbol &sym : _archive->symbols()) {
174 StringRef name = sym.getName();
175 Expected<Archive::Child> memberOrErr = sym.getMember();
176 if (!memberOrErr)
177 return errorToErrorCode(memberOrErr.takeError());
178 Archive::Child member = memberOrErr.get();
179 DEBUG_WITH_TYPE("FileArchive",
180 llvm::dbgs()
181 << llvm::format("0x%08llX ",
182 member.getBuffer()->data())
183 << "'" << name << "'\n");
184 _symbolMemberMap.insert(std::make_pair(name, member));
185 }
186 return std::error_code();
187 }
188
189 typedef std::unordered_map<StringRef, Archive::Child> MemberMap;
190 typedef std::set<const char *> InstantiatedSet;
191
192 std::shared_ptr<MemoryBuffer> _mb;
193 const Registry &_registry;
194 std::unique_ptr<Archive> _archive;
195 MemberMap _symbolMemberMap;
196 InstantiatedSet _membersInstantiated;
197 bool _logLoading;
198 std::vector<std::unique_ptr<MemoryBuffer>> _memberBuffers;
199 std::vector<std::unique_ptr<File>> _filesReturned;
200};
201
202class ArchiveReader : public Reader {
203public:
204 ArchiveReader(bool logLoading) : _logLoading(logLoading) {}
205
206 bool canParse(file_magic magic, MemoryBufferRef) const override {
207 return magic == file_magic::archive;
208 }
209
210 ErrorOr<std::unique_ptr<File>> loadFile(std::unique_ptr<MemoryBuffer> mb,
211 const Registry &reg) const override {
212 StringRef path = mb->getBufferIdentifier();
213 std::unique_ptr<File> ret =
214 llvm::make_unique<FileArchive>(std::move(mb), reg, path, _logLoading);
215 return std::move(ret);
216 }
217
218private:
219 bool _logLoading;
220};
221
222} // anonymous namespace
223
224void Registry::addSupportArchives(bool logLoading) {
225 add(std::unique_ptr<Reader>(new ArchiveReader(logLoading)));
226}
227
228} // namespace lld
deps/lld/lib/ReaderWriter/MachO/ArchHandler.cpp created+172
......@@ -0,0 +1,172 @@
1//===- lib/FileFormat/MachO/ArchHandler.cpp -------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10
11#include "ArchHandler.h"
12#include "Atoms.h"
13#include "MachONormalizedFileBinaryUtils.h"
14#include "llvm/ADT/StringRef.h"
15#include "llvm/ADT/StringSwitch.h"
16#include "llvm/ADT/Triple.h"
17#include "llvm/Support/ErrorHandling.h"
18
19using namespace llvm::MachO;
20using namespace lld::mach_o::normalized;
21
22namespace lld {
23namespace mach_o {
24
25
26ArchHandler::ArchHandler() {
27}
28
29ArchHandler::~ArchHandler() {
30}
31
32std::unique_ptr<mach_o::ArchHandler> ArchHandler::create(
33 MachOLinkingContext::Arch arch) {
34 switch (arch) {
35 case MachOLinkingContext::arch_x86_64:
36 return create_x86_64();
37 case MachOLinkingContext::arch_x86:
38 return create_x86();
39 case MachOLinkingContext::arch_armv6:
40 case MachOLinkingContext::arch_armv7:
41 case MachOLinkingContext::arch_armv7s:
42 return create_arm();
43 case MachOLinkingContext::arch_arm64:
44 return create_arm64();
45 default:
46 llvm_unreachable("Unknown arch");
47 }
48}
49
50
51bool ArchHandler::isLazyPointer(const Reference &ref) {
52 // A lazy bind entry is needed for a lazy pointer.
53 const StubInfo &info = stubInfo();
54 if (ref.kindNamespace() != Reference::KindNamespace::mach_o)
55 return false;
56 if (ref.kindArch() != info.lazyPointerReferenceToFinal.arch)
57 return false;
58 return (ref.kindValue() == info.lazyPointerReferenceToFinal.kind);
59}
60
61
62ArchHandler::RelocPattern ArchHandler::relocPattern(const Relocation &reloc) {
63 assert((reloc.type & 0xFFF0) == 0);
64 uint16_t result = reloc.type;
65 if (reloc.scattered)
66 result |= rScattered;
67 if (reloc.pcRel)
68 result |= rPcRel;
69 if (reloc.isExtern)
70 result |= rExtern;
71 switch(reloc.length) {
72 case 0:
73 break;
74 case 1:
75 result |= rLength2;
76 break;
77 case 2:
78 result |= rLength4;
79 break;
80 case 3:
81 result |= rLength8;
82 break;
83 default:
84 llvm_unreachable("bad r_length");
85 }
86 return result;
87}
88
89normalized::Relocation
90ArchHandler::relocFromPattern(ArchHandler::RelocPattern pattern) {
91 normalized::Relocation result;
92 result.offset = 0;
93 result.scattered = (pattern & rScattered);
94 result.type = (RelocationInfoType)(pattern & 0xF);
95 result.pcRel = (pattern & rPcRel);
96 result.isExtern = (pattern & rExtern);
97 result.value = 0;
98 result.symbol = 0;
99 switch (pattern & 0x300) {
100 case rLength1:
101 result.length = 0;
102 break;
103 case rLength2:
104 result.length = 1;
105 break;
106 case rLength4:
107 result.length = 2;
108 break;
109 case rLength8:
110 result.length = 3;
111 break;
112 }
113 return result;
114}
115
116void ArchHandler::appendReloc(normalized::Relocations &relocs, uint32_t offset,
117 uint32_t symbol, uint32_t value,
118 RelocPattern pattern) {
119 normalized::Relocation reloc = relocFromPattern(pattern);
120 reloc.offset = offset;
121 reloc.symbol = symbol;
122 reloc.value = value;
123 relocs.push_back(reloc);
124}
125
126
127int16_t ArchHandler::readS16(const uint8_t *addr, bool isBig) {
128 return read16(addr, isBig);
129}
130
131int32_t ArchHandler::readS32(const uint8_t *addr, bool isBig) {
132 return read32(addr, isBig);
133}
134
135uint32_t ArchHandler::readU32(const uint8_t *addr, bool isBig) {
136 return read32(addr, isBig);
137}
138
139 int64_t ArchHandler::readS64(const uint8_t *addr, bool isBig) {
140 return read64(addr, isBig);
141}
142
143bool ArchHandler::isDwarfCIE(bool isBig, const DefinedAtom *atom) {
144 assert(atom->contentType() == DefinedAtom::typeCFI);
145 if (atom->rawContent().size() < sizeof(uint32_t))
146 return false;
147 uint32_t size = read32(atom->rawContent().data(), isBig);
148
149 uint32_t idOffset = sizeof(uint32_t);
150 if (size == 0xffffffffU)
151 idOffset += sizeof(uint64_t);
152
153 return read32(atom->rawContent().data() + idOffset, isBig) == 0;
154}
155
156const Atom *ArchHandler::fdeTargetFunction(const DefinedAtom *fde) {
157 for (auto ref : *fde) {
158 if (ref->kindNamespace() == Reference::KindNamespace::mach_o &&
159 ref->kindValue() == unwindRefToFunctionKind()) {
160 assert(ref->kindArch() == kindArch() && "unexpected Reference arch");
161 return ref->target();
162 }
163 }
164
165 return nullptr;
166}
167
168} // namespace mach_o
169} // namespace lld
170
171
172
deps/lld/lib/ReaderWriter/MachO/ArchHandler.h created+323
......@@ -0,0 +1,323 @@
1//===- lib/FileFormat/MachO/ArchHandler.h ---------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_READER_WRITER_MACHO_ARCH_HANDLER_H
11#define LLD_READER_WRITER_MACHO_ARCH_HANDLER_H
12
13#include "Atoms.h"
14#include "File.h"
15#include "MachONormalizedFile.h"
16#include "lld/Core/LLVM.h"
17#include "lld/Core/Error.h"
18#include "lld/Core/Reference.h"
19#include "lld/Core/Simple.h"
20#include "lld/ReaderWriter/MachOLinkingContext.h"
21#include "llvm/ADT/Triple.h"
22
23namespace lld {
24namespace mach_o {
25
26///
27/// The ArchHandler class handles all architecture specific aspects of
28/// mach-o linking.
29///
30class ArchHandler {
31public:
32 virtual ~ArchHandler();
33
34 /// There is no public interface to subclasses of ArchHandler, so this
35 /// is the only way to instantiate an ArchHandler.
36 static std::unique_ptr<ArchHandler> create(MachOLinkingContext::Arch arch);
37
38 /// Get (arch specific) kind strings used by Registry.
39 virtual const Registry::KindStrings *kindStrings() = 0;
40
41 /// Convert mach-o Arch to Reference::KindArch.
42 virtual Reference::KindArch kindArch() = 0;
43
44 /// Used by StubPass to update References to shared library functions
45 /// to be references to a stub.
46 virtual bool isCallSite(const Reference &) = 0;
47
48 /// Used by GOTPass to locate GOT References
49 virtual bool isGOTAccess(const Reference &, bool &canBypassGOT) {
50 return false;
51 }
52
53 /// Used by TLVPass to locate TLV References.
54 virtual bool isTLVAccess(const Reference &) const { return false; }
55
56 /// Used by the TLVPass to update TLV References.
57 virtual void updateReferenceToTLV(const Reference *) {}
58
59 /// Used by ShimPass to insert shims in branches that switch mode.
60 virtual bool isNonCallBranch(const Reference &) = 0;
61
62 /// Used by GOTPass to update GOT References
63 virtual void updateReferenceToGOT(const Reference *, bool targetIsNowGOT) {}
64
65 /// Does this architecture make use of __unwind_info sections for exception
66 /// handling? If so, it will need a separate pass to create them.
67 virtual bool needsCompactUnwind() = 0;
68
69 /// Returns the kind of reference to use to synthesize a 32-bit image-offset
70 /// value, used in the __unwind_info section.
71 virtual Reference::KindValue imageOffsetKind() = 0;
72
73 /// Returns the kind of reference to use to synthesize a 32-bit image-offset
74 /// indirect value. Used for personality functions in the __unwind_info
75 /// section.
76 virtual Reference::KindValue imageOffsetKindIndirect() = 0;
77
78 /// Architecture specific compact unwind type that signals __eh_frame should
79 /// actually be used.
80 virtual uint32_t dwarfCompactUnwindType() = 0;
81
82 /// Reference from an __eh_frame CIE atom to its personality function it's
83 /// describing. Usually pointer-sized and PC-relative, but differs in whether
84 /// it needs to be in relocatable objects.
85 virtual Reference::KindValue unwindRefToPersonalityFunctionKind() = 0;
86
87 /// Reference from an __eh_frame FDE to the CIE it's based on.
88 virtual Reference::KindValue unwindRefToCIEKind() = 0;
89
90 /// Reference from an __eh_frame FDE atom to the function it's
91 /// describing. Usually pointer-sized and PC-relative, but differs in whether
92 /// it needs to be in relocatable objects.
93 virtual Reference::KindValue unwindRefToFunctionKind() = 0;
94
95 /// Reference from an __unwind_info entry of dwarfCompactUnwindType to the
96 /// required __eh_frame entry. On current architectures, the low 24 bits
97 /// represent the offset of the function's FDE entry from the start of
98 /// __eh_frame.
99 virtual Reference::KindValue unwindRefToEhFrameKind() = 0;
100
101 /// Returns a pointer sized reference kind. On 64-bit targets this will
102 /// likely be something like pointer64, and pointer32 on 32-bit targets.
103 virtual Reference::KindValue pointerKind() = 0;
104
105 virtual const Atom *fdeTargetFunction(const DefinedAtom *fde);
106
107 /// Used by normalizedFromAtoms() to know where to generated rebasing and
108 /// binding info in final executables.
109 virtual bool isPointer(const Reference &) = 0;
110
111 /// Used by normalizedFromAtoms() to know where to generated lazy binding
112 /// info in final executables.
113 virtual bool isLazyPointer(const Reference &);
114
115 /// Reference from an __stub_helper entry to the required offset of the
116 /// lazy bind commands.
117 virtual Reference::KindValue lazyImmediateLocationKind() = 0;
118
119 /// Returns true if the specified relocation is paired to the next relocation.
120 virtual bool isPairedReloc(const normalized::Relocation &) = 0;
121
122 /// Prototype for a helper function. Given a sectionIndex and address,
123 /// finds the atom and offset with that atom of that address.
124 typedef std::function<llvm::Error (uint32_t sectionIndex, uint64_t addr,
125 const lld::Atom **, Reference::Addend *)>
126 FindAtomBySectionAndAddress;
127
128 /// Prototype for a helper function. Given a symbolIndex, finds the atom
129 /// representing that symbol.
130 typedef std::function<llvm::Error (uint32_t symbolIndex,
131 const lld::Atom **)> FindAtomBySymbolIndex;
132
133 /// Analyzes a relocation from a .o file and returns the info
134 /// (kind, target, addend) needed to instantiate a Reference.
135 /// Two helper functions are passed as parameters to find the target atom
136 /// given a symbol index or address.
137 virtual llvm::Error
138 getReferenceInfo(const normalized::Relocation &reloc,
139 const DefinedAtom *inAtom,
140 uint32_t offsetInAtom,
141 uint64_t fixupAddress, bool isBigEndian,
142 FindAtomBySectionAndAddress atomFromAddress,
143 FindAtomBySymbolIndex atomFromSymbolIndex,
144 Reference::KindValue *kind,
145 const lld::Atom **target,
146 Reference::Addend *addend) = 0;
147
148 /// Analyzes a pair of relocations from a .o file and returns the info
149 /// (kind, target, addend) needed to instantiate a Reference.
150 /// Two helper functions are passed as parameters to find the target atom
151 /// given a symbol index or address.
152 virtual llvm::Error
153 getPairReferenceInfo(const normalized::Relocation &reloc1,
154 const normalized::Relocation &reloc2,
155 const DefinedAtom *inAtom,
156 uint32_t offsetInAtom,
157 uint64_t fixupAddress, bool isBig, bool scatterable,
158 FindAtomBySectionAndAddress atomFromAddress,
159 FindAtomBySymbolIndex atomFromSymbolIndex,
160 Reference::KindValue *kind,
161 const lld::Atom **target,
162 Reference::Addend *addend) = 0;
163
164 /// Prototype for a helper function. Given an atom, finds the symbol table
165 /// index for it in the output file.
166 typedef std::function<uint32_t (const Atom &atom)> FindSymbolIndexForAtom;
167
168 /// Prototype for a helper function. Given an atom, finds the index
169 /// of the section that will contain the atom.
170 typedef std::function<uint32_t (const Atom &atom)> FindSectionIndexForAtom;
171
172 /// Prototype for a helper function. Given an atom, finds the address
173 /// assigned to it in the output file.
174 typedef std::function<uint64_t (const Atom &atom)> FindAddressForAtom;
175
176 /// Some architectures require local symbols on anonymous atoms.
177 virtual bool needsLocalSymbolInRelocatableFile(const DefinedAtom *atom) {
178 return false;
179 }
180
181 /// Copy raw content then apply all fixup References on an Atom.
182 virtual void generateAtomContent(const DefinedAtom &atom, bool relocatable,
183 FindAddressForAtom findAddress,
184 FindAddressForAtom findSectionAddress,
185 uint64_t imageBaseAddress,
186 llvm::MutableArrayRef<uint8_t> atomContentBuffer) = 0;
187
188 /// Used in -r mode to convert a Reference to a mach-o relocation.
189 virtual void appendSectionRelocations(const DefinedAtom &atom,
190 uint64_t atomSectionOffset,
191 const Reference &ref,
192 FindSymbolIndexForAtom,
193 FindSectionIndexForAtom,
194 FindAddressForAtom,
195 normalized::Relocations&) = 0;
196
197 /// Add arch-specific References.
198 virtual void addAdditionalReferences(MachODefinedAtom &atom) { }
199
200 // Add Reference for data-in-code marker.
201 virtual void addDataInCodeReference(MachODefinedAtom &atom, uint32_t atomOff,
202 uint16_t length, uint16_t kind) { }
203
204 /// Returns true if the specificed Reference value marks the start or end
205 /// of a data-in-code range in an atom.
206 virtual bool isDataInCodeTransition(Reference::KindValue refKind) {
207 return false;
208 }
209
210 /// Returns the Reference value for a Reference that marks that start of
211 /// a data-in-code range.
212 virtual Reference::KindValue dataInCodeTransitionStart(
213 const MachODefinedAtom &atom) {
214 return 0;
215 }
216
217 /// Returns the Reference value for a Reference that marks that end of
218 /// a data-in-code range.
219 virtual Reference::KindValue dataInCodeTransitionEnd(
220 const MachODefinedAtom &atom) {
221 return 0;
222 }
223
224 /// Only relevant for 32-bit arm archs.
225 virtual bool isThumbFunction(const DefinedAtom &atom) { return false; }
226
227 /// Only relevant for 32-bit arm archs.
228 virtual const DefinedAtom *createShim(MachOFile &file, bool thumbToArm,
229 const DefinedAtom &) {
230 llvm_unreachable("shims only support on arm");
231 }
232
233 /// Does a given unwind-cfi atom represent a CIE (as opposed to an FDE).
234 static bool isDwarfCIE(bool isBig, const DefinedAtom *atom);
235
236 struct ReferenceInfo {
237 Reference::KindArch arch;
238 uint16_t kind;
239 uint32_t offset;
240 int32_t addend;
241 };
242
243 struct OptionalRefInfo {
244 bool used;
245 uint16_t kind;
246 uint32_t offset;
247 int32_t addend;
248 };
249
250 /// Table of architecture specific information for creating stubs.
251 struct StubInfo {
252 const char* binderSymbolName;
253 ReferenceInfo lazyPointerReferenceToHelper;
254 ReferenceInfo lazyPointerReferenceToFinal;
255 ReferenceInfo nonLazyPointerReferenceToBinder;
256 uint8_t codeAlignment;
257
258 uint32_t stubSize;
259 uint8_t stubBytes[16];
260 ReferenceInfo stubReferenceToLP;
261 OptionalRefInfo optStubReferenceToLP;
262
263 uint32_t stubHelperSize;
264 uint8_t stubHelperBytes[16];
265 ReferenceInfo stubHelperReferenceToImm;
266 ReferenceInfo stubHelperReferenceToHelperCommon;
267
268 DefinedAtom::ContentType stubHelperImageCacheContentType;
269
270 uint32_t stubHelperCommonSize;
271 uint8_t stubHelperCommonAlignment;
272 uint8_t stubHelperCommonBytes[36];
273 ReferenceInfo stubHelperCommonReferenceToCache;
274 OptionalRefInfo optStubHelperCommonReferenceToCache;
275 ReferenceInfo stubHelperCommonReferenceToBinder;
276 OptionalRefInfo optStubHelperCommonReferenceToBinder;
277 };
278
279 virtual const StubInfo &stubInfo() = 0;
280
281protected:
282 ArchHandler();
283
284 static std::unique_ptr<mach_o::ArchHandler> create_x86_64();
285 static std::unique_ptr<mach_o::ArchHandler> create_x86();
286 static std::unique_ptr<mach_o::ArchHandler> create_arm();
287 static std::unique_ptr<mach_o::ArchHandler> create_arm64();
288
289 // Handy way to pack mach-o r_type and other bit fields into one 16-bit value.
290 typedef uint16_t RelocPattern;
291 enum {
292 rScattered = 0x8000,
293 rPcRel = 0x4000,
294 rExtern = 0x2000,
295 rLength1 = 0x0000,
296 rLength2 = 0x0100,
297 rLength4 = 0x0200,
298 rLength8 = 0x0300,
299 rLenArmLo = rLength1,
300 rLenArmHi = rLength2,
301 rLenThmbLo = rLength4,
302 rLenThmbHi = rLength8
303 };
304 /// Extract RelocPattern from normalized mach-o relocation.
305 static RelocPattern relocPattern(const normalized::Relocation &reloc);
306 /// Create normalized Relocation initialized from pattern.
307 static normalized::Relocation relocFromPattern(RelocPattern pattern);
308 /// One liner to add a relocation.
309 static void appendReloc(normalized::Relocations &relocs, uint32_t offset,
310 uint32_t symbol, uint32_t value,
311 RelocPattern pattern);
312
313
314 static int16_t readS16(const uint8_t *addr, bool isBig);
315 static int32_t readS32(const uint8_t *addr, bool isBig);
316 static uint32_t readU32(const uint8_t *addr, bool isBig);
317 static int64_t readS64(const uint8_t *addr, bool isBig);
318};
319
320} // namespace mach_o
321} // namespace lld
322
323#endif // LLD_READER_WRITER_MACHO_ARCH_HANDLER_H
deps/lld/lib/ReaderWriter/MachO/ArchHandler_arm.cpp created+1523
......@@ -0,0 +1,1523 @@
1//===- lib/FileFormat/MachO/ArchHandler_arm.cpp ---------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "ArchHandler.h"
11#include "Atoms.h"
12#include "MachONormalizedFileBinaryUtils.h"
13#include "llvm/ADT/StringRef.h"
14#include "llvm/ADT/StringSwitch.h"
15#include "llvm/ADT/Triple.h"
16#include "llvm/Support/Endian.h"
17#include "llvm/Support/ErrorHandling.h"
18
19using namespace llvm::MachO;
20using namespace lld::mach_o::normalized;
21
22namespace lld {
23namespace mach_o {
24
25using llvm::support::ulittle32_t;
26using llvm::support::little32_t;
27
28
29class ArchHandler_arm : public ArchHandler {
30public:
31 ArchHandler_arm() = default;
32 ~ArchHandler_arm() override = default;
33
34 const Registry::KindStrings *kindStrings() override { return _sKindStrings; }
35
36 Reference::KindArch kindArch() override { return Reference::KindArch::ARM; }
37
38 const ArchHandler::StubInfo &stubInfo() override;
39 bool isCallSite(const Reference &) override;
40 bool isPointer(const Reference &) override;
41 bool isPairedReloc(const normalized::Relocation &) override;
42 bool isNonCallBranch(const Reference &) override;
43
44 bool needsCompactUnwind() override {
45 return false;
46 }
47 Reference::KindValue imageOffsetKind() override {
48 return invalid;
49 }
50 Reference::KindValue imageOffsetKindIndirect() override {
51 return invalid;
52 }
53
54 Reference::KindValue unwindRefToPersonalityFunctionKind() override {
55 return invalid;
56 }
57
58 Reference::KindValue unwindRefToCIEKind() override {
59 return invalid;
60 }
61
62 Reference::KindValue unwindRefToFunctionKind() override {
63 return invalid;
64 }
65
66 Reference::KindValue unwindRefToEhFrameKind() override {
67 return invalid;
68 }
69
70 Reference::KindValue lazyImmediateLocationKind() override {
71 return lazyImmediateLocation;
72 }
73
74 Reference::KindValue pointerKind() override {
75 return invalid;
76 }
77
78 uint32_t dwarfCompactUnwindType() override {
79 // FIXME
80 return -1;
81 }
82
83 llvm::Error getReferenceInfo(const normalized::Relocation &reloc,
84 const DefinedAtom *inAtom,
85 uint32_t offsetInAtom,
86 uint64_t fixupAddress, bool swap,
87 FindAtomBySectionAndAddress atomFromAddress,
88 FindAtomBySymbolIndex atomFromSymbolIndex,
89 Reference::KindValue *kind,
90 const lld::Atom **target,
91 Reference::Addend *addend) override;
92 llvm::Error
93 getPairReferenceInfo(const normalized::Relocation &reloc1,
94 const normalized::Relocation &reloc2,
95 const DefinedAtom *inAtom,
96 uint32_t offsetInAtom,
97 uint64_t fixupAddress, bool swap, bool scatterable,
98 FindAtomBySectionAndAddress atomFromAddress,
99 FindAtomBySymbolIndex atomFromSymbolIndex,
100 Reference::KindValue *kind,
101 const lld::Atom **target,
102 Reference::Addend *addend) override;
103
104 void generateAtomContent(const DefinedAtom &atom, bool relocatable,
105 FindAddressForAtom findAddress,
106 FindAddressForAtom findSectionAddress,
107 uint64_t imageBaseAddress,
108 llvm::MutableArrayRef<uint8_t> atomContentBuffer) override;
109
110 void appendSectionRelocations(const DefinedAtom &atom,
111 uint64_t atomSectionOffset,
112 const Reference &ref,
113 FindSymbolIndexForAtom,
114 FindSectionIndexForAtom,
115 FindAddressForAtom,
116 normalized::Relocations &) override;
117
118 void addAdditionalReferences(MachODefinedAtom &atom) override;
119
120 bool isDataInCodeTransition(Reference::KindValue refKind) override {
121 switch (refKind) {
122 case modeThumbCode:
123 case modeArmCode:
124 case modeData:
125 return true;
126 default:
127 return false;
128 break;
129 }
130 }
131
132 Reference::KindValue dataInCodeTransitionStart(
133 const MachODefinedAtom &atom) override {
134 return modeData;
135 }
136
137 Reference::KindValue dataInCodeTransitionEnd(
138 const MachODefinedAtom &atom) override {
139 return atom.isThumb() ? modeThumbCode : modeArmCode;
140 }
141
142 bool isThumbFunction(const DefinedAtom &atom) override;
143 const DefinedAtom *createShim(MachOFile &file, bool thumbToArm,
144 const DefinedAtom &) override;
145
146private:
147 friend class Thumb2ToArmShimAtom;
148 friend class ArmToThumbShimAtom;
149
150 static const Registry::KindStrings _sKindStrings[];
151 static const StubInfo _sStubInfoArmPIC;
152
153 enum ArmKind : Reference::KindValue {
154 invalid, /// for error condition
155
156 modeThumbCode, /// Content starting at this offset is thumb.
157 modeArmCode, /// Content starting at this offset is arm.
158 modeData, /// Content starting at this offset is data.
159
160 // Kinds found in mach-o .o files:
161 thumb_bl22, /// ex: bl _foo
162 thumb_b22, /// ex: b _foo
163 thumb_movw, /// ex: movw r1, :lower16:_foo
164 thumb_movt, /// ex: movt r1, :lower16:_foo
165 thumb_movw_funcRel, /// ex: movw r1, :lower16:(_foo-(L1+4))
166 thumb_movt_funcRel, /// ex: movt r1, :upper16:(_foo-(L1+4))
167 arm_bl24, /// ex: bl _foo
168 arm_b24, /// ex: b _foo
169 arm_movw, /// ex: movw r1, :lower16:_foo
170 arm_movt, /// ex: movt r1, :lower16:_foo
171 arm_movw_funcRel, /// ex: movw r1, :lower16:(_foo-(L1+4))
172 arm_movt_funcRel, /// ex: movt r1, :upper16:(_foo-(L1+4))
173 pointer32, /// ex: .long _foo
174 delta32, /// ex: .long _foo - .
175
176 // Kinds introduced by Passes:
177 lazyPointer, /// Location contains a lazy pointer.
178 lazyImmediateLocation, /// Location contains immediate value used in stub.
179 };
180
181 // Utility functions for inspecting/updating instructions.
182 static bool isThumbMovw(uint32_t instruction);
183 static bool isThumbMovt(uint32_t instruction);
184 static bool isArmMovw(uint32_t instruction);
185 static bool isArmMovt(uint32_t instruction);
186 static int32_t getDisplacementFromThumbBranch(uint32_t instruction, uint32_t);
187 static int32_t getDisplacementFromArmBranch(uint32_t instruction);
188 static uint16_t getWordFromThumbMov(uint32_t instruction);
189 static uint16_t getWordFromArmMov(uint32_t instruction);
190 static uint32_t clearThumbBit(uint32_t value, const Atom *target);
191 static uint32_t setDisplacementInArmBranch(uint32_t instr, int32_t disp,
192 bool targetIsThumb);
193 static uint32_t setDisplacementInThumbBranch(uint32_t instr, uint32_t ia,
194 int32_t disp, bool targetThumb);
195 static uint32_t setWordFromThumbMov(uint32_t instruction, uint16_t word);
196 static uint32_t setWordFromArmMov(uint32_t instruction, uint16_t word);
197
198 StringRef stubName(const DefinedAtom &);
199 bool useExternalRelocationTo(const Atom &target);
200
201 void applyFixupFinal(const Reference &ref, uint8_t *location,
202 uint64_t fixupAddress, uint64_t targetAddress,
203 uint64_t inAtomAddress, bool &thumbMode,
204 bool targetIsThumb);
205
206 void applyFixupRelocatable(const Reference &ref, uint8_t *location,
207 uint64_t fixupAddress,
208 uint64_t targetAddress,
209 uint64_t inAtomAddress, bool &thumbMode,
210 bool targetIsThumb);
211};
212
213//===----------------------------------------------------------------------===//
214// ArchHandler_arm
215//===----------------------------------------------------------------------===//
216
217const Registry::KindStrings ArchHandler_arm::_sKindStrings[] = {
218 LLD_KIND_STRING_ENTRY(invalid),
219 LLD_KIND_STRING_ENTRY(modeThumbCode),
220 LLD_KIND_STRING_ENTRY(modeArmCode),
221 LLD_KIND_STRING_ENTRY(modeData),
222 LLD_KIND_STRING_ENTRY(thumb_bl22),
223 LLD_KIND_STRING_ENTRY(thumb_b22),
224 LLD_KIND_STRING_ENTRY(thumb_movw),
225 LLD_KIND_STRING_ENTRY(thumb_movt),
226 LLD_KIND_STRING_ENTRY(thumb_movw_funcRel),
227 LLD_KIND_STRING_ENTRY(thumb_movt_funcRel),
228 LLD_KIND_STRING_ENTRY(arm_bl24),
229 LLD_KIND_STRING_ENTRY(arm_b24),
230 LLD_KIND_STRING_ENTRY(arm_movw),
231 LLD_KIND_STRING_ENTRY(arm_movt),
232 LLD_KIND_STRING_ENTRY(arm_movw_funcRel),
233 LLD_KIND_STRING_ENTRY(arm_movt_funcRel),
234 LLD_KIND_STRING_ENTRY(pointer32),
235 LLD_KIND_STRING_ENTRY(delta32),
236 LLD_KIND_STRING_ENTRY(lazyPointer),
237 LLD_KIND_STRING_ENTRY(lazyImmediateLocation),
238 LLD_KIND_STRING_END
239};
240
241const ArchHandler::StubInfo ArchHandler_arm::_sStubInfoArmPIC = {
242 "dyld_stub_binder",
243
244 // References in lazy pointer
245 { Reference::KindArch::ARM, pointer32, 0, 0 },
246 { Reference::KindArch::ARM, lazyPointer, 0, 0 },
247
248 // GOT pointer to dyld_stub_binder
249 { Reference::KindArch::ARM, pointer32, 0, 0 },
250
251 // arm code alignment 2^2
252 2,
253
254 // Stub size and code
255 16,
256 { 0x04, 0xC0, 0x9F, 0xE5, // ldr ip, pc + 12
257 0x0C, 0xC0, 0x8F, 0xE0, // add ip, pc, ip
258 0x00, 0xF0, 0x9C, 0xE5, // ldr pc, [ip]
259 0x00, 0x00, 0x00, 0x00 }, // .long L_foo$lazy_ptr - (L1$scv + 8)
260 { Reference::KindArch::ARM, delta32, 12, 0 },
261 { false, 0, 0, 0 },
262
263 // Stub Helper size and code
264 12,
265 { 0x00, 0xC0, 0x9F, 0xE5, // ldr ip, [pc, #0]
266 0x00, 0x00, 0x00, 0xEA, // b _helperhelper
267 0x00, 0x00, 0x00, 0x00 }, // .long lazy-info-offset
268 { Reference::KindArch::ARM, lazyImmediateLocation, 8, 0 },
269 { Reference::KindArch::ARM, arm_b24, 4, 0 },
270
271 // Stub helper image cache content type
272 DefinedAtom::typeGOT,
273
274 // Stub Helper-Common size and code
275 36,
276 // Stub helper alignment
277 2,
278 { // push lazy-info-offset
279 0x04, 0xC0, 0x2D, 0xE5, // str ip, [sp, #-4]!
280 // push address of dyld_mageLoaderCache
281 0x10, 0xC0, 0x9F, 0xE5, // ldr ip, L1
282 0x0C, 0xC0, 0x8F, 0xE0, // add ip, pc, ip
283 0x04, 0xC0, 0x2D, 0xE5, // str ip, [sp, #-4]!
284 // jump through dyld_stub_binder
285 0x08, 0xC0, 0x9F, 0xE5, // ldr ip, L2
286 0x0C, 0xC0, 0x8F, 0xE0, // add ip, pc, ip
287 0x00, 0xF0, 0x9C, 0xE5, // ldr pc, [ip]
288 0x00, 0x00, 0x00, 0x00, // L1: .long fFastStubGOTAtom - (helper+16)
289 0x00, 0x00, 0x00, 0x00 }, // L2: .long dyld_stub_binder - (helper+28)
290 { Reference::KindArch::ARM, delta32, 28, 0xC },
291 { false, 0, 0, 0 },
292 { Reference::KindArch::ARM, delta32, 32, 0x04 },
293 { false, 0, 0, 0 }
294};
295
296const ArchHandler::StubInfo &ArchHandler_arm::stubInfo() {
297 // If multiple kinds of stubs are supported, select which StubInfo here.
298 return _sStubInfoArmPIC;
299}
300
301bool ArchHandler_arm::isCallSite(const Reference &ref) {
302 switch (ref.kindValue()) {
303 case thumb_b22:
304 case thumb_bl22:
305 case arm_b24:
306 case arm_bl24:
307 return true;
308 default:
309 return false;
310 }
311}
312
313bool ArchHandler_arm::isPointer(const Reference &ref) {
314 return (ref.kindValue() == pointer32);
315}
316
317bool ArchHandler_arm::isNonCallBranch(const Reference &ref) {
318 switch (ref.kindValue()) {
319 case thumb_b22:
320 case arm_b24:
321 return true;
322 default:
323 return false;
324 }
325}
326
327bool ArchHandler_arm::isPairedReloc(const Relocation &reloc) {
328 switch (reloc.type) {
329 case ARM_RELOC_SECTDIFF:
330 case ARM_RELOC_LOCAL_SECTDIFF:
331 case ARM_RELOC_HALF_SECTDIFF:
332 case ARM_RELOC_HALF:
333 return true;
334 default:
335 return false;
336 }
337}
338
339/// Trace references from stub atom to lazy pointer to target and get its name.
340StringRef ArchHandler_arm::stubName(const DefinedAtom &stubAtom) {
341 assert(stubAtom.contentType() == DefinedAtom::typeStub);
342 for (const Reference *ref : stubAtom) {
343 if (const DefinedAtom* lp = dyn_cast<DefinedAtom>(ref->target())) {
344 if (lp->contentType() != DefinedAtom::typeLazyPointer)
345 continue;
346 for (const Reference *ref2 : *lp) {
347 if (ref2->kindValue() != lazyPointer)
348 continue;
349 return ref2->target()->name();
350 }
351 }
352 }
353 return "stub";
354}
355
356/// Extract displacement from an ARM b/bl/blx instruction.
357int32_t ArchHandler_arm::getDisplacementFromArmBranch(uint32_t instruction) {
358 // Sign-extend imm24
359 int32_t displacement = (instruction & 0x00FFFFFF) << 2;
360 if ((displacement & 0x02000000) != 0)
361 displacement |= 0xFC000000;
362 // If this is BLX and H bit set, add 2.
363 if ((instruction & 0xFF000000) == 0xFB000000)
364 displacement += 2;
365 return displacement;
366}
367
368/// Update an ARM b/bl/blx instruction, switching bl <-> blx as needed.
369uint32_t ArchHandler_arm::setDisplacementInArmBranch(uint32_t instruction,
370 int32_t displacement,
371 bool targetIsThumb) {
372 assert((displacement <= 33554428) && (displacement > (-33554432))
373 && "arm branch out of range");
374 bool is_blx = ((instruction & 0xF0000000) == 0xF0000000);
375 uint32_t newInstruction = (instruction & 0xFF000000);
376 uint32_t h = 0;
377 if (targetIsThumb) {
378 // Force use of BLX.
379 newInstruction = 0xFA000000;
380 if (!is_blx) {
381 assert(((instruction & 0xF0000000) == 0xE0000000)
382 && "no conditional arm blx");
383 assert(((instruction & 0xFF000000) == 0xEB000000)
384 && "no arm pc-rel BX instruction");
385 }
386 if (displacement & 2)
387 h = 1;
388 }
389 else {
390 // Force use of B/BL.
391 if (is_blx)
392 newInstruction = 0xEB000000;
393 }
394 newInstruction |= (h << 24) | ((displacement >> 2) & 0x00FFFFFF);
395 return newInstruction;
396}
397
398/// Extract displacement from a thumb b/bl/blx instruction.
399int32_t ArchHandler_arm::getDisplacementFromThumbBranch(uint32_t instruction,
400 uint32_t instrAddr) {
401 bool is_blx = ((instruction & 0xD000F800) == 0xC000F000);
402 uint32_t s = (instruction >> 10) & 0x1;
403 uint32_t j1 = (instruction >> 29) & 0x1;
404 uint32_t j2 = (instruction >> 27) & 0x1;
405 uint32_t imm10 = instruction & 0x3FF;
406 uint32_t imm11 = (instruction >> 16) & 0x7FF;
407 uint32_t i1 = (j1 == s);
408 uint32_t i2 = (j2 == s);
409 uint32_t dis =
410 (s << 24) | (i1 << 23) | (i2 << 22) | (imm10 << 12) | (imm11 << 1);
411 int32_t sdis = dis;
412 int32_t result = s ? (sdis | 0xFE000000) : sdis;
413 if (is_blx && (instrAddr & 0x2)) {
414 // The thumb blx instruction always has low bit of imm11 as zero. The way
415 // a 2-byte aligned blx can branch to a 4-byte aligned ARM target is that
416 // the blx instruction always 4-byte aligns the pc before adding the
417 // displacement from the blx. We must emulate that when decoding this.
418 result -= 2;
419 }
420 return result;
421}
422
423/// Update a thumb b/bl/blx instruction, switching bl <-> blx as needed.
424uint32_t ArchHandler_arm::setDisplacementInThumbBranch(uint32_t instruction,
425 uint32_t instrAddr,
426 int32_t displacement,
427 bool targetIsThumb) {
428 assert((displacement <= 16777214) && (displacement > (-16777216))
429 && "thumb branch out of range");
430 bool is_bl = ((instruction & 0xD000F800) == 0xD000F000);
431 bool is_blx = ((instruction & 0xD000F800) == 0xC000F000);
432 bool is_b = ((instruction & 0xD000F800) == 0x9000F000);
433 uint32_t newInstruction = (instruction & 0xD000F800);
434 if (is_bl || is_blx) {
435 if (targetIsThumb) {
436 newInstruction = 0xD000F000; // Use bl
437 } else {
438 newInstruction = 0xC000F000; // Use blx
439 // See note in getDisplacementFromThumbBranch() about blx.
440 if (instrAddr & 0x2)
441 displacement += 2;
442 }
443 } else if (is_b) {
444 assert(targetIsThumb && "no pc-rel thumb branch instruction that "
445 "switches to arm mode");
446 }
447 else {
448 llvm_unreachable("thumb branch22 reloc on a non-branch instruction");
449 }
450 uint32_t s = (uint32_t)(displacement >> 24) & 0x1;
451 uint32_t i1 = (uint32_t)(displacement >> 23) & 0x1;
452 uint32_t i2 = (uint32_t)(displacement >> 22) & 0x1;
453 uint32_t imm10 = (uint32_t)(displacement >> 12) & 0x3FF;
454 uint32_t imm11 = (uint32_t)(displacement >> 1) & 0x7FF;
455 uint32_t j1 = (i1 == s);
456 uint32_t j2 = (i2 == s);
457 uint32_t nextDisp = (j1 << 13) | (j2 << 11) | imm11;
458 uint32_t firstDisp = (s << 10) | imm10;
459 newInstruction |= (nextDisp << 16) | firstDisp;
460 return newInstruction;
461}
462
463bool ArchHandler_arm::isThumbMovw(uint32_t instruction) {
464 return (instruction & 0x8000FBF0) == 0x0000F240;
465}
466
467bool ArchHandler_arm::isThumbMovt(uint32_t instruction) {
468 return (instruction & 0x8000FBF0) == 0x0000F2C0;
469}
470
471bool ArchHandler_arm::isArmMovw(uint32_t instruction) {
472 return (instruction & 0x0FF00000) == 0x03000000;
473}
474
475bool ArchHandler_arm::isArmMovt(uint32_t instruction) {
476 return (instruction & 0x0FF00000) == 0x03400000;
477}
478
479uint16_t ArchHandler_arm::getWordFromThumbMov(uint32_t instruction) {
480 assert(isThumbMovw(instruction) || isThumbMovt(instruction));
481 uint32_t i = ((instruction & 0x00000400) >> 10);
482 uint32_t imm4 = (instruction & 0x0000000F);
483 uint32_t imm3 = ((instruction & 0x70000000) >> 28);
484 uint32_t imm8 = ((instruction & 0x00FF0000) >> 16);
485 return (imm4 << 12) | (i << 11) | (imm3 << 8) | imm8;
486}
487
488uint16_t ArchHandler_arm::getWordFromArmMov(uint32_t instruction) {
489 assert(isArmMovw(instruction) || isArmMovt(instruction));
490 uint32_t imm4 = ((instruction & 0x000F0000) >> 16);
491 uint32_t imm12 = (instruction & 0x00000FFF);
492 return (imm4 << 12) | imm12;
493}
494
495uint32_t ArchHandler_arm::setWordFromThumbMov(uint32_t instr, uint16_t word) {
496 assert(isThumbMovw(instr) || isThumbMovt(instr));
497 uint32_t imm4 = (word & 0xF000) >> 12;
498 uint32_t i = (word & 0x0800) >> 11;
499 uint32_t imm3 = (word & 0x0700) >> 8;
500 uint32_t imm8 = word & 0x00FF;
501 return (instr & 0x8F00FBF0) | imm4 | (i << 10) | (imm3 << 28) | (imm8 << 16);
502}
503
504uint32_t ArchHandler_arm::setWordFromArmMov(uint32_t instr, uint16_t word) {
505 assert(isArmMovw(instr) || isArmMovt(instr));
506 uint32_t imm4 = (word & 0xF000) >> 12;
507 uint32_t imm12 = word & 0x0FFF;
508 return (instr & 0xFFF0F000) | (imm4 << 16) | imm12;
509}
510
511uint32_t ArchHandler_arm::clearThumbBit(uint32_t value, const Atom *target) {
512 // The assembler often adds one to the address of a thumb function.
513 // We need to undo that so it does not look like an addend.
514 if (value & 1) {
515 if (isa<DefinedAtom>(target)) {
516 const MachODefinedAtom *machoTarget =
517 reinterpret_cast<const MachODefinedAtom *>(target);
518 if (machoTarget->isThumb())
519 value &= -2; // mask off thumb-bit
520 }
521 }
522 return value;
523}
524
525llvm::Error ArchHandler_arm::getReferenceInfo(
526 const Relocation &reloc, const DefinedAtom *inAtom, uint32_t offsetInAtom,
527 uint64_t fixupAddress, bool isBig,
528 FindAtomBySectionAndAddress atomFromAddress,
529 FindAtomBySymbolIndex atomFromSymbolIndex, Reference::KindValue *kind,
530 const lld::Atom **target, Reference::Addend *addend) {
531 const uint8_t *fixupContent = &inAtom->rawContent()[offsetInAtom];
532 uint64_t targetAddress;
533 uint32_t instruction = *(const ulittle32_t *)fixupContent;
534 int32_t displacement;
535 switch (relocPattern(reloc)) {
536 case ARM_THUMB_RELOC_BR22 | rPcRel | rExtern | rLength4:
537 // ex: bl _foo (and _foo is undefined)
538 if ((instruction & 0xD000F800) == 0x9000F000)
539 *kind = thumb_b22;
540 else
541 *kind = thumb_bl22;
542 if (auto ec = atomFromSymbolIndex(reloc.symbol, target))
543 return ec;
544 // Instruction contains branch to addend.
545 displacement = getDisplacementFromThumbBranch(instruction, fixupAddress);
546 *addend = fixupAddress + 4 + displacement;
547 return llvm::Error::success();
548 case ARM_THUMB_RELOC_BR22 | rPcRel | rLength4:
549 // ex: bl _foo (and _foo is defined)
550 if ((instruction & 0xD000F800) == 0x9000F000)
551 *kind = thumb_b22;
552 else
553 *kind = thumb_bl22;
554 displacement = getDisplacementFromThumbBranch(instruction, fixupAddress);
555 targetAddress = fixupAddress + 4 + displacement;
556 return atomFromAddress(reloc.symbol, targetAddress, target, addend);
557 case ARM_THUMB_RELOC_BR22 | rScattered | rPcRel | rLength4:
558 // ex: bl _foo+4 (and _foo is defined)
559 if ((instruction & 0xD000F800) == 0x9000F000)
560 *kind = thumb_b22;
561 else
562 *kind = thumb_bl22;
563 displacement = getDisplacementFromThumbBranch(instruction, fixupAddress);
564 targetAddress = fixupAddress + 4 + displacement;
565 if (auto ec = atomFromAddress(0, reloc.value, target, addend))
566 return ec;
567 // reloc.value is target atom's address. Instruction contains branch
568 // to atom+addend.
569 *addend += (targetAddress - reloc.value);
570 return llvm::Error::success();
571 case ARM_RELOC_BR24 | rPcRel | rExtern | rLength4:
572 // ex: bl _foo (and _foo is undefined)
573 if (((instruction & 0x0F000000) == 0x0A000000)
574 && ((instruction & 0xF0000000) != 0xF0000000))
575 *kind = arm_b24;
576 else
577 *kind = arm_bl24;
578 if (auto ec = atomFromSymbolIndex(reloc.symbol, target))
579 return ec;
580 // Instruction contains branch to addend.
581 displacement = getDisplacementFromArmBranch(instruction);
582 *addend = fixupAddress + 8 + displacement;
583 return llvm::Error::success();
584 case ARM_RELOC_BR24 | rPcRel | rLength4:
585 // ex: bl _foo (and _foo is defined)
586 if (((instruction & 0x0F000000) == 0x0A000000)
587 && ((instruction & 0xF0000000) != 0xF0000000))
588 *kind = arm_b24;
589 else
590 *kind = arm_bl24;
591 displacement = getDisplacementFromArmBranch(instruction);
592 targetAddress = fixupAddress + 8 + displacement;
593 return atomFromAddress(reloc.symbol, targetAddress, target, addend);
594 case ARM_RELOC_BR24 | rScattered | rPcRel | rLength4:
595 // ex: bl _foo+4 (and _foo is defined)
596 if (((instruction & 0x0F000000) == 0x0A000000)
597 && ((instruction & 0xF0000000) != 0xF0000000))
598 *kind = arm_b24;
599 else
600 *kind = arm_bl24;
601 displacement = getDisplacementFromArmBranch(instruction);
602 targetAddress = fixupAddress + 8 + displacement;
603 if (auto ec = atomFromAddress(0, reloc.value, target, addend))
604 return ec;
605 // reloc.value is target atom's address. Instruction contains branch
606 // to atom+addend.
607 *addend += (targetAddress - reloc.value);
608 return llvm::Error::success();
609 case ARM_RELOC_VANILLA | rExtern | rLength4:
610 // ex: .long _foo (and _foo is undefined)
611 *kind = pointer32;
612 if (auto ec = atomFromSymbolIndex(reloc.symbol, target))
613 return ec;
614 *addend = instruction;
615 return llvm::Error::success();
616 case ARM_RELOC_VANILLA | rLength4:
617 // ex: .long _foo (and _foo is defined)
618 *kind = pointer32;
619 if (auto ec = atomFromAddress(reloc.symbol, instruction, target, addend))
620 return ec;
621 *addend = clearThumbBit((uint32_t) * addend, *target);
622 return llvm::Error::success();
623 case ARM_RELOC_VANILLA | rScattered | rLength4:
624 // ex: .long _foo+a (and _foo is defined)
625 *kind = pointer32;
626 if (auto ec = atomFromAddress(0, reloc.value, target, addend))
627 return ec;
628 *addend += (clearThumbBit(instruction, *target) - reloc.value);
629 return llvm::Error::success();
630 default:
631 return llvm::make_error<GenericError>("unsupported arm relocation type");
632 }
633 return llvm::Error::success();
634}
635
636llvm::Error
637ArchHandler_arm::getPairReferenceInfo(const normalized::Relocation &reloc1,
638 const normalized::Relocation &reloc2,
639 const DefinedAtom *inAtom,
640 uint32_t offsetInAtom,
641 uint64_t fixupAddress, bool isBig,
642 bool scatterable,
643 FindAtomBySectionAndAddress atomFromAddr,
644 FindAtomBySymbolIndex atomFromSymbolIndex,
645 Reference::KindValue *kind,
646 const lld::Atom **target,
647 Reference::Addend *addend) {
648 bool pointerDiff = false;
649 bool funcRel;
650 bool top;
651 bool thumbReloc;
652 switch(relocPattern(reloc1) << 16 | relocPattern(reloc2)) {
653 case ((ARM_RELOC_HALF_SECTDIFF | rScattered | rLenThmbLo) << 16 |
654 ARM_RELOC_PAIR | rScattered | rLenThmbLo):
655 // ex: movw r1, :lower16:(_x-L1) [thumb mode]
656 *kind = thumb_movw_funcRel;
657 funcRel = true;
658 top = false;
659 thumbReloc = true;
660 break;
661 case ((ARM_RELOC_HALF_SECTDIFF | rScattered | rLenThmbHi) << 16 |
662 ARM_RELOC_PAIR | rScattered | rLenThmbHi):
663 // ex: movt r1, :upper16:(_x-L1) [thumb mode]
664 *kind = thumb_movt_funcRel;
665 funcRel = true;
666 top = true;
667 thumbReloc = true;
668 break;
669 case ((ARM_RELOC_HALF_SECTDIFF | rScattered | rLenArmLo) << 16 |
670 ARM_RELOC_PAIR | rScattered | rLenArmLo):
671 // ex: movw r1, :lower16:(_x-L1) [arm mode]
672 *kind = arm_movw_funcRel;
673 funcRel = true;
674 top = false;
675 thumbReloc = false;
676 break;
677 case ((ARM_RELOC_HALF_SECTDIFF | rScattered | rLenArmHi) << 16 |
678 ARM_RELOC_PAIR | rScattered | rLenArmHi):
679 // ex: movt r1, :upper16:(_x-L1) [arm mode]
680 *kind = arm_movt_funcRel;
681 funcRel = true;
682 top = true;
683 thumbReloc = false;
684 break;
685 case ((ARM_RELOC_HALF | rLenThmbLo) << 16 |
686 ARM_RELOC_PAIR | rLenThmbLo):
687 // ex: movw r1, :lower16:_x [thumb mode]
688 *kind = thumb_movw;
689 funcRel = false;
690 top = false;
691 thumbReloc = true;
692 break;
693 case ((ARM_RELOC_HALF | rLenThmbHi) << 16 |
694 ARM_RELOC_PAIR | rLenThmbHi):
695 // ex: movt r1, :upper16:_x [thumb mode]
696 *kind = thumb_movt;
697 funcRel = false;
698 top = true;
699 thumbReloc = true;
700 break;
701 case ((ARM_RELOC_HALF | rLenArmLo) << 16 |
702 ARM_RELOC_PAIR | rLenArmLo):
703 // ex: movw r1, :lower16:_x [arm mode]
704 *kind = arm_movw;
705 funcRel = false;
706 top = false;
707 thumbReloc = false;
708 break;
709 case ((ARM_RELOC_HALF | rLenArmHi) << 16 |
710 ARM_RELOC_PAIR | rLenArmHi):
711 // ex: movt r1, :upper16:_x [arm mode]
712 *kind = arm_movt;
713 funcRel = false;
714 top = true;
715 thumbReloc = false;
716 break;
717 case ((ARM_RELOC_HALF | rScattered | rLenThmbLo) << 16 |
718 ARM_RELOC_PAIR | rLenThmbLo):
719 // ex: movw r1, :lower16:_x+a [thumb mode]
720 *kind = thumb_movw;
721 funcRel = false;
722 top = false;
723 thumbReloc = true;
724 break;
725 case ((ARM_RELOC_HALF | rScattered | rLenThmbHi) << 16 |
726 ARM_RELOC_PAIR | rLenThmbHi):
727 // ex: movt r1, :upper16:_x+a [thumb mode]
728 *kind = thumb_movt;
729 funcRel = false;
730 top = true;
731 thumbReloc = true;
732 break;
733 case ((ARM_RELOC_HALF | rScattered | rLenArmLo) << 16 |
734 ARM_RELOC_PAIR | rLenArmLo):
735 // ex: movw r1, :lower16:_x+a [arm mode]
736 *kind = arm_movw;
737 funcRel = false;
738 top = false;
739 thumbReloc = false;
740 break;
741 case ((ARM_RELOC_HALF | rScattered | rLenArmHi) << 16 |
742 ARM_RELOC_PAIR | rLenArmHi):
743 // ex: movt r1, :upper16:_x+a [arm mode]
744 *kind = arm_movt;
745 funcRel = false;
746 top = true;
747 thumbReloc = false;
748 break;
749 case ((ARM_RELOC_HALF | rExtern | rLenThmbLo) << 16 |
750 ARM_RELOC_PAIR | rLenThmbLo):
751 // ex: movw r1, :lower16:_undef [thumb mode]
752 *kind = thumb_movw;
753 funcRel = false;
754 top = false;
755 thumbReloc = true;
756 break;
757 case ((ARM_RELOC_HALF | rExtern | rLenThmbHi) << 16 |
758 ARM_RELOC_PAIR | rLenThmbHi):
759 // ex: movt r1, :upper16:_undef [thumb mode]
760 *kind = thumb_movt;
761 funcRel = false;
762 top = true;
763 thumbReloc = true;
764 break;
765 case ((ARM_RELOC_HALF | rExtern | rLenArmLo) << 16 |
766 ARM_RELOC_PAIR | rLenArmLo):
767 // ex: movw r1, :lower16:_undef [arm mode]
768 *kind = arm_movw;
769 funcRel = false;
770 top = false;
771 thumbReloc = false;
772 break;
773 case ((ARM_RELOC_HALF | rExtern | rLenArmHi) << 16 |
774 ARM_RELOC_PAIR | rLenArmHi):
775 // ex: movt r1, :upper16:_undef [arm mode]
776 *kind = arm_movt;
777 funcRel = false;
778 top = true;
779 thumbReloc = false;
780 break;
781 case ((ARM_RELOC_SECTDIFF | rScattered | rLength4) << 16 |
782 ARM_RELOC_PAIR | rScattered | rLength4):
783 case ((ARM_RELOC_LOCAL_SECTDIFF | rScattered | rLength4) << 16 |
784 ARM_RELOC_PAIR | rScattered | rLength4):
785 // ex: .long _foo - .
786 pointerDiff = true;
787 break;
788 default:
789 return llvm::make_error<GenericError>("unsupported arm relocation pair");
790 }
791 const uint8_t *fixupContent = &inAtom->rawContent()[offsetInAtom];
792 uint32_t instruction = *(const ulittle32_t *)fixupContent;
793 uint32_t value;
794 uint32_t fromAddress;
795 uint32_t toAddress;
796 uint16_t instruction16;
797 uint16_t other16;
798 const lld::Atom *fromTarget;
799 Reference::Addend offsetInTo;
800 Reference::Addend offsetInFrom;
801 if (pointerDiff) {
802 toAddress = reloc1.value;
803 fromAddress = reloc2.value;
804 if (auto ec = atomFromAddr(0, toAddress, target, &offsetInTo))
805 return ec;
806 if (auto ec = atomFromAddr(0, fromAddress, &fromTarget, &offsetInFrom))
807 return ec;
808 if (scatterable && (fromTarget != inAtom))
809 return llvm::make_error<GenericError>(
810 "SECTDIFF relocation where subtrahend label is not in atom");
811 *kind = delta32;
812 value = clearThumbBit(instruction, *target);
813 *addend = (int32_t)(value - (toAddress - fixupAddress));
814 } else if (funcRel) {
815 toAddress = reloc1.value;
816 fromAddress = reloc2.value;
817 if (auto ec = atomFromAddr(0, toAddress, target, &offsetInTo))
818 return ec;
819 if (auto ec = atomFromAddr(0, fromAddress, &fromTarget, &offsetInFrom))
820 return ec;
821 if (fromTarget != inAtom)
822 return llvm::make_error<GenericError>("ARM_RELOC_HALF_SECTDIFF relocation"
823 " where subtrahend label is not in atom");
824 other16 = (reloc2.offset & 0xFFFF);
825 if (thumbReloc) {
826 if (top) {
827 if (!isThumbMovt(instruction))
828 return llvm::make_error<GenericError>("expected movt instruction");
829 }
830 else {
831 if (!isThumbMovw(instruction))
832 return llvm::make_error<GenericError>("expected movw instruction");
833 }
834 instruction16 = getWordFromThumbMov(instruction);
835 }
836 else {
837 if (top) {
838 if (!isArmMovt(instruction))
839 return llvm::make_error<GenericError>("expected movt instruction");
840 }
841 else {
842 if (!isArmMovw(instruction))
843 return llvm::make_error<GenericError>("expected movw instruction");
844 }
845 instruction16 = getWordFromArmMov(instruction);
846 }
847 if (top)
848 value = (instruction16 << 16) | other16;
849 else
850 value = (other16 << 16) | instruction16;
851 value = clearThumbBit(value, *target);
852 int64_t ta = (int64_t) value - (toAddress - fromAddress);
853 *addend = ta - offsetInFrom;
854 return llvm::Error::success();
855 } else {
856 uint32_t sectIndex;
857 if (thumbReloc) {
858 if (top) {
859 if (!isThumbMovt(instruction))
860 return llvm::make_error<GenericError>("expected movt instruction");
861 }
862 else {
863 if (!isThumbMovw(instruction))
864 return llvm::make_error<GenericError>("expected movw instruction");
865 }
866 instruction16 = getWordFromThumbMov(instruction);
867 }
868 else {
869 if (top) {
870 if (!isArmMovt(instruction))
871 return llvm::make_error<GenericError>("expected movt instruction");
872 }
873 else {
874 if (!isArmMovw(instruction))
875 return llvm::make_error<GenericError>("expected movw instruction");
876 }
877 instruction16 = getWordFromArmMov(instruction);
878 }
879 other16 = (reloc2.offset & 0xFFFF);
880 if (top)
881 value = (instruction16 << 16) | other16;
882 else
883 value = (other16 << 16) | instruction16;
884 if (reloc1.isExtern) {
885 if (auto ec = atomFromSymbolIndex(reloc1.symbol, target))
886 return ec;
887 *addend = value;
888 } else {
889 if (reloc1.scattered) {
890 toAddress = reloc1.value;
891 sectIndex = 0;
892 } else {
893 toAddress = value;
894 sectIndex = reloc1.symbol;
895 }
896 if (auto ec = atomFromAddr(sectIndex, toAddress, target, &offsetInTo))
897 return ec;
898 *addend = value - toAddress;
899 }
900 }
901
902 return llvm::Error::success();
903}
904
905void ArchHandler_arm::applyFixupFinal(const Reference &ref, uint8_t *loc,
906 uint64_t fixupAddress,
907 uint64_t targetAddress,
908 uint64_t inAtomAddress,
909 bool &thumbMode, bool targetIsThumb) {
910 if (ref.kindNamespace() != Reference::KindNamespace::mach_o)
911 return;
912 assert(ref.kindArch() == Reference::KindArch::ARM);
913 ulittle32_t *loc32 = reinterpret_cast<ulittle32_t *>(loc);
914 int32_t displacement;
915 uint16_t value16;
916 uint32_t value32;
917 switch (static_cast<ArmKind>(ref.kindValue())) {
918 case modeThumbCode:
919 thumbMode = true;
920 break;
921 case modeArmCode:
922 thumbMode = false;
923 break;
924 case modeData:
925 break;
926 case thumb_b22:
927 case thumb_bl22:
928 assert(thumbMode);
929 displacement = (targetAddress - (fixupAddress + 4)) + ref.addend();
930 value32 = setDisplacementInThumbBranch(*loc32, fixupAddress,
931 displacement, targetIsThumb);
932 *loc32 = value32;
933 break;
934 case thumb_movw:
935 assert(thumbMode);
936 value16 = (targetAddress + ref.addend()) & 0xFFFF;
937 if (targetIsThumb)
938 value16 |= 1;
939 *loc32 = setWordFromThumbMov(*loc32, value16);
940 break;
941 case thumb_movt:
942 assert(thumbMode);
943 value16 = (targetAddress + ref.addend()) >> 16;
944 *loc32 = setWordFromThumbMov(*loc32, value16);
945 break;
946 case thumb_movw_funcRel:
947 assert(thumbMode);
948 value16 = (targetAddress - inAtomAddress + ref.addend()) & 0xFFFF;
949 if (targetIsThumb)
950 value16 |= 1;
951 *loc32 = setWordFromThumbMov(*loc32, value16);
952 break;
953 case thumb_movt_funcRel:
954 assert(thumbMode);
955 value16 = (targetAddress - inAtomAddress + ref.addend()) >> 16;
956 *loc32 = setWordFromThumbMov(*loc32, value16);
957 break;
958 case arm_b24:
959 case arm_bl24:
960 assert(!thumbMode);
961 displacement = (targetAddress - (fixupAddress + 8)) + ref.addend();
962 value32 = setDisplacementInArmBranch(*loc32, displacement, targetIsThumb);
963 *loc32 = value32;
964 break;
965 case arm_movw:
966 assert(!thumbMode);
967 value16 = (targetAddress + ref.addend()) & 0xFFFF;
968 if (targetIsThumb)
969 value16 |= 1;
970 *loc32 = setWordFromArmMov(*loc32, value16);
971 break;
972 case arm_movt:
973 assert(!thumbMode);
974 value16 = (targetAddress + ref.addend()) >> 16;
975 *loc32 = setWordFromArmMov(*loc32, value16);
976 break;
977 case arm_movw_funcRel:
978 assert(!thumbMode);
979 value16 = (targetAddress - inAtomAddress + ref.addend()) & 0xFFFF;
980 if (targetIsThumb)
981 value16 |= 1;
982 *loc32 = setWordFromArmMov(*loc32, value16);
983 break;
984 case arm_movt_funcRel:
985 assert(!thumbMode);
986 value16 = (targetAddress - inAtomAddress + ref.addend()) >> 16;
987 *loc32 = setWordFromArmMov(*loc32, value16);
988 break;
989 case pointer32:
990 if (targetIsThumb)
991 *loc32 = targetAddress + ref.addend() + 1;
992 else
993 *loc32 = targetAddress + ref.addend();
994 break;
995 case delta32:
996 if (targetIsThumb)
997 *loc32 = targetAddress - fixupAddress + ref.addend() + 1;
998 else
999 *loc32 = targetAddress - fixupAddress + ref.addend();
1000 break;
1001 case lazyPointer:
1002 // do nothing
1003 break;
1004 case lazyImmediateLocation:
1005 *loc32 = ref.addend();
1006 break;
1007 case invalid:
1008 llvm_unreachable("invalid ARM Reference Kind");
1009 break;
1010 }
1011}
1012
1013void ArchHandler_arm::generateAtomContent(const DefinedAtom &atom,
1014 bool relocatable,
1015 FindAddressForAtom findAddress,
1016 FindAddressForAtom findSectionAddress,
1017 uint64_t imageBaseAddress,
1018 llvm::MutableArrayRef<uint8_t> atomContentBuffer) {
1019 // Copy raw bytes.
1020 std::copy(atom.rawContent().begin(), atom.rawContent().end(),
1021 atomContentBuffer.begin());
1022 // Apply fix-ups.
1023 bool thumbMode = false;
1024 for (const Reference *ref : atom) {
1025 uint32_t offset = ref->offsetInAtom();
1026 const Atom *target = ref->target();
1027 uint64_t targetAddress = 0;
1028 bool targetIsThumb = false;
1029 if (const DefinedAtom *defTarg = dyn_cast<DefinedAtom>(target)) {
1030 targetAddress = findAddress(*target);
1031 targetIsThumb = isThumbFunction(*defTarg);
1032 }
1033 uint64_t atomAddress = findAddress(atom);
1034 uint64_t fixupAddress = atomAddress + offset;
1035 if (relocatable) {
1036 applyFixupRelocatable(*ref, &atomContentBuffer[offset], fixupAddress,
1037 targetAddress, atomAddress, thumbMode,
1038 targetIsThumb);
1039 } else {
1040 applyFixupFinal(*ref, &atomContentBuffer[offset], fixupAddress,
1041 targetAddress, atomAddress, thumbMode, targetIsThumb);
1042 }
1043 }
1044}
1045
1046bool ArchHandler_arm::useExternalRelocationTo(const Atom &target) {
1047 // Undefined symbols are referenced via external relocations.
1048 if (isa<UndefinedAtom>(&target))
1049 return true;
1050 if (const DefinedAtom *defAtom = dyn_cast<DefinedAtom>(&target)) {
1051 switch (defAtom->merge()) {
1052 case DefinedAtom::mergeAsTentative:
1053 // Tentative definitions are referenced via external relocations.
1054 return true;
1055 case DefinedAtom::mergeAsWeak:
1056 case DefinedAtom::mergeAsWeakAndAddressUsed:
1057 // Global weak-defs are referenced via external relocations.
1058 return (defAtom->scope() == DefinedAtom::scopeGlobal);
1059 default:
1060 break;
1061 }
1062 }
1063 // Everything else is reference via an internal relocation.
1064 return false;
1065}
1066
1067void ArchHandler_arm::applyFixupRelocatable(const Reference &ref, uint8_t *loc,
1068 uint64_t fixupAddress,
1069 uint64_t targetAddress,
1070 uint64_t inAtomAddress,
1071 bool &thumbMode,
1072 bool targetIsThumb) {
1073 if (ref.kindNamespace() != Reference::KindNamespace::mach_o)
1074 return;
1075 assert(ref.kindArch() == Reference::KindArch::ARM);
1076 bool useExternalReloc = useExternalRelocationTo(*ref.target());
1077 ulittle32_t *loc32 = reinterpret_cast<ulittle32_t *>(loc);
1078 int32_t displacement;
1079 uint16_t value16;
1080 uint32_t value32;
1081 bool targetIsUndef = isa<UndefinedAtom>(ref.target());
1082 switch (static_cast<ArmKind>(ref.kindValue())) {
1083 case modeThumbCode:
1084 thumbMode = true;
1085 break;
1086 case modeArmCode:
1087 thumbMode = false;
1088 break;
1089 case modeData:
1090 break;
1091 case thumb_b22:
1092 case thumb_bl22:
1093 assert(thumbMode);
1094 if (useExternalReloc)
1095 displacement = (ref.addend() - (fixupAddress + 4));
1096 else
1097 displacement = (targetAddress - (fixupAddress + 4)) + ref.addend();
1098 value32 = setDisplacementInThumbBranch(*loc32, fixupAddress,
1099 displacement,
1100 targetIsUndef || targetIsThumb);
1101 *loc32 = value32;
1102 break;
1103 case thumb_movw:
1104 assert(thumbMode);
1105 if (useExternalReloc)
1106 value16 = ref.addend() & 0xFFFF;
1107 else
1108 value16 = (targetAddress + ref.addend()) & 0xFFFF;
1109 *loc32 = setWordFromThumbMov(*loc32, value16);
1110 break;
1111 case thumb_movt:
1112 assert(thumbMode);
1113 if (useExternalReloc)
1114 value16 = ref.addend() >> 16;
1115 else
1116 value16 = (targetAddress + ref.addend()) >> 16;
1117 *loc32 = setWordFromThumbMov(*loc32, value16);
1118 break;
1119 case thumb_movw_funcRel:
1120 assert(thumbMode);
1121 value16 = (targetAddress - inAtomAddress + ref.addend()) & 0xFFFF;
1122 *loc32 = setWordFromThumbMov(*loc32, value16);
1123 break;
1124 case thumb_movt_funcRel:
1125 assert(thumbMode);
1126 value16 = (targetAddress - inAtomAddress + ref.addend()) >> 16;
1127 *loc32 = setWordFromThumbMov(*loc32, value16);
1128 break;
1129 case arm_b24:
1130 case arm_bl24:
1131 assert(!thumbMode);
1132 if (useExternalReloc)
1133 displacement = (ref.addend() - (fixupAddress + 8));
1134 else
1135 displacement = (targetAddress - (fixupAddress + 8)) + ref.addend();
1136 value32 = setDisplacementInArmBranch(*loc32, displacement,
1137 targetIsThumb);
1138 *loc32 = value32;
1139 break;
1140 case arm_movw:
1141 assert(!thumbMode);
1142 if (useExternalReloc)
1143 value16 = ref.addend() & 0xFFFF;
1144 else
1145 value16 = (targetAddress + ref.addend()) & 0xFFFF;
1146 *loc32 = setWordFromArmMov(*loc32, value16);
1147 break;
1148 case arm_movt:
1149 assert(!thumbMode);
1150 if (useExternalReloc)
1151 value16 = ref.addend() >> 16;
1152 else
1153 value16 = (targetAddress + ref.addend()) >> 16;
1154 *loc32 = setWordFromArmMov(*loc32, value16);
1155 break;
1156 case arm_movw_funcRel:
1157 assert(!thumbMode);
1158 value16 = (targetAddress - inAtomAddress + ref.addend()) & 0xFFFF;
1159 *loc32 = setWordFromArmMov(*loc32, value16);
1160 break;
1161 case arm_movt_funcRel:
1162 assert(!thumbMode);
1163 value16 = (targetAddress - inAtomAddress + ref.addend()) >> 16;
1164 *loc32 = setWordFromArmMov(*loc32, value16);
1165 break;
1166 case pointer32:
1167 *loc32 = targetAddress + ref.addend();
1168 break;
1169 case delta32:
1170 *loc32 = targetAddress - fixupAddress + ref.addend();
1171 break;
1172 case lazyPointer:
1173 case lazyImmediateLocation:
1174 // do nothing
1175 break;
1176 case invalid:
1177 llvm_unreachable("invalid ARM Reference Kind");
1178 break;
1179 }
1180}
1181
1182void ArchHandler_arm::appendSectionRelocations(
1183 const DefinedAtom &atom,
1184 uint64_t atomSectionOffset,
1185 const Reference &ref,
1186 FindSymbolIndexForAtom symbolIndexForAtom,
1187 FindSectionIndexForAtom sectionIndexForAtom,
1188 FindAddressForAtom addressForAtom,
1189 normalized::Relocations &relocs) {
1190 if (ref.kindNamespace() != Reference::KindNamespace::mach_o)
1191 return;
1192 assert(ref.kindArch() == Reference::KindArch::ARM);
1193 uint32_t sectionOffset = atomSectionOffset + ref.offsetInAtom();
1194 bool useExternalReloc = useExternalRelocationTo(*ref.target());
1195 uint32_t targetAtomAddress;
1196 uint32_t fromAtomAddress;
1197 uint16_t other16;
1198 switch (static_cast<ArmKind>(ref.kindValue())) {
1199 case modeThumbCode:
1200 case modeArmCode:
1201 case modeData:
1202 // Do nothing.
1203 break;
1204 case thumb_b22:
1205 case thumb_bl22:
1206 if (useExternalReloc) {
1207 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
1208 ARM_THUMB_RELOC_BR22 | rExtern | rPcRel | rLength4);
1209 } else {
1210 if (ref.addend() != 0)
1211 appendReloc(relocs, sectionOffset, 0, addressForAtom(*ref.target()),
1212 ARM_THUMB_RELOC_BR22 | rScattered | rPcRel | rLength4);
1213 else
1214 appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()),0,
1215 ARM_THUMB_RELOC_BR22 | rPcRel | rLength4);
1216 }
1217 break;
1218 case thumb_movw:
1219 if (useExternalReloc) {
1220 other16 = ref.addend() >> 16;
1221 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
1222 ARM_RELOC_HALF | rExtern | rLenThmbLo);
1223 appendReloc(relocs, other16, 0, 0,
1224 ARM_RELOC_PAIR | rLenThmbLo);
1225 } else {
1226 targetAtomAddress = addressForAtom(*ref.target());
1227 if (ref.addend() != 0) {
1228 other16 = (targetAtomAddress + ref.addend()) >> 16;
1229 appendReloc(relocs, sectionOffset, 0, targetAtomAddress,
1230 ARM_RELOC_HALF | rScattered | rLenThmbLo);
1231 appendReloc(relocs, other16, 0, 0,
1232 ARM_RELOC_PAIR | rLenThmbLo);
1233 } else {
1234 other16 = (targetAtomAddress + ref.addend()) >> 16;
1235 appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()),0,
1236 ARM_RELOC_HALF | rLenThmbLo);
1237 appendReloc(relocs, other16, 0, 0,
1238 ARM_RELOC_PAIR | rLenThmbLo);
1239 }
1240 }
1241 break;
1242 case thumb_movt:
1243 if (useExternalReloc) {
1244 other16 = ref.addend() & 0xFFFF;
1245 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
1246 ARM_RELOC_HALF | rExtern | rLenThmbHi);
1247 appendReloc(relocs, other16, 0, 0,
1248 ARM_RELOC_PAIR | rLenThmbHi);
1249 } else {
1250 targetAtomAddress = addressForAtom(*ref.target());
1251 if (ref.addend() != 0) {
1252 other16 = (targetAtomAddress + ref.addend()) & 0xFFFF;
1253 appendReloc(relocs, sectionOffset, 0, targetAtomAddress,
1254 ARM_RELOC_HALF | rScattered | rLenThmbHi);
1255 appendReloc(relocs, other16, 0, 0,
1256 ARM_RELOC_PAIR | rLenThmbHi);
1257 } else {
1258 other16 = (targetAtomAddress + ref.addend()) & 0xFFFF;
1259 appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()),0,
1260 ARM_RELOC_HALF | rLenThmbHi);
1261 appendReloc(relocs, other16, 0, 0,
1262 ARM_RELOC_PAIR | rLenThmbHi);
1263 }
1264 }
1265 break;
1266 case thumb_movw_funcRel:
1267 fromAtomAddress = addressForAtom(atom);
1268 targetAtomAddress = addressForAtom(*ref.target());
1269 other16 = (targetAtomAddress - fromAtomAddress + ref.addend()) >> 16;
1270 appendReloc(relocs, sectionOffset, 0, targetAtomAddress,
1271 ARM_RELOC_HALF_SECTDIFF | rScattered | rLenThmbLo);
1272 appendReloc(relocs, other16, 0, fromAtomAddress,
1273 ARM_RELOC_PAIR | rScattered | rLenThmbLo);
1274 break;
1275 case thumb_movt_funcRel:
1276 fromAtomAddress = addressForAtom(atom);
1277 targetAtomAddress = addressForAtom(*ref.target());
1278 other16 = (targetAtomAddress - fromAtomAddress + ref.addend()) & 0xFFFF;
1279 appendReloc(relocs, sectionOffset, 0, targetAtomAddress,
1280 ARM_RELOC_HALF_SECTDIFF | rScattered | rLenThmbHi);
1281 appendReloc(relocs, other16, 0, fromAtomAddress,
1282 ARM_RELOC_PAIR | rScattered | rLenThmbHi);
1283 break;
1284 case arm_b24:
1285 case arm_bl24:
1286 if (useExternalReloc) {
1287 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
1288 ARM_RELOC_BR24 | rExtern | rPcRel | rLength4);
1289 } else {
1290 if (ref.addend() != 0)
1291 appendReloc(relocs, sectionOffset, 0, addressForAtom(*ref.target()),
1292 ARM_RELOC_BR24 | rScattered | rPcRel | rLength4);
1293 else
1294 appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()),0,
1295 ARM_RELOC_BR24 | rPcRel | rLength4);
1296 }
1297 break;
1298 case arm_movw:
1299 if (useExternalReloc) {
1300 other16 = ref.addend() >> 16;
1301 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
1302 ARM_RELOC_HALF | rExtern | rLenArmLo);
1303 appendReloc(relocs, other16, 0, 0,
1304 ARM_RELOC_PAIR | rLenArmLo);
1305 } else {
1306 targetAtomAddress = addressForAtom(*ref.target());
1307 if (ref.addend() != 0) {
1308 other16 = (targetAtomAddress + ref.addend()) >> 16;
1309 appendReloc(relocs, sectionOffset, 0, targetAtomAddress,
1310 ARM_RELOC_HALF | rScattered | rLenArmLo);
1311 appendReloc(relocs, other16, 0, 0,
1312 ARM_RELOC_PAIR | rLenArmLo);
1313 } else {
1314 other16 = (targetAtomAddress + ref.addend()) >> 16;
1315 appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()),0,
1316 ARM_RELOC_HALF | rLenArmLo);
1317 appendReloc(relocs, other16, 0, 0,
1318 ARM_RELOC_PAIR | rLenArmLo);
1319 }
1320 }
1321 break;
1322 case arm_movt:
1323 if (useExternalReloc) {
1324 other16 = ref.addend() & 0xFFFF;
1325 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
1326 ARM_RELOC_HALF | rExtern | rLenArmHi);
1327 appendReloc(relocs, other16, 0, 0,
1328 ARM_RELOC_PAIR | rLenArmHi);
1329 } else {
1330 targetAtomAddress = addressForAtom(*ref.target());
1331 if (ref.addend() != 0) {
1332 other16 = (targetAtomAddress + ref.addend()) & 0xFFFF;
1333 appendReloc(relocs, sectionOffset, 0, targetAtomAddress,
1334 ARM_RELOC_HALF | rScattered | rLenArmHi);
1335 appendReloc(relocs, other16, 0, 0,
1336 ARM_RELOC_PAIR | rLenArmHi);
1337 } else {
1338 other16 = (targetAtomAddress + ref.addend()) & 0xFFFF;
1339 appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()),0,
1340 ARM_RELOC_HALF | rLenArmHi);
1341 appendReloc(relocs, other16, 0, 0,
1342 ARM_RELOC_PAIR | rLenArmHi);
1343 }
1344 }
1345 break;
1346 case arm_movw_funcRel:
1347 fromAtomAddress = addressForAtom(atom);
1348 targetAtomAddress = addressForAtom(*ref.target());
1349 other16 = (targetAtomAddress - fromAtomAddress + ref.addend()) >> 16;
1350 appendReloc(relocs, sectionOffset, 0, targetAtomAddress,
1351 ARM_RELOC_HALF_SECTDIFF | rScattered | rLenArmLo);
1352 appendReloc(relocs, other16, 0, fromAtomAddress,
1353 ARM_RELOC_PAIR | rScattered | rLenArmLo);
1354 break;
1355 case arm_movt_funcRel:
1356 fromAtomAddress = addressForAtom(atom);
1357 targetAtomAddress = addressForAtom(*ref.target());
1358 other16 = (targetAtomAddress - fromAtomAddress + ref.addend()) & 0xFFFF;
1359 appendReloc(relocs, sectionOffset, 0, targetAtomAddress,
1360 ARM_RELOC_HALF_SECTDIFF | rScattered | rLenArmHi);
1361 appendReloc(relocs, other16, 0, fromAtomAddress,
1362 ARM_RELOC_PAIR | rScattered | rLenArmHi);
1363 break;
1364 case pointer32:
1365 if (useExternalReloc) {
1366 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
1367 ARM_RELOC_VANILLA | rExtern | rLength4);
1368 }
1369 else {
1370 if (ref.addend() != 0)
1371 appendReloc(relocs, sectionOffset, 0, addressForAtom(*ref.target()),
1372 ARM_RELOC_VANILLA | rScattered | rLength4);
1373 else
1374 appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()),0,
1375 ARM_RELOC_VANILLA | rLength4);
1376 }
1377 break;
1378 case delta32:
1379 appendReloc(relocs, sectionOffset, 0, addressForAtom(*ref.target()),
1380 ARM_RELOC_SECTDIFF | rScattered | rLength4);
1381 appendReloc(relocs, sectionOffset, 0, addressForAtom(atom) +
1382 ref.offsetInAtom(),
1383 ARM_RELOC_PAIR | rScattered | rLength4);
1384 break;
1385 case lazyPointer:
1386 case lazyImmediateLocation:
1387 // do nothing
1388 break;
1389 case invalid:
1390 llvm_unreachable("invalid ARM Reference Kind");
1391 break;
1392 }
1393}
1394
1395void ArchHandler_arm::addAdditionalReferences(MachODefinedAtom &atom) {
1396 if (atom.isThumb()) {
1397 atom.addReference(Reference::KindNamespace::mach_o,
1398 Reference::KindArch::ARM, modeThumbCode, 0, &atom, 0);
1399 }
1400}
1401
1402bool ArchHandler_arm::isThumbFunction(const DefinedAtom &atom) {
1403 for (const Reference *ref : atom) {
1404 if (ref->offsetInAtom() != 0)
1405 return false;
1406 if (ref->kindNamespace() != Reference::KindNamespace::mach_o)
1407 continue;
1408 assert(ref->kindArch() == Reference::KindArch::ARM);
1409 if (ref->kindValue() == modeThumbCode)
1410 return true;
1411 }
1412 return false;
1413}
1414
1415class Thumb2ToArmShimAtom : public SimpleDefinedAtom {
1416public:
1417 Thumb2ToArmShimAtom(MachOFile &file, StringRef targetName,
1418 const DefinedAtom &target)
1419 : SimpleDefinedAtom(file) {
1420 addReference(Reference::KindNamespace::mach_o, Reference::KindArch::ARM,
1421 ArchHandler_arm::modeThumbCode, 0, this, 0);
1422 addReference(Reference::KindNamespace::mach_o, Reference::KindArch::ARM,
1423 ArchHandler_arm::delta32, 8, &target, 0);
1424 std::string name = std::string(targetName) + "$shim";
1425 StringRef tmp(name);
1426 _name = tmp.copy(file.allocator());
1427 }
1428
1429 ~Thumb2ToArmShimAtom() override = default;
1430
1431 StringRef name() const override {
1432 return _name;
1433 }
1434
1435 ContentType contentType() const override {
1436 return DefinedAtom::typeCode;
1437 }
1438
1439 Alignment alignment() const override { return 4; }
1440
1441 uint64_t size() const override {
1442 return 12;
1443 }
1444
1445 ContentPermissions permissions() const override {
1446 return DefinedAtom::permR_X;
1447 }
1448
1449 ArrayRef<uint8_t> rawContent() const override {
1450 static const uint8_t bytes[] =
1451 { 0xDF, 0xF8, 0x04, 0xC0, // ldr ip, pc + 4
1452 0xFF, 0x44, // add ip, pc, ip
1453 0x60, 0x47, // ldr pc, [ip]
1454 0x00, 0x00, 0x00, 0x00 }; // .long target - this
1455 assert(sizeof(bytes) == size());
1456 return llvm::makeArrayRef(bytes, sizeof(bytes));
1457 }
1458private:
1459 StringRef _name;
1460};
1461
1462class ArmToThumbShimAtom : public SimpleDefinedAtom {
1463public:
1464 ArmToThumbShimAtom(MachOFile &file, StringRef targetName,
1465 const DefinedAtom &target)
1466 : SimpleDefinedAtom(file) {
1467 addReference(Reference::KindNamespace::mach_o, Reference::KindArch::ARM,
1468 ArchHandler_arm::delta32, 12, &target, 0);
1469 std::string name = std::string(targetName) + "$shim";
1470 StringRef tmp(name);
1471 _name = tmp.copy(file.allocator());
1472 }
1473
1474 ~ArmToThumbShimAtom() override = default;
1475
1476 StringRef name() const override {
1477 return _name;
1478 }
1479
1480 ContentType contentType() const override {
1481 return DefinedAtom::typeCode;
1482 }
1483
1484 Alignment alignment() const override { return 4; }
1485
1486 uint64_t size() const override {
1487 return 16;
1488 }
1489
1490 ContentPermissions permissions() const override {
1491 return DefinedAtom::permR_X;
1492 }
1493
1494 ArrayRef<uint8_t> rawContent() const override {
1495 static const uint8_t bytes[] =
1496 { 0x04, 0xC0, 0x9F, 0xE5, // ldr ip, pc + 4
1497 0x0C, 0xC0, 0x8F, 0xE0, // add ip, pc, ip
1498 0x1C, 0xFF, 0x2F, 0xE1, // ldr pc, [ip]
1499 0x00, 0x00, 0x00, 0x00 }; // .long target - this
1500 assert(sizeof(bytes) == size());
1501 return llvm::makeArrayRef(bytes, sizeof(bytes));
1502 }
1503private:
1504 StringRef _name;
1505};
1506
1507const DefinedAtom *ArchHandler_arm::createShim(MachOFile &file,
1508 bool thumbToArm,
1509 const DefinedAtom &target) {
1510 bool isStub = (target.contentType() == DefinedAtom::typeStub);
1511 StringRef targetName = isStub ? stubName(target) : target.name();
1512 if (thumbToArm)
1513 return new (file.allocator()) Thumb2ToArmShimAtom(file, targetName, target);
1514 else
1515 return new (file.allocator()) ArmToThumbShimAtom(file, targetName, target);
1516}
1517
1518std::unique_ptr<mach_o::ArchHandler> ArchHandler::create_arm() {
1519 return std::unique_ptr<mach_o::ArchHandler>(new ArchHandler_arm());
1520}
1521
1522} // namespace mach_o
1523} // namespace lld
deps/lld/lib/ReaderWriter/MachO/ArchHandler_arm64.cpp created+898
......@@ -0,0 +1,898 @@
1//===- lib/FileFormat/MachO/ArchHandler_arm64.cpp -------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "ArchHandler.h"
11#include "Atoms.h"
12#include "MachONormalizedFileBinaryUtils.h"
13#include "llvm/ADT/StringRef.h"
14#include "llvm/ADT/StringSwitch.h"
15#include "llvm/ADT/Triple.h"
16#include "llvm/Support/Endian.h"
17#include "llvm/Support/ErrorHandling.h"
18#include "llvm/Support/Format.h"
19
20using namespace llvm::MachO;
21using namespace lld::mach_o::normalized;
22
23namespace lld {
24namespace mach_o {
25
26using llvm::support::ulittle32_t;
27using llvm::support::ulittle64_t;
28
29using llvm::support::little32_t;
30using llvm::support::little64_t;
31
32class ArchHandler_arm64 : public ArchHandler {
33public:
34 ArchHandler_arm64() = default;
35 ~ArchHandler_arm64() override = default;
36
37 const Registry::KindStrings *kindStrings() override { return _sKindStrings; }
38
39 Reference::KindArch kindArch() override {
40 return Reference::KindArch::AArch64;
41 }
42
43 /// Used by GOTPass to locate GOT References
44 bool isGOTAccess(const Reference &ref, bool &canBypassGOT) override {
45 if (ref.kindNamespace() != Reference::KindNamespace::mach_o)
46 return false;
47 assert(ref.kindArch() == Reference::KindArch::AArch64);
48 switch (ref.kindValue()) {
49 case gotPage21:
50 case gotOffset12:
51 canBypassGOT = true;
52 return true;
53 case delta32ToGOT:
54 case unwindCIEToPersonalityFunction:
55 case imageOffsetGot:
56 canBypassGOT = false;
57 return true;
58 default:
59 return false;
60 }
61 }
62
63 /// Used by GOTPass to update GOT References.
64 void updateReferenceToGOT(const Reference *ref, bool targetNowGOT) override {
65 // If GOT slot was instanciated, transform:
66 // gotPage21/gotOffset12 -> page21/offset12scale8
67 // If GOT slot optimized away, transform:
68 // gotPage21/gotOffset12 -> page21/addOffset12
69 assert(ref->kindNamespace() == Reference::KindNamespace::mach_o);
70 assert(ref->kindArch() == Reference::KindArch::AArch64);
71 switch (ref->kindValue()) {
72 case gotPage21:
73 const_cast<Reference *>(ref)->setKindValue(page21);
74 break;
75 case gotOffset12:
76 const_cast<Reference *>(ref)->setKindValue(targetNowGOT ?
77 offset12scale8 : addOffset12);
78 break;
79 case delta32ToGOT:
80 const_cast<Reference *>(ref)->setKindValue(delta32);
81 break;
82 case imageOffsetGot:
83 const_cast<Reference *>(ref)->setKindValue(imageOffset);
84 break;
85 default:
86 llvm_unreachable("Not a GOT reference");
87 }
88 }
89
90 const StubInfo &stubInfo() override { return _sStubInfo; }
91
92 bool isCallSite(const Reference &) override;
93 bool isNonCallBranch(const Reference &) override {
94 return false;
95 }
96
97 bool isPointer(const Reference &) override;
98 bool isPairedReloc(const normalized::Relocation &) override;
99
100 bool needsCompactUnwind() override {
101 return true;
102 }
103 Reference::KindValue imageOffsetKind() override {
104 return imageOffset;
105 }
106 Reference::KindValue imageOffsetKindIndirect() override {
107 return imageOffsetGot;
108 }
109
110 Reference::KindValue unwindRefToPersonalityFunctionKind() override {
111 return unwindCIEToPersonalityFunction;
112 }
113
114 Reference::KindValue unwindRefToCIEKind() override {
115 return negDelta32;
116 }
117
118 Reference::KindValue unwindRefToFunctionKind() override {
119 return unwindFDEToFunction;
120 }
121
122 Reference::KindValue unwindRefToEhFrameKind() override {
123 return unwindInfoToEhFrame;
124 }
125
126 Reference::KindValue pointerKind() override {
127 return pointer64;
128 }
129
130 Reference::KindValue lazyImmediateLocationKind() override {
131 return lazyImmediateLocation;
132 }
133
134 uint32_t dwarfCompactUnwindType() override {
135 return 0x03000000;
136 }
137
138 llvm::Error getReferenceInfo(const normalized::Relocation &reloc,
139 const DefinedAtom *inAtom,
140 uint32_t offsetInAtom,
141 uint64_t fixupAddress, bool isBig,
142 FindAtomBySectionAndAddress atomFromAddress,
143 FindAtomBySymbolIndex atomFromSymbolIndex,
144 Reference::KindValue *kind,
145 const lld::Atom **target,
146 Reference::Addend *addend) override;
147 llvm::Error
148 getPairReferenceInfo(const normalized::Relocation &reloc1,
149 const normalized::Relocation &reloc2,
150 const DefinedAtom *inAtom,
151 uint32_t offsetInAtom,
152 uint64_t fixupAddress, bool isBig, bool scatterable,
153 FindAtomBySectionAndAddress atomFromAddress,
154 FindAtomBySymbolIndex atomFromSymbolIndex,
155 Reference::KindValue *kind,
156 const lld::Atom **target,
157 Reference::Addend *addend) override;
158
159 bool needsLocalSymbolInRelocatableFile(const DefinedAtom *atom) override {
160 return (atom->contentType() == DefinedAtom::typeCString);
161 }
162
163 void generateAtomContent(const DefinedAtom &atom, bool relocatable,
164 FindAddressForAtom findAddress,
165 FindAddressForAtom findSectionAddress,
166 uint64_t imageBaseAddress,
167 llvm::MutableArrayRef<uint8_t> atomContentBuffer) override;
168
169 void appendSectionRelocations(const DefinedAtom &atom,
170 uint64_t atomSectionOffset,
171 const Reference &ref,
172 FindSymbolIndexForAtom symbolIndexForAtom,
173 FindSectionIndexForAtom sectionIndexForAtom,
174 FindAddressForAtom addressForAtom,
175 normalized::Relocations &relocs) override;
176
177private:
178 static const Registry::KindStrings _sKindStrings[];
179 static const StubInfo _sStubInfo;
180
181 enum Arm64Kind : Reference::KindValue {
182 invalid, /// for error condition
183
184 // Kinds found in mach-o .o files:
185 branch26, /// ex: bl _foo
186 page21, /// ex: adrp x1, _foo@PAGE
187 offset12, /// ex: ldrb w0, [x1, _foo@PAGEOFF]
188 offset12scale2, /// ex: ldrs w0, [x1, _foo@PAGEOFF]
189 offset12scale4, /// ex: ldr w0, [x1, _foo@PAGEOFF]
190 offset12scale8, /// ex: ldr x0, [x1, _foo@PAGEOFF]
191 offset12scale16, /// ex: ldr q0, [x1, _foo@PAGEOFF]
192 gotPage21, /// ex: adrp x1, _foo@GOTPAGE
193 gotOffset12, /// ex: ldr w0, [x1, _foo@GOTPAGEOFF]
194 tlvPage21, /// ex: adrp x1, _foo@TLVPAGE
195 tlvOffset12, /// ex: ldr w0, [x1, _foo@TLVPAGEOFF]
196
197 pointer64, /// ex: .quad _foo
198 delta64, /// ex: .quad _foo - .
199 delta32, /// ex: .long _foo - .
200 negDelta32, /// ex: .long . - _foo
201 pointer64ToGOT, /// ex: .quad _foo@GOT
202 delta32ToGOT, /// ex: .long _foo@GOT - .
203
204 // Kinds introduced by Passes:
205 addOffset12, /// Location contains LDR to change into ADD.
206 lazyPointer, /// Location contains a lazy pointer.
207 lazyImmediateLocation, /// Location contains immediate value used in stub.
208 imageOffset, /// Location contains offset of atom in final image
209 imageOffsetGot, /// Location contains offset of GOT entry for atom in
210 /// final image (typically personality function).
211 unwindCIEToPersonalityFunction, /// Nearly delta32ToGOT, but cannot be
212 /// rematerialized in relocatable object
213 /// (yay for implicit contracts!).
214 unwindFDEToFunction, /// Nearly delta64, but cannot be rematerialized in
215 /// relocatable object (yay for implicit contracts!).
216 unwindInfoToEhFrame, /// Fix low 24 bits of compact unwind encoding to
217 /// refer to __eh_frame entry.
218 };
219
220 void applyFixupFinal(const Reference &ref, uint8_t *location,
221 uint64_t fixupAddress, uint64_t targetAddress,
222 uint64_t inAtomAddress, uint64_t imageBaseAddress,
223 FindAddressForAtom findSectionAddress);
224
225 void applyFixupRelocatable(const Reference &ref, uint8_t *location,
226 uint64_t fixupAddress, uint64_t targetAddress,
227 uint64_t inAtomAddress, bool targetUnnamed);
228
229 // Utility functions for inspecting/updating instructions.
230 static uint32_t setDisplacementInBranch26(uint32_t instr, int32_t disp);
231 static uint32_t setDisplacementInADRP(uint32_t instr, int64_t disp);
232 static Arm64Kind offset12KindFromInstruction(uint32_t instr);
233 static uint32_t setImm12(uint32_t instr, uint32_t offset);
234};
235
236const Registry::KindStrings ArchHandler_arm64::_sKindStrings[] = {
237 LLD_KIND_STRING_ENTRY(invalid),
238 LLD_KIND_STRING_ENTRY(branch26),
239 LLD_KIND_STRING_ENTRY(page21),
240 LLD_KIND_STRING_ENTRY(offset12),
241 LLD_KIND_STRING_ENTRY(offset12scale2),
242 LLD_KIND_STRING_ENTRY(offset12scale4),
243 LLD_KIND_STRING_ENTRY(offset12scale8),
244 LLD_KIND_STRING_ENTRY(offset12scale16),
245 LLD_KIND_STRING_ENTRY(gotPage21),
246 LLD_KIND_STRING_ENTRY(gotOffset12),
247 LLD_KIND_STRING_ENTRY(tlvPage21),
248 LLD_KIND_STRING_ENTRY(tlvOffset12),
249 LLD_KIND_STRING_ENTRY(pointer64),
250 LLD_KIND_STRING_ENTRY(delta64),
251 LLD_KIND_STRING_ENTRY(delta32),
252 LLD_KIND_STRING_ENTRY(negDelta32),
253 LLD_KIND_STRING_ENTRY(pointer64ToGOT),
254 LLD_KIND_STRING_ENTRY(delta32ToGOT),
255
256 LLD_KIND_STRING_ENTRY(addOffset12),
257 LLD_KIND_STRING_ENTRY(lazyPointer),
258 LLD_KIND_STRING_ENTRY(lazyImmediateLocation),
259 LLD_KIND_STRING_ENTRY(imageOffset),
260 LLD_KIND_STRING_ENTRY(imageOffsetGot),
261 LLD_KIND_STRING_ENTRY(unwindCIEToPersonalityFunction),
262 LLD_KIND_STRING_ENTRY(unwindFDEToFunction),
263 LLD_KIND_STRING_ENTRY(unwindInfoToEhFrame),
264
265 LLD_KIND_STRING_END
266};
267
268const ArchHandler::StubInfo ArchHandler_arm64::_sStubInfo = {
269 "dyld_stub_binder",
270
271 // Lazy pointer references
272 { Reference::KindArch::AArch64, pointer64, 0, 0 },
273 { Reference::KindArch::AArch64, lazyPointer, 0, 0 },
274
275 // GOT pointer to dyld_stub_binder
276 { Reference::KindArch::AArch64, pointer64, 0, 0 },
277
278 // arm64 code alignment 2^1
279 1,
280
281 // Stub size and code
282 12,
283 { 0x10, 0x00, 0x00, 0x90, // ADRP X16, lazy_pointer@page
284 0x10, 0x02, 0x40, 0xF9, // LDR X16, [X16, lazy_pointer@pageoff]
285 0x00, 0x02, 0x1F, 0xD6 }, // BR X16
286 { Reference::KindArch::AArch64, page21, 0, 0 },
287 { true, offset12scale8, 4, 0 },
288
289 // Stub Helper size and code
290 12,
291 { 0x50, 0x00, 0x00, 0x18, // LDR W16, L0
292 0x00, 0x00, 0x00, 0x14, // LDR B helperhelper
293 0x00, 0x00, 0x00, 0x00 }, // L0: .long 0
294 { Reference::KindArch::AArch64, lazyImmediateLocation, 8, 0 },
295 { Reference::KindArch::AArch64, branch26, 4, 0 },
296
297 // Stub helper image cache content type
298 DefinedAtom::typeGOT,
299
300 // Stub Helper-Common size and code
301 24,
302 // Stub helper alignment
303 2,
304 { 0x11, 0x00, 0x00, 0x90, // ADRP X17, dyld_ImageLoaderCache@page
305 0x31, 0x02, 0x00, 0x91, // ADD X17, X17, dyld_ImageLoaderCache@pageoff
306 0xF0, 0x47, 0xBF, 0xA9, // STP X16/X17, [SP, #-16]!
307 0x10, 0x00, 0x00, 0x90, // ADRP X16, _fast_lazy_bind@page
308 0x10, 0x02, 0x40, 0xF9, // LDR X16, [X16,_fast_lazy_bind@pageoff]
309 0x00, 0x02, 0x1F, 0xD6 }, // BR X16
310 { Reference::KindArch::AArch64, page21, 0, 0 },
311 { true, offset12, 4, 0 },
312 { Reference::KindArch::AArch64, page21, 12, 0 },
313 { true, offset12scale8, 16, 0 }
314};
315
316bool ArchHandler_arm64::isCallSite(const Reference &ref) {
317 if (ref.kindNamespace() != Reference::KindNamespace::mach_o)
318 return false;
319 assert(ref.kindArch() == Reference::KindArch::AArch64);
320 return (ref.kindValue() == branch26);
321}
322
323bool ArchHandler_arm64::isPointer(const Reference &ref) {
324 if (ref.kindNamespace() != Reference::KindNamespace::mach_o)
325 return false;
326 assert(ref.kindArch() == Reference::KindArch::AArch64);
327 Reference::KindValue kind = ref.kindValue();
328 return (kind == pointer64);
329}
330
331bool ArchHandler_arm64::isPairedReloc(const Relocation &r) {
332 return ((r.type == ARM64_RELOC_ADDEND) || (r.type == ARM64_RELOC_SUBTRACTOR));
333}
334
335uint32_t ArchHandler_arm64::setDisplacementInBranch26(uint32_t instr,
336 int32_t displacement) {
337 assert((displacement <= 134217727) && (displacement > (-134217728)) &&
338 "arm64 branch out of range");
339 return (instr & 0xFC000000) | ((uint32_t)(displacement >> 2) & 0x03FFFFFF);
340}
341
342uint32_t ArchHandler_arm64::setDisplacementInADRP(uint32_t instruction,
343 int64_t displacement) {
344 assert((displacement <= 0x100000000LL) && (displacement > (-0x100000000LL)) &&
345 "arm64 ADRP out of range");
346 assert(((instruction & 0x9F000000) == 0x90000000) &&
347 "reloc not on ADRP instruction");
348 uint32_t immhi = (displacement >> 9) & (0x00FFFFE0);
349 uint32_t immlo = (displacement << 17) & (0x60000000);
350 return (instruction & 0x9F00001F) | immlo | immhi;
351}
352
353ArchHandler_arm64::Arm64Kind
354ArchHandler_arm64::offset12KindFromInstruction(uint32_t instruction) {
355 if (instruction & 0x08000000) {
356 switch ((instruction >> 30) & 0x3) {
357 case 0:
358 if ((instruction & 0x04800000) == 0x04800000)
359 return offset12scale16;
360 return offset12;
361 case 1:
362 return offset12scale2;
363 case 2:
364 return offset12scale4;
365 case 3:
366 return offset12scale8;
367 }
368 }
369 return offset12;
370}
371
372uint32_t ArchHandler_arm64::setImm12(uint32_t instruction, uint32_t offset) {
373 assert(((offset & 0xFFFFF000) == 0) && "imm12 offset out of range");
374 uint32_t imm12 = offset << 10;
375 return (instruction & 0xFFC003FF) | imm12;
376}
377
378llvm::Error ArchHandler_arm64::getReferenceInfo(
379 const Relocation &reloc, const DefinedAtom *inAtom, uint32_t offsetInAtom,
380 uint64_t fixupAddress, bool isBig,
381 FindAtomBySectionAndAddress atomFromAddress,
382 FindAtomBySymbolIndex atomFromSymbolIndex, Reference::KindValue *kind,
383 const lld::Atom **target, Reference::Addend *addend) {
384 const uint8_t *fixupContent = &inAtom->rawContent()[offsetInAtom];
385 switch (relocPattern(reloc)) {
386 case ARM64_RELOC_BRANCH26 | rPcRel | rExtern | rLength4:
387 // ex: bl _foo
388 *kind = branch26;
389 if (auto ec = atomFromSymbolIndex(reloc.symbol, target))
390 return ec;
391 *addend = 0;
392 return llvm::Error::success();
393 case ARM64_RELOC_PAGE21 | rPcRel | rExtern | rLength4:
394 // ex: adrp x1, _foo@PAGE
395 *kind = page21;
396 if (auto ec = atomFromSymbolIndex(reloc.symbol, target))
397 return ec;
398 *addend = 0;
399 return llvm::Error::success();
400 case ARM64_RELOC_PAGEOFF12 | rExtern | rLength4:
401 // ex: ldr x0, [x1, _foo@PAGEOFF]
402 *kind = offset12KindFromInstruction(*(const little32_t *)fixupContent);
403 if (auto ec = atomFromSymbolIndex(reloc.symbol, target))
404 return ec;
405 *addend = 0;
406 return llvm::Error::success();
407 case ARM64_RELOC_GOT_LOAD_PAGE21 | rPcRel | rExtern | rLength4:
408 // ex: adrp x1, _foo@GOTPAGE
409 *kind = gotPage21;
410 if (auto ec = atomFromSymbolIndex(reloc.symbol, target))
411 return ec;
412 *addend = 0;
413 return llvm::Error::success();
414 case ARM64_RELOC_GOT_LOAD_PAGEOFF12 | rExtern | rLength4:
415 // ex: ldr x0, [x1, _foo@GOTPAGEOFF]
416 *kind = gotOffset12;
417 if (auto ec = atomFromSymbolIndex(reloc.symbol, target))
418 return ec;
419 *addend = 0;
420 return llvm::Error::success();
421 case ARM64_RELOC_TLVP_LOAD_PAGE21 | rPcRel | rExtern | rLength4:
422 // ex: adrp x1, _foo@TLVPAGE
423 *kind = tlvPage21;
424 if (auto ec = atomFromSymbolIndex(reloc.symbol, target))
425 return ec;
426 *addend = 0;
427 return llvm::Error::success();
428 case ARM64_RELOC_TLVP_LOAD_PAGEOFF12 | rExtern | rLength4:
429 // ex: ldr x0, [x1, _foo@TLVPAGEOFF]
430 *kind = tlvOffset12;
431 if (auto ec = atomFromSymbolIndex(reloc.symbol, target))
432 return ec;
433 *addend = 0;
434 return llvm::Error::success();
435 case ARM64_RELOC_UNSIGNED | rExtern | rLength8:
436 // ex: .quad _foo + N
437 *kind = pointer64;
438 if (auto ec = atomFromSymbolIndex(reloc.symbol, target))
439 return ec;
440 *addend = *(const little64_t *)fixupContent;
441 return llvm::Error::success();
442 case ARM64_RELOC_UNSIGNED | rLength8:
443 // ex: .quad Lfoo + N
444 *kind = pointer64;
445 return atomFromAddress(reloc.symbol, *(const little64_t *)fixupContent,
446 target, addend);
447 case ARM64_RELOC_POINTER_TO_GOT | rExtern | rLength8:
448 // ex: .quad _foo@GOT
449 *kind = pointer64ToGOT;
450 if (auto ec = atomFromSymbolIndex(reloc.symbol, target))
451 return ec;
452 *addend = 0;
453 return llvm::Error::success();
454 case ARM64_RELOC_POINTER_TO_GOT | rPcRel | rExtern | rLength4:
455 // ex: .long _foo@GOT - .
456
457 // If we are in an .eh_frame section, then the kind of the relocation should
458 // not be delta32ToGOT. It may instead be unwindCIEToPersonalityFunction.
459 if (inAtom->contentType() == DefinedAtom::typeCFI)
460 *kind = unwindCIEToPersonalityFunction;
461 else
462 *kind = delta32ToGOT;
463
464 if (auto ec = atomFromSymbolIndex(reloc.symbol, target))
465 return ec;
466 *addend = 0;
467 return llvm::Error::success();
468 default:
469 return llvm::make_error<GenericError>("unsupported arm64 relocation type");
470 }
471}
472
473llvm::Error ArchHandler_arm64::getPairReferenceInfo(
474 const normalized::Relocation &reloc1, const normalized::Relocation &reloc2,
475 const DefinedAtom *inAtom, uint32_t offsetInAtom, uint64_t fixupAddress,
476 bool swap, bool scatterable, FindAtomBySectionAndAddress atomFromAddress,
477 FindAtomBySymbolIndex atomFromSymbolIndex, Reference::KindValue *kind,
478 const lld::Atom **target, Reference::Addend *addend) {
479 const uint8_t *fixupContent = &inAtom->rawContent()[offsetInAtom];
480 switch (relocPattern(reloc1) << 16 | relocPattern(reloc2)) {
481 case ((ARM64_RELOC_ADDEND | rLength4) << 16 |
482 ARM64_RELOC_BRANCH26 | rPcRel | rExtern | rLength4):
483 // ex: bl _foo+8
484 *kind = branch26;
485 if (auto ec = atomFromSymbolIndex(reloc2.symbol, target))
486 return ec;
487 *addend = reloc1.symbol;
488 return llvm::Error::success();
489 case ((ARM64_RELOC_ADDEND | rLength4) << 16 |
490 ARM64_RELOC_PAGE21 | rPcRel | rExtern | rLength4):
491 // ex: adrp x1, _foo@PAGE
492 *kind = page21;
493 if (auto ec = atomFromSymbolIndex(reloc2.symbol, target))
494 return ec;
495 *addend = reloc1.symbol;
496 return llvm::Error::success();
497 case ((ARM64_RELOC_ADDEND | rLength4) << 16 |
498 ARM64_RELOC_PAGEOFF12 | rExtern | rLength4): {
499 // ex: ldr w0, [x1, _foo@PAGEOFF]
500 uint32_t cont32 = (int32_t)*(const little32_t *)fixupContent;
501 *kind = offset12KindFromInstruction(cont32);
502 if (auto ec = atomFromSymbolIndex(reloc2.symbol, target))
503 return ec;
504 *addend = reloc1.symbol;
505 return llvm::Error::success();
506 }
507 case ((ARM64_RELOC_SUBTRACTOR | rExtern | rLength8) << 16 |
508 ARM64_RELOC_UNSIGNED | rExtern | rLength8):
509 // ex: .quad _foo - .
510 if (auto ec = atomFromSymbolIndex(reloc2.symbol, target))
511 return ec;
512
513 // If we are in an .eh_frame section, then the kind of the relocation should
514 // not be delta64. It may instead be unwindFDEToFunction.
515 if (inAtom->contentType() == DefinedAtom::typeCFI)
516 *kind = unwindFDEToFunction;
517 else
518 *kind = delta64;
519
520 // The offsets of the 2 relocations must match
521 if (reloc1.offset != reloc2.offset)
522 return llvm::make_error<GenericError>(
523 "paired relocs must have the same offset");
524 *addend = (int64_t)*(const little64_t *)fixupContent + offsetInAtom;
525 return llvm::Error::success();
526 case ((ARM64_RELOC_SUBTRACTOR | rExtern | rLength4) << 16 |
527 ARM64_RELOC_UNSIGNED | rExtern | rLength4):
528 // ex: .quad _foo - .
529 *kind = delta32;
530 if (auto ec = atomFromSymbolIndex(reloc2.symbol, target))
531 return ec;
532 *addend = (int32_t)*(const little32_t *)fixupContent + offsetInAtom;
533 return llvm::Error::success();
534 default:
535 return llvm::make_error<GenericError>("unsupported arm64 relocation pair");
536 }
537}
538
539void ArchHandler_arm64::generateAtomContent(
540 const DefinedAtom &atom, bool relocatable, FindAddressForAtom findAddress,
541 FindAddressForAtom findSectionAddress, uint64_t imageBaseAddress,
542 llvm::MutableArrayRef<uint8_t> atomContentBuffer) {
543 // Copy raw bytes.
544 std::copy(atom.rawContent().begin(), atom.rawContent().end(),
545 atomContentBuffer.begin());
546 // Apply fix-ups.
547#ifndef NDEBUG
548 if (atom.begin() != atom.end()) {
549 DEBUG_WITH_TYPE("atom-content", llvm::dbgs()
550 << "Applying fixups to atom:\n"
551 << " address="
552 << llvm::format(" 0x%09lX", &atom)
553 << ", file=#"
554 << atom.file().ordinal()
555 << ", atom=#"
556 << atom.ordinal()
557 << ", name="
558 << atom.name()
559 << ", type="
560 << atom.contentType()
561 << "\n");
562 }
563#endif
564 for (const Reference *ref : atom) {
565 uint32_t offset = ref->offsetInAtom();
566 const Atom *target = ref->target();
567 bool targetUnnamed = target->name().empty();
568 uint64_t targetAddress = 0;
569 if (isa<DefinedAtom>(target))
570 targetAddress = findAddress(*target);
571 uint64_t atomAddress = findAddress(atom);
572 uint64_t fixupAddress = atomAddress + offset;
573 if (relocatable) {
574 applyFixupRelocatable(*ref, &atomContentBuffer[offset], fixupAddress,
575 targetAddress, atomAddress, targetUnnamed);
576 } else {
577 applyFixupFinal(*ref, &atomContentBuffer[offset], fixupAddress,
578 targetAddress, atomAddress, imageBaseAddress,
579 findSectionAddress);
580 }
581 }
582}
583
584void ArchHandler_arm64::applyFixupFinal(const Reference &ref, uint8_t *loc,
585 uint64_t fixupAddress,
586 uint64_t targetAddress,
587 uint64_t inAtomAddress,
588 uint64_t imageBaseAddress,
589 FindAddressForAtom findSectionAddress) {
590 if (ref.kindNamespace() != Reference::KindNamespace::mach_o)
591 return;
592 assert(ref.kindArch() == Reference::KindArch::AArch64);
593 ulittle32_t *loc32 = reinterpret_cast<ulittle32_t *>(loc);
594 ulittle64_t *loc64 = reinterpret_cast<ulittle64_t *>(loc);
595 int32_t displacement;
596 uint32_t instruction;
597 uint32_t value32;
598 uint32_t value64;
599 switch (static_cast<Arm64Kind>(ref.kindValue())) {
600 case branch26:
601 displacement = (targetAddress - fixupAddress) + ref.addend();
602 *loc32 = setDisplacementInBranch26(*loc32, displacement);
603 return;
604 case page21:
605 case gotPage21:
606 case tlvPage21:
607 displacement =
608 ((targetAddress + ref.addend()) & (-4096)) - (fixupAddress & (-4096));
609 *loc32 = setDisplacementInADRP(*loc32, displacement);
610 return;
611 case offset12:
612 case gotOffset12:
613 case tlvOffset12:
614 displacement = (targetAddress + ref.addend()) & 0x00000FFF;
615 *loc32 = setImm12(*loc32, displacement);
616 return;
617 case offset12scale2:
618 displacement = (targetAddress + ref.addend()) & 0x00000FFF;
619 assert(((displacement & 0x1) == 0) &&
620 "scaled imm12 not accessing 2-byte aligneds");
621 *loc32 = setImm12(*loc32, displacement >> 1);
622 return;
623 case offset12scale4:
624 displacement = (targetAddress + ref.addend()) & 0x00000FFF;
625 assert(((displacement & 0x3) == 0) &&
626 "scaled imm12 not accessing 4-byte aligned");
627 *loc32 = setImm12(*loc32, displacement >> 2);
628 return;
629 case offset12scale8:
630 displacement = (targetAddress + ref.addend()) & 0x00000FFF;
631 assert(((displacement & 0x7) == 0) &&
632 "scaled imm12 not accessing 8-byte aligned");
633 *loc32 = setImm12(*loc32, displacement >> 3);
634 return;
635 case offset12scale16:
636 displacement = (targetAddress + ref.addend()) & 0x00000FFF;
637 assert(((displacement & 0xF) == 0) &&
638 "scaled imm12 not accessing 16-byte aligned");
639 *loc32 = setImm12(*loc32, displacement >> 4);
640 return;
641 case addOffset12:
642 instruction = *loc32;
643 assert(((instruction & 0xFFC00000) == 0xF9400000) &&
644 "GOT reloc is not an LDR instruction");
645 displacement = (targetAddress + ref.addend()) & 0x00000FFF;
646 value32 = 0x91000000 | (instruction & 0x000003FF);
647 instruction = setImm12(value32, displacement);
648 *loc32 = instruction;
649 return;
650 case pointer64:
651 case pointer64ToGOT:
652 *loc64 = targetAddress + ref.addend();
653 return;
654 case delta64:
655 case unwindFDEToFunction:
656 *loc64 = (targetAddress - fixupAddress) + ref.addend();
657 return;
658 case delta32:
659 case delta32ToGOT:
660 case unwindCIEToPersonalityFunction:
661 *loc32 = (targetAddress - fixupAddress) + ref.addend();
662 return;
663 case negDelta32:
664 *loc32 = fixupAddress - targetAddress + ref.addend();
665 return;
666 case lazyPointer:
667 // Do nothing
668 return;
669 case lazyImmediateLocation:
670 *loc32 = ref.addend();
671 return;
672 case imageOffset:
673 *loc32 = (targetAddress - imageBaseAddress) + ref.addend();
674 return;
675 case imageOffsetGot:
676 llvm_unreachable("imageOffsetGot should have been changed to imageOffset");
677 break;
678 case unwindInfoToEhFrame:
679 value64 = targetAddress - findSectionAddress(*ref.target()) + ref.addend();
680 assert(value64 < 0xffffffU && "offset in __eh_frame too large");
681 *loc32 = (*loc32 & 0xff000000U) | value64;
682 return;
683 case invalid:
684 // Fall into llvm_unreachable().
685 break;
686 }
687 llvm_unreachable("invalid arm64 Reference Kind");
688}
689
690void ArchHandler_arm64::applyFixupRelocatable(const Reference &ref,
691 uint8_t *loc,
692 uint64_t fixupAddress,
693 uint64_t targetAddress,
694 uint64_t inAtomAddress,
695 bool targetUnnamed) {
696 if (ref.kindNamespace() != Reference::KindNamespace::mach_o)
697 return;
698 assert(ref.kindArch() == Reference::KindArch::AArch64);
699 ulittle32_t *loc32 = reinterpret_cast<ulittle32_t *>(loc);
700 ulittle64_t *loc64 = reinterpret_cast<ulittle64_t *>(loc);
701 switch (static_cast<Arm64Kind>(ref.kindValue())) {
702 case branch26:
703 *loc32 = setDisplacementInBranch26(*loc32, 0);
704 return;
705 case page21:
706 case gotPage21:
707 case tlvPage21:
708 *loc32 = setDisplacementInADRP(*loc32, 0);
709 return;
710 case offset12:
711 case offset12scale2:
712 case offset12scale4:
713 case offset12scale8:
714 case offset12scale16:
715 case gotOffset12:
716 case tlvOffset12:
717 *loc32 = setImm12(*loc32, 0);
718 return;
719 case pointer64:
720 if (targetUnnamed)
721 *loc64 = targetAddress + ref.addend();
722 else
723 *loc64 = ref.addend();
724 return;
725 case delta64:
726 *loc64 = ref.addend() + inAtomAddress - fixupAddress;
727 return;
728 case unwindFDEToFunction:
729 // We don't emit unwindFDEToFunction in -r mode as they are implicitly
730 // generated from the data in the __eh_frame section. So here we need
731 // to use the targetAddress so that we can generate the full relocation
732 // when we parse again later.
733 *loc64 = targetAddress - fixupAddress;
734 return;
735 case delta32:
736 *loc32 = ref.addend() + inAtomAddress - fixupAddress;
737 return;
738 case negDelta32:
739 // We don't emit negDelta32 in -r mode as they are implicitly
740 // generated from the data in the __eh_frame section. So here we need
741 // to use the targetAddress so that we can generate the full relocation
742 // when we parse again later.
743 *loc32 = fixupAddress - targetAddress + ref.addend();
744 return;
745 case pointer64ToGOT:
746 *loc64 = 0;
747 return;
748 case delta32ToGOT:
749 *loc32 = inAtomAddress - fixupAddress;
750 return;
751 case unwindCIEToPersonalityFunction:
752 // We don't emit unwindCIEToPersonalityFunction in -r mode as they are
753 // implicitly generated from the data in the __eh_frame section. So here we
754 // need to use the targetAddress so that we can generate the full relocation
755 // when we parse again later.
756 *loc32 = targetAddress - fixupAddress;
757 return;
758 case addOffset12:
759 llvm_unreachable("lazy reference kind implies GOT pass was run");
760 case lazyPointer:
761 case lazyImmediateLocation:
762 llvm_unreachable("lazy reference kind implies Stubs pass was run");
763 case imageOffset:
764 case imageOffsetGot:
765 case unwindInfoToEhFrame:
766 llvm_unreachable("fixup implies __unwind_info");
767 return;
768 case invalid:
769 // Fall into llvm_unreachable().
770 break;
771 }
772 llvm_unreachable("unknown arm64 Reference Kind");
773}
774
775void ArchHandler_arm64::appendSectionRelocations(
776 const DefinedAtom &atom, uint64_t atomSectionOffset, const Reference &ref,
777 FindSymbolIndexForAtom symbolIndexForAtom,
778 FindSectionIndexForAtom sectionIndexForAtom,
779 FindAddressForAtom addressForAtom, normalized::Relocations &relocs) {
780 if (ref.kindNamespace() != Reference::KindNamespace::mach_o)
781 return;
782 assert(ref.kindArch() == Reference::KindArch::AArch64);
783 uint32_t sectionOffset = atomSectionOffset + ref.offsetInAtom();
784 switch (static_cast<Arm64Kind>(ref.kindValue())) {
785 case branch26:
786 if (ref.addend()) {
787 appendReloc(relocs, sectionOffset, ref.addend(), 0,
788 ARM64_RELOC_ADDEND | rLength4);
789 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
790 ARM64_RELOC_BRANCH26 | rPcRel | rExtern | rLength4);
791 } else {
792 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
793 ARM64_RELOC_BRANCH26 | rPcRel | rExtern | rLength4);
794 }
795 return;
796 case page21:
797 if (ref.addend()) {
798 appendReloc(relocs, sectionOffset, ref.addend(), 0,
799 ARM64_RELOC_ADDEND | rLength4);
800 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
801 ARM64_RELOC_PAGE21 | rPcRel | rExtern | rLength4);
802 } else {
803 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
804 ARM64_RELOC_PAGE21 | rPcRel | rExtern | rLength4);
805 }
806 return;
807 case offset12:
808 case offset12scale2:
809 case offset12scale4:
810 case offset12scale8:
811 case offset12scale16:
812 if (ref.addend()) {
813 appendReloc(relocs, sectionOffset, ref.addend(), 0,
814 ARM64_RELOC_ADDEND | rLength4);
815 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
816 ARM64_RELOC_PAGEOFF12 | rExtern | rLength4);
817 } else {
818 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
819 ARM64_RELOC_PAGEOFF12 | rExtern | rLength4);
820 }
821 return;
822 case gotPage21:
823 assert(ref.addend() == 0);
824 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
825 ARM64_RELOC_GOT_LOAD_PAGE21 | rPcRel | rExtern | rLength4);
826 return;
827 case gotOffset12:
828 assert(ref.addend() == 0);
829 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
830 ARM64_RELOC_GOT_LOAD_PAGEOFF12 | rExtern | rLength4);
831 return;
832 case tlvPage21:
833 assert(ref.addend() == 0);
834 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
835 ARM64_RELOC_TLVP_LOAD_PAGE21 | rPcRel | rExtern | rLength4);
836 return;
837 case tlvOffset12:
838 assert(ref.addend() == 0);
839 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
840 ARM64_RELOC_TLVP_LOAD_PAGEOFF12 | rExtern | rLength4);
841 return;
842 case pointer64:
843 if (ref.target()->name().empty())
844 appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()), 0,
845 ARM64_RELOC_UNSIGNED | rLength8);
846 else
847 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
848 ARM64_RELOC_UNSIGNED | rExtern | rLength8);
849 return;
850 case delta64:
851 appendReloc(relocs, sectionOffset, symbolIndexForAtom(atom), 0,
852 ARM64_RELOC_SUBTRACTOR | rExtern | rLength8);
853 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
854 ARM64_RELOC_UNSIGNED | rExtern | rLength8);
855 return;
856 case delta32:
857 appendReloc(relocs, sectionOffset, symbolIndexForAtom(atom), 0,
858 ARM64_RELOC_SUBTRACTOR | rExtern | rLength4 );
859 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
860 ARM64_RELOC_UNSIGNED | rExtern | rLength4 );
861 return;
862 case pointer64ToGOT:
863 assert(ref.addend() == 0);
864 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
865 ARM64_RELOC_POINTER_TO_GOT | rExtern | rLength8);
866 return;
867 case delta32ToGOT:
868 assert(ref.addend() == 0);
869 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
870 ARM64_RELOC_POINTER_TO_GOT | rPcRel | rExtern | rLength4);
871 return;
872 case addOffset12:
873 llvm_unreachable("lazy reference kind implies GOT pass was run");
874 case lazyPointer:
875 case lazyImmediateLocation:
876 llvm_unreachable("lazy reference kind implies Stubs pass was run");
877 case imageOffset:
878 case imageOffsetGot:
879 llvm_unreachable("deltas from mach_header can only be in final images");
880 case unwindCIEToPersonalityFunction:
881 case unwindFDEToFunction:
882 case unwindInfoToEhFrame:
883 case negDelta32:
884 // Do nothing.
885 return;
886 case invalid:
887 // Fall into llvm_unreachable().
888 break;
889 }
890 llvm_unreachable("unknown arm64 Reference Kind");
891}
892
893std::unique_ptr<mach_o::ArchHandler> ArchHandler::create_arm64() {
894 return std::unique_ptr<mach_o::ArchHandler>(new ArchHandler_arm64());
895}
896
897} // namespace mach_o
898} // namespace lld
deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86.cpp created+644
......@@ -0,0 +1,644 @@
1//===- lib/FileFormat/MachO/ArchHandler_x86.cpp ---------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "ArchHandler.h"
11#include "Atoms.h"
12#include "MachONormalizedFileBinaryUtils.h"
13#include "llvm/ADT/StringRef.h"
14#include "llvm/ADT/StringSwitch.h"
15#include "llvm/ADT/Triple.h"
16#include "llvm/Support/Endian.h"
17#include "llvm/Support/ErrorHandling.h"
18
19using namespace llvm::MachO;
20using namespace lld::mach_o::normalized;
21
22namespace lld {
23namespace mach_o {
24
25using llvm::support::ulittle16_t;
26using llvm::support::ulittle32_t;
27
28using llvm::support::little16_t;
29using llvm::support::little32_t;
30
31class ArchHandler_x86 : public ArchHandler {
32public:
33 ArchHandler_x86() = default;
34 ~ArchHandler_x86() override = default;
35
36 const Registry::KindStrings *kindStrings() override { return _sKindStrings; }
37
38 Reference::KindArch kindArch() override { return Reference::KindArch::x86; }
39
40 const StubInfo &stubInfo() override { return _sStubInfo; }
41 bool isCallSite(const Reference &) override;
42 bool isNonCallBranch(const Reference &) override {
43 return false;
44 }
45
46 bool isPointer(const Reference &) override;
47 bool isPairedReloc(const normalized::Relocation &) override;
48
49 bool needsCompactUnwind() override {
50 return false;
51 }
52
53 Reference::KindValue imageOffsetKind() override {
54 return invalid;
55 }
56
57 Reference::KindValue imageOffsetKindIndirect() override {
58 return invalid;
59 }
60
61 Reference::KindValue unwindRefToPersonalityFunctionKind() override {
62 return invalid;
63 }
64
65 Reference::KindValue unwindRefToCIEKind() override {
66 return negDelta32;
67 }
68
69 Reference::KindValue unwindRefToFunctionKind() override{
70 return delta32;
71 }
72
73 Reference::KindValue lazyImmediateLocationKind() override {
74 return lazyImmediateLocation;
75 }
76
77 Reference::KindValue unwindRefToEhFrameKind() override {
78 return invalid;
79 }
80
81 Reference::KindValue pointerKind() override {
82 return invalid;
83 }
84
85 uint32_t dwarfCompactUnwindType() override {
86 return 0x04000000U;
87 }
88
89 llvm::Error getReferenceInfo(const normalized::Relocation &reloc,
90 const DefinedAtom *inAtom,
91 uint32_t offsetInAtom,
92 uint64_t fixupAddress, bool swap,
93 FindAtomBySectionAndAddress atomFromAddress,
94 FindAtomBySymbolIndex atomFromSymbolIndex,
95 Reference::KindValue *kind,
96 const lld::Atom **target,
97 Reference::Addend *addend) override;
98 llvm::Error
99 getPairReferenceInfo(const normalized::Relocation &reloc1,
100 const normalized::Relocation &reloc2,
101 const DefinedAtom *inAtom,
102 uint32_t offsetInAtom,
103 uint64_t fixupAddress, bool swap, bool scatterable,
104 FindAtomBySectionAndAddress atomFromAddress,
105 FindAtomBySymbolIndex atomFromSymbolIndex,
106 Reference::KindValue *kind,
107 const lld::Atom **target,
108 Reference::Addend *addend) override;
109
110 void generateAtomContent(const DefinedAtom &atom, bool relocatable,
111 FindAddressForAtom findAddress,
112 FindAddressForAtom findSectionAddress,
113 uint64_t imageBaseAddress,
114 llvm::MutableArrayRef<uint8_t> atomContentBuffer) override;
115
116 void appendSectionRelocations(const DefinedAtom &atom,
117 uint64_t atomSectionOffset,
118 const Reference &ref,
119 FindSymbolIndexForAtom symbolIndexForAtom,
120 FindSectionIndexForAtom sectionIndexForAtom,
121 FindAddressForAtom addressForAtom,
122 normalized::Relocations &relocs) override;
123
124 bool isDataInCodeTransition(Reference::KindValue refKind) override {
125 return refKind == modeCode || refKind == modeData;
126 }
127
128 Reference::KindValue dataInCodeTransitionStart(
129 const MachODefinedAtom &atom) override {
130 return modeData;
131 }
132
133 Reference::KindValue dataInCodeTransitionEnd(
134 const MachODefinedAtom &atom) override {
135 return modeCode;
136 }
137
138private:
139 static const Registry::KindStrings _sKindStrings[];
140 static const StubInfo _sStubInfo;
141
142 enum X86Kind : Reference::KindValue {
143 invalid, /// for error condition
144
145 modeCode, /// Content starting at this offset is code.
146 modeData, /// Content starting at this offset is data.
147
148 // Kinds found in mach-o .o files:
149 branch32, /// ex: call _foo
150 branch16, /// ex: callw _foo
151 abs32, /// ex: movl _foo, %eax
152 funcRel32, /// ex: movl _foo-L1(%eax), %eax
153 pointer32, /// ex: .long _foo
154 delta32, /// ex: .long _foo - .
155 negDelta32, /// ex: .long . - _foo
156
157 // Kinds introduced by Passes:
158 lazyPointer, /// Location contains a lazy pointer.
159 lazyImmediateLocation, /// Location contains immediate value used in stub.
160 };
161
162 static bool useExternalRelocationTo(const Atom &target);
163
164 void applyFixupFinal(const Reference &ref, uint8_t *location,
165 uint64_t fixupAddress, uint64_t targetAddress,
166 uint64_t inAtomAddress);
167
168 void applyFixupRelocatable(const Reference &ref, uint8_t *location,
169 uint64_t fixupAddress,
170 uint64_t targetAddress,
171 uint64_t inAtomAddress);
172};
173
174//===----------------------------------------------------------------------===//
175// ArchHandler_x86
176//===----------------------------------------------------------------------===//
177
178const Registry::KindStrings ArchHandler_x86::_sKindStrings[] = {
179 LLD_KIND_STRING_ENTRY(invalid),
180 LLD_KIND_STRING_ENTRY(modeCode),
181 LLD_KIND_STRING_ENTRY(modeData),
182 LLD_KIND_STRING_ENTRY(branch32),
183 LLD_KIND_STRING_ENTRY(branch16),
184 LLD_KIND_STRING_ENTRY(abs32),
185 LLD_KIND_STRING_ENTRY(funcRel32),
186 LLD_KIND_STRING_ENTRY(pointer32),
187 LLD_KIND_STRING_ENTRY(delta32),
188 LLD_KIND_STRING_ENTRY(negDelta32),
189 LLD_KIND_STRING_ENTRY(lazyPointer),
190 LLD_KIND_STRING_ENTRY(lazyImmediateLocation),
191 LLD_KIND_STRING_END
192};
193
194const ArchHandler::StubInfo ArchHandler_x86::_sStubInfo = {
195 "dyld_stub_binder",
196
197 // Lazy pointer references
198 { Reference::KindArch::x86, pointer32, 0, 0 },
199 { Reference::KindArch::x86, lazyPointer, 0, 0 },
200
201 // GOT pointer to dyld_stub_binder
202 { Reference::KindArch::x86, pointer32, 0, 0 },
203
204 // x86 code alignment
205 1,
206
207 // Stub size and code
208 6,
209 { 0xff, 0x25, 0x00, 0x00, 0x00, 0x00 }, // jmp *lazyPointer
210 { Reference::KindArch::x86, abs32, 2, 0 },
211 { false, 0, 0, 0 },
212
213 // Stub Helper size and code
214 10,
215 { 0x68, 0x00, 0x00, 0x00, 0x00, // pushl $lazy-info-offset
216 0xE9, 0x00, 0x00, 0x00, 0x00 }, // jmp helperhelper
217 { Reference::KindArch::x86, lazyImmediateLocation, 1, 0 },
218 { Reference::KindArch::x86, branch32, 6, 0 },
219
220 // Stub helper image cache content type
221 DefinedAtom::typeNonLazyPointer,
222
223 // Stub Helper-Common size and code
224 12,
225 // Stub helper alignment
226 2,
227 { 0x68, 0x00, 0x00, 0x00, 0x00, // pushl $dyld_ImageLoaderCache
228 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp *_fast_lazy_bind
229 0x90 }, // nop
230 { Reference::KindArch::x86, abs32, 1, 0 },
231 { false, 0, 0, 0 },
232 { Reference::KindArch::x86, abs32, 7, 0 },
233 { false, 0, 0, 0 }
234};
235
236bool ArchHandler_x86::isCallSite(const Reference &ref) {
237 return (ref.kindValue() == branch32);
238}
239
240bool ArchHandler_x86::isPointer(const Reference &ref) {
241 return (ref.kindValue() == pointer32);
242}
243
244bool ArchHandler_x86::isPairedReloc(const Relocation &reloc) {
245 if (!reloc.scattered)
246 return false;
247 return (reloc.type == GENERIC_RELOC_LOCAL_SECTDIFF) ||
248 (reloc.type == GENERIC_RELOC_SECTDIFF);
249}
250
251llvm::Error
252ArchHandler_x86::getReferenceInfo(const Relocation &reloc,
253 const DefinedAtom *inAtom,
254 uint32_t offsetInAtom,
255 uint64_t fixupAddress, bool swap,
256 FindAtomBySectionAndAddress atomFromAddress,
257 FindAtomBySymbolIndex atomFromSymbolIndex,
258 Reference::KindValue *kind,
259 const lld::Atom **target,
260 Reference::Addend *addend) {
261 DefinedAtom::ContentPermissions perms;
262 const uint8_t *fixupContent = &inAtom->rawContent()[offsetInAtom];
263 uint64_t targetAddress;
264 switch (relocPattern(reloc)) {
265 case GENERIC_RELOC_VANILLA | rPcRel | rExtern | rLength4:
266 // ex: call _foo (and _foo undefined)
267 *kind = branch32;
268 if (auto ec = atomFromSymbolIndex(reloc.symbol, target))
269 return ec;
270 *addend = fixupAddress + 4 + (int32_t)*(const little32_t *)fixupContent;
271 break;
272 case GENERIC_RELOC_VANILLA | rPcRel | rLength4:
273 // ex: call _foo (and _foo defined)
274 *kind = branch32;
275 targetAddress =
276 fixupAddress + 4 + (int32_t) * (const little32_t *)fixupContent;
277 return atomFromAddress(reloc.symbol, targetAddress, target, addend);
278 break;
279 case GENERIC_RELOC_VANILLA | rScattered | rPcRel | rLength4:
280 // ex: call _foo+n (and _foo defined)
281 *kind = branch32;
282 targetAddress =
283 fixupAddress + 4 + (int32_t) * (const little32_t *)fixupContent;
284 if (auto ec = atomFromAddress(0, reloc.value, target, addend))
285 return ec;
286 *addend = targetAddress - reloc.value;
287 break;
288 case GENERIC_RELOC_VANILLA | rPcRel | rExtern | rLength2:
289 // ex: callw _foo (and _foo undefined)
290 *kind = branch16;
291 if (auto ec = atomFromSymbolIndex(reloc.symbol, target))
292 return ec;
293 *addend = fixupAddress + 2 + (int16_t)*(const little16_t *)fixupContent;
294 break;
295 case GENERIC_RELOC_VANILLA | rPcRel | rLength2:
296 // ex: callw _foo (and _foo defined)
297 *kind = branch16;
298 targetAddress =
299 fixupAddress + 2 + (int16_t) * (const little16_t *)fixupContent;
300 return atomFromAddress(reloc.symbol, targetAddress, target, addend);
301 break;
302 case GENERIC_RELOC_VANILLA | rScattered | rPcRel | rLength2:
303 // ex: callw _foo+n (and _foo defined)
304 *kind = branch16;
305 targetAddress =
306 fixupAddress + 2 + (int16_t) * (const little16_t *)fixupContent;
307 if (auto ec = atomFromAddress(0, reloc.value, target, addend))
308 return ec;
309 *addend = targetAddress - reloc.value;
310 break;
311 case GENERIC_RELOC_VANILLA | rExtern | rLength4:
312 // ex: movl _foo, %eax (and _foo undefined)
313 // ex: .long _foo (and _foo undefined)
314 perms = inAtom->permissions();
315 *kind =
316 ((perms & DefinedAtom::permR_X) == DefinedAtom::permR_X) ? abs32
317 : pointer32;
318 if (auto ec = atomFromSymbolIndex(reloc.symbol, target))
319 return ec;
320 *addend = *(const ulittle32_t *)fixupContent;
321 break;
322 case GENERIC_RELOC_VANILLA | rLength4:
323 // ex: movl _foo, %eax (and _foo defined)
324 // ex: .long _foo (and _foo defined)
325 perms = inAtom->permissions();
326 *kind =
327 ((perms & DefinedAtom::permR_X) == DefinedAtom::permR_X) ? abs32
328 : pointer32;
329 targetAddress = *(const ulittle32_t *)fixupContent;
330 return atomFromAddress(reloc.symbol, targetAddress, target, addend);
331 break;
332 case GENERIC_RELOC_VANILLA | rScattered | rLength4:
333 // ex: .long _foo+n (and _foo defined)
334 perms = inAtom->permissions();
335 *kind =
336 ((perms & DefinedAtom::permR_X) == DefinedAtom::permR_X) ? abs32
337 : pointer32;
338 if (auto ec = atomFromAddress(0, reloc.value, target, addend))
339 return ec;
340 *addend = *(const ulittle32_t *)fixupContent - reloc.value;
341 break;
342 default:
343 return llvm::make_error<GenericError>("unsupported i386 relocation type");
344 }
345 return llvm::Error::success();
346}
347
348llvm::Error
349ArchHandler_x86::getPairReferenceInfo(const normalized::Relocation &reloc1,
350 const normalized::Relocation &reloc2,
351 const DefinedAtom *inAtom,
352 uint32_t offsetInAtom,
353 uint64_t fixupAddress, bool swap,
354 bool scatterable,
355 FindAtomBySectionAndAddress atomFromAddr,
356 FindAtomBySymbolIndex atomFromSymbolIndex,
357 Reference::KindValue *kind,
358 const lld::Atom **target,
359 Reference::Addend *addend) {
360 const uint8_t *fixupContent = &inAtom->rawContent()[offsetInAtom];
361 DefinedAtom::ContentPermissions perms = inAtom->permissions();
362 uint32_t fromAddress;
363 uint32_t toAddress;
364 uint32_t value;
365 const lld::Atom *fromTarget;
366 Reference::Addend offsetInTo;
367 Reference::Addend offsetInFrom;
368 switch (relocPattern(reloc1) << 16 | relocPattern(reloc2)) {
369 case ((GENERIC_RELOC_SECTDIFF | rScattered | rLength4) << 16 |
370 GENERIC_RELOC_PAIR | rScattered | rLength4):
371 case ((GENERIC_RELOC_LOCAL_SECTDIFF | rScattered | rLength4) << 16 |
372 GENERIC_RELOC_PAIR | rScattered | rLength4):
373 toAddress = reloc1.value;
374 fromAddress = reloc2.value;
375 value = *(const little32_t *)fixupContent;
376 if (auto ec = atomFromAddr(0, toAddress, target, &offsetInTo))
377 return ec;
378 if (auto ec = atomFromAddr(0, fromAddress, &fromTarget, &offsetInFrom))
379 return ec;
380 if (fromTarget != inAtom) {
381 if (*target != inAtom)
382 return llvm::make_error<GenericError>(
383 "SECTDIFF relocation where neither target is in atom");
384 *kind = negDelta32;
385 *addend = toAddress - value - fromAddress;
386 *target = fromTarget;
387 } else {
388 if ((perms & DefinedAtom::permR_X) == DefinedAtom::permR_X) {
389 // SECTDIFF relocations are used in i386 codegen where the function
390 // prolog does a CALL to the next instruction which POPs the return
391 // address into EBX which becomes the pic-base register. The POP
392 // instruction is label the used for the subtrahend in expressions.
393 // The funcRel32 kind represents the 32-bit delta to some symbol from
394 // the start of the function (atom) containing the funcRel32.
395 *kind = funcRel32;
396 uint32_t ta = fromAddress + value - toAddress;
397 *addend = ta - offsetInFrom;
398 } else {
399 *kind = delta32;
400 *addend = fromAddress + value - toAddress;
401 }
402 }
403 return llvm::Error::success();
404 break;
405 default:
406 return llvm::make_error<GenericError>("unsupported i386 relocation type");
407 }
408}
409
410void ArchHandler_x86::generateAtomContent(const DefinedAtom &atom,
411 bool relocatable,
412 FindAddressForAtom findAddress,
413 FindAddressForAtom findSectionAddress,
414 uint64_t imageBaseAddress,
415 llvm::MutableArrayRef<uint8_t> atomContentBuffer) {
416 // Copy raw bytes.
417 std::copy(atom.rawContent().begin(), atom.rawContent().end(),
418 atomContentBuffer.begin());
419 // Apply fix-ups.
420 for (const Reference *ref : atom) {
421 uint32_t offset = ref->offsetInAtom();
422 const Atom *target = ref->target();
423 uint64_t targetAddress = 0;
424 if (isa<DefinedAtom>(target))
425 targetAddress = findAddress(*target);
426 uint64_t atomAddress = findAddress(atom);
427 uint64_t fixupAddress = atomAddress + offset;
428 if (relocatable) {
429 applyFixupRelocatable(*ref, &atomContentBuffer[offset],
430 fixupAddress, targetAddress,
431 atomAddress);
432 } else {
433 applyFixupFinal(*ref, &atomContentBuffer[offset],
434 fixupAddress, targetAddress,
435 atomAddress);
436 }
437 }
438}
439
440void ArchHandler_x86::applyFixupFinal(const Reference &ref, uint8_t *loc,
441 uint64_t fixupAddress,
442 uint64_t targetAddress,
443 uint64_t inAtomAddress) {
444 if (ref.kindNamespace() != Reference::KindNamespace::mach_o)
445 return;
446 assert(ref.kindArch() == Reference::KindArch::x86);
447 ulittle32_t *loc32 = reinterpret_cast<ulittle32_t *>(loc);
448 switch (static_cast<X86Kind>(ref.kindValue())) {
449 case branch32:
450 *loc32 = (targetAddress - (fixupAddress + 4)) + ref.addend();
451 break;
452 case branch16:
453 *loc32 = (targetAddress - (fixupAddress + 2)) + ref.addend();
454 break;
455 case pointer32:
456 case abs32:
457 *loc32 = targetAddress + ref.addend();
458 break;
459 case funcRel32:
460 *loc32 = targetAddress - inAtomAddress + ref.addend();
461 break;
462 case delta32:
463 *loc32 = targetAddress - fixupAddress + ref.addend();
464 break;
465 case negDelta32:
466 *loc32 = fixupAddress - targetAddress + ref.addend();
467 break;
468 case modeCode:
469 case modeData:
470 case lazyPointer:
471 // do nothing
472 break;
473 case lazyImmediateLocation:
474 *loc32 = ref.addend();
475 break;
476 case invalid:
477 llvm_unreachable("invalid x86 Reference Kind");
478 break;
479 }
480}
481
482void ArchHandler_x86::applyFixupRelocatable(const Reference &ref,
483 uint8_t *loc,
484 uint64_t fixupAddress,
485 uint64_t targetAddress,
486 uint64_t inAtomAddress) {
487 if (ref.kindNamespace() != Reference::KindNamespace::mach_o)
488 return;
489 assert(ref.kindArch() == Reference::KindArch::x86);
490 bool useExternalReloc = useExternalRelocationTo(*ref.target());
491 ulittle16_t *loc16 = reinterpret_cast<ulittle16_t *>(loc);
492 ulittle32_t *loc32 = reinterpret_cast<ulittle32_t *>(loc);
493 switch (static_cast<X86Kind>(ref.kindValue())) {
494 case branch32:
495 if (useExternalReloc)
496 *loc32 = ref.addend() - (fixupAddress + 4);
497 else
498 *loc32 =(targetAddress - (fixupAddress+4)) + ref.addend();
499 break;
500 case branch16:
501 if (useExternalReloc)
502 *loc16 = ref.addend() - (fixupAddress + 2);
503 else
504 *loc16 = (targetAddress - (fixupAddress+2)) + ref.addend();
505 break;
506 case pointer32:
507 case abs32:
508 *loc32 = targetAddress + ref.addend();
509 break;
510 case funcRel32:
511 *loc32 = targetAddress - inAtomAddress + ref.addend(); // FIXME
512 break;
513 case delta32:
514 *loc32 = targetAddress - fixupAddress + ref.addend();
515 break;
516 case negDelta32:
517 *loc32 = fixupAddress - targetAddress + ref.addend();
518 break;
519 case modeCode:
520 case modeData:
521 case lazyPointer:
522 case lazyImmediateLocation:
523 // do nothing
524 break;
525 case invalid:
526 llvm_unreachable("invalid x86 Reference Kind");
527 break;
528 }
529}
530
531bool ArchHandler_x86::useExternalRelocationTo(const Atom &target) {
532 // Undefined symbols are referenced via external relocations.
533 if (isa<UndefinedAtom>(&target))
534 return true;
535 if (const DefinedAtom *defAtom = dyn_cast<DefinedAtom>(&target)) {
536 switch (defAtom->merge()) {
537 case DefinedAtom::mergeAsTentative:
538 // Tentative definitions are referenced via external relocations.
539 return true;
540 case DefinedAtom::mergeAsWeak:
541 case DefinedAtom::mergeAsWeakAndAddressUsed:
542 // Global weak-defs are referenced via external relocations.
543 return (defAtom->scope() == DefinedAtom::scopeGlobal);
544 default:
545 break;
546 }
547 }
548 // Everything else is reference via an internal relocation.
549 return false;
550}
551
552void ArchHandler_x86::appendSectionRelocations(
553 const DefinedAtom &atom,
554 uint64_t atomSectionOffset,
555 const Reference &ref,
556 FindSymbolIndexForAtom symbolIndexForAtom,
557 FindSectionIndexForAtom sectionIndexForAtom,
558 FindAddressForAtom addressForAtom,
559 normalized::Relocations &relocs) {
560 if (ref.kindNamespace() != Reference::KindNamespace::mach_o)
561 return;
562 assert(ref.kindArch() == Reference::KindArch::x86);
563 uint32_t sectionOffset = atomSectionOffset + ref.offsetInAtom();
564 bool useExternalReloc = useExternalRelocationTo(*ref.target());
565 switch (static_cast<X86Kind>(ref.kindValue())) {
566 case modeCode:
567 case modeData:
568 break;
569 case branch32:
570 if (useExternalReloc) {
571 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
572 GENERIC_RELOC_VANILLA | rExtern | rPcRel | rLength4);
573 } else {
574 if (ref.addend() != 0)
575 appendReloc(relocs, sectionOffset, 0, addressForAtom(*ref.target()),
576 GENERIC_RELOC_VANILLA | rScattered | rPcRel | rLength4);
577 else
578 appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()),0,
579 GENERIC_RELOC_VANILLA | rPcRel | rLength4);
580 }
581 break;
582 case branch16:
583 if (useExternalReloc) {
584 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
585 GENERIC_RELOC_VANILLA | rExtern | rPcRel | rLength2);
586 } else {
587 if (ref.addend() != 0)
588 appendReloc(relocs, sectionOffset, 0, addressForAtom(*ref.target()),
589 GENERIC_RELOC_VANILLA | rScattered | rPcRel | rLength2);
590 else
591 appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()),0,
592 GENERIC_RELOC_VANILLA | rPcRel | rLength2);
593 }
594 break;
595 case pointer32:
596 case abs32:
597 if (useExternalReloc)
598 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
599 GENERIC_RELOC_VANILLA | rExtern | rLength4);
600 else {
601 if (ref.addend() != 0)
602 appendReloc(relocs, sectionOffset, 0, addressForAtom(*ref.target()),
603 GENERIC_RELOC_VANILLA | rScattered | rLength4);
604 else
605 appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()), 0,
606 GENERIC_RELOC_VANILLA | rLength4);
607 }
608 break;
609 case funcRel32:
610 appendReloc(relocs, sectionOffset, 0, addressForAtom(*ref.target()),
611 GENERIC_RELOC_SECTDIFF | rScattered | rLength4);
612 appendReloc(relocs, sectionOffset, 0, addressForAtom(atom) - ref.addend(),
613 GENERIC_RELOC_PAIR | rScattered | rLength4);
614 break;
615 case delta32:
616 appendReloc(relocs, sectionOffset, 0, addressForAtom(*ref.target()),
617 GENERIC_RELOC_SECTDIFF | rScattered | rLength4);
618 appendReloc(relocs, sectionOffset, 0, addressForAtom(atom) +
619 ref.offsetInAtom(),
620 GENERIC_RELOC_PAIR | rScattered | rLength4);
621 break;
622 case negDelta32:
623 appendReloc(relocs, sectionOffset, 0, addressForAtom(atom) +
624 ref.offsetInAtom(),
625 GENERIC_RELOC_SECTDIFF | rScattered | rLength4);
626 appendReloc(relocs, sectionOffset, 0, addressForAtom(*ref.target()),
627 GENERIC_RELOC_PAIR | rScattered | rLength4);
628 break;
629 case lazyPointer:
630 case lazyImmediateLocation:
631 llvm_unreachable("lazy reference kind implies Stubs pass was run");
632 break;
633 case invalid:
634 llvm_unreachable("unknown x86 Reference Kind");
635 break;
636 }
637}
638
639std::unique_ptr<mach_o::ArchHandler> ArchHandler::create_x86() {
640 return std::unique_ptr<mach_o::ArchHandler>(new ArchHandler_x86());
641}
642
643} // namespace mach_o
644} // namespace lld
deps/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp created+865
......@@ -0,0 +1,865 @@
1//===- lib/FileFormat/MachO/ArchHandler_x86_64.cpp ------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "ArchHandler.h"
11#include "Atoms.h"
12#include "MachONormalizedFileBinaryUtils.h"
13#include "llvm/ADT/StringRef.h"
14#include "llvm/ADT/StringSwitch.h"
15#include "llvm/ADT/Triple.h"
16#include "llvm/Support/Endian.h"
17#include "llvm/Support/ErrorHandling.h"
18
19using namespace llvm::MachO;
20using namespace lld::mach_o::normalized;
21
22namespace lld {
23namespace mach_o {
24
25using llvm::support::ulittle32_t;
26using llvm::support::ulittle64_t;
27
28using llvm::support::little32_t;
29using llvm::support::little64_t;
30
31class ArchHandler_x86_64 : public ArchHandler {
32public:
33 ArchHandler_x86_64() = default;
34 ~ArchHandler_x86_64() override = default;
35
36 const Registry::KindStrings *kindStrings() override { return _sKindStrings; }
37
38 Reference::KindArch kindArch() override {
39 return Reference::KindArch::x86_64;
40 }
41
42 /// Used by GOTPass to locate GOT References
43 bool isGOTAccess(const Reference &ref, bool &canBypassGOT) override {
44 if (ref.kindNamespace() != Reference::KindNamespace::mach_o)
45 return false;
46 assert(ref.kindArch() == Reference::KindArch::x86_64);
47 switch (ref.kindValue()) {
48 case ripRel32GotLoad:
49 canBypassGOT = true;
50 return true;
51 case ripRel32Got:
52 canBypassGOT = false;
53 return true;
54 case imageOffsetGot:
55 canBypassGOT = false;
56 return true;
57 default:
58 return false;
59 }
60 }
61
62 bool isTLVAccess(const Reference &ref) const override {
63 assert(ref.kindNamespace() == Reference::KindNamespace::mach_o);
64 assert(ref.kindArch() == Reference::KindArch::x86_64);
65 return ref.kindValue() == ripRel32Tlv;
66 }
67
68 void updateReferenceToTLV(const Reference *ref) override {
69 assert(ref->kindNamespace() == Reference::KindNamespace::mach_o);
70 assert(ref->kindArch() == Reference::KindArch::x86_64);
71 assert(ref->kindValue() == ripRel32Tlv);
72 const_cast<Reference*>(ref)->setKindValue(ripRel32);
73 }
74
75 /// Used by GOTPass to update GOT References
76 void updateReferenceToGOT(const Reference *ref, bool targetNowGOT) override {
77 assert(ref->kindNamespace() == Reference::KindNamespace::mach_o);
78 assert(ref->kindArch() == Reference::KindArch::x86_64);
79
80 switch (ref->kindValue()) {
81 case ripRel32Got:
82 assert(targetNowGOT && "target must be GOT");
83 case ripRel32GotLoad:
84 const_cast<Reference *>(ref)
85 ->setKindValue(targetNowGOT ? ripRel32 : ripRel32GotLoadNowLea);
86 break;
87 case imageOffsetGot:
88 const_cast<Reference *>(ref)->setKindValue(imageOffset);
89 break;
90 default:
91 llvm_unreachable("unknown GOT reference kind");
92 }
93 }
94
95 bool needsCompactUnwind() override {
96 return true;
97 }
98
99 Reference::KindValue imageOffsetKind() override {
100 return imageOffset;
101 }
102
103 Reference::KindValue imageOffsetKindIndirect() override {
104 return imageOffsetGot;
105 }
106
107 Reference::KindValue unwindRefToPersonalityFunctionKind() override {
108 return ripRel32Got;
109 }
110
111 Reference::KindValue unwindRefToCIEKind() override {
112 return negDelta32;
113 }
114
115 Reference::KindValue unwindRefToFunctionKind() override{
116 return unwindFDEToFunction;
117 }
118
119 Reference::KindValue lazyImmediateLocationKind() override {
120 return lazyImmediateLocation;
121 }
122
123 Reference::KindValue unwindRefToEhFrameKind() override {
124 return unwindInfoToEhFrame;
125 }
126
127 Reference::KindValue pointerKind() override {
128 return pointer64;
129 }
130
131 uint32_t dwarfCompactUnwindType() override {
132 return 0x04000000U;
133 }
134
135 const StubInfo &stubInfo() override { return _sStubInfo; }
136
137 bool isNonCallBranch(const Reference &) override {
138 return false;
139 }
140
141 bool isCallSite(const Reference &) override;
142 bool isPointer(const Reference &) override;
143 bool isPairedReloc(const normalized::Relocation &) override;
144
145 llvm::Error getReferenceInfo(const normalized::Relocation &reloc,
146 const DefinedAtom *inAtom,
147 uint32_t offsetInAtom,
148 uint64_t fixupAddress, bool swap,
149 FindAtomBySectionAndAddress atomFromAddress,
150 FindAtomBySymbolIndex atomFromSymbolIndex,
151 Reference::KindValue *kind,
152 const lld::Atom **target,
153 Reference::Addend *addend) override;
154 llvm::Error
155 getPairReferenceInfo(const normalized::Relocation &reloc1,
156 const normalized::Relocation &reloc2,
157 const DefinedAtom *inAtom,
158 uint32_t offsetInAtom,
159 uint64_t fixupAddress, bool swap, bool scatterable,
160 FindAtomBySectionAndAddress atomFromAddress,
161 FindAtomBySymbolIndex atomFromSymbolIndex,
162 Reference::KindValue *kind,
163 const lld::Atom **target,
164 Reference::Addend *addend) override;
165
166 bool needsLocalSymbolInRelocatableFile(const DefinedAtom *atom) override {
167 return (atom->contentType() == DefinedAtom::typeCString);
168 }
169
170 void generateAtomContent(const DefinedAtom &atom, bool relocatable,
171 FindAddressForAtom findAddress,
172 FindAddressForAtom findSectionAddress,
173 uint64_t imageBase,
174 llvm::MutableArrayRef<uint8_t> atomContentBuffer) override;
175
176 void appendSectionRelocations(const DefinedAtom &atom,
177 uint64_t atomSectionOffset,
178 const Reference &ref,
179 FindSymbolIndexForAtom symbolIndexForAtom,
180 FindSectionIndexForAtom sectionIndexForAtom,
181 FindAddressForAtom addressForAtom,
182 normalized::Relocations &relocs) override;
183
184private:
185 static const Registry::KindStrings _sKindStrings[];
186 static const StubInfo _sStubInfo;
187
188 enum X86_64Kind: Reference::KindValue {
189 invalid, /// for error condition
190
191 // Kinds found in mach-o .o files:
192 branch32, /// ex: call _foo
193 ripRel32, /// ex: movq _foo(%rip), %rax
194 ripRel32Minus1, /// ex: movb $0x12, _foo(%rip)
195 ripRel32Minus2, /// ex: movw $0x1234, _foo(%rip)
196 ripRel32Minus4, /// ex: movl $0x12345678, _foo(%rip)
197 ripRel32Anon, /// ex: movq L1(%rip), %rax
198 ripRel32Minus1Anon, /// ex: movb $0x12, L1(%rip)
199 ripRel32Minus2Anon, /// ex: movw $0x1234, L1(%rip)
200 ripRel32Minus4Anon, /// ex: movw $0x12345678, L1(%rip)
201 ripRel32GotLoad, /// ex: movq _foo@GOTPCREL(%rip), %rax
202 ripRel32Got, /// ex: pushq _foo@GOTPCREL(%rip)
203 ripRel32Tlv, /// ex: movq _foo@TLVP(%rip), %rdi
204 pointer64, /// ex: .quad _foo
205 pointer64Anon, /// ex: .quad L1
206 delta64, /// ex: .quad _foo - .
207 delta32, /// ex: .long _foo - .
208 delta64Anon, /// ex: .quad L1 - .
209 delta32Anon, /// ex: .long L1 - .
210 negDelta64, /// ex: .quad . - _foo
211 negDelta32, /// ex: .long . - _foo
212
213 // Kinds introduced by Passes:
214 ripRel32GotLoadNowLea, /// Target of GOT load is in linkage unit so
215 /// "movq _foo@GOTPCREL(%rip), %rax" can be changed
216 /// to "leaq _foo(%rip), %rax
217 lazyPointer, /// Location contains a lazy pointer.
218 lazyImmediateLocation, /// Location contains immediate value used in stub.
219
220 imageOffset, /// Location contains offset of atom in final image
221 imageOffsetGot, /// Location contains offset of GOT entry for atom in
222 /// final image (typically personality function).
223 unwindFDEToFunction, /// Nearly delta64, but cannot be rematerialized in
224 /// relocatable object (yay for implicit contracts!).
225 unwindInfoToEhFrame, /// Fix low 24 bits of compact unwind encoding to
226 /// refer to __eh_frame entry.
227 tlvInitSectionOffset /// Location contains offset tlv init-value atom
228 /// within the __thread_data section.
229 };
230
231 Reference::KindValue kindFromReloc(const normalized::Relocation &reloc);
232
233 void applyFixupFinal(const Reference &ref, uint8_t *location,
234 uint64_t fixupAddress, uint64_t targetAddress,
235 uint64_t inAtomAddress, uint64_t imageBaseAddress,
236 FindAddressForAtom findSectionAddress);
237
238 void applyFixupRelocatable(const Reference &ref, uint8_t *location,
239 uint64_t fixupAddress,
240 uint64_t targetAddress,
241 uint64_t inAtomAddress);
242};
243
244const Registry::KindStrings ArchHandler_x86_64::_sKindStrings[] = {
245 LLD_KIND_STRING_ENTRY(invalid), LLD_KIND_STRING_ENTRY(branch32),
246 LLD_KIND_STRING_ENTRY(ripRel32), LLD_KIND_STRING_ENTRY(ripRel32Minus1),
247 LLD_KIND_STRING_ENTRY(ripRel32Minus2), LLD_KIND_STRING_ENTRY(ripRel32Minus4),
248 LLD_KIND_STRING_ENTRY(ripRel32Anon),
249 LLD_KIND_STRING_ENTRY(ripRel32Minus1Anon),
250 LLD_KIND_STRING_ENTRY(ripRel32Minus2Anon),
251 LLD_KIND_STRING_ENTRY(ripRel32Minus4Anon),
252 LLD_KIND_STRING_ENTRY(ripRel32GotLoad),
253 LLD_KIND_STRING_ENTRY(ripRel32GotLoadNowLea),
254 LLD_KIND_STRING_ENTRY(ripRel32Got), LLD_KIND_STRING_ENTRY(ripRel32Tlv),
255 LLD_KIND_STRING_ENTRY(lazyPointer),
256 LLD_KIND_STRING_ENTRY(lazyImmediateLocation),
257 LLD_KIND_STRING_ENTRY(pointer64), LLD_KIND_STRING_ENTRY(pointer64Anon),
258 LLD_KIND_STRING_ENTRY(delta32), LLD_KIND_STRING_ENTRY(delta64),
259 LLD_KIND_STRING_ENTRY(delta32Anon), LLD_KIND_STRING_ENTRY(delta64Anon),
260 LLD_KIND_STRING_ENTRY(negDelta64),
261 LLD_KIND_STRING_ENTRY(negDelta32),
262 LLD_KIND_STRING_ENTRY(imageOffset), LLD_KIND_STRING_ENTRY(imageOffsetGot),
263 LLD_KIND_STRING_ENTRY(unwindFDEToFunction),
264 LLD_KIND_STRING_ENTRY(unwindInfoToEhFrame),
265 LLD_KIND_STRING_ENTRY(tlvInitSectionOffset),
266 LLD_KIND_STRING_END
267};
268
269const ArchHandler::StubInfo ArchHandler_x86_64::_sStubInfo = {
270 "dyld_stub_binder",
271
272 // Lazy pointer references
273 { Reference::KindArch::x86_64, pointer64, 0, 0 },
274 { Reference::KindArch::x86_64, lazyPointer, 0, 0 },
275
276 // GOT pointer to dyld_stub_binder
277 { Reference::KindArch::x86_64, pointer64, 0, 0 },
278
279 // x86_64 code alignment 2^1
280 1,
281
282 // Stub size and code
283 6,
284 { 0xff, 0x25, 0x00, 0x00, 0x00, 0x00 }, // jmp *lazyPointer
285 { Reference::KindArch::x86_64, ripRel32, 2, 0 },
286 { false, 0, 0, 0 },
287
288 // Stub Helper size and code
289 10,
290 { 0x68, 0x00, 0x00, 0x00, 0x00, // pushq $lazy-info-offset
291 0xE9, 0x00, 0x00, 0x00, 0x00 }, // jmp helperhelper
292 { Reference::KindArch::x86_64, lazyImmediateLocation, 1, 0 },
293 { Reference::KindArch::x86_64, branch32, 6, 0 },
294
295 // Stub helper image cache content type
296 DefinedAtom::typeNonLazyPointer,
297
298 // Stub Helper-Common size and code
299 16,
300 // Stub helper alignment
301 2,
302 { 0x4C, 0x8D, 0x1D, 0x00, 0x00, 0x00, 0x00, // leaq cache(%rip),%r11
303 0x41, 0x53, // push %r11
304 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp *binder(%rip)
305 0x90 }, // nop
306 { Reference::KindArch::x86_64, ripRel32, 3, 0 },
307 { false, 0, 0, 0 },
308 { Reference::KindArch::x86_64, ripRel32, 11, 0 },
309 { false, 0, 0, 0 }
310
311};
312
313bool ArchHandler_x86_64::isCallSite(const Reference &ref) {
314 if (ref.kindNamespace() != Reference::KindNamespace::mach_o)
315 return false;
316 assert(ref.kindArch() == Reference::KindArch::x86_64);
317 return (ref.kindValue() == branch32);
318}
319
320bool ArchHandler_x86_64::isPointer(const Reference &ref) {
321 if (ref.kindNamespace() != Reference::KindNamespace::mach_o)
322 return false;
323 assert(ref.kindArch() == Reference::KindArch::x86_64);
324 Reference::KindValue kind = ref.kindValue();
325 return (kind == pointer64 || kind == pointer64Anon);
326}
327
328bool ArchHandler_x86_64::isPairedReloc(const Relocation &reloc) {
329 return (reloc.type == X86_64_RELOC_SUBTRACTOR);
330}
331
332Reference::KindValue
333ArchHandler_x86_64::kindFromReloc(const Relocation &reloc) {
334 switch(relocPattern(reloc)) {
335 case X86_64_RELOC_BRANCH | rPcRel | rExtern | rLength4:
336 return branch32;
337 case X86_64_RELOC_SIGNED | rPcRel | rExtern | rLength4:
338 return ripRel32;
339 case X86_64_RELOC_SIGNED | rPcRel | rLength4:
340 return ripRel32Anon;
341 case X86_64_RELOC_SIGNED_1 | rPcRel | rExtern | rLength4:
342 return ripRel32Minus1;
343 case X86_64_RELOC_SIGNED_1 | rPcRel | rLength4:
344 return ripRel32Minus1Anon;
345 case X86_64_RELOC_SIGNED_2 | rPcRel | rExtern | rLength4:
346 return ripRel32Minus2;
347 case X86_64_RELOC_SIGNED_2 | rPcRel | rLength4:
348 return ripRel32Minus2Anon;
349 case X86_64_RELOC_SIGNED_4 | rPcRel | rExtern | rLength4:
350 return ripRel32Minus4;
351 case X86_64_RELOC_SIGNED_4 | rPcRel | rLength4:
352 return ripRel32Minus4Anon;
353 case X86_64_RELOC_GOT_LOAD | rPcRel | rExtern | rLength4:
354 return ripRel32GotLoad;
355 case X86_64_RELOC_GOT | rPcRel | rExtern | rLength4:
356 return ripRel32Got;
357 case X86_64_RELOC_TLV | rPcRel | rExtern | rLength4:
358 return ripRel32Tlv;
359 case X86_64_RELOC_UNSIGNED | rExtern | rLength8:
360 return pointer64;
361 case X86_64_RELOC_UNSIGNED | rLength8:
362 return pointer64Anon;
363 default:
364 return invalid;
365 }
366}
367
368llvm::Error
369ArchHandler_x86_64::getReferenceInfo(const Relocation &reloc,
370 const DefinedAtom *inAtom,
371 uint32_t offsetInAtom,
372 uint64_t fixupAddress, bool swap,
373 FindAtomBySectionAndAddress atomFromAddress,
374 FindAtomBySymbolIndex atomFromSymbolIndex,
375 Reference::KindValue *kind,
376 const lld::Atom **target,
377 Reference::Addend *addend) {
378 *kind = kindFromReloc(reloc);
379 if (*kind == invalid)
380 return llvm::make_error<GenericError>("unknown type");
381 const uint8_t *fixupContent = &inAtom->rawContent()[offsetInAtom];
382 uint64_t targetAddress;
383 switch (*kind) {
384 case branch32:
385 case ripRel32:
386 if (auto ec = atomFromSymbolIndex(reloc.symbol, target))
387 return ec;
388 *addend = *(const little32_t *)fixupContent;
389 return llvm::Error::success();
390 case ripRel32Minus1:
391 if (auto ec = atomFromSymbolIndex(reloc.symbol, target))
392 return ec;
393 *addend = (int32_t)*(const little32_t *)fixupContent + 1;
394 return llvm::Error::success();
395 case ripRel32Minus2:
396 if (auto ec = atomFromSymbolIndex(reloc.symbol, target))
397 return ec;
398 *addend = (int32_t)*(const little32_t *)fixupContent + 2;
399 return llvm::Error::success();
400 case ripRel32Minus4:
401 if (auto ec = atomFromSymbolIndex(reloc.symbol, target))
402 return ec;
403 *addend = (int32_t)*(const little32_t *)fixupContent + 4;
404 return llvm::Error::success();
405 case ripRel32Anon:
406 targetAddress = fixupAddress + 4 + *(const little32_t *)fixupContent;
407 return atomFromAddress(reloc.symbol, targetAddress, target, addend);
408 case ripRel32Minus1Anon:
409 targetAddress = fixupAddress + 5 + *(const little32_t *)fixupContent;
410 return atomFromAddress(reloc.symbol, targetAddress, target, addend);
411 case ripRel32Minus2Anon:
412 targetAddress = fixupAddress + 6 + *(const little32_t *)fixupContent;
413 return atomFromAddress(reloc.symbol, targetAddress, target, addend);
414 case ripRel32Minus4Anon:
415 targetAddress = fixupAddress + 8 + *(const little32_t *)fixupContent;
416 return atomFromAddress(reloc.symbol, targetAddress, target, addend);
417 case ripRel32GotLoad:
418 case ripRel32Got:
419 case ripRel32Tlv:
420 if (auto ec = atomFromSymbolIndex(reloc.symbol, target))
421 return ec;
422 *addend = *(const little32_t *)fixupContent;
423 return llvm::Error::success();
424 case tlvInitSectionOffset:
425 case pointer64:
426 if (auto ec = atomFromSymbolIndex(reloc.symbol, target))
427 return ec;
428 // If this is the 3rd pointer of a tlv-thunk (i.e. the pointer to the TLV's
429 // initial value) we need to handle it specially.
430 if (inAtom->contentType() == DefinedAtom::typeThunkTLV &&
431 offsetInAtom == 16) {
432 *kind = tlvInitSectionOffset;
433 assert(*addend == 0 && "TLV-init has non-zero addend?");
434 } else
435 *addend = *(const little64_t *)fixupContent;
436 return llvm::Error::success();
437 case pointer64Anon:
438 targetAddress = *(const little64_t *)fixupContent;
439 return atomFromAddress(reloc.symbol, targetAddress, target, addend);
440 default:
441 llvm_unreachable("bad reloc kind");
442 }
443}
444
445llvm::Error
446ArchHandler_x86_64::getPairReferenceInfo(const normalized::Relocation &reloc1,
447 const normalized::Relocation &reloc2,
448 const DefinedAtom *inAtom,
449 uint32_t offsetInAtom,
450 uint64_t fixupAddress, bool swap,
451 bool scatterable,
452 FindAtomBySectionAndAddress atomFromAddress,
453 FindAtomBySymbolIndex atomFromSymbolIndex,
454 Reference::KindValue *kind,
455 const lld::Atom **target,
456 Reference::Addend *addend) {
457 const uint8_t *fixupContent = &inAtom->rawContent()[offsetInAtom];
458 uint64_t targetAddress;
459 const lld::Atom *fromTarget;
460 if (auto ec = atomFromSymbolIndex(reloc1.symbol, &fromTarget))
461 return ec;
462
463 switch(relocPattern(reloc1) << 16 | relocPattern(reloc2)) {
464 case ((X86_64_RELOC_SUBTRACTOR | rExtern | rLength8) << 16 |
465 X86_64_RELOC_UNSIGNED | rExtern | rLength8): {
466 if (auto ec = atomFromSymbolIndex(reloc2.symbol, target))
467 return ec;
468 uint64_t encodedAddend = (int64_t)*(const little64_t *)fixupContent;
469 if (inAtom == fromTarget) {
470 if (inAtom->contentType() == DefinedAtom::typeCFI)
471 *kind = unwindFDEToFunction;
472 else
473 *kind = delta64;
474 *addend = encodedAddend + offsetInAtom;
475 } else if (inAtom == *target) {
476 *kind = negDelta64;
477 *addend = encodedAddend - offsetInAtom;
478 *target = fromTarget;
479 } else
480 return llvm::make_error<GenericError>("Invalid pointer diff");
481 return llvm::Error::success();
482 }
483 case ((X86_64_RELOC_SUBTRACTOR | rExtern | rLength4) << 16 |
484 X86_64_RELOC_UNSIGNED | rExtern | rLength4): {
485 if (auto ec = atomFromSymbolIndex(reloc2.symbol, target))
486 return ec;
487 uint32_t encodedAddend = (int32_t)*(const little32_t *)fixupContent;
488 if (inAtom == fromTarget) {
489 *kind = delta32;
490 *addend = encodedAddend + offsetInAtom;
491 } else if (inAtom == *target) {
492 *kind = negDelta32;
493 *addend = encodedAddend - offsetInAtom;
494 *target = fromTarget;
495 } else
496 return llvm::make_error<GenericError>("Invalid pointer diff");
497 return llvm::Error::success();
498 }
499 case ((X86_64_RELOC_SUBTRACTOR | rExtern | rLength8) << 16 |
500 X86_64_RELOC_UNSIGNED | rLength8):
501 if (fromTarget != inAtom)
502 return llvm::make_error<GenericError>("pointer diff not in base atom");
503 *kind = delta64Anon;
504 targetAddress = offsetInAtom + (int64_t)*(const little64_t *)fixupContent;
505 return atomFromAddress(reloc2.symbol, targetAddress, target, addend);
506 case ((X86_64_RELOC_SUBTRACTOR | rExtern | rLength4) << 16 |
507 X86_64_RELOC_UNSIGNED | rLength4):
508 if (fromTarget != inAtom)
509 return llvm::make_error<GenericError>("pointer diff not in base atom");
510 *kind = delta32Anon;
511 targetAddress = offsetInAtom + (int32_t)*(const little32_t *)fixupContent;
512 return atomFromAddress(reloc2.symbol, targetAddress, target, addend);
513 default:
514 return llvm::make_error<GenericError>("unknown pair");
515 }
516}
517
518void ArchHandler_x86_64::generateAtomContent(
519 const DefinedAtom &atom, bool relocatable, FindAddressForAtom findAddress,
520 FindAddressForAtom findSectionAddress, uint64_t imageBaseAddress,
521 llvm::MutableArrayRef<uint8_t> atomContentBuffer) {
522 // Copy raw bytes.
523 std::copy(atom.rawContent().begin(), atom.rawContent().end(),
524 atomContentBuffer.begin());
525 // Apply fix-ups.
526 for (const Reference *ref : atom) {
527 uint32_t offset = ref->offsetInAtom();
528 const Atom *target = ref->target();
529 uint64_t targetAddress = 0;
530 if (isa<DefinedAtom>(target))
531 targetAddress = findAddress(*target);
532 uint64_t atomAddress = findAddress(atom);
533 uint64_t fixupAddress = atomAddress + offset;
534 if (relocatable) {
535 applyFixupRelocatable(*ref, &atomContentBuffer[offset],
536 fixupAddress, targetAddress,
537 atomAddress);
538 } else {
539 applyFixupFinal(*ref, &atomContentBuffer[offset],
540 fixupAddress, targetAddress,
541 atomAddress, imageBaseAddress, findSectionAddress);
542 }
543 }
544}
545
546void ArchHandler_x86_64::applyFixupFinal(
547 const Reference &ref, uint8_t *loc, uint64_t fixupAddress,
548 uint64_t targetAddress, uint64_t inAtomAddress, uint64_t imageBaseAddress,
549 FindAddressForAtom findSectionAddress) {
550 if (ref.kindNamespace() != Reference::KindNamespace::mach_o)
551 return;
552 assert(ref.kindArch() == Reference::KindArch::x86_64);
553 ulittle32_t *loc32 = reinterpret_cast<ulittle32_t *>(loc);
554 ulittle64_t *loc64 = reinterpret_cast<ulittle64_t *>(loc);
555 switch (static_cast<X86_64Kind>(ref.kindValue())) {
556 case branch32:
557 case ripRel32:
558 case ripRel32Anon:
559 case ripRel32Got:
560 case ripRel32GotLoad:
561 case ripRel32Tlv:
562 *loc32 = targetAddress - (fixupAddress + 4) + ref.addend();
563 return;
564 case pointer64:
565 case pointer64Anon:
566 *loc64 = targetAddress + ref.addend();
567 return;
568 case tlvInitSectionOffset:
569 *loc64 = targetAddress - findSectionAddress(*ref.target()) + ref.addend();
570 return;
571 case ripRel32Minus1:
572 case ripRel32Minus1Anon:
573 *loc32 = targetAddress - (fixupAddress + 5) + ref.addend();
574 return;
575 case ripRel32Minus2:
576 case ripRel32Minus2Anon:
577 *loc32 = targetAddress - (fixupAddress + 6) + ref.addend();
578 return;
579 case ripRel32Minus4:
580 case ripRel32Minus4Anon:
581 *loc32 = targetAddress - (fixupAddress + 8) + ref.addend();
582 return;
583 case delta32:
584 case delta32Anon:
585 *loc32 = targetAddress - fixupAddress + ref.addend();
586 return;
587 case delta64:
588 case delta64Anon:
589 case unwindFDEToFunction:
590 *loc64 = targetAddress - fixupAddress + ref.addend();
591 return;
592 case ripRel32GotLoadNowLea:
593 // Change MOVQ to LEA
594 assert(loc[-2] == 0x8B);
595 loc[-2] = 0x8D;
596 *loc32 = targetAddress - (fixupAddress + 4) + ref.addend();
597 return;
598 case negDelta64:
599 *loc64 = fixupAddress - targetAddress + ref.addend();
600 return;
601 case negDelta32:
602 *loc32 = fixupAddress - targetAddress + ref.addend();
603 return;
604 case lazyPointer:
605 // Do nothing
606 return;
607 case lazyImmediateLocation:
608 *loc32 = ref.addend();
609 return;
610 case imageOffset:
611 case imageOffsetGot:
612 *loc32 = (targetAddress - imageBaseAddress) + ref.addend();
613 return;
614 case unwindInfoToEhFrame: {
615 uint64_t val = targetAddress - findSectionAddress(*ref.target()) + ref.addend();
616 assert(val < 0xffffffU && "offset in __eh_frame too large");
617 *loc32 = (*loc32 & 0xff000000U) | val;
618 return;
619 }
620 case invalid:
621 // Fall into llvm_unreachable().
622 break;
623 }
624 return;
625}
626
627void ArchHandler_x86_64::applyFixupRelocatable(const Reference &ref,
628 uint8_t *loc,
629 uint64_t fixupAddress,
630 uint64_t targetAddress,
631 uint64_t inAtomAddress) {
632 if (ref.kindNamespace() != Reference::KindNamespace::mach_o)
633 return;
634 assert(ref.kindArch() == Reference::KindArch::x86_64);
635 ulittle32_t *loc32 = reinterpret_cast<ulittle32_t *>(loc);
636 ulittle64_t *loc64 = reinterpret_cast<ulittle64_t *>(loc);
637 switch (static_cast<X86_64Kind>(ref.kindValue())) {
638 case branch32:
639 case ripRel32:
640 case ripRel32Got:
641 case ripRel32GotLoad:
642 case ripRel32Tlv:
643 *loc32 = ref.addend();
644 return;
645 case ripRel32Anon:
646 *loc32 = (targetAddress - (fixupAddress + 4)) + ref.addend();
647 return;
648 case tlvInitSectionOffset:
649 case pointer64:
650 *loc64 = ref.addend();
651 return;
652 case pointer64Anon:
653 *loc64 = targetAddress + ref.addend();
654 return;
655 case ripRel32Minus1:
656 *loc32 = ref.addend() - 1;
657 return;
658 case ripRel32Minus1Anon:
659 *loc32 = (targetAddress - (fixupAddress + 5)) + ref.addend();
660 return;
661 case ripRel32Minus2:
662 *loc32 = ref.addend() - 2;
663 return;
664 case ripRel32Minus2Anon:
665 *loc32 = (targetAddress - (fixupAddress + 6)) + ref.addend();
666 return;
667 case ripRel32Minus4:
668 *loc32 = ref.addend() - 4;
669 return;
670 case ripRel32Minus4Anon:
671 *loc32 = (targetAddress - (fixupAddress + 8)) + ref.addend();
672 return;
673 case delta32:
674 *loc32 = ref.addend() + inAtomAddress - fixupAddress;
675 return;
676 case delta32Anon:
677 // The value we write here should be the the delta to the target
678 // after taking in to account the difference from the fixup back to the
679 // last defined label
680 // ie, if we have:
681 // _base: ...
682 // Lfixup: .quad Ltarget - .
683 // ...
684 // Ltarget:
685 //
686 // Then we want to encode the value (Ltarget + addend) - (LFixup - _base)
687 *loc32 = (targetAddress + ref.addend()) - (fixupAddress - inAtomAddress);
688 return;
689 case delta64:
690 *loc64 = ref.addend() + inAtomAddress - fixupAddress;
691 return;
692 case delta64Anon:
693 // The value we write here should be the the delta to the target
694 // after taking in to account the difference from the fixup back to the
695 // last defined label
696 // ie, if we have:
697 // _base: ...
698 // Lfixup: .quad Ltarget - .
699 // ...
700 // Ltarget:
701 //
702 // Then we want to encode the value (Ltarget + addend) - (LFixup - _base)
703 *loc64 = (targetAddress + ref.addend()) - (fixupAddress - inAtomAddress);
704 return;
705 case negDelta64:
706 *loc64 = ref.addend() + fixupAddress - inAtomAddress;
707 return;
708 case negDelta32:
709 *loc32 = ref.addend() + fixupAddress - inAtomAddress;
710 return;
711 case ripRel32GotLoadNowLea:
712 llvm_unreachable("ripRel32GotLoadNowLea implies GOT pass was run");
713 return;
714 case lazyPointer:
715 case lazyImmediateLocation:
716 llvm_unreachable("lazy reference kind implies Stubs pass was run");
717 return;
718 case imageOffset:
719 case imageOffsetGot:
720 case unwindInfoToEhFrame:
721 llvm_unreachable("fixup implies __unwind_info");
722 return;
723 case unwindFDEToFunction:
724 // Do nothing for now
725 return;
726 case invalid:
727 // Fall into llvm_unreachable().
728 break;
729 }
730 llvm_unreachable("unknown x86_64 Reference Kind");
731}
732
733void ArchHandler_x86_64::appendSectionRelocations(
734 const DefinedAtom &atom,
735 uint64_t atomSectionOffset,
736 const Reference &ref,
737 FindSymbolIndexForAtom symbolIndexForAtom,
738 FindSectionIndexForAtom sectionIndexForAtom,
739 FindAddressForAtom addressForAtom,
740 normalized::Relocations &relocs) {
741 if (ref.kindNamespace() != Reference::KindNamespace::mach_o)
742 return;
743 assert(ref.kindArch() == Reference::KindArch::x86_64);
744 uint32_t sectionOffset = atomSectionOffset + ref.offsetInAtom();
745 switch (static_cast<X86_64Kind>(ref.kindValue())) {
746 case branch32:
747 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
748 X86_64_RELOC_BRANCH | rPcRel | rExtern | rLength4);
749 return;
750 case ripRel32:
751 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
752 X86_64_RELOC_SIGNED | rPcRel | rExtern | rLength4 );
753 return;
754 case ripRel32Anon:
755 appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()), 0,
756 X86_64_RELOC_SIGNED | rPcRel | rLength4 );
757 return;
758 case ripRel32Got:
759 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
760 X86_64_RELOC_GOT | rPcRel | rExtern | rLength4 );
761 return;
762 case ripRel32GotLoad:
763 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
764 X86_64_RELOC_GOT_LOAD | rPcRel | rExtern | rLength4 );
765 return;
766 case ripRel32Tlv:
767 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
768 X86_64_RELOC_TLV | rPcRel | rExtern | rLength4 );
769 return;
770 case tlvInitSectionOffset:
771 case pointer64:
772 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
773 X86_64_RELOC_UNSIGNED | rExtern | rLength8);
774 return;
775 case pointer64Anon:
776 appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()), 0,
777 X86_64_RELOC_UNSIGNED | rLength8);
778 return;
779 case ripRel32Minus1:
780 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
781 X86_64_RELOC_SIGNED_1 | rPcRel | rExtern | rLength4 );
782 return;
783 case ripRel32Minus1Anon:
784 appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()), 0,
785 X86_64_RELOC_SIGNED_1 | rPcRel | rLength4 );
786 return;
787 case ripRel32Minus2:
788 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
789 X86_64_RELOC_SIGNED_2 | rPcRel | rExtern | rLength4 );
790 return;
791 case ripRel32Minus2Anon:
792 appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()), 0,
793 X86_64_RELOC_SIGNED_2 | rPcRel | rLength4 );
794 return;
795 case ripRel32Minus4:
796 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
797 X86_64_RELOC_SIGNED_4 | rPcRel | rExtern | rLength4 );
798 return;
799 case ripRel32Minus4Anon:
800 appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()), 0,
801 X86_64_RELOC_SIGNED_4 | rPcRel | rLength4 );
802 return;
803 case delta32:
804 appendReloc(relocs, sectionOffset, symbolIndexForAtom(atom), 0,
805 X86_64_RELOC_SUBTRACTOR | rExtern | rLength4 );
806 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
807 X86_64_RELOC_UNSIGNED | rExtern | rLength4 );
808 return;
809 case delta32Anon:
810 appendReloc(relocs, sectionOffset, symbolIndexForAtom(atom), 0,
811 X86_64_RELOC_SUBTRACTOR | rExtern | rLength4 );
812 appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()), 0,
813 X86_64_RELOC_UNSIGNED | rLength4 );
814 return;
815 case delta64:
816 appendReloc(relocs, sectionOffset, symbolIndexForAtom(atom), 0,
817 X86_64_RELOC_SUBTRACTOR | rExtern | rLength8 );
818 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
819 X86_64_RELOC_UNSIGNED | rExtern | rLength8 );
820 return;
821 case delta64Anon:
822 appendReloc(relocs, sectionOffset, symbolIndexForAtom(atom), 0,
823 X86_64_RELOC_SUBTRACTOR | rExtern | rLength8 );
824 appendReloc(relocs, sectionOffset, sectionIndexForAtom(*ref.target()), 0,
825 X86_64_RELOC_UNSIGNED | rLength8 );
826 return;
827 case unwindFDEToFunction:
828 case unwindInfoToEhFrame:
829 return;
830 case negDelta32:
831 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
832 X86_64_RELOC_SUBTRACTOR | rExtern | rLength4 );
833 appendReloc(relocs, sectionOffset, symbolIndexForAtom(atom), 0,
834 X86_64_RELOC_UNSIGNED | rExtern | rLength4 );
835 return;
836 case negDelta64:
837 appendReloc(relocs, sectionOffset, symbolIndexForAtom(*ref.target()), 0,
838 X86_64_RELOC_SUBTRACTOR | rExtern | rLength8 );
839 appendReloc(relocs, sectionOffset, symbolIndexForAtom(atom), 0,
840 X86_64_RELOC_UNSIGNED | rExtern | rLength8 );
841 return;
842 case ripRel32GotLoadNowLea:
843 llvm_unreachable("ripRel32GotLoadNowLea implies GOT pass was run");
844 return;
845 case lazyPointer:
846 case lazyImmediateLocation:
847 llvm_unreachable("lazy reference kind implies Stubs pass was run");
848 return;
849 case imageOffset:
850 case imageOffsetGot:
851 llvm_unreachable("__unwind_info references should have been resolved");
852 return;
853 case invalid:
854 // Fall into llvm_unreachable().
855 break;
856 }
857 llvm_unreachable("unknown x86_64 Reference Kind");
858}
859
860std::unique_ptr<mach_o::ArchHandler> ArchHandler::create_x86_64() {
861 return std::unique_ptr<mach_o::ArchHandler>(new ArchHandler_x86_64());
862}
863
864} // namespace mach_o
865} // namespace lld
deps/lld/lib/ReaderWriter/MachO/Atoms.h created+181
......@@ -0,0 +1,181 @@
1//===- lib/ReaderWriter/MachO/Atoms.h ---------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_READER_WRITER_MACHO_ATOMS_H
11#define LLD_READER_WRITER_MACHO_ATOMS_H
12
13#include "lld/Core/Atom.h"
14#include "lld/Core/DefinedAtom.h"
15#include "lld/Core/SharedLibraryAtom.h"
16#include "lld/Core/Simple.h"
17#include "llvm/ADT/ArrayRef.h"
18#include "llvm/ADT/StringRef.h"
19#include <cstdint>
20#include <string>
21
22namespace lld {
23
24class File;
25
26namespace mach_o {
27
28class MachODefinedAtom : public SimpleDefinedAtom {
29public:
30 MachODefinedAtom(const File &f, const StringRef name, Scope scope,
31 ContentType type, Merge merge, bool thumb, bool noDeadStrip,
32 const ArrayRef<uint8_t> content, Alignment align)
33 : SimpleDefinedAtom(f), _name(name), _content(content),
34 _align(align), _contentType(type), _scope(scope), _merge(merge),
35 _thumb(thumb), _noDeadStrip(noDeadStrip) {}
36
37 // Constructor for zero-fill content
38 MachODefinedAtom(const File &f, const StringRef name, Scope scope,
39 ContentType type, uint64_t size, bool noDeadStrip,
40 Alignment align)
41 : SimpleDefinedAtom(f), _name(name),
42 _content(ArrayRef<uint8_t>(nullptr, size)), _align(align),
43 _contentType(type), _scope(scope), _merge(mergeNo), _thumb(false),
44 _noDeadStrip(noDeadStrip) {}
45
46 ~MachODefinedAtom() override = default;
47
48 uint64_t size() const override { return _content.size(); }
49
50 ContentType contentType() const override { return _contentType; }
51
52 Alignment alignment() const override { return _align; }
53
54 StringRef name() const override { return _name; }
55
56 Scope scope() const override { return _scope; }
57
58 Merge merge() const override { return _merge; }
59
60 DeadStripKind deadStrip() const override {
61 if (_contentType == DefinedAtom::typeInitializerPtr)
62 return deadStripNever;
63 if (_contentType == DefinedAtom::typeTerminatorPtr)
64 return deadStripNever;
65 if (_noDeadStrip)
66 return deadStripNever;
67 return deadStripNormal;
68 }
69
70 ArrayRef<uint8_t> rawContent() const override {
71 // Note: Zerofill atoms have a content pointer which is null.
72 return _content;
73 }
74
75 bool isThumb() const { return _thumb; }
76
77private:
78 const StringRef _name;
79 const ArrayRef<uint8_t> _content;
80 const DefinedAtom::Alignment _align;
81 const ContentType _contentType;
82 const Scope _scope;
83 const Merge _merge;
84 const bool _thumb;
85 const bool _noDeadStrip;
86};
87
88class MachODefinedCustomSectionAtom : public MachODefinedAtom {
89public:
90 MachODefinedCustomSectionAtom(const File &f, const StringRef name,
91 Scope scope, ContentType type, Merge merge,
92 bool thumb, bool noDeadStrip,
93 const ArrayRef<uint8_t> content,
94 StringRef sectionName, Alignment align)
95 : MachODefinedAtom(f, name, scope, type, merge, thumb, noDeadStrip,
96 content, align),
97 _sectionName(sectionName) {}
98
99 ~MachODefinedCustomSectionAtom() override = default;
100
101 SectionChoice sectionChoice() const override {
102 return DefinedAtom::sectionCustomRequired;
103 }
104
105 StringRef customSectionName() const override {
106 return _sectionName;
107 }
108private:
109 StringRef _sectionName;
110};
111
112class MachOTentativeDefAtom : public SimpleDefinedAtom {
113public:
114 MachOTentativeDefAtom(const File &f, const StringRef name, Scope scope,
115 uint64_t size, DefinedAtom::Alignment align)
116 : SimpleDefinedAtom(f), _name(name), _scope(scope), _size(size),
117 _align(align) {}
118
119 ~MachOTentativeDefAtom() override = default;
120
121 uint64_t size() const override { return _size; }
122
123 Merge merge() const override { return DefinedAtom::mergeAsTentative; }
124
125 ContentType contentType() const override { return DefinedAtom::typeZeroFill; }
126
127 Alignment alignment() const override { return _align; }
128
129 StringRef name() const override { return _name; }
130
131 Scope scope() const override { return _scope; }
132
133 ArrayRef<uint8_t> rawContent() const override { return ArrayRef<uint8_t>(); }
134
135private:
136 const std::string _name;
137 const Scope _scope;
138 const uint64_t _size;
139 const DefinedAtom::Alignment _align;
140};
141
142class MachOSharedLibraryAtom : public SharedLibraryAtom {
143public:
144 MachOSharedLibraryAtom(const File &file, StringRef name,
145 StringRef dylibInstallName, bool weakDef)
146 : SharedLibraryAtom(), _file(file), _name(name),
147 _dylibInstallName(dylibInstallName) {}
148 ~MachOSharedLibraryAtom() override = default;
149
150 StringRef loadName() const override { return _dylibInstallName; }
151
152 bool canBeNullAtRuntime() const override {
153 // FIXME: this may actually be changeable. For now, all symbols are strongly
154 // defined though.
155 return false;
156 }
157
158 const File &file() const override { return _file; }
159
160 StringRef name() const override { return _name; }
161
162 Type type() const override {
163 // Unused in MachO (I think).
164 return Type::Unknown;
165 }
166
167 uint64_t size() const override {
168 // Unused in MachO (I think)
169 return 0;
170 }
171
172private:
173 const File &_file;
174 StringRef _name;
175 StringRef _dylibInstallName;
176};
177
178} // end namespace mach_o
179} // end namespace lld
180
181#endif // LLD_READER_WRITER_MACHO_ATOMS_H
deps/lld/lib/ReaderWriter/MachO/CMakeLists.txt created+34
......@@ -0,0 +1,34 @@
1add_lld_library(lldMachO
2 ArchHandler.cpp
3 ArchHandler_arm.cpp
4 ArchHandler_arm64.cpp
5 ArchHandler_x86.cpp
6 ArchHandler_x86_64.cpp
7 CompactUnwindPass.cpp
8 GOTPass.cpp
9 LayoutPass.cpp
10 MachOLinkingContext.cpp
11 MachONormalizedFileBinaryReader.cpp
12 MachONormalizedFileBinaryWriter.cpp
13 MachONormalizedFileFromAtoms.cpp
14 MachONormalizedFileToAtoms.cpp
15 MachONormalizedFileYAML.cpp
16 ObjCPass.cpp
17 ShimPass.cpp
18 StubsPass.cpp
19 TLVPass.cpp
20 WriterMachO.cpp
21
22 LINK_COMPONENTS
23 DebugInfoDWARF
24 Object
25 Support
26 Demangle
27
28 LINK_LIBS
29 lldCore
30 lldYAML
31 ${LLVM_PTHREAD_LIB}
32 )
33
34include_directories(.)
deps/lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp created+582
......@@ -0,0 +1,582 @@
1//===- lib/ReaderWriter/MachO/CompactUnwindPass.cpp -------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file A pass to convert MachO's __compact_unwind sections into the final
11/// __unwind_info format used during runtime. See
12/// mach-o/compact_unwind_encoding.h for more details on the formats involved.
13///
14//===----------------------------------------------------------------------===//
15
16#include "ArchHandler.h"
17#include "File.h"
18#include "MachONormalizedFileBinaryUtils.h"
19#include "MachOPasses.h"
20#include "lld/Core/DefinedAtom.h"
21#include "lld/Core/File.h"
22#include "lld/Core/LLVM.h"
23#include "lld/Core/Reference.h"
24#include "lld/Core/Simple.h"
25#include "llvm/ADT/DenseMap.h"
26#include "llvm/Support/Debug.h"
27#include "llvm/Support/Format.h"
28
29#define DEBUG_TYPE "macho-compact-unwind"
30
31namespace lld {
32namespace mach_o {
33
34namespace {
35struct CompactUnwindEntry {
36 const Atom *rangeStart;
37 const Atom *personalityFunction;
38 const Atom *lsdaLocation;
39 const Atom *ehFrame;
40
41 uint32_t rangeLength;
42
43 // There are 3 types of compact unwind entry, distinguished by the encoding
44 // value: 0 indicates a function with no unwind info;
45 // _archHandler.dwarfCompactUnwindType() indicates that the entry defers to
46 // __eh_frame, and that the ehFrame entry will be valid; any other value is a
47 // real compact unwind entry -- personalityFunction will be set and
48 // lsdaLocation may be.
49 uint32_t encoding;
50
51 CompactUnwindEntry(const DefinedAtom *function)
52 : rangeStart(function), personalityFunction(nullptr),
53 lsdaLocation(nullptr), ehFrame(nullptr), rangeLength(function->size()),
54 encoding(0) {}
55
56 CompactUnwindEntry()
57 : rangeStart(nullptr), personalityFunction(nullptr),
58 lsdaLocation(nullptr), ehFrame(nullptr), rangeLength(0), encoding(0) {}
59};
60
61struct UnwindInfoPage {
62 ArrayRef<CompactUnwindEntry> entries;
63};
64}
65
66class UnwindInfoAtom : public SimpleDefinedAtom {
67public:
68 UnwindInfoAtom(ArchHandler &archHandler, const File &file, bool isBig,
69 std::vector<const Atom *> &personalities,
70 std::vector<uint32_t> &commonEncodings,
71 std::vector<UnwindInfoPage> &pages, uint32_t numLSDAs)
72 : SimpleDefinedAtom(file), _archHandler(archHandler),
73 _commonEncodingsOffset(7 * sizeof(uint32_t)),
74 _personalityArrayOffset(_commonEncodingsOffset +
75 commonEncodings.size() * sizeof(uint32_t)),
76 _topLevelIndexOffset(_personalityArrayOffset +
77 personalities.size() * sizeof(uint32_t)),
78 _lsdaIndexOffset(_topLevelIndexOffset +
79 3 * (pages.size() + 1) * sizeof(uint32_t)),
80 _firstPageOffset(_lsdaIndexOffset + 2 * numLSDAs * sizeof(uint32_t)),
81 _isBig(isBig) {
82
83 addHeader(commonEncodings.size(), personalities.size(), pages.size());
84 addCommonEncodings(commonEncodings);
85 addPersonalityFunctions(personalities);
86 addTopLevelIndexes(pages);
87 addLSDAIndexes(pages, numLSDAs);
88 addSecondLevelPages(pages);
89 }
90
91 ~UnwindInfoAtom() override = default;
92
93 ContentType contentType() const override {
94 return DefinedAtom::typeProcessedUnwindInfo;
95 }
96
97 Alignment alignment() const override { return 4; }
98
99 uint64_t size() const override { return _contents.size(); }
100
101 ContentPermissions permissions() const override {
102 return DefinedAtom::permR__;
103 }
104
105 ArrayRef<uint8_t> rawContent() const override { return _contents; }
106
107 void addHeader(uint32_t numCommon, uint32_t numPersonalities,
108 uint32_t numPages) {
109 using normalized::write32;
110
111 uint32_t headerSize = 7 * sizeof(uint32_t);
112 _contents.resize(headerSize);
113
114 uint8_t *headerEntries = _contents.data();
115 // version
116 write32(headerEntries, 1, _isBig);
117 // commonEncodingsArraySectionOffset
118 write32(headerEntries + sizeof(uint32_t), _commonEncodingsOffset, _isBig);
119 // commonEncodingsArrayCount
120 write32(headerEntries + 2 * sizeof(uint32_t), numCommon, _isBig);
121 // personalityArraySectionOffset
122 write32(headerEntries + 3 * sizeof(uint32_t), _personalityArrayOffset,
123 _isBig);
124 // personalityArrayCount
125 write32(headerEntries + 4 * sizeof(uint32_t), numPersonalities, _isBig);
126 // indexSectionOffset
127 write32(headerEntries + 5 * sizeof(uint32_t), _topLevelIndexOffset, _isBig);
128 // indexCount
129 write32(headerEntries + 6 * sizeof(uint32_t), numPages + 1, _isBig);
130 }
131
132 /// Add the list of common encodings to the section; this is simply an array
133 /// of uint32_t compact values. Size has already been specified in the header.
134 void addCommonEncodings(std::vector<uint32_t> &commonEncodings) {
135 using normalized::write32;
136
137 _contents.resize(_commonEncodingsOffset +
138 commonEncodings.size() * sizeof(uint32_t));
139 uint8_t *commonEncodingsArea =
140 reinterpret_cast<uint8_t *>(_contents.data() + _commonEncodingsOffset);
141
142 for (uint32_t encoding : commonEncodings) {
143 write32(commonEncodingsArea, encoding, _isBig);
144 commonEncodingsArea += sizeof(uint32_t);
145 }
146 }
147
148 void addPersonalityFunctions(std::vector<const Atom *> personalities) {
149 _contents.resize(_personalityArrayOffset +
150 personalities.size() * sizeof(uint32_t));
151
152 for (unsigned i = 0; i < personalities.size(); ++i)
153 addImageReferenceIndirect(_personalityArrayOffset + i * sizeof(uint32_t),
154 personalities[i]);
155 }
156
157 void addTopLevelIndexes(std::vector<UnwindInfoPage> &pages) {
158 using normalized::write32;
159
160 uint32_t numIndexes = pages.size() + 1;
161 _contents.resize(_topLevelIndexOffset + numIndexes * 3 * sizeof(uint32_t));
162
163 uint32_t pageLoc = _firstPageOffset;
164
165 // The most difficult job here is calculating the LSDAs; everything else
166 // follows fairly naturally, but we can't state where the first
167 uint8_t *indexData = &_contents[_topLevelIndexOffset];
168 uint32_t numLSDAs = 0;
169 for (unsigned i = 0; i < pages.size(); ++i) {
170 // functionOffset
171 addImageReference(_topLevelIndexOffset + 3 * i * sizeof(uint32_t),
172 pages[i].entries[0].rangeStart);
173 // secondLevelPagesSectionOffset
174 write32(indexData + (3 * i + 1) * sizeof(uint32_t), pageLoc, _isBig);
175 write32(indexData + (3 * i + 2) * sizeof(uint32_t),
176 _lsdaIndexOffset + numLSDAs * 2 * sizeof(uint32_t), _isBig);
177
178 for (auto &entry : pages[i].entries)
179 if (entry.lsdaLocation)
180 ++numLSDAs;
181 }
182
183 // Finally, write out the final sentinel index
184 auto &finalEntry = pages[pages.size() - 1].entries.back();
185 addImageReference(_topLevelIndexOffset +
186 3 * pages.size() * sizeof(uint32_t),
187 finalEntry.rangeStart, finalEntry.rangeLength);
188 // secondLevelPagesSectionOffset => 0
189 write32(indexData + (3 * pages.size() + 2) * sizeof(uint32_t),
190 _lsdaIndexOffset + numLSDAs * 2 * sizeof(uint32_t), _isBig);
191 }
192
193 void addLSDAIndexes(std::vector<UnwindInfoPage> &pages, uint32_t numLSDAs) {
194 _contents.resize(_lsdaIndexOffset + numLSDAs * 2 * sizeof(uint32_t));
195
196 uint32_t curOffset = _lsdaIndexOffset;
197 for (auto &page : pages) {
198 for (auto &entry : page.entries) {
199 if (!entry.lsdaLocation)
200 continue;
201
202 addImageReference(curOffset, entry.rangeStart);
203 addImageReference(curOffset + sizeof(uint32_t), entry.lsdaLocation);
204 curOffset += 2 * sizeof(uint32_t);
205 }
206 }
207 }
208
209 void addSecondLevelPages(std::vector<UnwindInfoPage> &pages) {
210 for (auto &page : pages) {
211 addRegularSecondLevelPage(page);
212 }
213 }
214
215 void addRegularSecondLevelPage(const UnwindInfoPage &page) {
216 uint32_t curPageOffset = _contents.size();
217 const int16_t headerSize = sizeof(uint32_t) + 2 * sizeof(uint16_t);
218 uint32_t curPageSize =
219 headerSize + 2 * page.entries.size() * sizeof(uint32_t);
220 _contents.resize(curPageOffset + curPageSize);
221
222 using normalized::write32;
223 using normalized::write16;
224 // 2 => regular page
225 write32(&_contents[curPageOffset], 2, _isBig);
226 // offset of 1st entry
227 write16(&_contents[curPageOffset + 4], headerSize, _isBig);
228 write16(&_contents[curPageOffset + 6], page.entries.size(), _isBig);
229
230 uint32_t pagePos = curPageOffset + headerSize;
231 for (auto &entry : page.entries) {
232 addImageReference(pagePos, entry.rangeStart);
233
234 write32(_contents.data() + pagePos + sizeof(uint32_t), entry.encoding,
235 _isBig);
236 if ((entry.encoding & 0x0f000000U) ==
237 _archHandler.dwarfCompactUnwindType())
238 addEhFrameReference(pagePos + sizeof(uint32_t), entry.ehFrame);
239
240 pagePos += 2 * sizeof(uint32_t);
241 }
242 }
243
244 void addEhFrameReference(uint32_t offset, const Atom *dest,
245 Reference::Addend addend = 0) {
246 addReference(Reference::KindNamespace::mach_o, _archHandler.kindArch(),
247 _archHandler.unwindRefToEhFrameKind(), offset, dest, addend);
248 }
249
250 void addImageReference(uint32_t offset, const Atom *dest,
251 Reference::Addend addend = 0) {
252 addReference(Reference::KindNamespace::mach_o, _archHandler.kindArch(),
253 _archHandler.imageOffsetKind(), offset, dest, addend);
254 }
255
256 void addImageReferenceIndirect(uint32_t offset, const Atom *dest) {
257 addReference(Reference::KindNamespace::mach_o, _archHandler.kindArch(),
258 _archHandler.imageOffsetKindIndirect(), offset, dest, 0);
259 }
260
261private:
262 mach_o::ArchHandler &_archHandler;
263 std::vector<uint8_t> _contents;
264 uint32_t _commonEncodingsOffset;
265 uint32_t _personalityArrayOffset;
266 uint32_t _topLevelIndexOffset;
267 uint32_t _lsdaIndexOffset;
268 uint32_t _firstPageOffset;
269 bool _isBig;
270};
271
272/// Pass for instantiating and optimizing GOT slots.
273///
274class CompactUnwindPass : public Pass {
275public:
276 CompactUnwindPass(const MachOLinkingContext &context)
277 : _ctx(context), _archHandler(_ctx.archHandler()),
278 _file(*_ctx.make_file<MachOFile>("<mach-o Compact Unwind Pass>")),
279 _isBig(MachOLinkingContext::isBigEndian(_ctx.arch())) {
280 _file.setOrdinal(_ctx.getNextOrdinalAndIncrement());
281 }
282
283private:
284 llvm::Error perform(SimpleFile &mergedFile) override {
285 DEBUG(llvm::dbgs() << "MachO Compact Unwind pass\n");
286
287 std::map<const Atom *, CompactUnwindEntry> unwindLocs;
288 std::map<const Atom *, const Atom *> dwarfFrames;
289 std::vector<const Atom *> personalities;
290 uint32_t numLSDAs = 0;
291
292 // First collect all __compact_unwind and __eh_frame entries, addressable by
293 // the function referred to.
294 collectCompactUnwindEntries(mergedFile, unwindLocs, personalities,
295 numLSDAs);
296
297 collectDwarfFrameEntries(mergedFile, dwarfFrames);
298
299 // Skip rest of pass if no unwind info.
300 if (unwindLocs.empty() && dwarfFrames.empty())
301 return llvm::Error::success();
302
303 // FIXME: if there are more than 4 personality functions then we need to
304 // defer to DWARF info for the ones we don't put in the list. They should
305 // also probably be sorted by frequency.
306 assert(personalities.size() <= 4);
307
308 // TODO: Find commmon encodings for use by compressed pages.
309 std::vector<uint32_t> commonEncodings;
310
311 // Now sort the entries by final address and fixup the compact encoding to
312 // its final form (i.e. set personality function bits & create DWARF
313 // references where needed).
314 std::vector<CompactUnwindEntry> unwindInfos = createUnwindInfoEntries(
315 mergedFile, unwindLocs, personalities, dwarfFrames);
316
317 // Remove any unused eh-frame atoms.
318 pruneUnusedEHFrames(mergedFile, unwindInfos, unwindLocs, dwarfFrames);
319
320 // Finally, we can start creating pages based on these entries.
321
322 DEBUG(llvm::dbgs() << " Splitting entries into pages\n");
323 // FIXME: we split the entries into pages naively: lots of 4k pages followed
324 // by a small one. ld64 tried to minimize space and align them to real 4k
325 // boundaries. That might be worth doing, or perhaps we could perform some
326 // minor balancing for expected number of lookups.
327 std::vector<UnwindInfoPage> pages;
328 auto remainingInfos = llvm::makeArrayRef(unwindInfos);
329 do {
330 pages.push_back(UnwindInfoPage());
331
332 // FIXME: we only create regular pages at the moment. These can hold up to
333 // 1021 entries according to the documentation.
334 unsigned entriesInPage = std::min(1021U, (unsigned)remainingInfos.size());
335
336 pages.back().entries = remainingInfos.slice(0, entriesInPage);
337 remainingInfos = remainingInfos.slice(entriesInPage);
338
339 DEBUG(llvm::dbgs()
340 << " Page from " << pages.back().entries[0].rangeStart->name()
341 << " to " << pages.back().entries.back().rangeStart->name() << " + "
342 << llvm::format("0x%x", pages.back().entries.back().rangeLength)
343 << " has " << entriesInPage << " entries\n");
344 } while (!remainingInfos.empty());
345
346 auto *unwind = new (_file.allocator())
347 UnwindInfoAtom(_archHandler, _file, _isBig, personalities,
348 commonEncodings, pages, numLSDAs);
349 mergedFile.addAtom(*unwind);
350
351 // Finally, remove all __compact_unwind atoms now that we've processed them.
352 mergedFile.removeDefinedAtomsIf([](const DefinedAtom *atom) {
353 return atom->contentType() == DefinedAtom::typeCompactUnwindInfo;
354 });
355
356 return llvm::Error::success();
357 }
358
359 void collectCompactUnwindEntries(
360 const SimpleFile &mergedFile,
361 std::map<const Atom *, CompactUnwindEntry> &unwindLocs,
362 std::vector<const Atom *> &personalities, uint32_t &numLSDAs) {
363 DEBUG(llvm::dbgs() << " Collecting __compact_unwind entries\n");
364
365 for (const DefinedAtom *atom : mergedFile.defined()) {
366 if (atom->contentType() != DefinedAtom::typeCompactUnwindInfo)
367 continue;
368
369 auto unwindEntry = extractCompactUnwindEntry(atom);
370 unwindLocs.insert(std::make_pair(unwindEntry.rangeStart, unwindEntry));
371
372 DEBUG(llvm::dbgs() << " Entry for " << unwindEntry.rangeStart->name()
373 << ", encoding="
374 << llvm::format("0x%08x", unwindEntry.encoding));
375 if (unwindEntry.personalityFunction)
376 DEBUG(llvm::dbgs() << ", personality="
377 << unwindEntry.personalityFunction->name()
378 << ", lsdaLoc=" << unwindEntry.lsdaLocation->name());
379 DEBUG(llvm::dbgs() << '\n');
380
381 // Count number of LSDAs we see, since we need to know how big the index
382 // will be while laying out the section.
383 if (unwindEntry.lsdaLocation)
384 ++numLSDAs;
385
386 // Gather the personality functions now, so that they're in deterministic
387 // order (derived from the DefinedAtom order).
388 if (unwindEntry.personalityFunction) {
389 auto pFunc = std::find(personalities.begin(), personalities.end(),
390 unwindEntry.personalityFunction);
391 if (pFunc == personalities.end())
392 personalities.push_back(unwindEntry.personalityFunction);
393 }
394 }
395 }
396
397 CompactUnwindEntry extractCompactUnwindEntry(const DefinedAtom *atom) {
398 CompactUnwindEntry entry;
399
400 for (const Reference *ref : *atom) {
401 switch (ref->offsetInAtom()) {
402 case 0:
403 // FIXME: there could legitimately be functions with multiple encoding
404 // entries. However, nothing produces them at the moment.
405 assert(ref->addend() == 0 && "unexpected offset into function");
406 entry.rangeStart = ref->target();
407 break;
408 case 0x10:
409 assert(ref->addend() == 0 && "unexpected offset into personality fn");
410 entry.personalityFunction = ref->target();
411 break;
412 case 0x18:
413 assert(ref->addend() == 0 && "unexpected offset into LSDA atom");
414 entry.lsdaLocation = ref->target();
415 break;
416 }
417 }
418
419 if (atom->rawContent().size() < 4 * sizeof(uint32_t))
420 return entry;
421
422 using normalized::read32;
423 entry.rangeLength =
424 read32(atom->rawContent().data() + 2 * sizeof(uint32_t), _isBig);
425 entry.encoding =
426 read32(atom->rawContent().data() + 3 * sizeof(uint32_t), _isBig);
427 return entry;
428 }
429
430 void
431 collectDwarfFrameEntries(const SimpleFile &mergedFile,
432 std::map<const Atom *, const Atom *> &dwarfFrames) {
433 for (const DefinedAtom *ehFrameAtom : mergedFile.defined()) {
434 if (ehFrameAtom->contentType() != DefinedAtom::typeCFI)
435 continue;
436 if (ArchHandler::isDwarfCIE(_isBig, ehFrameAtom))
437 continue;
438
439 if (const Atom *function = _archHandler.fdeTargetFunction(ehFrameAtom))
440 dwarfFrames[function] = ehFrameAtom;
441 }
442 }
443
444 /// Every atom defined in __TEXT,__text needs an entry in the final
445 /// __unwind_info section (in order). These comes from two sources:
446 /// + Input __compact_unwind sections where possible (after adding the
447 /// personality function offset which is only known now).
448 /// + A synthesised reference to __eh_frame if there's no __compact_unwind
449 /// or too many personality functions to be accommodated.
450 std::vector<CompactUnwindEntry> createUnwindInfoEntries(
451 const SimpleFile &mergedFile,
452 const std::map<const Atom *, CompactUnwindEntry> &unwindLocs,
453 const std::vector<const Atom *> &personalities,
454 const std::map<const Atom *, const Atom *> &dwarfFrames) {
455 std::vector<CompactUnwindEntry> unwindInfos;
456
457 DEBUG(llvm::dbgs() << " Creating __unwind_info entries\n");
458 // The final order in the __unwind_info section must be derived from the
459 // order of typeCode atoms, since that's how they'll be put into the object
460 // file eventually (yuck!).
461 for (const DefinedAtom *atom : mergedFile.defined()) {
462 if (atom->contentType() != DefinedAtom::typeCode)
463 continue;
464
465 unwindInfos.push_back(finalizeUnwindInfoEntryForAtom(
466 atom, unwindLocs, personalities, dwarfFrames));
467
468 DEBUG(llvm::dbgs() << " Entry for " << atom->name()
469 << ", final encoding="
470 << llvm::format("0x%08x", unwindInfos.back().encoding)
471 << '\n');
472 }
473
474 return unwindInfos;
475 }
476
477 /// Remove unused EH frames.
478 ///
479 /// An EH frame is considered unused if there is a corresponding compact
480 /// unwind atom that doesn't require the EH frame.
481 void pruneUnusedEHFrames(
482 SimpleFile &mergedFile,
483 const std::vector<CompactUnwindEntry> &unwindInfos,
484 const std::map<const Atom *, CompactUnwindEntry> &unwindLocs,
485 const std::map<const Atom *, const Atom *> &dwarfFrames) {
486
487 // Worklist of all 'used' FDEs.
488 std::vector<const DefinedAtom *> usedDwarfWorklist;
489
490 // We have to check two conditions when building the worklist:
491 // (1) EH frames used by compact unwind entries.
492 for (auto &entry : unwindInfos)
493 if (entry.ehFrame)
494 usedDwarfWorklist.push_back(cast<DefinedAtom>(entry.ehFrame));
495
496 // (2) EH frames that reference functions with no corresponding compact
497 // unwind info.
498 for (auto &entry : dwarfFrames)
499 if (!unwindLocs.count(entry.first))
500 usedDwarfWorklist.push_back(cast<DefinedAtom>(entry.second));
501
502 // Add all transitively referenced CFI atoms by processing the worklist.
503 std::set<const Atom *> usedDwarfFrames;
504 while (!usedDwarfWorklist.empty()) {
505 const DefinedAtom *cfiAtom = usedDwarfWorklist.back();
506 usedDwarfWorklist.pop_back();
507 usedDwarfFrames.insert(cfiAtom);
508 for (const auto *ref : *cfiAtom) {
509 const DefinedAtom *cfiTarget = dyn_cast<DefinedAtom>(ref->target());
510 if (cfiTarget->contentType() == DefinedAtom::typeCFI)
511 usedDwarfWorklist.push_back(cfiTarget);
512 }
513 }
514
515 // Finally, delete all unreferenced CFI atoms.
516 mergedFile.removeDefinedAtomsIf([&](const DefinedAtom *atom) {
517 if ((atom->contentType() == DefinedAtom::typeCFI) &&
518 !usedDwarfFrames.count(atom))
519 return true;
520 return false;
521 });
522 }
523
524 CompactUnwindEntry finalizeUnwindInfoEntryForAtom(
525 const DefinedAtom *function,
526 const std::map<const Atom *, CompactUnwindEntry> &unwindLocs,
527 const std::vector<const Atom *> &personalities,
528 const std::map<const Atom *, const Atom *> &dwarfFrames) {
529 auto unwindLoc = unwindLocs.find(function);
530
531 CompactUnwindEntry entry;
532 if (unwindLoc == unwindLocs.end()) {
533 // Default entry has correct encoding (0 => no unwind), but we need to
534 // synthesise the function.
535 entry.rangeStart = function;
536 entry.rangeLength = function->size();
537 } else
538 entry = unwindLoc->second;
539
540
541 // If there's no __compact_unwind entry, or it explicitly says to use
542 // __eh_frame, we need to try and fill in the correct DWARF atom.
543 if (entry.encoding == _archHandler.dwarfCompactUnwindType() ||
544 entry.encoding == 0) {
545 auto dwarfFrame = dwarfFrames.find(function);
546 if (dwarfFrame != dwarfFrames.end()) {
547 entry.encoding = _archHandler.dwarfCompactUnwindType();
548 entry.ehFrame = dwarfFrame->second;
549 }
550 }
551
552 auto personality = std::find(personalities.begin(), personalities.end(),
553 entry.personalityFunction);
554 uint32_t personalityIdx = personality == personalities.end()
555 ? 0
556 : personality - personalities.begin() + 1;
557
558 // FIXME: We should also use DWARF when there isn't enough room for the
559 // personality function in the compact encoding.
560 assert(personalityIdx < 4 && "too many personality functions");
561
562 entry.encoding |= personalityIdx << 28;
563
564 if (entry.lsdaLocation)
565 entry.encoding |= 1U << 30;
566
567 return entry;
568 }
569
570 const MachOLinkingContext &_ctx;
571 mach_o::ArchHandler &_archHandler;
572 MachOFile &_file;
573 bool _isBig;
574};
575
576void addCompactUnwindPass(PassManager &pm, const MachOLinkingContext &ctx) {
577 assert(ctx.needsCompactUnwindPass());
578 pm.add(llvm::make_unique<CompactUnwindPass>(ctx));
579}
580
581} // end namesapce mach_o
582} // end namesapce lld
deps/lld/lib/ReaderWriter/MachO/DebugInfo.h created+106
......@@ -0,0 +1,106 @@
1//===- lib/ReaderWriter/MachO/File.h ----------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_READER_WRITER_MACHO_DEBUGINFO_H
11#define LLD_READER_WRITER_MACHO_DEBUGINFO_H
12
13#include "lld/Core/Atom.h"
14#include <vector>
15
16#include "llvm/Support/Format.h"
17#include "llvm/Support/raw_ostream.h"
18
19
20namespace lld {
21namespace mach_o {
22
23class DebugInfo {
24public:
25 enum class Kind {
26 Dwarf,
27 Stabs
28 };
29
30 Kind kind() const { return _kind; }
31
32 void setAllocator(std::unique_ptr<llvm::BumpPtrAllocator> allocator) {
33 _allocator = std::move(allocator);
34 }
35
36protected:
37 DebugInfo(Kind kind) : _kind(kind) {}
38
39private:
40 std::unique_ptr<llvm::BumpPtrAllocator> _allocator;
41 Kind _kind;
42};
43
44struct TranslationUnitSource {
45 StringRef name;
46 StringRef path;
47};
48
49class DwarfDebugInfo : public DebugInfo {
50public:
51 DwarfDebugInfo(TranslationUnitSource tu)
52 : DebugInfo(Kind::Dwarf), _tu(std::move(tu)) {}
53
54 static inline bool classof(const DebugInfo *di) {
55 return di->kind() == Kind::Dwarf;
56 }
57
58 const TranslationUnitSource &translationUnitSource() const { return _tu; }
59
60private:
61 TranslationUnitSource _tu;
62};
63
64struct Stab {
65 Stab(const Atom* atom, uint8_t type, uint8_t other, uint16_t desc,
66 uint32_t value, StringRef str)
67 : atom(atom), type(type), other(other), desc(desc), value(value),
68 str(str) {}
69
70 const class Atom* atom;
71 uint8_t type;
72 uint8_t other;
73 uint16_t desc;
74 uint32_t value;
75 StringRef str;
76};
77
78inline raw_ostream& operator<<(raw_ostream &os, Stab &s) {
79 os << "Stab -- atom: " << llvm::format("%p", s.atom) << ", type: " << (uint32_t)s.type
80 << ", other: " << (uint32_t)s.other << ", desc: " << s.desc << ", value: " << s.value
81 << ", str: '" << s.str << "'";
82 return os;
83}
84
85class StabsDebugInfo : public DebugInfo {
86public:
87
88 typedef std::vector<Stab> StabsList;
89
90 StabsDebugInfo(StabsList stabs)
91 : DebugInfo(Kind::Stabs), _stabs(std::move(stabs)) {}
92
93 static inline bool classof(const DebugInfo *di) {
94 return di->kind() == Kind::Stabs;
95 }
96
97 const StabsList& stabs() const { return _stabs; }
98
99public:
100 StabsList _stabs;
101};
102
103} // end namespace mach_o
104} // end namespace lld
105
106#endif // LLD_READER_WRITER_MACHO_DEBUGINFO_H
deps/lld/lib/ReaderWriter/MachO/ExecutableAtoms.h created+155
......@@ -0,0 +1,155 @@
1//===- lib/ReaderWriter/MachO/ExecutableAtoms.h ---------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_READER_WRITER_MACHO_EXECUTABLE_ATOMS_H
11#define LLD_READER_WRITER_MACHO_EXECUTABLE_ATOMS_H
12
13#include "Atoms.h"
14#include "File.h"
15
16#include "llvm/BinaryFormat/MachO.h"
17
18#include "lld/Core/DefinedAtom.h"
19#include "lld/Core/File.h"
20#include "lld/Core/LinkingContext.h"
21#include "lld/Core/Reference.h"
22#include "lld/Core/Simple.h"
23#include "lld/Core/UndefinedAtom.h"
24#include "lld/ReaderWriter/MachOLinkingContext.h"
25
26namespace lld {
27namespace mach_o {
28
29
30//
31// CEntryFile adds an UndefinedAtom for "_main" so that the Resolving
32// phase will fail if "_main" is undefined.
33//
34class CEntryFile : public SimpleFile {
35public:
36 CEntryFile(const MachOLinkingContext &context)
37 : SimpleFile("C entry", kindCEntryObject),
38 _undefMain(*this, context.entrySymbolName()) {
39 this->addAtom(_undefMain);
40 }
41
42private:
43 SimpleUndefinedAtom _undefMain;
44};
45
46
47//
48// StubHelperFile adds an UndefinedAtom for "dyld_stub_binder" so that
49// the Resolveing phase will fail if "dyld_stub_binder" is undefined.
50//
51class StubHelperFile : public SimpleFile {
52public:
53 StubHelperFile(const MachOLinkingContext &context)
54 : SimpleFile("stub runtime", kindStubHelperObject),
55 _undefBinder(*this, context.binderSymbolName()) {
56 this->addAtom(_undefBinder);
57 }
58
59private:
60 SimpleUndefinedAtom _undefBinder;
61};
62
63
64//
65// MachHeaderAliasFile lazily instantiates the magic symbols that mark the start
66// of the mach_header for final linked images.
67//
68class MachHeaderAliasFile : public SimpleFile {
69public:
70 MachHeaderAliasFile(const MachOLinkingContext &context)
71 : SimpleFile("mach_header symbols", kindHeaderObject) {
72 StringRef machHeaderSymbolName;
73 DefinedAtom::Scope symbolScope = DefinedAtom::scopeLinkageUnit;
74 StringRef dsoHandleName;
75 switch (context.outputMachOType()) {
76 case llvm::MachO::MH_OBJECT:
77 machHeaderSymbolName = "__mh_object_header";
78 break;
79 case llvm::MachO::MH_EXECUTE:
80 machHeaderSymbolName = "__mh_execute_header";
81 symbolScope = DefinedAtom::scopeGlobal;
82 dsoHandleName = "___dso_handle";
83 break;
84 case llvm::MachO::MH_FVMLIB:
85 llvm_unreachable("no mach_header symbol for file type");
86 case llvm::MachO::MH_CORE:
87 llvm_unreachable("no mach_header symbol for file type");
88 case llvm::MachO::MH_PRELOAD:
89 llvm_unreachable("no mach_header symbol for file type");
90 case llvm::MachO::MH_DYLIB:
91 machHeaderSymbolName = "__mh_dylib_header";
92 dsoHandleName = "___dso_handle";
93 break;
94 case llvm::MachO::MH_DYLINKER:
95 machHeaderSymbolName = "__mh_dylinker_header";
96 dsoHandleName = "___dso_handle";
97 break;
98 case llvm::MachO::MH_BUNDLE:
99 machHeaderSymbolName = "__mh_bundle_header";
100 dsoHandleName = "___dso_handle";
101 break;
102 case llvm::MachO::MH_DYLIB_STUB:
103 llvm_unreachable("no mach_header symbol for file type");
104 case llvm::MachO::MH_DSYM:
105 llvm_unreachable("no mach_header symbol for file type");
106 case llvm::MachO::MH_KEXT_BUNDLE:
107 dsoHandleName = "___dso_handle";
108 break;
109 }
110 if (!machHeaderSymbolName.empty())
111 _definedAtoms.push_back(new (allocator()) MachODefinedAtom(
112 *this, machHeaderSymbolName, symbolScope,
113 DefinedAtom::typeMachHeader, DefinedAtom::mergeNo, false,
114 true /* noDeadStrip */,
115 ArrayRef<uint8_t>(), DefinedAtom::Alignment(4096)));
116
117 if (!dsoHandleName.empty())
118 _definedAtoms.push_back(new (allocator()) MachODefinedAtom(
119 *this, dsoHandleName, DefinedAtom::scopeLinkageUnit,
120 DefinedAtom::typeDSOHandle, DefinedAtom::mergeNo, false,
121 true /* noDeadStrip */,
122 ArrayRef<uint8_t>(), DefinedAtom::Alignment(1)));
123 }
124
125 const AtomRange<DefinedAtom> defined() const override {
126 return _definedAtoms;
127 }
128 const AtomRange<UndefinedAtom> undefined() const override {
129 return _noUndefinedAtoms;
130 }
131
132 const AtomRange<SharedLibraryAtom> sharedLibrary() const override {
133 return _noSharedLibraryAtoms;
134 }
135
136 const AtomRange<AbsoluteAtom> absolute() const override {
137 return _noAbsoluteAtoms;
138 }
139
140 void clearAtoms() override {
141 _definedAtoms.clear();
142 _noUndefinedAtoms.clear();
143 _noSharedLibraryAtoms.clear();
144 _noAbsoluteAtoms.clear();
145 }
146
147
148private:
149 mutable AtomVector<DefinedAtom> _definedAtoms;
150};
151
152} // namespace mach_o
153} // namespace lld
154
155#endif // LLD_READER_WRITER_MACHO_EXECUTABLE_ATOMS_H
deps/lld/lib/ReaderWriter/MachO/File.h created+400
......@@ -0,0 +1,400 @@
1//===- lib/ReaderWriter/MachO/File.h ----------------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_READER_WRITER_MACHO_FILE_H
11#define LLD_READER_WRITER_MACHO_FILE_H
12
13#include "Atoms.h"
14#include "DebugInfo.h"
15#include "MachONormalizedFile.h"
16#include "lld/Core/SharedLibraryFile.h"
17#include "lld/Core/Simple.h"
18#include "llvm/ADT/DenseMap.h"
19#include "llvm/ADT/StringMap.h"
20#include "llvm/Support/Format.h"
21#include <unordered_map>
22
23namespace lld {
24namespace mach_o {
25
26using lld::mach_o::normalized::Section;
27
28class MachOFile : public SimpleFile {
29public:
30
31 /// Real file constructor - for on-disk files.
32 MachOFile(std::unique_ptr<MemoryBuffer> mb, MachOLinkingContext *ctx)
33 : SimpleFile(mb->getBufferIdentifier(), File::kindMachObject),
34 _mb(std::move(mb)), _ctx(ctx) {}
35
36 /// Dummy file constructor - for virtual files.
37 MachOFile(StringRef path)
38 : SimpleFile(path, File::kindMachObject) {}
39
40 void addDefinedAtom(StringRef name, Atom::Scope scope,
41 DefinedAtom::ContentType type, DefinedAtom::Merge merge,
42 uint64_t sectionOffset, uint64_t contentSize, bool thumb,
43 bool noDeadStrip, bool copyRefs,
44 const Section *inSection) {
45 assert(sectionOffset+contentSize <= inSection->content.size());
46 ArrayRef<uint8_t> content = inSection->content.slice(sectionOffset,
47 contentSize);
48 if (copyRefs) {
49 // Make a copy of the atom's name and content that is owned by this file.
50 name = name.copy(allocator());
51 content = content.copy(allocator());
52 }
53 DefinedAtom::Alignment align(
54 inSection->alignment,
55 sectionOffset % inSection->alignment);
56 auto *atom =
57 new (allocator()) MachODefinedAtom(*this, name, scope, type, merge,
58 thumb, noDeadStrip, content, align);
59 addAtomForSection(inSection, atom, sectionOffset);
60 }
61
62 void addDefinedAtomInCustomSection(StringRef name, Atom::Scope scope,
63 DefinedAtom::ContentType type, DefinedAtom::Merge merge,
64 bool thumb, bool noDeadStrip, uint64_t sectionOffset,
65 uint64_t contentSize, StringRef sectionName,
66 bool copyRefs, const Section *inSection) {
67 assert(sectionOffset+contentSize <= inSection->content.size());
68 ArrayRef<uint8_t> content = inSection->content.slice(sectionOffset,
69 contentSize);
70 if (copyRefs) {
71 // Make a copy of the atom's name and content that is owned by this file.
72 name = name.copy(allocator());
73 content = content.copy(allocator());
74 sectionName = sectionName.copy(allocator());
75 }
76 DefinedAtom::Alignment align(
77 inSection->alignment,
78 sectionOffset % inSection->alignment);
79 auto *atom =
80 new (allocator()) MachODefinedCustomSectionAtom(*this, name, scope, type,
81 merge, thumb,
82 noDeadStrip, content,
83 sectionName, align);
84 addAtomForSection(inSection, atom, sectionOffset);
85 }
86
87 void addZeroFillDefinedAtom(StringRef name, Atom::Scope scope,
88 uint64_t sectionOffset, uint64_t size,
89 bool noDeadStrip, bool copyRefs,
90 const Section *inSection) {
91 if (copyRefs) {
92 // Make a copy of the atom's name and content that is owned by this file.
93 name = name.copy(allocator());
94 }
95 DefinedAtom::Alignment align(
96 inSection->alignment,
97 sectionOffset % inSection->alignment);
98
99 DefinedAtom::ContentType type = DefinedAtom::typeUnknown;
100 switch (inSection->type) {
101 case llvm::MachO::S_ZEROFILL:
102 type = DefinedAtom::typeZeroFill;
103 break;
104 case llvm::MachO::S_THREAD_LOCAL_ZEROFILL:
105 type = DefinedAtom::typeTLVInitialZeroFill;
106 break;
107 default:
108 llvm_unreachable("Unrecognized zero-fill section");
109 }
110
111 auto *atom =
112 new (allocator()) MachODefinedAtom(*this, name, scope, type, size,
113 noDeadStrip, align);
114 addAtomForSection(inSection, atom, sectionOffset);
115 }
116
117 void addUndefinedAtom(StringRef name, bool copyRefs) {
118 if (copyRefs) {
119 // Make a copy of the atom's name that is owned by this file.
120 name = name.copy(allocator());
121 }
122 auto *atom = new (allocator()) SimpleUndefinedAtom(*this, name);
123 addAtom(*atom);
124 _undefAtoms[name] = atom;
125 }
126
127 void addTentativeDefAtom(StringRef name, Atom::Scope scope, uint64_t size,
128 DefinedAtom::Alignment align, bool copyRefs) {
129 if (copyRefs) {
130 // Make a copy of the atom's name that is owned by this file.
131 name = name.copy(allocator());
132 }
133 auto *atom =
134 new (allocator()) MachOTentativeDefAtom(*this, name, scope, size, align);
135 addAtom(*atom);
136 _undefAtoms[name] = atom;
137 }
138
139 /// Search this file for an the atom from 'section' that covers
140 /// 'offsetInSect'. Returns nullptr is no atom found.
141 MachODefinedAtom *findAtomCoveringAddress(const Section &section,
142 uint64_t offsetInSect,
143 uint32_t *foundOffsetAtom=nullptr) {
144 const auto &pos = _sectionAtoms.find(&section);
145 if (pos == _sectionAtoms.end())
146 return nullptr;
147 const auto &vec = pos->second;
148 assert(offsetInSect < section.content.size());
149 // Vector of atoms for section are already sorted, so do binary search.
150 const auto &atomPos = std::lower_bound(vec.begin(), vec.end(), offsetInSect,
151 [offsetInSect](const SectionOffsetAndAtom &ao,
152 uint64_t targetAddr) -> bool {
153 // Each atom has a start offset of its slice of the
154 // section's content. This compare function must return true
155 // iff the atom's range is before the offset being searched for.
156 uint64_t atomsEndOffset = ao.offset+ao.atom->rawContent().size();
157 return (atomsEndOffset <= offsetInSect);
158 });
159 if (atomPos == vec.end())
160 return nullptr;
161 if (foundOffsetAtom)
162 *foundOffsetAtom = offsetInSect - atomPos->offset;
163 return atomPos->atom;
164 }
165
166 /// Searches this file for an UndefinedAtom named 'name'. Returns
167 /// nullptr is no such atom found.
168 const lld::Atom *findUndefAtom(StringRef name) {
169 auto pos = _undefAtoms.find(name);
170 if (pos == _undefAtoms.end())
171 return nullptr;
172 return pos->second;
173 }
174
175 typedef std::function<void (MachODefinedAtom* atom)> DefinedAtomVisitor;
176
177 void eachDefinedAtom(DefinedAtomVisitor vistor) {
178 for (auto &sectAndAtoms : _sectionAtoms) {
179 for (auto &offAndAtom : sectAndAtoms.second) {
180 vistor(offAndAtom.atom);
181 }
182 }
183 }
184
185 typedef std::function<void(MachODefinedAtom *atom, uint64_t offset)>
186 SectionAtomVisitor;
187
188 void eachAtomInSection(const Section &section, SectionAtomVisitor visitor) {
189 auto pos = _sectionAtoms.find(&section);
190 if (pos == _sectionAtoms.end())
191 return;
192 auto vec = pos->second;
193
194 for (auto &offAndAtom : vec)
195 visitor(offAndAtom.atom, offAndAtom.offset);
196 }
197
198 MachOLinkingContext::Arch arch() const { return _arch; }
199 void setArch(MachOLinkingContext::Arch arch) { _arch = arch; }
200
201 MachOLinkingContext::OS OS() const { return _os; }
202 void setOS(MachOLinkingContext::OS os) { _os = os; }
203
204 MachOLinkingContext::ObjCConstraint objcConstraint() const {
205 return _objcConstraint;
206 }
207 void setObjcConstraint(MachOLinkingContext::ObjCConstraint v) {
208 _objcConstraint = v;
209 }
210
211 uint32_t minVersion() const { return _minVersion; }
212 void setMinVersion(uint32_t v) { _minVersion = v; }
213
214 LoadCommandType minVersionLoadCommandKind() const {
215 return _minVersionLoadCommandKind;
216 }
217 void setMinVersionLoadCommandKind(LoadCommandType v) {
218 _minVersionLoadCommandKind = v;
219 }
220
221 uint32_t swiftVersion() const { return _swiftVersion; }
222 void setSwiftVersion(uint32_t v) { _swiftVersion = v; }
223
224 bool subsectionsViaSymbols() const {
225 return _flags & llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS;
226 }
227 void setFlags(normalized::FileFlags v) { _flags = v; }
228
229 /// Methods for support type inquiry through isa, cast, and dyn_cast:
230 static inline bool classof(const File *F) {
231 return F->kind() == File::kindMachObject;
232 }
233
234 void setDebugInfo(std::unique_ptr<DebugInfo> debugInfo) {
235 _debugInfo = std::move(debugInfo);
236 }
237
238 DebugInfo* debugInfo() const { return _debugInfo.get(); }
239 std::unique_ptr<DebugInfo> takeDebugInfo() { return std::move(_debugInfo); }
240
241protected:
242 std::error_code doParse() override {
243 // Convert binary file to normalized mach-o.
244 auto normFile = normalized::readBinary(_mb, _ctx->arch());
245 if (auto ec = normFile.takeError())
246 return llvm::errorToErrorCode(std::move(ec));
247 // Convert normalized mach-o to atoms.
248 if (auto ec = normalized::normalizedObjectToAtoms(this, **normFile, false))
249 return llvm::errorToErrorCode(std::move(ec));
250 return std::error_code();
251 }
252
253private:
254 struct SectionOffsetAndAtom { uint64_t offset; MachODefinedAtom *atom; };
255
256 void addAtomForSection(const Section *inSection, MachODefinedAtom* atom,
257 uint64_t sectionOffset) {
258 SectionOffsetAndAtom offAndAtom;
259 offAndAtom.offset = sectionOffset;
260 offAndAtom.atom = atom;
261 _sectionAtoms[inSection].push_back(offAndAtom);
262 addAtom(*atom);
263 }
264
265 typedef llvm::DenseMap<const normalized::Section *,
266 std::vector<SectionOffsetAndAtom>> SectionToAtoms;
267 typedef llvm::StringMap<const lld::Atom *> NameToAtom;
268
269 std::unique_ptr<MemoryBuffer> _mb;
270 MachOLinkingContext *_ctx;
271 SectionToAtoms _sectionAtoms;
272 NameToAtom _undefAtoms;
273 MachOLinkingContext::Arch _arch = MachOLinkingContext::arch_unknown;
274 MachOLinkingContext::OS _os = MachOLinkingContext::OS::unknown;
275 uint32_t _minVersion = 0;
276 LoadCommandType _minVersionLoadCommandKind = (LoadCommandType)0;
277 MachOLinkingContext::ObjCConstraint _objcConstraint =
278 MachOLinkingContext::objc_unknown;
279 uint32_t _swiftVersion = 0;
280 normalized::FileFlags _flags = llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS;
281 std::unique_ptr<DebugInfo> _debugInfo;
282};
283
284class MachODylibFile : public SharedLibraryFile {
285public:
286 MachODylibFile(std::unique_ptr<MemoryBuffer> mb, MachOLinkingContext *ctx)
287 : SharedLibraryFile(mb->getBufferIdentifier()),
288 _mb(std::move(mb)), _ctx(ctx) {}
289
290 MachODylibFile(StringRef path) : SharedLibraryFile(path) {}
291
292 OwningAtomPtr<SharedLibraryAtom> exports(StringRef name) const override {
293 // Pass down _installName so that if this requested symbol
294 // is re-exported through this dylib, the SharedLibraryAtom's loadName()
295 // is this dylib installName and not the implementation dylib's.
296 // NOTE: isData is not needed for dylibs (it matters for static libs).
297 return exports(name, _installName);
298 }
299
300 /// Adds symbol name that this dylib exports. The corresponding
301 /// SharedLibraryAtom is created lazily (since most symbols are not used).
302 void addExportedSymbol(StringRef name, bool weakDef, bool copyRefs) {
303 if (copyRefs) {
304 name = name.copy(allocator());
305 }
306 AtomAndFlags info(weakDef);
307 _nameToAtom[name] = info;
308 }
309
310 void addReExportedDylib(StringRef dylibPath) {
311 _reExportedDylibs.emplace_back(dylibPath);
312 }
313
314 StringRef installName() const { return _installName; }
315 uint32_t currentVersion() { return _currentVersion; }
316 uint32_t compatVersion() { return _compatVersion; }
317
318 void setInstallName(StringRef name) { _installName = name; }
319 void setCompatVersion(uint32_t version) { _compatVersion = version; }
320 void setCurrentVersion(uint32_t version) { _currentVersion = version; }
321
322 typedef std::function<MachODylibFile *(StringRef)> FindDylib;
323
324 void loadReExportedDylibs(FindDylib find) {
325 for (ReExportedDylib &entry : _reExportedDylibs) {
326 entry.file = find(entry.path);
327 }
328 }
329
330 StringRef getDSOName() const override { return _installName; }
331
332 std::error_code doParse() override {
333 // Convert binary file to normalized mach-o.
334 auto normFile = normalized::readBinary(_mb, _ctx->arch());
335 if (auto ec = normFile.takeError())
336 return llvm::errorToErrorCode(std::move(ec));
337 // Convert normalized mach-o to atoms.
338 if (auto ec = normalized::normalizedDylibToAtoms(this, **normFile, false))
339 return llvm::errorToErrorCode(std::move(ec));
340 return std::error_code();
341 }
342
343private:
344 OwningAtomPtr<SharedLibraryAtom> exports(StringRef name,
345 StringRef installName) const {
346 // First, check if requested symbol is directly implemented by this dylib.
347 auto entry = _nameToAtom.find(name);
348 if (entry != _nameToAtom.end()) {
349 // FIXME: Make this map a set and only used in assert builds.
350 // Note, its safe to assert here as the resolver is the only client of
351 // this API and it only requests exports for undefined symbols.
352 // If we return from here we are no longer undefined so we should never
353 // get here again.
354 assert(!entry->second.atom && "Duplicate shared library export");
355 bool weakDef = entry->second.weakDef;
356 auto *atom = new (allocator()) MachOSharedLibraryAtom(*this, name,
357 installName,
358 weakDef);
359 entry->second.atom = atom;
360 return atom;
361 }
362
363 // Next, check if symbol is implemented in some re-exported dylib.
364 for (const ReExportedDylib &dylib : _reExportedDylibs) {
365 assert(dylib.file);
366 auto atom = dylib.file->exports(name, installName);
367 if (atom.get())
368 return atom;
369 }
370
371 // Symbol not exported or re-exported by this dylib.
372 return nullptr;
373 }
374
375 struct ReExportedDylib {
376 ReExportedDylib(StringRef p) : path(p), file(nullptr) { }
377 StringRef path;
378 MachODylibFile *file;
379 };
380
381 struct AtomAndFlags {
382 AtomAndFlags() : atom(nullptr), weakDef(false) { }
383 AtomAndFlags(bool weak) : atom(nullptr), weakDef(weak) { }
384 const SharedLibraryAtom *atom;
385 bool weakDef;
386 };
387
388 std::unique_ptr<MemoryBuffer> _mb;
389 MachOLinkingContext *_ctx;
390 StringRef _installName;
391 uint32_t _currentVersion;
392 uint32_t _compatVersion;
393 std::vector<ReExportedDylib> _reExportedDylibs;
394 mutable std::unordered_map<StringRef, AtomAndFlags> _nameToAtom;
395};
396
397} // end namespace mach_o
398} // end namespace lld
399
400#endif // LLD_READER_WRITER_MACHO_FILE_H
deps/lld/lib/ReaderWriter/MachO/FlatNamespaceFile.h created+61
......@@ -0,0 +1,61 @@
1//===- lib/ReaderWriter/MachO/FlatNamespaceFile.h -------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_READER_WRITER_MACHO_FLAT_NAMESPACE_FILE_H
11#define LLD_READER_WRITER_MACHO_FLAT_NAMESPACE_FILE_H
12
13#include "lld/Core/SharedLibraryFile.h"
14#include "llvm/Support/Debug.h"
15
16namespace lld {
17namespace mach_o {
18
19//
20// A FlateNamespaceFile instance may be added as a resolution source of last
21// resort, depending on how -flat_namespace and -undefined are set.
22//
23class FlatNamespaceFile : public SharedLibraryFile {
24public:
25 FlatNamespaceFile(const MachOLinkingContext &context)
26 : SharedLibraryFile("flat namespace") { }
27
28 OwningAtomPtr<SharedLibraryAtom> exports(StringRef name) const override {
29 return new (allocator()) MachOSharedLibraryAtom(*this, name, getDSOName(),
30 false);
31 }
32
33 StringRef getDSOName() const override { return "flat-namespace"; }
34
35 const AtomRange<DefinedAtom> defined() const override {
36 return _noDefinedAtoms;
37 }
38 const AtomRange<UndefinedAtom> undefined() const override {
39 return _noUndefinedAtoms;
40 }
41
42 const AtomRange<SharedLibraryAtom> sharedLibrary() const override {
43 return _noSharedLibraryAtoms;
44 }
45
46 const AtomRange<AbsoluteAtom> absolute() const override {
47 return _noAbsoluteAtoms;
48 }
49
50 void clearAtoms() override {
51 _noDefinedAtoms.clear();
52 _noUndefinedAtoms.clear();
53 _noSharedLibraryAtoms.clear();
54 _noAbsoluteAtoms.clear();
55 }
56};
57
58} // namespace mach_o
59} // namespace lld
60
61#endif // LLD_READER_WRITER_MACHO_FLAT_NAMESPACE_FILE_H
deps/lld/lib/ReaderWriter/MachO/GOTPass.cpp created+184
......@@ -0,0 +1,184 @@
1//===- lib/ReaderWriter/MachO/GOTPass.cpp -----------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11/// This linker pass transforms all GOT kind references to real references.
12/// That is, in assembly you can write something like:
13/// movq foo@GOTPCREL(%rip), %rax
14/// which means you want to load a pointer to "foo" out of the GOT (global
15/// Offsets Table). In the object file, the Atom containing this instruction
16/// has a Reference whose target is an Atom named "foo" and the Reference
17/// kind is a GOT load. The linker needs to instantiate a pointer sized
18/// GOT entry. This is done be creating a GOT Atom to represent that pointer
19/// sized data in this pass, and altering the Atom graph so the Reference now
20/// points to the GOT Atom entry (corresponding to "foo") and changing the
21/// Reference Kind to reflect it is now pointing to a GOT entry (rather
22/// then needing a GOT entry).
23///
24/// There is one optimization the linker can do here. If the target of the GOT
25/// is in the same linkage unit and does not need to be interposable, and
26/// the GOT use is just a load (not some other operation), this pass can
27/// transform that load into an LEA (add). This optimizes away one memory load
28/// which at runtime that could stall the pipeline. This optimization only
29/// works for architectures in which a (GOT) load instruction can be change to
30/// an LEA instruction that is the same size. The method isGOTAccess() should
31/// only return true for "canBypassGOT" if this optimization is supported.
32///
33//===----------------------------------------------------------------------===//
34
35#include "ArchHandler.h"
36#include "File.h"
37#include "MachOPasses.h"
38#include "lld/Core/DefinedAtom.h"
39#include "lld/Core/File.h"
40#include "lld/Core/LLVM.h"
41#include "lld/Core/Reference.h"
42#include "lld/Core/Simple.h"
43#include "llvm/ADT/DenseMap.h"
44#include "llvm/ADT/STLExtras.h"
45
46namespace lld {
47namespace mach_o {
48
49//
50// GOT Entry Atom created by the GOT pass.
51//
52class GOTEntryAtom : public SimpleDefinedAtom {
53public:
54 GOTEntryAtom(const File &file, bool is64, StringRef name)
55 : SimpleDefinedAtom(file), _is64(is64), _name(name) { }
56
57 ~GOTEntryAtom() override = default;
58
59 ContentType contentType() const override {
60 return DefinedAtom::typeGOT;
61 }
62
63 Alignment alignment() const override {
64 return _is64 ? 8 : 4;
65 }
66
67 uint64_t size() const override {
68 return _is64 ? 8 : 4;
69 }
70
71 ContentPermissions permissions() const override {
72 return DefinedAtom::permRW_;
73 }
74
75 ArrayRef<uint8_t> rawContent() const override {
76 static const uint8_t zeros[] =
77 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
78 return llvm::makeArrayRef(zeros, size());
79 }
80
81 StringRef slotName() const {
82 return _name;
83 }
84
85private:
86 const bool _is64;
87 StringRef _name;
88};
89
90/// Pass for instantiating and optimizing GOT slots.
91///
92class GOTPass : public Pass {
93public:
94 GOTPass(const MachOLinkingContext &context)
95 : _ctx(context), _archHandler(_ctx.archHandler()),
96 _file(*_ctx.make_file<MachOFile>("<mach-o GOT Pass>")) {
97 _file.setOrdinal(_ctx.getNextOrdinalAndIncrement());
98 }
99
100private:
101 llvm::Error perform(SimpleFile &mergedFile) override {
102 // Scan all references in all atoms.
103 for (const DefinedAtom *atom : mergedFile.defined()) {
104 for (const Reference *ref : *atom) {
105 // Look at instructions accessing the GOT.
106 bool canBypassGOT;
107 if (!_archHandler.isGOTAccess(*ref, canBypassGOT))
108 continue;
109 const Atom *target = ref->target();
110 assert(target != nullptr);
111
112 if (!shouldReplaceTargetWithGOTAtom(target, canBypassGOT)) {
113 // Update reference kind to reflect that target is a direct accesss.
114 _archHandler.updateReferenceToGOT(ref, false);
115 } else {
116 // Replace the target with a reference to a GOT entry.
117 const DefinedAtom *gotEntry = makeGOTEntry(target);
118 const_cast<Reference *>(ref)->setTarget(gotEntry);
119 // Update reference kind to reflect that target is now a GOT entry.
120 _archHandler.updateReferenceToGOT(ref, true);
121 }
122 }
123 }
124
125 // Sort and add all created GOT Atoms to master file
126 std::vector<const GOTEntryAtom *> entries;
127 entries.reserve(_targetToGOT.size());
128 for (auto &it : _targetToGOT)
129 entries.push_back(it.second);
130 std::sort(entries.begin(), entries.end(),
131 [](const GOTEntryAtom *left, const GOTEntryAtom *right) {
132 return (left->slotName().compare(right->slotName()) < 0);
133 });
134 for (const GOTEntryAtom *slot : entries)
135 mergedFile.addAtom(*slot);
136
137 return llvm::Error::success();
138 }
139
140 bool shouldReplaceTargetWithGOTAtom(const Atom *target, bool canBypassGOT) {
141 // Accesses to shared library symbols must go through GOT.
142 if (isa<SharedLibraryAtom>(target))
143 return true;
144 // Accesses to interposable symbols in same linkage unit must also go
145 // through GOT.
146 const DefinedAtom *defTarget = dyn_cast<DefinedAtom>(target);
147 if (defTarget != nullptr &&
148 defTarget->interposable() != DefinedAtom::interposeNo) {
149 assert(defTarget->scope() != DefinedAtom::scopeTranslationUnit);
150 return true;
151 }
152 // Target does not require indirection. So, if instruction allows GOT to be
153 // by-passed, do that optimization and don't create GOT entry.
154 return !canBypassGOT;
155 }
156
157 const DefinedAtom *makeGOTEntry(const Atom *target) {
158 auto pos = _targetToGOT.find(target);
159 if (pos == _targetToGOT.end()) {
160 auto *gotEntry = new (_file.allocator())
161 GOTEntryAtom(_file, _ctx.is64Bit(), target->name());
162 _targetToGOT[target] = gotEntry;
163 const ArchHandler::ReferenceInfo &nlInfo = _archHandler.stubInfo().
164 nonLazyPointerReferenceToBinder;
165 gotEntry->addReference(Reference::KindNamespace::mach_o, nlInfo.arch,
166 nlInfo.kind, 0, target, 0);
167 return gotEntry;
168 }
169 return pos->second;
170 }
171
172 const MachOLinkingContext &_ctx;
173 mach_o::ArchHandler &_archHandler;
174 MachOFile &_file;
175 llvm::DenseMap<const Atom*, const GOTEntryAtom*> _targetToGOT;
176};
177
178void addGOTPass(PassManager &pm, const MachOLinkingContext &ctx) {
179 assert(ctx.needsGOTPass());
180 pm.add(llvm::make_unique<GOTPass>(ctx));
181}
182
183} // end namesapce mach_o
184} // end namesapce lld
deps/lld/lib/ReaderWriter/MachO/LayoutPass.cpp created+489
......@@ -0,0 +1,489 @@
1//===-- ReaderWriter/MachO/LayoutPass.cpp - Layout atoms ------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "LayoutPass.h"
11#include "lld/Core/Instrumentation.h"
12#include "lld/Core/PassManager.h"
13#include "lld/ReaderWriter/MachOLinkingContext.h"
14#include "llvm/ADT/STLExtras.h"
15#include "llvm/ADT/Twine.h"
16#include "llvm/Support/Debug.h"
17#include "llvm/Support/Parallel.h"
18#include <algorithm>
19#include <set>
20#include <utility>
21
22using namespace lld;
23
24#define DEBUG_TYPE "LayoutPass"
25
26namespace lld {
27namespace mach_o {
28
29static bool compareAtoms(const LayoutPass::SortKey &,
30 const LayoutPass::SortKey &,
31 LayoutPass::SortOverride customSorter);
32
33#ifndef NDEBUG
34// Return "reason (leftval, rightval)"
35static std::string formatReason(StringRef reason, int leftVal, int rightVal) {
36 return (Twine(reason) + " (" + Twine(leftVal) + ", " + Twine(rightVal) + ")")
37 .str();
38}
39
40// Less-than relationship of two atoms must be transitive, which is, if a < b
41// and b < c, a < c must be true. This function checks the transitivity by
42// checking the sort results.
43static void checkTransitivity(std::vector<LayoutPass::SortKey> &vec,
44 LayoutPass::SortOverride customSorter) {
45 for (auto i = vec.begin(), e = vec.end(); (i + 1) != e; ++i) {
46 for (auto j = i + 1; j != e; ++j) {
47 assert(compareAtoms(*i, *j, customSorter));
48 assert(!compareAtoms(*j, *i, customSorter));
49 }
50 }
51}
52
53// Helper functions to check follow-on graph.
54typedef llvm::DenseMap<const DefinedAtom *, const DefinedAtom *> AtomToAtomT;
55
56static std::string atomToDebugString(const Atom *atom) {
57 const DefinedAtom *definedAtom = dyn_cast<DefinedAtom>(atom);
58 std::string str;
59 llvm::raw_string_ostream s(str);
60 if (definedAtom->name().empty())
61 s << "<anonymous " << definedAtom << ">";
62 else
63 s << definedAtom->name();
64 s << " in ";
65 if (definedAtom->customSectionName().empty())
66 s << "<anonymous>";
67 else
68 s << definedAtom->customSectionName();
69 s.flush();
70 return str;
71}
72
73static void showCycleDetectedError(const Registry &registry,
74 AtomToAtomT &followOnNexts,
75 const DefinedAtom *atom) {
76 const DefinedAtom *start = atom;
77 llvm::dbgs() << "There's a cycle in a follow-on chain!\n";
78 do {
79 llvm::dbgs() << " " << atomToDebugString(atom) << "\n";
80 for (const Reference *ref : *atom) {
81 StringRef kindValStr;
82 if (!registry.referenceKindToString(ref->kindNamespace(), ref->kindArch(),
83 ref->kindValue(), kindValStr)) {
84 kindValStr = "<unknown>";
85 }
86 llvm::dbgs() << " " << kindValStr
87 << ": " << atomToDebugString(ref->target()) << "\n";
88 }
89 atom = followOnNexts[atom];
90 } while (atom != start);
91 llvm::report_fatal_error("Cycle detected");
92}
93
94/// Exit if there's a cycle in a followon chain reachable from the
95/// given root atom. Uses the tortoise and hare algorithm to detect a
96/// cycle.
97static void checkNoCycleInFollowonChain(const Registry &registry,
98 AtomToAtomT &followOnNexts,
99 const DefinedAtom *root) {
100 const DefinedAtom *tortoise = root;
101 const DefinedAtom *hare = followOnNexts[root];
102 while (true) {
103 if (!tortoise || !hare)
104 return;
105 if (tortoise == hare)
106 showCycleDetectedError(registry, followOnNexts, tortoise);
107 tortoise = followOnNexts[tortoise];
108 hare = followOnNexts[followOnNexts[hare]];
109 }
110}
111
112static void checkReachabilityFromRoot(AtomToAtomT &followOnRoots,
113 const DefinedAtom *atom) {
114 if (!atom) return;
115 auto i = followOnRoots.find(atom);
116 if (i == followOnRoots.end()) {
117 llvm_unreachable(((Twine("Atom <") + atomToDebugString(atom) +
118 "> has no follow-on root!"))
119 .str()
120 .c_str());
121 }
122 const DefinedAtom *ap = i->second;
123 while (true) {
124 const DefinedAtom *next = followOnRoots[ap];
125 if (!next) {
126 llvm_unreachable((Twine("Atom <" + atomToDebugString(atom) +
127 "> is not reachable from its root!"))
128 .str()
129 .c_str());
130 }
131 if (next == ap)
132 return;
133 ap = next;
134 }
135}
136
137static void printDefinedAtoms(const File::AtomRange<DefinedAtom> &atomRange) {
138 for (const DefinedAtom *atom : atomRange) {
139 llvm::dbgs() << " file=" << atom->file().path()
140 << ", name=" << atom->name()
141 << ", size=" << atom->size()
142 << ", type=" << atom->contentType()
143 << ", ordinal=" << atom->ordinal()
144 << "\n";
145 }
146}
147
148/// Verify that the followon chain is sane. Should not be called in
149/// release binary.
150void LayoutPass::checkFollowonChain(const File::AtomRange<DefinedAtom> &range) {
151 ScopedTask task(getDefaultDomain(), "LayoutPass::checkFollowonChain");
152
153 // Verify that there's no cycle in follow-on chain.
154 std::set<const DefinedAtom *> roots;
155 for (const auto &ai : _followOnRoots)
156 roots.insert(ai.second);
157 for (const DefinedAtom *root : roots)
158 checkNoCycleInFollowonChain(_registry, _followOnNexts, root);
159
160 // Verify that all the atoms in followOnNexts have references to
161 // their roots.
162 for (const auto &ai : _followOnNexts) {
163 checkReachabilityFromRoot(_followOnRoots, ai.first);
164 checkReachabilityFromRoot(_followOnRoots, ai.second);
165 }
166}
167#endif // #ifndef NDEBUG
168
169/// The function compares atoms by sorting atoms in the following order
170/// a) Sorts atoms by their ordinal overrides (layout-after/ingroup)
171/// b) Sorts atoms by their permissions
172/// c) Sorts atoms by their content
173/// d) Sorts atoms by custom sorter
174/// e) Sorts atoms on how they appear using File Ordinality
175/// f) Sorts atoms on how they appear within the File
176static bool compareAtomsSub(const LayoutPass::SortKey &lc,
177 const LayoutPass::SortKey &rc,
178 LayoutPass::SortOverride customSorter,
179 std::string &reason) {
180 const DefinedAtom *left = lc._atom.get();
181 const DefinedAtom *right = rc._atom.get();
182 if (left == right) {
183 reason = "same";
184 return false;
185 }
186
187 // Find the root of the chain if it is a part of a follow-on chain.
188 const DefinedAtom *leftRoot = lc._root;
189 const DefinedAtom *rightRoot = rc._root;
190
191 // Sort atoms by their ordinal overrides only if they fall in the same
192 // chain.
193 if (leftRoot == rightRoot) {
194 DEBUG(reason = formatReason("override", lc._override, rc._override));
195 return lc._override < rc._override;
196 }
197
198 // Sort same permissions together.
199 DefinedAtom::ContentPermissions leftPerms = leftRoot->permissions();
200 DefinedAtom::ContentPermissions rightPerms = rightRoot->permissions();
201
202 if (leftPerms != rightPerms) {
203 DEBUG(reason =
204 formatReason("contentPerms", (int)leftPerms, (int)rightPerms));
205 return leftPerms < rightPerms;
206 }
207
208 // Sort same content types together.
209 DefinedAtom::ContentType leftType = leftRoot->contentType();
210 DefinedAtom::ContentType rightType = rightRoot->contentType();
211
212 if (leftType != rightType) {
213 DEBUG(reason = formatReason("contentType", (int)leftType, (int)rightType));
214 return leftType < rightType;
215 }
216
217 // Use custom sorter if supplied.
218 if (customSorter) {
219 bool leftBeforeRight;
220 if (customSorter(leftRoot, rightRoot, leftBeforeRight))
221 return leftBeforeRight;
222 }
223
224 // Sort by .o order.
225 const File *leftFile = &leftRoot->file();
226 const File *rightFile = &rightRoot->file();
227
228 if (leftFile != rightFile) {
229 DEBUG(reason = formatReason(".o order", (int)leftFile->ordinal(),
230 (int)rightFile->ordinal()));
231 return leftFile->ordinal() < rightFile->ordinal();
232 }
233
234 // Sort by atom order with .o file.
235 uint64_t leftOrdinal = leftRoot->ordinal();
236 uint64_t rightOrdinal = rightRoot->ordinal();
237
238 if (leftOrdinal != rightOrdinal) {
239 DEBUG(reason = formatReason("ordinal", (int)leftRoot->ordinal(),
240 (int)rightRoot->ordinal()));
241 return leftOrdinal < rightOrdinal;
242 }
243
244 llvm::errs() << "Unordered: <" << left->name() << "> <"
245 << right->name() << ">\n";
246 llvm_unreachable("Atoms with Same Ordinal!");
247}
248
249static bool compareAtoms(const LayoutPass::SortKey &lc,
250 const LayoutPass::SortKey &rc,
251 LayoutPass::SortOverride customSorter) {
252 std::string reason;
253 bool result = compareAtomsSub(lc, rc, customSorter, reason);
254 DEBUG({
255 StringRef comp = result ? "<" : ">=";
256 llvm::dbgs() << "Layout: '" << lc._atom.get()->name()
257 << "' " << comp << " '"
258 << rc._atom.get()->name() << "' (" << reason << ")\n";
259 });
260 return result;
261}
262
263LayoutPass::LayoutPass(const Registry &registry, SortOverride sorter)
264 : _registry(registry), _customSorter(std::move(sorter)) {}
265
266// Returns the atom immediately followed by the given atom in the followon
267// chain.
268const DefinedAtom *LayoutPass::findAtomFollowedBy(
269 const DefinedAtom *targetAtom) {
270 // Start from the beginning of the chain and follow the chain until
271 // we find the targetChain.
272 const DefinedAtom *atom = _followOnRoots[targetAtom];
273 while (true) {
274 const DefinedAtom *prevAtom = atom;
275 AtomToAtomT::iterator targetFollowOnAtomsIter = _followOnNexts.find(atom);
276 // The target atom must be in the chain of its root.
277 assert(targetFollowOnAtomsIter != _followOnNexts.end());
278 atom = targetFollowOnAtomsIter->second;
279 if (atom == targetAtom)
280 return prevAtom;
281 }
282}
283
284// Check if all the atoms followed by the given target atom are of size zero.
285// When this method is called, an atom being added is not of size zero and
286// will be added to the head of the followon chain. All the atoms between the
287// atom and the targetAtom (specified by layout-after) need to be of size zero
288// in this case. Otherwise the desired layout is impossible.
289bool LayoutPass::checkAllPrevAtomsZeroSize(const DefinedAtom *targetAtom) {
290 const DefinedAtom *atom = _followOnRoots[targetAtom];
291 while (true) {
292 if (atom == targetAtom)
293 return true;
294 if (atom->size() != 0)
295 // TODO: print warning that an impossible layout is being desired by the
296 // user.
297 return false;
298 AtomToAtomT::iterator targetFollowOnAtomsIter = _followOnNexts.find(atom);
299 // The target atom must be in the chain of its root.
300 assert(targetFollowOnAtomsIter != _followOnNexts.end());
301 atom = targetFollowOnAtomsIter->second;
302 }
303}
304
305// Set the root of all atoms in targetAtom's chain to the given root.
306void LayoutPass::setChainRoot(const DefinedAtom *targetAtom,
307 const DefinedAtom *root) {
308 // Walk through the followon chain and override each node's root.
309 while (true) {
310 _followOnRoots[targetAtom] = root;
311 AtomToAtomT::iterator targetFollowOnAtomsIter =
312 _followOnNexts.find(targetAtom);
313 if (targetFollowOnAtomsIter == _followOnNexts.end())
314 return;
315 targetAtom = targetFollowOnAtomsIter->second;
316 }
317}
318
319/// This pass builds the followon tables described by two DenseMaps
320/// followOnRoots and followonNexts.
321/// The followOnRoots map contains a mapping of a DefinedAtom to its root
322/// The followOnNexts map contains a mapping of what DefinedAtom follows the
323/// current Atom
324/// The algorithm follows a very simple approach
325/// a) If the atom is first seen, then make that as the root atom
326/// b) The targetAtom which this Atom contains, has the root thats set to the
327/// root of the current atom
328/// c) If the targetAtom is part of a different tree and the root of the
329/// targetAtom is itself, Chain all the atoms that are contained in the tree
330/// to the current Tree
331/// d) If the targetAtom is part of a different chain and the root of the
332/// targetAtom until the targetAtom has all atoms of size 0, then chain the
333/// targetAtoms and its tree to the current chain
334void LayoutPass::buildFollowOnTable(const File::AtomRange<DefinedAtom> &range) {
335 ScopedTask task(getDefaultDomain(), "LayoutPass::buildFollowOnTable");
336 // Set the initial size of the followon and the followonNext hash to the
337 // number of atoms that we have.
338 _followOnRoots.reserve(range.size());
339 _followOnNexts.reserve(range.size());
340 for (const DefinedAtom *ai : range) {
341 for (const Reference *r : *ai) {
342 if (r->kindNamespace() != lld::Reference::KindNamespace::all ||
343 r->kindValue() != lld::Reference::kindLayoutAfter)
344 continue;
345 const DefinedAtom *targetAtom = dyn_cast<DefinedAtom>(r->target());
346 _followOnNexts[ai] = targetAtom;
347
348 // If we find a followon for the first time, let's make that atom as the
349 // root atom.
350 if (_followOnRoots.count(ai) == 0)
351 _followOnRoots[ai] = ai;
352
353 auto iter = _followOnRoots.find(targetAtom);
354 if (iter == _followOnRoots.end()) {
355 // If the targetAtom is not a root of any chain, let's make the root of
356 // the targetAtom to the root of the current chain.
357
358 // The expression m[i] = m[j] where m is a DenseMap and i != j is not
359 // safe. m[j] returns a reference, which would be invalidated when a
360 // rehashing occurs. If rehashing occurs to make room for m[i], m[j]
361 // becomes invalid, and that invalid reference would be used as the RHS
362 // value of the expression.
363 // Copy the value to workaround.
364 const DefinedAtom *tmp = _followOnRoots[ai];
365 _followOnRoots[targetAtom] = tmp;
366 continue;
367 }
368 if (iter->second == targetAtom) {
369 // If the targetAtom is the root of a chain, the chain becomes part of
370 // the current chain. Rewrite the subchain's root to the current
371 // chain's root.
372 setChainRoot(targetAtom, _followOnRoots[ai]);
373 continue;
374 }
375 // The targetAtom is already a part of a chain. If the current atom is
376 // of size zero, we can insert it in the middle of the chain just
377 // before the target atom, while not breaking other atom's followon
378 // relationships. If it's not, we can only insert the current atom at
379 // the beginning of the chain. All the atoms followed by the target
380 // atom must be of size zero in that case to satisfy the followon
381 // relationships.
382 size_t currentAtomSize = ai->size();
383 if (currentAtomSize == 0) {
384 const DefinedAtom *targetPrevAtom = findAtomFollowedBy(targetAtom);
385 _followOnNexts[targetPrevAtom] = ai;
386 const DefinedAtom *tmp = _followOnRoots[targetPrevAtom];
387 _followOnRoots[ai] = tmp;
388 continue;
389 }
390 if (!checkAllPrevAtomsZeroSize(targetAtom))
391 break;
392 _followOnNexts[ai] = _followOnRoots[targetAtom];
393 setChainRoot(_followOnRoots[targetAtom], _followOnRoots[ai]);
394 }
395 }
396}
397
398/// Build an ordinal override map by traversing the followon chain, and
399/// assigning ordinals to each atom, if the atoms have their ordinals
400/// already assigned skip the atom and move to the next. This is the
401/// main map thats used to sort the atoms while comparing two atoms together
402void
403LayoutPass::buildOrdinalOverrideMap(const File::AtomRange<DefinedAtom> &range) {
404 ScopedTask task(getDefaultDomain(), "LayoutPass::buildOrdinalOverrideMap");
405 uint64_t index = 0;
406 for (const DefinedAtom *ai : range) {
407 const DefinedAtom *atom = ai;
408 if (_ordinalOverrideMap.find(atom) != _ordinalOverrideMap.end())
409 continue;
410 AtomToAtomT::iterator start = _followOnRoots.find(atom);
411 if (start == _followOnRoots.end())
412 continue;
413 for (const DefinedAtom *nextAtom = start->second; nextAtom;
414 nextAtom = _followOnNexts[nextAtom]) {
415 AtomToOrdinalT::iterator pos = _ordinalOverrideMap.find(nextAtom);
416 if (pos == _ordinalOverrideMap.end())
417 _ordinalOverrideMap[nextAtom] = index++;
418 }
419 }
420}
421
422std::vector<LayoutPass::SortKey>
423LayoutPass::decorate(File::AtomRange<DefinedAtom> &atomRange) const {
424 std::vector<SortKey> ret;
425 for (OwningAtomPtr<DefinedAtom> &atom : atomRange.owning_ptrs()) {
426 auto ri = _followOnRoots.find(atom.get());
427 auto oi = _ordinalOverrideMap.find(atom.get());
428 const auto *root = (ri == _followOnRoots.end()) ? atom.get() : ri->second;
429 uint64_t override = (oi == _ordinalOverrideMap.end()) ? 0 : oi->second;
430 ret.push_back(SortKey(std::move(atom), root, override));
431 }
432 return ret;
433}
434
435void LayoutPass::undecorate(File::AtomRange<DefinedAtom> &atomRange,
436 std::vector<SortKey> &keys) const {
437 size_t i = 0;
438 for (SortKey &k : keys)
439 atomRange[i++] = std::move(k._atom);
440}
441
442/// Perform the actual pass
443llvm::Error LayoutPass::perform(SimpleFile &mergedFile) {
444 DEBUG(llvm::dbgs() << "******** Laying out atoms:\n");
445 // sort the atoms
446 ScopedTask task(getDefaultDomain(), "LayoutPass");
447 File::AtomRange<DefinedAtom> atomRange = mergedFile.defined();
448
449 // Build follow on tables
450 buildFollowOnTable(atomRange);
451
452 // Check the structure of followon graph if running in debug mode.
453 DEBUG(checkFollowonChain(atomRange));
454
455 // Build override maps
456 buildOrdinalOverrideMap(atomRange);
457
458 DEBUG({
459 llvm::dbgs() << "unsorted atoms:\n";
460 printDefinedAtoms(atomRange);
461 });
462
463 std::vector<LayoutPass::SortKey> vec = decorate(atomRange);
464 sort(llvm::parallel::par, vec.begin(), vec.end(),
465 [&](const LayoutPass::SortKey &l, const LayoutPass::SortKey &r) -> bool {
466 return compareAtoms(l, r, _customSorter);
467 });
468 DEBUG(checkTransitivity(vec, _customSorter));
469 undecorate(atomRange, vec);
470
471 DEBUG({
472 llvm::dbgs() << "sorted atoms:\n";
473 printDefinedAtoms(atomRange);
474 });
475
476 DEBUG(llvm::dbgs() << "******** Finished laying out atoms\n");
477 return llvm::Error::success();
478}
479
480void addLayoutPass(PassManager &pm, const MachOLinkingContext &ctx) {
481 pm.add(llvm::make_unique<LayoutPass>(
482 ctx.registry(), [&](const DefinedAtom * left, const DefinedAtom * right,
483 bool & leftBeforeRight) ->bool {
484 return ctx.customAtomOrderer(left, right, leftBeforeRight);
485 }));
486}
487
488} // namespace mach_o
489} // namespace lld
deps/lld/lib/ReaderWriter/MachO/LayoutPass.h created+119
......@@ -0,0 +1,119 @@
1//===------ lib/ReaderWriter/MachO/LayoutPass.h - Handles Layout of atoms -===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_READER_WRITER_MACHO_LAYOUT_PASS_H
11#define LLD_READER_WRITER_MACHO_LAYOUT_PASS_H
12
13#include "lld/Core/File.h"
14#include "lld/Core/Pass.h"
15#include "lld/Core/Reader.h"
16#include "lld/Core/Simple.h"
17#include "llvm/ADT/DenseMap.h"
18#include <map>
19#include <string>
20#include <vector>
21
22namespace lld {
23class DefinedAtom;
24class SimpleFile;
25
26namespace mach_o {
27
28/// This linker pass does the layout of the atoms. The pass is done after the
29/// order their .o files were found on the command line, then by order of the
30/// atoms (address) in the .o file. But some atoms have a preferred location
31/// in their section (such as pinned to the start or end of the section), so
32/// the sort must take that into account too.
33class LayoutPass : public Pass {
34public:
35 struct SortKey {
36 SortKey(OwningAtomPtr<DefinedAtom> &&atom,
37 const DefinedAtom *root, uint64_t override)
38 : _atom(std::move(atom)), _root(root), _override(override) {}
39 OwningAtomPtr<DefinedAtom> _atom;
40 const DefinedAtom *_root;
41 uint64_t _override;
42
43 // Note, these are only here to appease MSVC bots which didn't like
44 // the same methods being implemented/deleted in OwningAtomPtr.
45 SortKey(SortKey &&key) : _atom(std::move(key._atom)), _root(key._root),
46 _override(key._override) {
47 key._root = nullptr;
48 }
49
50 SortKey &operator=(SortKey &&key) {
51 _atom = std::move(key._atom);
52 _root = key._root;
53 key._root = nullptr;
54 _override = key._override;
55 return *this;
56 }
57
58 private:
59 SortKey(const SortKey &) = delete;
60 void operator=(const SortKey&) = delete;
61 };
62
63 typedef std::function<bool (const DefinedAtom *left, const DefinedAtom *right,
64 bool &leftBeforeRight)> SortOverride;
65
66 LayoutPass(const Registry &registry, SortOverride sorter);
67
68 /// Sorts atoms in mergedFile by content type then by command line order.
69 llvm::Error perform(SimpleFile &mergedFile) override;
70
71 ~LayoutPass() override = default;
72
73private:
74 // Build the followOn atoms chain as specified by the kindLayoutAfter
75 // reference type
76 void buildFollowOnTable(const File::AtomRange<DefinedAtom> &range);
77
78 // Build a map of Atoms to ordinals for sorting the atoms
79 void buildOrdinalOverrideMap(const File::AtomRange<DefinedAtom> &range);
80
81 const Registry &_registry;
82 SortOverride _customSorter;
83
84 typedef llvm::DenseMap<const DefinedAtom *, const DefinedAtom *> AtomToAtomT;
85 typedef llvm::DenseMap<const DefinedAtom *, uint64_t> AtomToOrdinalT;
86
87 // A map to be used to sort atoms. It represents the order of atoms in the
88 // result; if Atom X is mapped to atom Y in this map, X will be located
89 // immediately before Y in the output file. Y might be mapped to another
90 // atom, constructing a follow-on chain. An atom cannot be mapped to more
91 // than one atom unless all but one atom are of size zero.
92 AtomToAtomT _followOnNexts;
93
94 // A map to be used to sort atoms. It's a map from an atom to its root of
95 // follow-on chain. A root atom is mapped to itself. If an atom is not in
96 // _followOnNexts, the atom is not in this map, and vice versa.
97 AtomToAtomT _followOnRoots;
98
99 AtomToOrdinalT _ordinalOverrideMap;
100
101 // Helper methods for buildFollowOnTable().
102 const DefinedAtom *findAtomFollowedBy(const DefinedAtom *targetAtom);
103 bool checkAllPrevAtomsZeroSize(const DefinedAtom *targetAtom);
104
105 void setChainRoot(const DefinedAtom *targetAtom, const DefinedAtom *root);
106
107 std::vector<SortKey> decorate(File::AtomRange<DefinedAtom> &atomRange) const;
108
109 void undecorate(File::AtomRange<DefinedAtom> &atomRange,
110 std::vector<SortKey> &keys) const;
111
112 // Check if the follow-on graph is a correct structure. For debugging only.
113 void checkFollowonChain(const File::AtomRange<DefinedAtom> &range);
114};
115
116} // namespace mach_o
117} // namespace lld
118
119#endif // LLD_READER_WRITER_MACHO_LAYOUT_PASS_H
deps/lld/lib/ReaderWriter/MachO/MachOLinkingContext.cpp created+1102
......@@ -0,0 +1,1102 @@
1//===- lib/ReaderWriter/MachO/MachOLinkingContext.cpp ---------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lld/ReaderWriter/MachOLinkingContext.h"
11#include "ArchHandler.h"
12#include "File.h"
13#include "FlatNamespaceFile.h"
14#include "MachONormalizedFile.h"
15#include "MachOPasses.h"
16#include "SectCreateFile.h"
17#include "lld/Core/ArchiveLibraryFile.h"
18#include "lld/Core/PassManager.h"
19#include "lld/Core/Reader.h"
20#include "lld/Core/Writer.h"
21#include "lld/Driver/Driver.h"
22#include "llvm/ADT/STLExtras.h"
23#include "llvm/ADT/StringExtras.h"
24#include "llvm/ADT/Triple.h"
25#include "llvm/BinaryFormat/MachO.h"
26#include "llvm/Demangle/Demangle.h"
27#include "llvm/Support/Debug.h"
28#include "llvm/Support/Errc.h"
29#include "llvm/Support/Host.h"
30#include "llvm/Support/Path.h"
31#include <algorithm>
32
33using lld::mach_o::ArchHandler;
34using lld::mach_o::MachOFile;
35using lld::mach_o::MachODylibFile;
36using namespace llvm::MachO;
37
38namespace lld {
39
40bool MachOLinkingContext::parsePackedVersion(StringRef str, uint32_t &result) {
41 result = 0;
42
43 if (str.empty())
44 return false;
45
46 SmallVector<StringRef, 3> parts;
47 llvm::SplitString(str, parts, ".");
48
49 unsigned long long num;
50 if (llvm::getAsUnsignedInteger(parts[0], 10, num))
51 return true;
52 if (num > 65535)
53 return true;
54 result = num << 16;
55
56 if (parts.size() > 1) {
57 if (llvm::getAsUnsignedInteger(parts[1], 10, num))
58 return true;
59 if (num > 255)
60 return true;
61 result |= (num << 8);
62 }
63
64 if (parts.size() > 2) {
65 if (llvm::getAsUnsignedInteger(parts[2], 10, num))
66 return true;
67 if (num > 255)
68 return true;
69 result |= num;
70 }
71
72 return false;
73}
74
75bool MachOLinkingContext::parsePackedVersion(StringRef str, uint64_t &result) {
76 result = 0;
77
78 if (str.empty())
79 return false;
80
81 SmallVector<StringRef, 5> parts;
82 llvm::SplitString(str, parts, ".");
83
84 unsigned long long num;
85 if (llvm::getAsUnsignedInteger(parts[0], 10, num))
86 return true;
87 if (num > 0xFFFFFF)
88 return true;
89 result = num << 40;
90
91 unsigned Shift = 30;
92 for (StringRef str : llvm::makeArrayRef(parts).slice(1)) {
93 if (llvm::getAsUnsignedInteger(str, 10, num))
94 return true;
95 if (num > 0x3FF)
96 return true;
97 result |= (num << Shift);
98 Shift -= 10;
99 }
100
101 return false;
102}
103
104MachOLinkingContext::ArchInfo MachOLinkingContext::_s_archInfos[] = {
105 { "x86_64", arch_x86_64, true, CPU_TYPE_X86_64, CPU_SUBTYPE_X86_64_ALL },
106 { "i386", arch_x86, true, CPU_TYPE_I386, CPU_SUBTYPE_X86_ALL },
107 { "ppc", arch_ppc, false, CPU_TYPE_POWERPC, CPU_SUBTYPE_POWERPC_ALL },
108 { "armv6", arch_armv6, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V6 },
109 { "armv7", arch_armv7, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7 },
110 { "armv7s", arch_armv7s, true, CPU_TYPE_ARM, CPU_SUBTYPE_ARM_V7S },
111 { "arm64", arch_arm64, true, CPU_TYPE_ARM64, CPU_SUBTYPE_ARM64_ALL },
112 { "", arch_unknown,false, 0, 0 }
113};
114
115MachOLinkingContext::Arch
116MachOLinkingContext::archFromCpuType(uint32_t cputype, uint32_t cpusubtype) {
117 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
118 if ((info->cputype == cputype) && (info->cpusubtype == cpusubtype))
119 return info->arch;
120 }
121 return arch_unknown;
122}
123
124MachOLinkingContext::Arch
125MachOLinkingContext::archFromName(StringRef archName) {
126 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
127 if (info->archName.equals(archName))
128 return info->arch;
129 }
130 return arch_unknown;
131}
132
133StringRef MachOLinkingContext::nameFromArch(Arch arch) {
134 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
135 if (info->arch == arch)
136 return info->archName;
137 }
138 return "<unknown>";
139}
140
141uint32_t MachOLinkingContext::cpuTypeFromArch(Arch arch) {
142 assert(arch != arch_unknown);
143 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
144 if (info->arch == arch)
145 return info->cputype;
146 }
147 llvm_unreachable("Unknown arch type");
148}
149
150uint32_t MachOLinkingContext::cpuSubtypeFromArch(Arch arch) {
151 assert(arch != arch_unknown);
152 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
153 if (info->arch == arch)
154 return info->cpusubtype;
155 }
156 llvm_unreachable("Unknown arch type");
157}
158
159bool MachOLinkingContext::isThinObjectFile(StringRef path, Arch &arch) {
160 return mach_o::normalized::isThinObjectFile(path, arch);
161}
162
163bool MachOLinkingContext::sliceFromFatFile(MemoryBufferRef mb, uint32_t &offset,
164 uint32_t &size) {
165 return mach_o::normalized::sliceFromFatFile(mb, _arch, offset, size);
166}
167
168MachOLinkingContext::MachOLinkingContext() {}
169
170MachOLinkingContext::~MachOLinkingContext() {
171 // Atoms are allocated on BumpPtrAllocator's on File's.
172 // As we transfer atoms from one file to another, we need to clear all of the
173 // atoms before we remove any of the BumpPtrAllocator's.
174 auto &nodes = getNodes();
175 for (unsigned i = 0, e = nodes.size(); i != e; ++i) {
176 FileNode *node = dyn_cast<FileNode>(nodes[i].get());
177 if (!node)
178 continue;
179 File *file = node->getFile();
180 file->clearAtoms();
181 }
182}
183
184void MachOLinkingContext::configure(HeaderFileType type, Arch arch, OS os,
185 uint32_t minOSVersion,
186 bool exportDynamicSymbols) {
187 _outputMachOType = type;
188 _arch = arch;
189 _os = os;
190 _osMinVersion = minOSVersion;
191
192 // If min OS not specified on command line, use reasonable defaults.
193 // Note that we only do sensible defaults when emitting something other than
194 // object and preload.
195 if (_outputMachOType != llvm::MachO::MH_OBJECT &&
196 _outputMachOType != llvm::MachO::MH_PRELOAD) {
197 if (minOSVersion == 0) {
198 switch (_arch) {
199 case arch_x86_64:
200 case arch_x86:
201 parsePackedVersion("10.8", _osMinVersion);
202 _os = MachOLinkingContext::OS::macOSX;
203 break;
204 case arch_armv6:
205 case arch_armv7:
206 case arch_armv7s:
207 case arch_arm64:
208 parsePackedVersion("7.0", _osMinVersion);
209 _os = MachOLinkingContext::OS::iOS;
210 break;
211 default:
212 break;
213 }
214 }
215 }
216
217 switch (_outputMachOType) {
218 case llvm::MachO::MH_EXECUTE:
219 // If targeting newer OS, use _main
220 if (minOS("10.8", "6.0")) {
221 _entrySymbolName = "_main";
222 } else {
223 // If targeting older OS, use start (in crt1.o)
224 _entrySymbolName = "start";
225 }
226
227 // __PAGEZERO defaults to 4GB on 64-bit (except for PP64 which lld does not
228 // support) and 4KB on 32-bit.
229 if (is64Bit(_arch)) {
230 _pageZeroSize = 0x100000000;
231 } else {
232 _pageZeroSize = 0x1000;
233 }
234
235 // Initial base address is __PAGEZERO size.
236 _baseAddress = _pageZeroSize;
237
238 // Make PIE by default when targetting newer OSs.
239 switch (os) {
240 case OS::macOSX:
241 if (minOSVersion >= 0x000A0700) // MacOSX 10.7
242 _pie = true;
243 break;
244 case OS::iOS:
245 if (minOSVersion >= 0x00040300) // iOS 4.3
246 _pie = true;
247 break;
248 case OS::iOS_simulator:
249 _pie = true;
250 break;
251 case OS::unknown:
252 break;
253 }
254 setGlobalsAreDeadStripRoots(exportDynamicSymbols);
255 break;
256 case llvm::MachO::MH_DYLIB:
257 setGlobalsAreDeadStripRoots(exportDynamicSymbols);
258 break;
259 case llvm::MachO::MH_BUNDLE:
260 break;
261 case llvm::MachO::MH_OBJECT:
262 _printRemainingUndefines = false;
263 _allowRemainingUndefines = true;
264 default:
265 break;
266 }
267
268 // Set default segment page sizes based on arch.
269 if (arch == arch_arm64)
270 _pageSize = 4*4096;
271}
272
273uint32_t MachOLinkingContext::getCPUType() const {
274 return cpuTypeFromArch(_arch);
275}
276
277uint32_t MachOLinkingContext::getCPUSubType() const {
278 return cpuSubtypeFromArch(_arch);
279}
280
281bool MachOLinkingContext::is64Bit(Arch arch) {
282 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
283 if (info->arch == arch) {
284 return (info->cputype & CPU_ARCH_ABI64);
285 }
286 }
287 // unknown archs are not 64-bit.
288 return false;
289}
290
291bool MachOLinkingContext::isHostEndian(Arch arch) {
292 assert(arch != arch_unknown);
293 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
294 if (info->arch == arch) {
295 return (info->littleEndian == llvm::sys::IsLittleEndianHost);
296 }
297 }
298 llvm_unreachable("Unknown arch type");
299}
300
301bool MachOLinkingContext::isBigEndian(Arch arch) {
302 assert(arch != arch_unknown);
303 for (ArchInfo *info = _s_archInfos; !info->archName.empty(); ++info) {
304 if (info->arch == arch) {
305 return ! info->littleEndian;
306 }
307 }
308 llvm_unreachable("Unknown arch type");
309}
310
311bool MachOLinkingContext::is64Bit() const {
312 return is64Bit(_arch);
313}
314
315bool MachOLinkingContext::outputTypeHasEntry() const {
316 switch (_outputMachOType) {
317 case MH_EXECUTE:
318 case MH_DYLINKER:
319 case MH_PRELOAD:
320 return true;
321 default:
322 return false;
323 }
324}
325
326bool MachOLinkingContext::needsStubsPass() const {
327 switch (_outputMachOType) {
328 case MH_EXECUTE:
329 return !_outputMachOTypeStatic;
330 case MH_DYLIB:
331 case MH_BUNDLE:
332 return true;
333 default:
334 return false;
335 }
336}
337
338bool MachOLinkingContext::needsGOTPass() const {
339 // GOT pass not used in -r mode.
340 if (_outputMachOType == MH_OBJECT)
341 return false;
342 // Only some arches use GOT pass.
343 switch (_arch) {
344 case arch_x86_64:
345 case arch_arm64:
346 return true;
347 default:
348 return false;
349 }
350}
351
352bool MachOLinkingContext::needsCompactUnwindPass() const {
353 switch (_outputMachOType) {
354 case MH_EXECUTE:
355 case MH_DYLIB:
356 case MH_BUNDLE:
357 return archHandler().needsCompactUnwind();
358 default:
359 return false;
360 }
361}
362
363bool MachOLinkingContext::needsObjCPass() const {
364 // ObjC pass is only needed if any of the inputs were ObjC.
365 return _objcConstraint != objc_unknown;
366}
367
368bool MachOLinkingContext::needsShimPass() const {
369 // Shim pass only used in final executables.
370 if (_outputMachOType == MH_OBJECT)
371 return false;
372 // Only 32-bit arm arches use Shim pass.
373 switch (_arch) {
374 case arch_armv6:
375 case arch_armv7:
376 case arch_armv7s:
377 return true;
378 default:
379 return false;
380 }
381}
382
383bool MachOLinkingContext::needsTLVPass() const {
384 switch (_outputMachOType) {
385 case MH_BUNDLE:
386 case MH_EXECUTE:
387 case MH_DYLIB:
388 return true;
389 default:
390 return false;
391 }
392}
393
394StringRef MachOLinkingContext::binderSymbolName() const {
395 return archHandler().stubInfo().binderSymbolName;
396}
397
398bool MachOLinkingContext::minOS(StringRef mac, StringRef iOS) const {
399 uint32_t parsedVersion;
400 switch (_os) {
401 case OS::macOSX:
402 if (parsePackedVersion(mac, parsedVersion))
403 return false;
404 return _osMinVersion >= parsedVersion;
405 case OS::iOS:
406 case OS::iOS_simulator:
407 if (parsePackedVersion(iOS, parsedVersion))
408 return false;
409 return _osMinVersion >= parsedVersion;
410 case OS::unknown:
411 // If we don't know the target, then assume that we don't meet the min OS.
412 // This matches the ld64 behaviour
413 return false;
414 }
415 llvm_unreachable("invalid OS enum");
416}
417
418bool MachOLinkingContext::addEntryPointLoadCommand() const {
419 if ((_outputMachOType == MH_EXECUTE) && !_outputMachOTypeStatic) {
420 return minOS("10.8", "6.0");
421 }
422 return false;
423}
424
425bool MachOLinkingContext::addUnixThreadLoadCommand() const {
426 switch (_outputMachOType) {
427 case MH_EXECUTE:
428 if (_outputMachOTypeStatic)
429 return true;
430 else
431 return !minOS("10.8", "6.0");
432 break;
433 case MH_DYLINKER:
434 case MH_PRELOAD:
435 return true;
436 default:
437 return false;
438 }
439}
440
441bool MachOLinkingContext::pathExists(StringRef path) const {
442 if (!_testingFileUsage)
443 return llvm::sys::fs::exists(path.str());
444
445 // Otherwise, we're in test mode: only files explicitly provided on the
446 // command-line exist.
447 std::string key = path.str();
448 std::replace(key.begin(), key.end(), '\\', '/');
449 return _existingPaths.find(key) != _existingPaths.end();
450}
451
452bool MachOLinkingContext::fileExists(StringRef path) const {
453 bool found = pathExists(path);
454 // Log search misses.
455 if (!found)
456 addInputFileNotFound(path);
457
458 // When testing, file is never opened, so logging is done here.
459 if (_testingFileUsage && found)
460 addInputFileDependency(path);
461
462 return found;
463}
464
465void MachOLinkingContext::setSysLibRoots(const StringRefVector &paths) {
466 _syslibRoots = paths;
467}
468
469void MachOLinkingContext::addRpath(StringRef rpath) {
470 _rpaths.push_back(rpath);
471}
472
473void MachOLinkingContext::addModifiedSearchDir(StringRef libPath,
474 bool isSystemPath) {
475 bool addedModifiedPath = false;
476
477 // -syslibroot only applies to absolute paths.
478 if (libPath.startswith("/")) {
479 for (auto syslibRoot : _syslibRoots) {
480 SmallString<256> path(syslibRoot);
481 llvm::sys::path::append(path, libPath);
482 if (pathExists(path)) {
483 _searchDirs.push_back(path.str().copy(_allocator));
484 addedModifiedPath = true;
485 }
486 }
487 }
488
489 if (addedModifiedPath)
490 return;
491
492 // Finally, if only one -syslibroot is given, system paths which aren't in it
493 // get suppressed.
494 if (_syslibRoots.size() != 1 || !isSystemPath) {
495 if (pathExists(libPath)) {
496 _searchDirs.push_back(libPath);
497 }
498 }
499}
500
501void MachOLinkingContext::addFrameworkSearchDir(StringRef fwPath,
502 bool isSystemPath) {
503 bool pathAdded = false;
504
505 // -syslibroot only used with to absolute framework search paths.
506 if (fwPath.startswith("/")) {
507 for (auto syslibRoot : _syslibRoots) {
508 SmallString<256> path(syslibRoot);
509 llvm::sys::path::append(path, fwPath);
510 if (pathExists(path)) {
511 _frameworkDirs.push_back(path.str().copy(_allocator));
512 pathAdded = true;
513 }
514 }
515 }
516 // If fwPath found in any -syslibroot, then done.
517 if (pathAdded)
518 return;
519
520 // If only one -syslibroot, system paths not in that SDK are suppressed.
521 if (isSystemPath && (_syslibRoots.size() == 1))
522 return;
523
524 // Only use raw fwPath if that directory exists.
525 if (pathExists(fwPath))
526 _frameworkDirs.push_back(fwPath);
527}
528
529llvm::Optional<StringRef>
530MachOLinkingContext::searchDirForLibrary(StringRef path,
531 StringRef libName) const {
532 SmallString<256> fullPath;
533 if (libName.endswith(".o")) {
534 // A request ending in .o is special: just search for the file directly.
535 fullPath.assign(path);
536 llvm::sys::path::append(fullPath, libName);
537 if (fileExists(fullPath))
538 return fullPath.str().copy(_allocator);
539 return llvm::None;
540 }
541
542 // Search for dynamic library
543 fullPath.assign(path);
544 llvm::sys::path::append(fullPath, Twine("lib") + libName + ".dylib");
545 if (fileExists(fullPath))
546 return fullPath.str().copy(_allocator);
547
548 // If not, try for a static library
549 fullPath.assign(path);
550 llvm::sys::path::append(fullPath, Twine("lib") + libName + ".a");
551 if (fileExists(fullPath))
552 return fullPath.str().copy(_allocator);
553
554 return llvm::None;
555}
556
557llvm::Optional<StringRef>
558MachOLinkingContext::searchLibrary(StringRef libName) const {
559 SmallString<256> path;
560 for (StringRef dir : searchDirs()) {
561 llvm::Optional<StringRef> searchDir = searchDirForLibrary(dir, libName);
562 if (searchDir)
563 return searchDir;
564 }
565
566 return llvm::None;
567}
568
569llvm::Optional<StringRef>
570MachOLinkingContext::findPathForFramework(StringRef fwName) const{
571 SmallString<256> fullPath;
572 for (StringRef dir : frameworkDirs()) {
573 fullPath.assign(dir);
574 llvm::sys::path::append(fullPath, Twine(fwName) + ".framework", fwName);
575 if (fileExists(fullPath))
576 return fullPath.str().copy(_allocator);
577 }
578
579 return llvm::None;
580}
581
582bool MachOLinkingContext::validateImpl(raw_ostream &diagnostics) {
583 // TODO: if -arch not specified, look at arch of first .o file.
584
585 if (_currentVersion && _outputMachOType != MH_DYLIB) {
586 diagnostics << "error: -current_version can only be used with dylibs\n";
587 return false;
588 }
589
590 if (_compatibilityVersion && _outputMachOType != MH_DYLIB) {
591 diagnostics
592 << "error: -compatibility_version can only be used with dylibs\n";
593 return false;
594 }
595
596 if (_deadStrippableDylib && _outputMachOType != MH_DYLIB) {
597 diagnostics
598 << "error: -mark_dead_strippable_dylib can only be used with dylibs.\n";
599 return false;
600 }
601
602 if (!_bundleLoader.empty() && outputMachOType() != MH_BUNDLE) {
603 diagnostics
604 << "error: -bundle_loader can only be used with Mach-O bundles\n";
605 return false;
606 }
607
608 // If -exported_symbols_list used, all exported symbols must be defined.
609 if (_exportMode == ExportMode::whiteList) {
610 for (const auto &symbol : _exportedSymbols)
611 addInitialUndefinedSymbol(symbol.getKey());
612 }
613
614 // If -dead_strip, set up initial live symbols.
615 if (deadStrip()) {
616 // Entry point is live.
617 if (outputTypeHasEntry())
618 addDeadStripRoot(entrySymbolName());
619 // Lazy binding helper is live.
620 if (needsStubsPass())
621 addDeadStripRoot(binderSymbolName());
622 // If using -exported_symbols_list, make all exported symbols live.
623 if (_exportMode == ExportMode::whiteList) {
624 setGlobalsAreDeadStripRoots(false);
625 for (const auto &symbol : _exportedSymbols)
626 addDeadStripRoot(symbol.getKey());
627 }
628 }
629
630 addOutputFileDependency(outputPath());
631
632 return true;
633}
634
635void MachOLinkingContext::addPasses(PassManager &pm) {
636 // objc pass should be before layout pass. Otherwise test cases may contain
637 // no atoms which confuses the layout pass.
638 if (needsObjCPass())
639 mach_o::addObjCPass(pm, *this);
640 mach_o::addLayoutPass(pm, *this);
641 if (needsStubsPass())
642 mach_o::addStubsPass(pm, *this);
643 if (needsCompactUnwindPass())
644 mach_o::addCompactUnwindPass(pm, *this);
645 if (needsGOTPass())
646 mach_o::addGOTPass(pm, *this);
647 if (needsTLVPass())
648 mach_o::addTLVPass(pm, *this);
649 if (needsShimPass())
650 mach_o::addShimPass(pm, *this); // Shim pass must run after stubs pass.
651}
652
653Writer &MachOLinkingContext::writer() const {
654 if (!_writer)
655 _writer = createWriterMachO(*this);
656 return *_writer;
657}
658
659ErrorOr<std::unique_ptr<MemoryBuffer>>
660MachOLinkingContext::getMemoryBuffer(StringRef path) {
661 addInputFileDependency(path);
662
663 ErrorOr<std::unique_ptr<MemoryBuffer>> mbOrErr =
664 MemoryBuffer::getFileOrSTDIN(path);
665 if (std::error_code ec = mbOrErr.getError())
666 return ec;
667 std::unique_ptr<MemoryBuffer> mb = std::move(mbOrErr.get());
668
669 // If buffer contains a fat file, find required arch in fat buffer
670 // and switch buffer to point to just that required slice.
671 uint32_t offset;
672 uint32_t size;
673 if (sliceFromFatFile(mb->getMemBufferRef(), offset, size))
674 return MemoryBuffer::getFileSlice(path, size, offset);
675 return std::move(mb);
676}
677
678MachODylibFile* MachOLinkingContext::loadIndirectDylib(StringRef path) {
679 ErrorOr<std::unique_ptr<MemoryBuffer>> mbOrErr = getMemoryBuffer(path);
680 if (mbOrErr.getError())
681 return nullptr;
682
683 ErrorOr<std::unique_ptr<File>> fileOrErr =
684 registry().loadFile(std::move(mbOrErr.get()));
685 if (!fileOrErr)
686 return nullptr;
687 std::unique_ptr<File> &file = fileOrErr.get();
688 file->parse();
689 MachODylibFile *result = reinterpret_cast<MachODylibFile *>(file.get());
690 // Node object now owned by _indirectDylibs vector.
691 _indirectDylibs.push_back(std::move(file));
692 return result;
693}
694
695MachODylibFile* MachOLinkingContext::findIndirectDylib(StringRef path) {
696 // See if already loaded.
697 auto pos = _pathToDylibMap.find(path);
698 if (pos != _pathToDylibMap.end())
699 return pos->second;
700
701 // Search -L paths if of the form "libXXX.dylib"
702 std::pair<StringRef, StringRef> split = path.rsplit('/');
703 StringRef leafName = split.second;
704 if (leafName.startswith("lib") && leafName.endswith(".dylib")) {
705 // FIXME: Need to enhance searchLibrary() to only look for .dylib
706 auto libPath = searchLibrary(leafName);
707 if (libPath)
708 return loadIndirectDylib(libPath.getValue());
709 }
710
711 // Try full path with sysroot.
712 for (StringRef sysPath : _syslibRoots) {
713 SmallString<256> fullPath;
714 fullPath.assign(sysPath);
715 llvm::sys::path::append(fullPath, path);
716 if (pathExists(fullPath))
717 return loadIndirectDylib(fullPath);
718 }
719
720 // Try full path.
721 if (pathExists(path)) {
722 return loadIndirectDylib(path);
723 }
724
725 return nullptr;
726}
727
728uint32_t MachOLinkingContext::dylibCurrentVersion(StringRef installName) const {
729 auto pos = _pathToDylibMap.find(installName);
730 if (pos != _pathToDylibMap.end())
731 return pos->second->currentVersion();
732 else
733 return 0x10000; // 1.0
734}
735
736uint32_t MachOLinkingContext::dylibCompatVersion(StringRef installName) const {
737 auto pos = _pathToDylibMap.find(installName);
738 if (pos != _pathToDylibMap.end())
739 return pos->second->compatVersion();
740 else
741 return 0x10000; // 1.0
742}
743
744void MachOLinkingContext::createImplicitFiles(
745 std::vector<std::unique_ptr<File> > &result) {
746 // Add indirect dylibs by asking each linked dylib to add its indirects.
747 // Iterate until no more dylibs get loaded.
748 size_t dylibCount = 0;
749 while (dylibCount != _allDylibs.size()) {
750 dylibCount = _allDylibs.size();
751 for (MachODylibFile *dylib : _allDylibs) {
752 dylib->loadReExportedDylibs([this] (StringRef path) -> MachODylibFile* {
753 return findIndirectDylib(path); });
754 }
755 }
756
757 // Let writer add output type specific extras.
758 writer().createImplicitFiles(result);
759
760 // If undefinedMode is != error, add a FlatNamespaceFile instance. This will
761 // provide a SharedLibraryAtom for symbols that aren't defined elsewhere.
762 if (undefinedMode() != UndefinedMode::error) {
763 result.emplace_back(new mach_o::FlatNamespaceFile(*this));
764 _flatNamespaceFile = result.back().get();
765 }
766}
767
768void MachOLinkingContext::registerDylib(MachODylibFile *dylib,
769 bool upward) const {
770 std::lock_guard<std::mutex> lock(_dylibsMutex);
771
772 if (std::find(_allDylibs.begin(),
773 _allDylibs.end(), dylib) == _allDylibs.end())
774 _allDylibs.push_back(dylib);
775 _pathToDylibMap[dylib->installName()] = dylib;
776 // If path is different than install name, register path too.
777 if (!dylib->path().equals(dylib->installName()))
778 _pathToDylibMap[dylib->path()] = dylib;
779 if (upward)
780 _upwardDylibs.insert(dylib);
781}
782
783bool MachOLinkingContext::isUpwardDylib(StringRef installName) const {
784 for (MachODylibFile *dylib : _upwardDylibs) {
785 if (dylib->installName().equals(installName))
786 return true;
787 }
788 return false;
789}
790
791ArchHandler &MachOLinkingContext::archHandler() const {
792 if (!_archHandler)
793 _archHandler = ArchHandler::create(_arch);
794 return *_archHandler;
795}
796
797void MachOLinkingContext::addSectionAlignment(StringRef seg, StringRef sect,
798 uint16_t align) {
799 SectionAlign entry = { seg, sect, align };
800 _sectAligns.push_back(entry);
801}
802
803void MachOLinkingContext::addSectCreateSection(
804 StringRef seg, StringRef sect,
805 std::unique_ptr<MemoryBuffer> content) {
806
807 if (!_sectCreateFile) {
808 auto sectCreateFile = llvm::make_unique<mach_o::SectCreateFile>();
809 _sectCreateFile = sectCreateFile.get();
810 getNodes().push_back(llvm::make_unique<FileNode>(std::move(sectCreateFile)));
811 }
812
813 assert(_sectCreateFile && "sectcreate file does not exist.");
814 _sectCreateFile->addSection(seg, sect, std::move(content));
815}
816
817bool MachOLinkingContext::sectionAligned(StringRef seg, StringRef sect,
818 uint16_t &align) const {
819 for (const SectionAlign &entry : _sectAligns) {
820 if (seg.equals(entry.segmentName) && sect.equals(entry.sectionName)) {
821 align = entry.align;
822 return true;
823 }
824 }
825 return false;
826}
827
828void MachOLinkingContext::addExportSymbol(StringRef sym) {
829 // Support old crufty export lists with bogus entries.
830 if (sym.endswith(".eh") || sym.startswith(".objc_category_name_")) {
831 llvm::errs() << "warning: ignoring " << sym << " in export list\n";
832 return;
833 }
834 // Only i386 MacOSX uses old ABI, so don't change those.
835 if ((_os != OS::macOSX) || (_arch != arch_x86)) {
836 // ObjC has two differnent ABIs. Be nice and allow one export list work for
837 // both ABIs by renaming symbols.
838 if (sym.startswith(".objc_class_name_")) {
839 std::string abi2className("_OBJC_CLASS_$_");
840 abi2className += sym.substr(17);
841 _exportedSymbols.insert(copy(abi2className));
842 std::string abi2metaclassName("_OBJC_METACLASS_$_");
843 abi2metaclassName += sym.substr(17);
844 _exportedSymbols.insert(copy(abi2metaclassName));
845 return;
846 }
847 }
848
849 // FIXME: Support wildcards.
850 _exportedSymbols.insert(sym);
851}
852
853bool MachOLinkingContext::exportSymbolNamed(StringRef sym) const {
854 switch (_exportMode) {
855 case ExportMode::globals:
856 llvm_unreachable("exportSymbolNamed() should not be called in this mode");
857 break;
858 case ExportMode::whiteList:
859 return _exportedSymbols.count(sym);
860 case ExportMode::blackList:
861 return !_exportedSymbols.count(sym);
862 }
863 llvm_unreachable("_exportMode unknown enum value");
864}
865
866std::string MachOLinkingContext::demangle(StringRef symbolName) const {
867 // Only try to demangle symbols if -demangle on command line
868 if (!demangleSymbols())
869 return symbolName;
870
871 // Only try to demangle symbols that look like C++ symbols
872 if (!symbolName.startswith("__Z"))
873 return symbolName;
874
875 SmallString<256> symBuff;
876 StringRef nullTermSym = Twine(symbolName).toNullTerminatedStringRef(symBuff);
877 // Mach-O has extra leading underscore that needs to be removed.
878 const char *cstr = nullTermSym.data() + 1;
879 int status;
880 char *demangled = llvm::itaniumDemangle(cstr, nullptr, nullptr, &status);
881 if (demangled) {
882 std::string result(demangled);
883 // __cxa_demangle() always uses a malloc'ed buffer to return the result.
884 free(demangled);
885 return result;
886 }
887
888 return symbolName;
889}
890
891static void addDependencyInfoHelper(llvm::raw_fd_ostream *DepInfo,
892 char Opcode, StringRef Path) {
893 if (!DepInfo)
894 return;
895
896 *DepInfo << Opcode;
897 *DepInfo << Path;
898 *DepInfo << '\0';
899}
900
901std::error_code MachOLinkingContext::createDependencyFile(StringRef path) {
902 std::error_code ec;
903 _dependencyInfo = std::unique_ptr<llvm::raw_fd_ostream>(new
904 llvm::raw_fd_ostream(path, ec, llvm::sys::fs::F_None));
905 if (ec) {
906 _dependencyInfo.reset();
907 return ec;
908 }
909
910 addDependencyInfoHelper(_dependencyInfo.get(), 0x00, "lld" /*FIXME*/);
911 return std::error_code();
912}
913
914void MachOLinkingContext::addInputFileDependency(StringRef path) const {
915 addDependencyInfoHelper(_dependencyInfo.get(), 0x10, path);
916}
917
918void MachOLinkingContext::addInputFileNotFound(StringRef path) const {
919 addDependencyInfoHelper(_dependencyInfo.get(), 0x11, path);
920}
921
922void MachOLinkingContext::addOutputFileDependency(StringRef path) const {
923 addDependencyInfoHelper(_dependencyInfo.get(), 0x40, path);
924}
925
926void MachOLinkingContext::appendOrderedSymbol(StringRef symbol,
927 StringRef filename) {
928 // To support sorting static functions which may have the same name in
929 // multiple .o files, _orderFiles maps the symbol name to a vector
930 // of OrderFileNode each of which can specify a file prefix.
931 OrderFileNode info;
932 if (!filename.empty())
933 info.fileFilter = copy(filename);
934 info.order = _orderFileEntries++;
935 _orderFiles[symbol].push_back(info);
936}
937
938bool
939MachOLinkingContext::findOrderOrdinal(const std::vector<OrderFileNode> &nodes,
940 const DefinedAtom *atom,
941 unsigned &ordinal) {
942 const File *objFile = &atom->file();
943 assert(objFile);
944 StringRef objName = objFile->path();
945 std::pair<StringRef, StringRef> dirAndLeaf = objName.rsplit('/');
946 if (!dirAndLeaf.second.empty())
947 objName = dirAndLeaf.second;
948 for (const OrderFileNode &info : nodes) {
949 if (info.fileFilter.empty()) {
950 // Have unprefixed symbol name in order file that matches this atom.
951 ordinal = info.order;
952 return true;
953 }
954 if (info.fileFilter.equals(objName)) {
955 // Have prefixed symbol name in order file that matches atom's path.
956 ordinal = info.order;
957 return true;
958 }
959 }
960 return false;
961}
962
963bool MachOLinkingContext::customAtomOrderer(const DefinedAtom *left,
964 const DefinedAtom *right,
965 bool &leftBeforeRight) const {
966 // No custom sorting if no order file entries.
967 if (!_orderFileEntries)
968 return false;
969
970 // Order files can only order named atoms.
971 StringRef leftName = left->name();
972 StringRef rightName = right->name();
973 if (leftName.empty() || rightName.empty())
974 return false;
975
976 // If neither is in order file list, no custom sorter.
977 auto leftPos = _orderFiles.find(leftName);
978 auto rightPos = _orderFiles.find(rightName);
979 bool leftIsOrdered = (leftPos != _orderFiles.end());
980 bool rightIsOrdered = (rightPos != _orderFiles.end());
981 if (!leftIsOrdered && !rightIsOrdered)
982 return false;
983
984 // There could be multiple symbols with same name but different file prefixes.
985 unsigned leftOrder;
986 unsigned rightOrder;
987 bool foundLeft =
988 leftIsOrdered && findOrderOrdinal(leftPos->getValue(), left, leftOrder);
989 bool foundRight = rightIsOrdered &&
990 findOrderOrdinal(rightPos->getValue(), right, rightOrder);
991 if (!foundLeft && !foundRight)
992 return false;
993
994 // If only one is in order file list, ordered one goes first.
995 if (foundLeft != foundRight)
996 leftBeforeRight = foundLeft;
997 else
998 leftBeforeRight = (leftOrder < rightOrder);
999
1000 return true;
1001}
1002
1003static bool isLibrary(const std::unique_ptr<Node> &elem) {
1004 if (FileNode *node = dyn_cast<FileNode>(const_cast<Node *>(elem.get()))) {
1005 File *file = node->getFile();
1006 return isa<SharedLibraryFile>(file) || isa<ArchiveLibraryFile>(file);
1007 }
1008 return false;
1009}
1010
1011// The darwin linker processes input files in two phases. The first phase
1012// links in all object (.o) files in command line order. The second phase
1013// links in libraries in command line order.
1014// In this function we reorder the input files so that all the object files
1015// comes before any library file. We also make a group for the library files
1016// so that the Resolver will reiterate over the libraries as long as we find
1017// new undefines from libraries.
1018void MachOLinkingContext::finalizeInputFiles() {
1019 std::vector<std::unique_ptr<Node>> &elements = getNodes();
1020 std::stable_sort(elements.begin(), elements.end(),
1021 [](const std::unique_ptr<Node> &a,
1022 const std::unique_ptr<Node> &b) {
1023 return !isLibrary(a) && isLibrary(b);
1024 });
1025 size_t numLibs = std::count_if(elements.begin(), elements.end(), isLibrary);
1026 elements.push_back(llvm::make_unique<GroupEnd>(numLibs));
1027}
1028
1029llvm::Error MachOLinkingContext::handleLoadedFile(File &file) {
1030 auto *machoFile = dyn_cast<MachOFile>(&file);
1031 if (!machoFile)
1032 return llvm::Error::success();
1033
1034 // Check that the arch of the context matches that of the file.
1035 // Also set the arch of the context if it didn't have one.
1036 if (_arch == arch_unknown) {
1037 _arch = machoFile->arch();
1038 } else if (machoFile->arch() != arch_unknown && machoFile->arch() != _arch) {
1039 // Archs are different.
1040 return llvm::make_error<GenericError>(file.path() +
1041 Twine(" cannot be linked due to incompatible architecture"));
1042 }
1043
1044 // Check that the OS of the context matches that of the file.
1045 // Also set the OS of the context if it didn't have one.
1046 if (_os == OS::unknown) {
1047 _os = machoFile->OS();
1048 } else if (machoFile->OS() != OS::unknown && machoFile->OS() != _os) {
1049 // OSes are different.
1050 return llvm::make_error<GenericError>(file.path() +
1051 Twine(" cannot be linked due to incompatible operating systems"));
1052 }
1053
1054 // Check that if the objc info exists, that it is compatible with the target
1055 // OS.
1056 switch (machoFile->objcConstraint()) {
1057 case objc_unknown:
1058 // The file is not compiled with objc, so skip the checks.
1059 break;
1060 case objc_gc_only:
1061 case objc_supports_gc:
1062 llvm_unreachable("GC support should already have thrown an error");
1063 case objc_retainReleaseForSimulator:
1064 // The file is built with simulator objc, so make sure that the context
1065 // is also building with simulator support.
1066 if (_os != OS::iOS_simulator)
1067 return llvm::make_error<GenericError>(file.path() +
1068 Twine(" cannot be linked. It contains ObjC built for the simulator"
1069 " while we are linking a non-simulator target"));
1070 assert((_objcConstraint == objc_unknown ||
1071 _objcConstraint == objc_retainReleaseForSimulator) &&
1072 "Must be linking with retain/release for the simulator");
1073 _objcConstraint = objc_retainReleaseForSimulator;
1074 break;
1075 case objc_retainRelease:
1076 // The file is built without simulator objc, so make sure that the
1077 // context is also building without simulator support.
1078 if (_os == OS::iOS_simulator)
1079 return llvm::make_error<GenericError>(file.path() +
1080 Twine(" cannot be linked. It contains ObjC built for a non-simulator"
1081 " target while we are linking a simulator target"));
1082 assert((_objcConstraint == objc_unknown ||
1083 _objcConstraint == objc_retainRelease) &&
1084 "Must be linking with retain/release for a non-simulator target");
1085 _objcConstraint = objc_retainRelease;
1086 break;
1087 }
1088
1089 // Check that the swift version of the context matches that of the file.
1090 // Also set the swift version of the context if it didn't have one.
1091 if (!_swiftVersion) {
1092 _swiftVersion = machoFile->swiftVersion();
1093 } else if (machoFile->swiftVersion() &&
1094 machoFile->swiftVersion() != _swiftVersion) {
1095 // Swift versions are different.
1096 return llvm::make_error<GenericError>("different swift versions");
1097 }
1098
1099 return llvm::Error::success();
1100}
1101
1102} // end namespace lld
deps/lld/lib/ReaderWriter/MachO/MachONormalizedFile.h created+345
......@@ -0,0 +1,345 @@
1//===- lib/ReaderWriter/MachO/MachONormalizedFile.h -----------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10///
11/// \file These data structures comprise the "normalized" view of
12/// mach-o object files. The normalized view is an in-memory only data structure
13/// which is always in native endianness and pointer size.
14///
15/// The normalized view easily converts to and from YAML using YAML I/O.
16///
17/// The normalized view converts to and from binary mach-o object files using
18/// the writeBinary() and readBinary() functions.
19///
20/// The normalized view converts to and from lld::Atoms using the
21/// normalizedToAtoms() and normalizedFromAtoms().
22///
23/// Overall, the conversion paths available look like:
24///
25/// +---------------+
26/// | binary mach-o |
27/// +---------------+
28/// ^
29/// |
30/// v
31/// +------------+ +------+
32/// | normalized | <-> | yaml |
33/// +------------+ +------+
34/// ^
35/// |
36/// v
37/// +-------+
38/// | Atoms |
39/// +-------+
40///
41
42#ifndef LLD_READER_WRITER_MACHO_NORMALIZE_FILE_H
43#define LLD_READER_WRITER_MACHO_NORMALIZE_FILE_H
44
45#include "DebugInfo.h"
46#include "lld/Core/Error.h"
47#include "lld/Core/LLVM.h"
48#include "lld/ReaderWriter/MachOLinkingContext.h"
49#include "llvm/ADT/SmallString.h"
50#include "llvm/ADT/StringRef.h"
51#include "llvm/BinaryFormat/MachO.h"
52#include "llvm/Support/Allocator.h"
53#include "llvm/Support/Debug.h"
54#include "llvm/Support/ErrorOr.h"
55#include "llvm/Support/YAMLTraits.h"
56
57using llvm::BumpPtrAllocator;
58using llvm::yaml::Hex64;
59using llvm::yaml::Hex32;
60using llvm::yaml::Hex16;
61using llvm::yaml::Hex8;
62using llvm::yaml::SequenceTraits;
63using llvm::MachO::HeaderFileType;
64using llvm::MachO::BindType;
65using llvm::MachO::RebaseType;
66using llvm::MachO::NListType;
67using llvm::MachO::RelocationInfoType;
68using llvm::MachO::SectionType;
69using llvm::MachO::LoadCommandType;
70using llvm::MachO::ExportSymbolKind;
71using llvm::MachO::DataRegionType;
72
73namespace lld {
74namespace mach_o {
75namespace normalized {
76
77
78/// The real mach-o relocation record is 8-bytes on disk and is
79/// encoded in one of two different bit-field patterns. This
80/// normalized form has the union of all possible fields.
81struct Relocation {
82 Relocation() : offset(0), scattered(false),
83 type(llvm::MachO::GENERIC_RELOC_VANILLA),
84 length(0), pcRel(false), isExtern(false), value(0),
85 symbol(0) { }
86
87 Hex32 offset;
88 bool scattered;
89 RelocationInfoType type;
90 uint8_t length;
91 bool pcRel;
92 bool isExtern;
93 Hex32 value;
94 uint32_t symbol;
95};
96
97/// A typedef so that YAML I/O can treat this vector as a sequence.
98typedef std::vector<Relocation> Relocations;
99
100/// A typedef so that YAML I/O can process the raw bytes in a section.
101typedef std::vector<Hex8> ContentBytes;
102
103/// A typedef so that YAML I/O can treat indirect symbols as a flow sequence.
104typedef std::vector<uint32_t> IndirectSymbols;
105
106/// A typedef so that YAML I/O can encode/decode section attributes.
107LLVM_YAML_STRONG_TYPEDEF(uint32_t, SectionAttr)
108
109/// A typedef so that YAML I/O can encode/decode section alignment.
110LLVM_YAML_STRONG_TYPEDEF(uint16_t, SectionAlignment)
111
112/// Mach-O has a 32-bit and 64-bit section record. This normalized form
113/// can support either kind.
114struct Section {
115 Section() : type(llvm::MachO::S_REGULAR),
116 attributes(0), alignment(1), address(0) { }
117
118 StringRef segmentName;
119 StringRef sectionName;
120 SectionType type;
121 SectionAttr attributes;
122 SectionAlignment alignment;
123 Hex64 address;
124 ArrayRef<uint8_t> content;
125 Relocations relocations;
126 IndirectSymbols indirectSymbols;
127
128#ifndef NDEBUG
129 raw_ostream& operator<<(raw_ostream &OS) const {
130 dump(OS);
131 return OS;
132 }
133
134 void dump(raw_ostream &OS = llvm::dbgs()) const;
135#endif
136};
137
138
139/// A typedef so that YAML I/O can encode/decode the scope bits of an nlist.
140LLVM_YAML_STRONG_TYPEDEF(uint8_t, SymbolScope)
141
142/// A typedef so that YAML I/O can encode/decode the desc bits of an nlist.
143LLVM_YAML_STRONG_TYPEDEF(uint16_t, SymbolDesc)
144
145/// Mach-O has a 32-bit and 64-bit symbol table entry (nlist), and the symbol
146/// type and scope and mixed in the same n_type field. This normalized form
147/// works for any pointer size and separates out the type and scope.
148struct Symbol {
149 Symbol() : type(llvm::MachO::N_UNDF), scope(0), sect(0), desc(0), value(0) { }
150
151 StringRef name;
152 NListType type;
153 SymbolScope scope;
154 uint8_t sect;
155 SymbolDesc desc;
156 Hex64 value;
157};
158
159/// Check whether the given section type indicates a zero-filled section.
160// FIXME: Utility functions of this kind should probably be moved into
161// llvm/Support.
162inline bool isZeroFillSection(SectionType T) {
163 return (T == llvm::MachO::S_ZEROFILL ||
164 T == llvm::MachO::S_THREAD_LOCAL_ZEROFILL);
165}
166
167/// A typedef so that YAML I/O can (de/en)code the protection bits of a segment.
168LLVM_YAML_STRONG_TYPEDEF(uint32_t, VMProtect)
169
170/// A typedef to hold verions X.Y.X packed into 32-bit xxxx.yy.zz
171LLVM_YAML_STRONG_TYPEDEF(uint32_t, PackedVersion)
172
173/// Segments are only used in normalized final linked images (not in relocatable
174/// object files). They specify how a range of the file is loaded.
175struct Segment {
176 StringRef name;
177 Hex64 address;
178 Hex64 size;
179 VMProtect init_access;
180 VMProtect max_access;
181};
182
183/// Only used in normalized final linked images to specify on which dylibs
184/// it depends.
185struct DependentDylib {
186 StringRef path;
187 LoadCommandType kind;
188 PackedVersion compatVersion;
189 PackedVersion currentVersion;
190};
191
192/// A normalized rebasing entry. Only used in normalized final linked images.
193struct RebaseLocation {
194 Hex32 segOffset;
195 uint8_t segIndex;
196 RebaseType kind;
197};
198
199/// A normalized binding entry. Only used in normalized final linked images.
200struct BindLocation {
201 Hex32 segOffset;
202 uint8_t segIndex;
203 BindType kind;
204 bool canBeNull;
205 int ordinal;
206 StringRef symbolName;
207 Hex64 addend;
208};
209
210/// A typedef so that YAML I/O can encode/decode export flags.
211LLVM_YAML_STRONG_TYPEDEF(uint32_t, ExportFlags)
212
213/// A normalized export entry. Only used in normalized final linked images.
214struct Export {
215 StringRef name;
216 Hex64 offset;
217 ExportSymbolKind kind;
218 ExportFlags flags;
219 Hex32 otherOffset;
220 StringRef otherName;
221};
222
223/// A normalized data-in-code entry.
224struct DataInCode {
225 Hex32 offset;
226 Hex16 length;
227 DataRegionType kind;
228};
229
230/// A typedef so that YAML I/O can encode/decode mach_header.flags.
231LLVM_YAML_STRONG_TYPEDEF(uint32_t, FileFlags)
232
233///
234struct NormalizedFile {
235 MachOLinkingContext::Arch arch = MachOLinkingContext::arch_unknown;
236 HeaderFileType fileType = llvm::MachO::MH_OBJECT;
237 FileFlags flags = 0;
238 std::vector<Segment> segments; // Not used in object files.
239 std::vector<Section> sections;
240
241 // Symbols sorted by kind.
242 std::vector<Symbol> localSymbols;
243 std::vector<Symbol> globalSymbols;
244 std::vector<Symbol> undefinedSymbols;
245 std::vector<Symbol> stabsSymbols;
246
247 // Maps to load commands with no LINKEDIT content (final linked images only).
248 std::vector<DependentDylib> dependentDylibs;
249 StringRef installName; // dylibs only
250 PackedVersion compatVersion = 0; // dylibs only
251 PackedVersion currentVersion = 0; // dylibs only
252 bool hasUUID = false;
253 bool hasMinVersionLoadCommand = false;
254 bool generateDataInCodeLoadCommand = false;
255 std::vector<StringRef> rpaths;
256 Hex64 entryAddress = 0;
257 Hex64 stackSize = 0;
258 MachOLinkingContext::OS os = MachOLinkingContext::OS::unknown;
259 Hex64 sourceVersion = 0;
260 PackedVersion minOSverson = 0;
261 PackedVersion sdkVersion = 0;
262 LoadCommandType minOSVersionKind = (LoadCommandType)0;
263
264 // Maps to load commands with LINKEDIT content (final linked images only).
265 Hex32 pageSize = 0;
266 std::vector<RebaseLocation> rebasingInfo;
267 std::vector<BindLocation> bindingInfo;
268 std::vector<BindLocation> weakBindingInfo;
269 std::vector<BindLocation> lazyBindingInfo;
270 std::vector<Export> exportInfo;
271 std::vector<uint8_t> functionStarts;
272 std::vector<DataInCode> dataInCode;
273
274 // TODO:
275 // code-signature
276 // split-seg-info
277 // function-starts
278
279 // For any allocations in this struct which need to be owned by this struct.
280 BumpPtrAllocator ownedAllocations;
281};
282
283/// Tests if a file is a non-fat mach-o object file.
284bool isThinObjectFile(StringRef path, MachOLinkingContext::Arch &arch);
285
286/// If the buffer is a fat file with the request arch, then this function
287/// returns true with 'offset' and 'size' set to location of the arch slice
288/// within the buffer. Otherwise returns false;
289bool sliceFromFatFile(MemoryBufferRef mb, MachOLinkingContext::Arch arch,
290 uint32_t &offset, uint32_t &size);
291
292/// Reads a mach-o file and produces an in-memory normalized view.
293llvm::Expected<std::unique_ptr<NormalizedFile>>
294readBinary(std::unique_ptr<MemoryBuffer> &mb,
295 const MachOLinkingContext::Arch arch);
296
297/// Takes in-memory normalized view and writes a mach-o object file.
298llvm::Error writeBinary(const NormalizedFile &file, StringRef path);
299
300size_t headerAndLoadCommandsSize(const NormalizedFile &file);
301
302
303/// Parses a yaml encoded mach-o file to produce an in-memory normalized view.
304llvm::Expected<std::unique_ptr<NormalizedFile>>
305readYaml(std::unique_ptr<MemoryBuffer> &mb);
306
307/// Writes a yaml encoded mach-o files given an in-memory normalized view.
308std::error_code writeYaml(const NormalizedFile &file, raw_ostream &out);
309
310llvm::Error
311normalizedObjectToAtoms(MachOFile *file,
312 const NormalizedFile &normalizedFile,
313 bool copyRefs);
314
315llvm::Error
316normalizedDylibToAtoms(MachODylibFile *file,
317 const NormalizedFile &normalizedFile,
318 bool copyRefs);
319
320/// Takes in-memory normalized dylib or object and parses it into lld::File
321llvm::Expected<std::unique_ptr<lld::File>>
322normalizedToAtoms(const NormalizedFile &normalizedFile, StringRef path,
323 bool copyRefs);
324
325/// Takes atoms and generates a normalized macho-o view.
326llvm::Expected<std::unique_ptr<NormalizedFile>>
327normalizedFromAtoms(const lld::File &atomFile, const MachOLinkingContext &ctxt);
328
329
330} // namespace normalized
331
332/// Class for interfacing mach-o yaml files into generic yaml parsing
333class MachOYamlIOTaggedDocumentHandler : public YamlIOTaggedDocumentHandler {
334public:
335 MachOYamlIOTaggedDocumentHandler(MachOLinkingContext::Arch arch)
336 : _arch(arch) { }
337 bool handledDocTag(llvm::yaml::IO &io, const lld::File *&file) const override;
338private:
339 const MachOLinkingContext::Arch _arch;
340};
341
342} // namespace mach_o
343} // namespace lld
344
345#endif // LLD_READER_WRITER_MACHO_NORMALIZE_FILE_H
deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp created+591
......@@ -0,0 +1,591 @@
1//===- lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp ---------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10///
11/// \file For mach-o object files, this implementation converts from
12/// mach-o on-disk binary format to in-memory normalized mach-o.
13///
14/// +---------------+
15/// | binary mach-o |
16/// +---------------+
17/// |
18/// |
19/// v
20/// +------------+
21/// | normalized |
22/// +------------+
23
24#include "ArchHandler.h"
25#include "MachONormalizedFile.h"
26#include "MachONormalizedFileBinaryUtils.h"
27#include "lld/Core/Error.h"
28#include "lld/Core/LLVM.h"
29#include "lld/Core/SharedLibraryFile.h"
30#include "llvm/ADT/STLExtras.h"
31#include "llvm/ADT/SmallString.h"
32#include "llvm/ADT/StringRef.h"
33#include "llvm/ADT/StringSwitch.h"
34#include "llvm/ADT/Twine.h"
35#include "llvm/BinaryFormat/MachO.h"
36#include "llvm/BinaryFormat/Magic.h"
37#include "llvm/Object/MachO.h"
38#include "llvm/Support/Casting.h"
39#include "llvm/Support/Errc.h"
40#include "llvm/Support/ErrorHandling.h"
41#include "llvm/Support/FileOutputBuffer.h"
42#include "llvm/Support/Host.h"
43#include "llvm/Support/MemoryBuffer.h"
44#include "llvm/Support/raw_ostream.h"
45#include <functional>
46#include <system_error>
47
48using namespace llvm::MachO;
49using llvm::object::ExportEntry;
50using llvm::file_magic;
51using llvm::object::MachOObjectFile;
52
53namespace lld {
54namespace mach_o {
55namespace normalized {
56
57// Utility to call a lambda expression on each load command.
58static llvm::Error forEachLoadCommand(
59 StringRef lcRange, unsigned lcCount, bool isBig, bool is64,
60 std::function<bool(uint32_t cmd, uint32_t size, const char *lc)> func) {
61 const char* p = lcRange.begin();
62 for (unsigned i=0; i < lcCount; ++i) {
63 const load_command *lc = reinterpret_cast<const load_command*>(p);
64 load_command lcCopy;
65 const load_command *slc = lc;
66 if (isBig != llvm::sys::IsBigEndianHost) {
67 memcpy(&lcCopy, lc, sizeof(load_command));
68 swapStruct(lcCopy);
69 slc = &lcCopy;
70 }
71 if ( (p + slc->cmdsize) > lcRange.end() )
72 return llvm::make_error<GenericError>("Load command exceeds range");
73
74 if (func(slc->cmd, slc->cmdsize, p))
75 return llvm::Error::success();
76
77 p += slc->cmdsize;
78 }
79
80 return llvm::Error::success();
81}
82
83static std::error_code appendRelocations(Relocations &relocs, StringRef buffer,
84 bool bigEndian,
85 uint32_t reloff, uint32_t nreloc) {
86 if ((reloff + nreloc*8) > buffer.size())
87 return make_error_code(llvm::errc::executable_format_error);
88 const any_relocation_info* relocsArray =
89 reinterpret_cast<const any_relocation_info*>(buffer.begin()+reloff);
90
91 for(uint32_t i=0; i < nreloc; ++i) {
92 relocs.push_back(unpackRelocation(relocsArray[i], bigEndian));
93 }
94 return std::error_code();
95}
96
97static std::error_code
98appendIndirectSymbols(IndirectSymbols &isyms, StringRef buffer, bool isBig,
99 uint32_t istOffset, uint32_t istCount,
100 uint32_t startIndex, uint32_t count) {
101 if ((istOffset + istCount*4) > buffer.size())
102 return make_error_code(llvm::errc::executable_format_error);
103 if (startIndex+count > istCount)
104 return make_error_code(llvm::errc::executable_format_error);
105 const uint8_t *indirectSymbolArray = (const uint8_t *)buffer.data();
106
107 for(uint32_t i=0; i < count; ++i) {
108 isyms.push_back(read32(
109 indirectSymbolArray + (startIndex + i) * sizeof(uint32_t), isBig));
110 }
111 return std::error_code();
112}
113
114
115template <typename T> static T readBigEndian(T t) {
116 if (llvm::sys::IsLittleEndianHost)
117 llvm::sys::swapByteOrder(t);
118 return t;
119}
120
121
122static bool isMachOHeader(const mach_header *mh, bool &is64, bool &isBig) {
123 switch (read32(&mh->magic, false)) {
124 case llvm::MachO::MH_MAGIC:
125 is64 = false;
126 isBig = false;
127 return true;
128 case llvm::MachO::MH_MAGIC_64:
129 is64 = true;
130 isBig = false;
131 return true;
132 case llvm::MachO::MH_CIGAM:
133 is64 = false;
134 isBig = true;
135 return true;
136 case llvm::MachO::MH_CIGAM_64:
137 is64 = true;
138 isBig = true;
139 return true;
140 default:
141 return false;
142 }
143}
144
145
146bool isThinObjectFile(StringRef path, MachOLinkingContext::Arch &arch) {
147 // Try opening and mapping file at path.
148 ErrorOr<std::unique_ptr<MemoryBuffer>> b = MemoryBuffer::getFileOrSTDIN(path);
149 if (b.getError())
150 return false;
151
152 // If file length < 32 it is too small to be mach-o object file.
153 StringRef fileBuffer = b->get()->getBuffer();
154 if (fileBuffer.size() < 32)
155 return false;
156
157 // If file buffer does not start with MH_MAGIC (and variants), not obj file.
158 const mach_header *mh = reinterpret_cast<const mach_header *>(
159 fileBuffer.begin());
160 bool is64, isBig;
161 if (!isMachOHeader(mh, is64, isBig))
162 return false;
163
164 // If not MH_OBJECT, not object file.
165 if (read32(&mh->filetype, isBig) != MH_OBJECT)
166 return false;
167
168 // Lookup up arch from cpu/subtype pair.
169 arch = MachOLinkingContext::archFromCpuType(
170 read32(&mh->cputype, isBig),
171 read32(&mh->cpusubtype, isBig));
172 return true;
173}
174
175bool sliceFromFatFile(MemoryBufferRef mb, MachOLinkingContext::Arch arch,
176 uint32_t &offset, uint32_t &size) {
177 const char *start = mb.getBufferStart();
178 const llvm::MachO::fat_header *fh =
179 reinterpret_cast<const llvm::MachO::fat_header *>(start);
180 if (readBigEndian(fh->magic) != llvm::MachO::FAT_MAGIC)
181 return false;
182 uint32_t nfat_arch = readBigEndian(fh->nfat_arch);
183 const fat_arch *fstart =
184 reinterpret_cast<const fat_arch *>(start + sizeof(fat_header));
185 const fat_arch *fend =
186 reinterpret_cast<const fat_arch *>(start + sizeof(fat_header) +
187 sizeof(fat_arch) * nfat_arch);
188 const uint32_t reqCpuType = MachOLinkingContext::cpuTypeFromArch(arch);
189 const uint32_t reqCpuSubtype = MachOLinkingContext::cpuSubtypeFromArch(arch);
190 for (const fat_arch *fa = fstart; fa < fend; ++fa) {
191 if ((readBigEndian(fa->cputype) == reqCpuType) &&
192 (readBigEndian(fa->cpusubtype) == reqCpuSubtype)) {
193 offset = readBigEndian(fa->offset);
194 size = readBigEndian(fa->size);
195 if ((offset + size) > mb.getBufferSize())
196 return false;
197 return true;
198 }
199 }
200 return false;
201}
202
203/// Reads a mach-o file and produces an in-memory normalized view.
204llvm::Expected<std::unique_ptr<NormalizedFile>>
205readBinary(std::unique_ptr<MemoryBuffer> &mb,
206 const MachOLinkingContext::Arch arch) {
207 // Make empty NormalizedFile.
208 std::unique_ptr<NormalizedFile> f(new NormalizedFile());
209
210 const char *start = mb->getBufferStart();
211 size_t objSize = mb->getBufferSize();
212 const mach_header *mh = reinterpret_cast<const mach_header *>(start);
213
214 uint32_t sliceOffset;
215 uint32_t sliceSize;
216 if (sliceFromFatFile(mb->getMemBufferRef(), arch, sliceOffset, sliceSize)) {
217 start = &start[sliceOffset];
218 objSize = sliceSize;
219 mh = reinterpret_cast<const mach_header *>(start);
220 }
221
222 // Determine endianness and pointer size for mach-o file.
223 bool is64, isBig;
224 if (!isMachOHeader(mh, is64, isBig))
225 return llvm::make_error<GenericError>("File is not a mach-o");
226
227 // Endian swap header, if needed.
228 mach_header headerCopy;
229 const mach_header *smh = mh;
230 if (isBig != llvm::sys::IsBigEndianHost) {
231 memcpy(&headerCopy, mh, sizeof(mach_header));
232 swapStruct(headerCopy);
233 smh = &headerCopy;
234 }
235
236 // Validate head and load commands fit in buffer.
237 const uint32_t lcCount = smh->ncmds;
238 const char *lcStart =
239 start + (is64 ? sizeof(mach_header_64) : sizeof(mach_header));
240 StringRef lcRange(lcStart, smh->sizeofcmds);
241 if (lcRange.end() > (start + objSize))
242 return llvm::make_error<GenericError>("Load commands exceed file size");
243
244 // Get architecture from mach_header.
245 f->arch = MachOLinkingContext::archFromCpuType(smh->cputype, smh->cpusubtype);
246 if (f->arch != arch) {
247 return llvm::make_error<GenericError>(
248 Twine("file is wrong architecture. Expected "
249 "(" + MachOLinkingContext::nameFromArch(arch)
250 + ") found ("
251 + MachOLinkingContext::nameFromArch(f->arch)
252 + ")" ));
253 }
254 // Copy file type and flags
255 f->fileType = HeaderFileType(smh->filetype);
256 f->flags = smh->flags;
257
258
259 // Pre-scan load commands looking for indirect symbol table.
260 uint32_t indirectSymbolTableOffset = 0;
261 uint32_t indirectSymbolTableCount = 0;
262 auto ec = forEachLoadCommand(lcRange, lcCount, isBig, is64,
263 [&](uint32_t cmd, uint32_t size,
264 const char *lc) -> bool {
265 if (cmd == LC_DYSYMTAB) {
266 const dysymtab_command *d = reinterpret_cast<const dysymtab_command*>(lc);
267 indirectSymbolTableOffset = read32(&d->indirectsymoff, isBig);
268 indirectSymbolTableCount = read32(&d->nindirectsyms, isBig);
269 return true;
270 }
271 return false;
272 });
273 if (ec)
274 return std::move(ec);
275
276 // Walk load commands looking for segments/sections and the symbol table.
277 const data_in_code_entry *dataInCode = nullptr;
278 const dyld_info_command *dyldInfo = nullptr;
279 uint32_t dataInCodeSize = 0;
280 ec = forEachLoadCommand(lcRange, lcCount, isBig, is64,
281 [&] (uint32_t cmd, uint32_t size, const char* lc) -> bool {
282 switch(cmd) {
283 case LC_SEGMENT_64:
284 if (is64) {
285 const segment_command_64 *seg =
286 reinterpret_cast<const segment_command_64*>(lc);
287 const unsigned sectionCount = read32(&seg->nsects, isBig);
288 const section_64 *sects = reinterpret_cast<const section_64*>
289 (lc + sizeof(segment_command_64));
290 const unsigned lcSize = sizeof(segment_command_64)
291 + sectionCount*sizeof(section_64);
292 // Verify sections don't extend beyond end of segment load command.
293 if (lcSize > size)
294 return true;
295 for (unsigned i=0; i < sectionCount; ++i) {
296 const section_64 *sect = &sects[i];
297 Section section;
298 section.segmentName = getString16(sect->segname);
299 section.sectionName = getString16(sect->sectname);
300 section.type = (SectionType)(read32(&sect->flags, isBig) &
301 SECTION_TYPE);
302 section.attributes = read32(&sect->flags, isBig) & SECTION_ATTRIBUTES;
303 section.alignment = 1 << read32(&sect->align, isBig);
304 section.address = read64(&sect->addr, isBig);
305 const uint8_t *content =
306 (const uint8_t *)start + read32(&sect->offset, isBig);
307 size_t contentSize = read64(&sect->size, isBig);
308 // Note: this assign() is copying the content bytes. Ideally,
309 // we can use a custom allocator for vector to avoid the copy.
310 section.content = llvm::makeArrayRef(content, contentSize);
311 appendRelocations(section.relocations, mb->getBuffer(), isBig,
312 read32(&sect->reloff, isBig),
313 read32(&sect->nreloc, isBig));
314 if (section.type == S_NON_LAZY_SYMBOL_POINTERS) {
315 appendIndirectSymbols(section.indirectSymbols, mb->getBuffer(),
316 isBig,
317 indirectSymbolTableOffset,
318 indirectSymbolTableCount,
319 read32(&sect->reserved1, isBig),
320 contentSize/4);
321 }
322 f->sections.push_back(section);
323 }
324 }
325 break;
326 case LC_SEGMENT:
327 if (!is64) {
328 const segment_command *seg =
329 reinterpret_cast<const segment_command*>(lc);
330 const unsigned sectionCount = read32(&seg->nsects, isBig);
331 const section *sects = reinterpret_cast<const section*>
332 (lc + sizeof(segment_command));
333 const unsigned lcSize = sizeof(segment_command)
334 + sectionCount*sizeof(section);
335 // Verify sections don't extend beyond end of segment load command.
336 if (lcSize > size)
337 return true;
338 for (unsigned i=0; i < sectionCount; ++i) {
339 const section *sect = &sects[i];
340 Section section;
341 section.segmentName = getString16(sect->segname);
342 section.sectionName = getString16(sect->sectname);
343 section.type = (SectionType)(read32(&sect->flags, isBig) &
344 SECTION_TYPE);
345 section.attributes =
346 read32((const uint8_t *)&sect->flags, isBig) & SECTION_ATTRIBUTES;
347 section.alignment = 1 << read32(&sect->align, isBig);
348 section.address = read32(&sect->addr, isBig);
349 const uint8_t *content =
350 (const uint8_t *)start + read32(&sect->offset, isBig);
351 size_t contentSize = read32(&sect->size, isBig);
352 // Note: this assign() is copying the content bytes. Ideally,
353 // we can use a custom allocator for vector to avoid the copy.
354 section.content = llvm::makeArrayRef(content, contentSize);
355 appendRelocations(section.relocations, mb->getBuffer(), isBig,
356 read32(&sect->reloff, isBig),
357 read32(&sect->nreloc, isBig));
358 if (section.type == S_NON_LAZY_SYMBOL_POINTERS) {
359 appendIndirectSymbols(
360 section.indirectSymbols, mb->getBuffer(), isBig,
361 indirectSymbolTableOffset, indirectSymbolTableCount,
362 read32(&sect->reserved1, isBig), contentSize / 4);
363 }
364 f->sections.push_back(section);
365 }
366 }
367 break;
368 case LC_SYMTAB: {
369 const symtab_command *st = reinterpret_cast<const symtab_command*>(lc);
370 const char *strings = start + read32(&st->stroff, isBig);
371 const uint32_t strSize = read32(&st->strsize, isBig);
372 // Validate string pool and symbol table all in buffer.
373 if (read32((const uint8_t *)&st->stroff, isBig) +
374 read32((const uint8_t *)&st->strsize, isBig) >
375 objSize)
376 return true;
377 if (is64) {
378 const uint32_t symOffset = read32(&st->symoff, isBig);
379 const uint32_t symCount = read32(&st->nsyms, isBig);
380 if ( symOffset+(symCount*sizeof(nlist_64)) > objSize)
381 return true;
382 const nlist_64 *symbols =
383 reinterpret_cast<const nlist_64 *>(start + symOffset);
384 // Convert each nlist_64 to a lld::mach_o::normalized::Symbol.
385 for(uint32_t i=0; i < symCount; ++i) {
386 nlist_64 tempSym;
387 memcpy(&tempSym, &symbols[i], sizeof(nlist_64));
388 const nlist_64 *sin = &tempSym;
389 if (isBig != llvm::sys::IsBigEndianHost)
390 swapStruct(tempSym);
391 Symbol sout;
392 if (sin->n_strx > strSize)
393 return true;
394 sout.name = &strings[sin->n_strx];
395 sout.type = static_cast<NListType>(sin->n_type & (N_STAB|N_TYPE));
396 sout.scope = (sin->n_type & (N_PEXT|N_EXT));
397 sout.sect = sin->n_sect;
398 sout.desc = sin->n_desc;
399 sout.value = sin->n_value;
400 if (sin->n_type & N_STAB)
401 f->stabsSymbols.push_back(sout);
402 else if (sout.type == N_UNDF)
403 f->undefinedSymbols.push_back(sout);
404 else if (sin->n_type & N_EXT)
405 f->globalSymbols.push_back(sout);
406 else
407 f->localSymbols.push_back(sout);
408 }
409 } else {
410 const uint32_t symOffset = read32(&st->symoff, isBig);
411 const uint32_t symCount = read32(&st->nsyms, isBig);
412 if ( symOffset+(symCount*sizeof(nlist)) > objSize)
413 return true;
414 const nlist *symbols =
415 reinterpret_cast<const nlist *>(start + symOffset);
416 // Convert each nlist to a lld::mach_o::normalized::Symbol.
417 for(uint32_t i=0; i < symCount; ++i) {
418 const nlist *sin = &symbols[i];
419 nlist tempSym;
420 if (isBig != llvm::sys::IsBigEndianHost) {
421 tempSym = *sin; swapStruct(tempSym); sin = &tempSym;
422 }
423 Symbol sout;
424 if (sin->n_strx > strSize)
425 return true;
426 sout.name = &strings[sin->n_strx];
427 sout.type = (NListType)(sin->n_type & N_TYPE);
428 sout.scope = (sin->n_type & (N_PEXT|N_EXT));
429 sout.sect = sin->n_sect;
430 sout.desc = sin->n_desc;
431 sout.value = sin->n_value;
432 if (sout.type == N_UNDF)
433 f->undefinedSymbols.push_back(sout);
434 else if (sout.scope == (SymbolScope)N_EXT)
435 f->globalSymbols.push_back(sout);
436 else if (sin->n_type & N_STAB)
437 f->stabsSymbols.push_back(sout);
438 else
439 f->localSymbols.push_back(sout);
440 }
441 }
442 }
443 break;
444 case LC_ID_DYLIB: {
445 const dylib_command *dl = reinterpret_cast<const dylib_command*>(lc);
446 f->installName = lc + read32(&dl->dylib.name, isBig);
447 f->currentVersion = read32(&dl->dylib.current_version, isBig);
448 f->compatVersion = read32(&dl->dylib.compatibility_version, isBig);
449 }
450 break;
451 case LC_DATA_IN_CODE: {
452 const linkedit_data_command *ldc =
453 reinterpret_cast<const linkedit_data_command*>(lc);
454 dataInCode = reinterpret_cast<const data_in_code_entry *>(
455 start + read32(&ldc->dataoff, isBig));
456 dataInCodeSize = read32(&ldc->datasize, isBig);
457 }
458 break;
459 case LC_LOAD_DYLIB:
460 case LC_LOAD_WEAK_DYLIB:
461 case LC_REEXPORT_DYLIB:
462 case LC_LOAD_UPWARD_DYLIB: {
463 const dylib_command *dl = reinterpret_cast<const dylib_command*>(lc);
464 DependentDylib entry;
465 entry.path = lc + read32(&dl->dylib.name, isBig);
466 entry.kind = LoadCommandType(cmd);
467 entry.compatVersion = read32(&dl->dylib.compatibility_version, isBig);
468 entry.currentVersion = read32(&dl->dylib.current_version, isBig);
469 f->dependentDylibs.push_back(entry);
470 }
471 break;
472 case LC_RPATH: {
473 const rpath_command *rpc = reinterpret_cast<const rpath_command *>(lc);
474 f->rpaths.push_back(lc + read32(&rpc->path, isBig));
475 }
476 break;
477 case LC_DYLD_INFO:
478 case LC_DYLD_INFO_ONLY:
479 dyldInfo = reinterpret_cast<const dyld_info_command*>(lc);
480 break;
481 case LC_VERSION_MIN_MACOSX:
482 case LC_VERSION_MIN_IPHONEOS:
483 case LC_VERSION_MIN_WATCHOS:
484 case LC_VERSION_MIN_TVOS:
485 // If we are emitting an object file, then we may take the load command
486 // kind from these commands and pass it on to the output
487 // file.
488 f->minOSVersionKind = (LoadCommandType)cmd;
489 break;
490 }
491 return false;
492 });
493 if (ec)
494 return std::move(ec);
495
496 if (dataInCode) {
497 // Convert on-disk data_in_code_entry array to DataInCode vector.
498 for (unsigned i=0; i < dataInCodeSize/sizeof(data_in_code_entry); ++i) {
499 DataInCode entry;
500 entry.offset = read32(&dataInCode[i].offset, isBig);
501 entry.length = read16(&dataInCode[i].length, isBig);
502 entry.kind =
503 (DataRegionType)read16((const uint8_t *)&dataInCode[i].kind, isBig);
504 f->dataInCode.push_back(entry);
505 }
506 }
507
508 if (dyldInfo) {
509 // If any exports, extract and add to normalized exportInfo vector.
510 if (dyldInfo->export_size) {
511 const uint8_t *trieStart = reinterpret_cast<const uint8_t *>(
512 start + read32(&dyldInfo->export_off, isBig));
513 ArrayRef<uint8_t> trie(trieStart, read32(&dyldInfo->export_size, isBig));
514 for (const ExportEntry &trieExport : MachOObjectFile::exports(trie)) {
515 Export normExport;
516 normExport.name = trieExport.name().copy(f->ownedAllocations);
517 normExport.offset = trieExport.address();
518 normExport.kind = ExportSymbolKind(trieExport.flags() & EXPORT_SYMBOL_FLAGS_KIND_MASK);
519 normExport.flags = trieExport.flags() & ~EXPORT_SYMBOL_FLAGS_KIND_MASK;
520 normExport.otherOffset = trieExport.other();
521 if (!trieExport.otherName().empty())
522 normExport.otherName = trieExport.otherName().copy(f->ownedAllocations);
523 f->exportInfo.push_back(normExport);
524 }
525 }
526 }
527
528 return std::move(f);
529}
530
531class MachOObjectReader : public Reader {
532public:
533 MachOObjectReader(MachOLinkingContext &ctx) : _ctx(ctx) {}
534
535 bool canParse(file_magic magic, MemoryBufferRef mb) const override {
536 return (magic == file_magic::macho_object && mb.getBufferSize() > 32);
537 }
538
539 ErrorOr<std::unique_ptr<File>>
540 loadFile(std::unique_ptr<MemoryBuffer> mb,
541 const Registry &registry) const override {
542 std::unique_ptr<File> ret =
543 llvm::make_unique<MachOFile>(std::move(mb), &_ctx);
544 return std::move(ret);
545 }
546
547private:
548 MachOLinkingContext &_ctx;
549};
550
551class MachODylibReader : public Reader {
552public:
553 MachODylibReader(MachOLinkingContext &ctx) : _ctx(ctx) {}
554
555 bool canParse(file_magic magic, MemoryBufferRef mb) const override {
556 switch (magic) {
557 case file_magic::macho_dynamically_linked_shared_lib:
558 case file_magic::macho_dynamically_linked_shared_lib_stub:
559 return mb.getBufferSize() > 32;
560 default:
561 return false;
562 }
563 }
564
565 ErrorOr<std::unique_ptr<File>>
566 loadFile(std::unique_ptr<MemoryBuffer> mb,
567 const Registry &registry) const override {
568 std::unique_ptr<File> ret =
569 llvm::make_unique<MachODylibFile>(std::move(mb), &_ctx);
570 return std::move(ret);
571 }
572
573private:
574 MachOLinkingContext &_ctx;
575};
576
577} // namespace normalized
578} // namespace mach_o
579
580void Registry::addSupportMachOObjects(MachOLinkingContext &ctx) {
581 MachOLinkingContext::Arch arch = ctx.arch();
582 add(std::unique_ptr<Reader>(new mach_o::normalized::MachOObjectReader(ctx)));
583 add(std::unique_ptr<Reader>(new mach_o::normalized::MachODylibReader(ctx)));
584 addKindTable(Reference::KindNamespace::mach_o, ctx.archHandler().kindArch(),
585 ctx.archHandler().kindStrings());
586 add(std::unique_ptr<YamlIOTaggedDocumentHandler>(
587 new mach_o::MachOYamlIOTaggedDocumentHandler(arch)));
588}
589
590
591} // namespace lld
deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h created+215
......@@ -0,0 +1,215 @@
1//===- lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h ------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_READER_WRITER_MACHO_NORMALIZED_FILE_BINARY_UTILS_H
11#define LLD_READER_WRITER_MACHO_NORMALIZED_FILE_BINARY_UTILS_H
12
13#include "MachONormalizedFile.h"
14#include "lld/Core/Error.h"
15#include "lld/Core/LLVM.h"
16#include "llvm/ADT/StringRef.h"
17#include "llvm/BinaryFormat/MachO.h"
18#include "llvm/Support/Casting.h"
19#include "llvm/Support/Endian.h"
20#include "llvm/Support/ErrorHandling.h"
21#include "llvm/Support/Host.h"
22#include "llvm/Support/LEB128.h"
23#include <system_error>
24
25namespace lld {
26namespace mach_o {
27namespace normalized {
28
29class ByteBuffer {
30public:
31 ByteBuffer() : _ostream(_bytes) { }
32
33 void append_byte(uint8_t b) {
34 _ostream << b;
35 }
36 void append_uleb128(uint64_t value) {
37 llvm::encodeULEB128(value, _ostream);
38 }
39 void append_uleb128Fixed(uint64_t value, unsigned byteCount) {
40 unsigned min = llvm::getULEB128Size(value);
41 assert(min <= byteCount);
42 unsigned pad = byteCount - min;
43 llvm::encodeULEB128(value, _ostream, pad);
44 }
45 void append_sleb128(int64_t value) {
46 llvm::encodeSLEB128(value, _ostream);
47 }
48 void append_string(StringRef str) {
49 _ostream << str;
50 append_byte(0);
51 }
52 void align(unsigned alignment) {
53 while ( (_ostream.tell() % alignment) != 0 )
54 append_byte(0);
55 }
56 size_t size() {
57 return _ostream.tell();
58 }
59 const uint8_t *bytes() {
60 return reinterpret_cast<const uint8_t*>(_ostream.str().data());
61 }
62
63private:
64 SmallVector<char, 128> _bytes;
65 // Stream ivar must be after SmallVector ivar to construct properly.
66 llvm::raw_svector_ostream _ostream;
67};
68
69using namespace llvm::support::endian;
70using llvm::sys::getSwappedBytes;
71
72template<typename T>
73static inline uint16_t read16(const T *loc, bool isBig) {
74 assert((uint64_t)loc % alignof(T) == 0 && "invalid pointer alignment");
75 return isBig ? read16be(loc) : read16le(loc);
76}
77
78template<typename T>
79static inline uint32_t read32(const T *loc, bool isBig) {
80 assert((uint64_t)loc % alignof(T) == 0 && "invalid pointer alignment");
81 return isBig ? read32be(loc) : read32le(loc);
82}
83
84template<typename T>
85static inline uint64_t read64(const T *loc, bool isBig) {
86 assert((uint64_t)loc % alignof(T) == 0 && "invalid pointer alignment");
87 return isBig ? read64be(loc) : read64le(loc);
88}
89
90inline void write16(uint8_t *loc, uint16_t value, bool isBig) {
91 if (isBig)
92 write16be(loc, value);
93 else
94 write16le(loc, value);
95}
96
97inline void write32(uint8_t *loc, uint32_t value, bool isBig) {
98 if (isBig)
99 write32be(loc, value);
100 else
101 write32le(loc, value);
102}
103
104inline void write64(uint8_t *loc, uint64_t value, bool isBig) {
105 if (isBig)
106 write64be(loc, value);
107 else
108 write64le(loc, value);
109}
110
111inline uint32_t
112bitFieldExtract(uint32_t value, bool isBigEndianBigField, uint8_t firstBit,
113 uint8_t bitCount) {
114 const uint32_t mask = ((1<<bitCount)-1);
115 const uint8_t shift = isBigEndianBigField ? (32-firstBit-bitCount) : firstBit;
116 return (value >> shift) & mask;
117}
118
119inline void
120bitFieldSet(uint32_t &bits, bool isBigEndianBigField, uint32_t newBits,
121 uint8_t firstBit, uint8_t bitCount) {
122 const uint32_t mask = ((1<<bitCount)-1);
123 assert((newBits & mask) == newBits);
124 const uint8_t shift = isBigEndianBigField ? (32-firstBit-bitCount) : firstBit;
125 bits &= ~(mask << shift);
126 bits |= (newBits << shift);
127}
128
129inline Relocation unpackRelocation(const llvm::MachO::any_relocation_info &r,
130 bool isBigEndian) {
131 uint32_t r0 = read32(&r.r_word0, isBigEndian);
132 uint32_t r1 = read32(&r.r_word1, isBigEndian);
133
134 Relocation result;
135 if (r0 & llvm::MachO::R_SCATTERED) {
136 // scattered relocation record always laid out like big endian bit field
137 result.offset = bitFieldExtract(r0, true, 8, 24);
138 result.scattered = true;
139 result.type = (RelocationInfoType)
140 bitFieldExtract(r0, true, 4, 4);
141 result.length = bitFieldExtract(r0, true, 2, 2);
142 result.pcRel = bitFieldExtract(r0, true, 1, 1);
143 result.isExtern = false;
144 result.value = r1;
145 result.symbol = 0;
146 } else {
147 result.offset = r0;
148 result.scattered = false;
149 result.type = (RelocationInfoType)
150 bitFieldExtract(r1, isBigEndian, 28, 4);
151 result.length = bitFieldExtract(r1, isBigEndian, 25, 2);
152 result.pcRel = bitFieldExtract(r1, isBigEndian, 24, 1);
153 result.isExtern = bitFieldExtract(r1, isBigEndian, 27, 1);
154 result.value = 0;
155 result.symbol = bitFieldExtract(r1, isBigEndian, 0, 24);
156 }
157 return result;
158}
159
160
161inline llvm::MachO::any_relocation_info
162packRelocation(const Relocation &r, bool swap, bool isBigEndian) {
163 uint32_t r0 = 0;
164 uint32_t r1 = 0;
165
166 if (r.scattered) {
167 r1 = r.value;
168 bitFieldSet(r0, true, r.offset, 8, 24);
169 bitFieldSet(r0, true, r.type, 4, 4);
170 bitFieldSet(r0, true, r.length, 2, 2);
171 bitFieldSet(r0, true, r.pcRel, 1, 1);
172 bitFieldSet(r0, true, r.scattered, 0, 1); // R_SCATTERED
173 } else {
174 r0 = r.offset;
175 bitFieldSet(r1, isBigEndian, r.type, 28, 4);
176 bitFieldSet(r1, isBigEndian, r.isExtern, 27, 1);
177 bitFieldSet(r1, isBigEndian, r.length, 25, 2);
178 bitFieldSet(r1, isBigEndian, r.pcRel, 24, 1);
179 bitFieldSet(r1, isBigEndian, r.symbol, 0, 24);
180 }
181
182 llvm::MachO::any_relocation_info result;
183 result.r_word0 = swap ? getSwappedBytes(r0) : r0;
184 result.r_word1 = swap ? getSwappedBytes(r1) : r1;
185 return result;
186}
187
188inline StringRef getString16(const char s[16]) {
189 StringRef x = s;
190 if ( x.size() > 16 )
191 return x.substr(0, 16);
192 else
193 return x;
194}
195
196inline void setString16(StringRef str, char s[16]) {
197 memset(s, 0, 16);
198 memcpy(s, str.begin(), (str.size() > 16) ? 16: str.size());
199}
200
201// Implemented in normalizedToAtoms() and used by normalizedFromAtoms() so
202// that the same table can be used to map mach-o sections to and from
203// DefinedAtom::ContentType.
204void relocatableSectionInfoForContentType(DefinedAtom::ContentType atomType,
205 StringRef &segmentName,
206 StringRef &sectionName,
207 SectionType &sectionType,
208 SectionAttr &sectionAttrs,
209 bool &relocsToDefinedCanBeImplicit);
210
211} // namespace normalized
212} // namespace mach_o
213} // namespace lld
214
215#endif // LLD_READER_WRITER_MACHO_NORMALIZED_FILE_BINARY_UTILS_H
deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp created+1551
......@@ -0,0 +1,1551 @@
1//===- lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp ---------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10///
11/// \file For mach-o object files, this implementation converts normalized
12/// mach-o in memory to mach-o binary on disk.
13///
14/// +---------------+
15/// | binary mach-o |
16/// +---------------+
17/// ^
18/// |
19/// |
20/// +------------+
21/// | normalized |
22/// +------------+
23
24#include "MachONormalizedFile.h"
25#include "MachONormalizedFileBinaryUtils.h"
26#include "lld/Core/Error.h"
27#include "lld/Core/LLVM.h"
28#include "llvm/ADT/SmallString.h"
29#include "llvm/ADT/SmallVector.h"
30#include "llvm/ADT/StringRef.h"
31#include "llvm/ADT/ilist.h"
32#include "llvm/ADT/ilist_node.h"
33#include "llvm/BinaryFormat/MachO.h"
34#include "llvm/Support/Casting.h"
35#include "llvm/Support/Debug.h"
36#include "llvm/Support/Errc.h"
37#include "llvm/Support/ErrorHandling.h"
38#include "llvm/Support/FileOutputBuffer.h"
39#include "llvm/Support/Format.h"
40#include "llvm/Support/Host.h"
41#include "llvm/Support/MemoryBuffer.h"
42#include "llvm/Support/raw_ostream.h"
43#include <functional>
44#include <list>
45#include <map>
46#include <system_error>
47
48using namespace llvm::MachO;
49
50namespace lld {
51namespace mach_o {
52namespace normalized {
53
54struct TrieNode; // Forward declaration.
55
56struct TrieEdge : public llvm::ilist_node<TrieEdge> {
57 TrieEdge(StringRef s, TrieNode *node) : _subString(s), _child(node) {}
58
59 StringRef _subString;
60 struct TrieNode *_child;
61};
62
63} // namespace normalized
64} // namespace mach_o
65} // namespace lld
66
67
68namespace llvm {
69using lld::mach_o::normalized::TrieEdge;
70template <>
71struct ilist_alloc_traits<TrieEdge> : ilist_noalloc_traits<TrieEdge> {};
72} // namespace llvm
73
74
75namespace lld {
76namespace mach_o {
77namespace normalized {
78
79struct TrieNode {
80 typedef llvm::ilist<TrieEdge> TrieEdgeList;
81
82 TrieNode(StringRef s)
83 : _cummulativeString(s), _address(0), _flags(0), _other(0),
84 _trieOffset(0), _hasExportInfo(false) {}
85 ~TrieNode() = default;
86
87 void addSymbol(const Export &entry, BumpPtrAllocator &allocator,
88 std::vector<TrieNode *> &allNodes);
89
90 void addOrderedNodes(const Export &entry,
91 std::vector<TrieNode *> &allNodes);
92 bool updateOffset(uint32_t &offset);
93 void appendToByteBuffer(ByteBuffer &out);
94
95private:
96 StringRef _cummulativeString;
97 TrieEdgeList _children;
98 uint64_t _address;
99 uint64_t _flags;
100 uint64_t _other;
101 StringRef _importedName;
102 uint32_t _trieOffset;
103 bool _hasExportInfo;
104 bool _ordered = false;
105};
106
107/// Utility class for writing a mach-o binary file given an in-memory
108/// normalized file.
109class MachOFileLayout {
110public:
111 /// All layout computation is done in the constructor.
112 MachOFileLayout(const NormalizedFile &file);
113
114 /// Returns the final file size as computed in the constructor.
115 size_t size() const;
116
117 // Returns size of the mach_header and load commands.
118 size_t headerAndLoadCommandsSize() const;
119
120 /// Writes the normalized file as a binary mach-o file to the specified
121 /// path. This does not have a stream interface because the generated
122 /// file may need the 'x' bit set.
123 llvm::Error writeBinary(StringRef path);
124
125private:
126 uint32_t loadCommandsSize(uint32_t &count);
127 void buildFileOffsets();
128 void writeMachHeader();
129 llvm::Error writeLoadCommands();
130 void writeSectionContent();
131 void writeRelocations();
132 void writeSymbolTable();
133 void writeRebaseInfo();
134 void writeBindingInfo();
135 void writeLazyBindingInfo();
136 void writeExportInfo();
137 void writeFunctionStartsInfo();
138 void writeDataInCodeInfo();
139 void writeLinkEditContent();
140 void buildLinkEditInfo();
141 void buildRebaseInfo();
142 void buildBindInfo();
143 void buildLazyBindInfo();
144 void buildExportTrie();
145 void computeFunctionStartsSize();
146 void computeDataInCodeSize();
147 void computeSymbolTableSizes();
148 void buildSectionRelocations();
149 void appendSymbols(const std::vector<Symbol> &symbols,
150 uint32_t &symOffset, uint32_t &strOffset);
151 uint32_t indirectSymbolIndex(const Section &sect, uint32_t &index);
152 uint32_t indirectSymbolElementSize(const Section &sect);
153
154 // For use as template parameter to load command methods.
155 struct MachO64Trait {
156 typedef llvm::MachO::segment_command_64 command;
157 typedef llvm::MachO::section_64 section;
158 enum { LC = llvm::MachO::LC_SEGMENT_64 };
159 };
160
161 // For use as template parameter to load command methods.
162 struct MachO32Trait {
163 typedef llvm::MachO::segment_command command;
164 typedef llvm::MachO::section section;
165 enum { LC = llvm::MachO::LC_SEGMENT };
166 };
167
168 template <typename T>
169 llvm::Error writeSingleSegmentLoadCommand(uint8_t *&lc);
170 template <typename T> llvm::Error writeSegmentLoadCommands(uint8_t *&lc);
171
172 uint32_t pointerAlign(uint32_t value);
173 static StringRef dyldPath();
174
175 struct SegExtraInfo {
176 uint32_t fileOffset;
177 uint32_t fileSize;
178 std::vector<const Section*> sections;
179 };
180 typedef std::map<const Segment*, SegExtraInfo> SegMap;
181 struct SectionExtraInfo {
182 uint32_t fileOffset;
183 };
184 typedef std::map<const Section*, SectionExtraInfo> SectionMap;
185
186 const NormalizedFile &_file;
187 std::error_code _ec;
188 uint8_t *_buffer;
189 const bool _is64;
190 const bool _swap;
191 const bool _bigEndianArch;
192 uint64_t _seg1addr;
193 uint32_t _startOfLoadCommands;
194 uint32_t _countOfLoadCommands;
195 uint32_t _endOfLoadCommands;
196 uint32_t _startOfRelocations;
197 uint32_t _startOfFunctionStarts;
198 uint32_t _startOfDataInCode;
199 uint32_t _startOfSymbols;
200 uint32_t _startOfIndirectSymbols;
201 uint32_t _startOfSymbolStrings;
202 uint32_t _endOfSymbolStrings;
203 uint32_t _symbolTableLocalsStartIndex;
204 uint32_t _symbolTableGlobalsStartIndex;
205 uint32_t _symbolTableUndefinesStartIndex;
206 uint32_t _symbolStringPoolSize;
207 uint32_t _symbolTableSize;
208 uint32_t _functionStartsSize;
209 uint32_t _dataInCodeSize;
210 uint32_t _indirectSymbolTableCount;
211 // Used in object file creation only
212 uint32_t _startOfSectionsContent;
213 uint32_t _endOfSectionsContent;
214 // Used in final linked image only
215 uint32_t _startOfLinkEdit;
216 uint32_t _startOfRebaseInfo;
217 uint32_t _endOfRebaseInfo;
218 uint32_t _startOfBindingInfo;
219 uint32_t _endOfBindingInfo;
220 uint32_t _startOfLazyBindingInfo;
221 uint32_t _endOfLazyBindingInfo;
222 uint32_t _startOfExportTrie;
223 uint32_t _endOfExportTrie;
224 uint32_t _endOfLinkEdit;
225 uint64_t _addressOfLinkEdit;
226 SegMap _segInfo;
227 SectionMap _sectInfo;
228 ByteBuffer _rebaseInfo;
229 ByteBuffer _bindingInfo;
230 ByteBuffer _lazyBindingInfo;
231 ByteBuffer _weakBindingInfo;
232 ByteBuffer _exportTrie;
233};
234
235size_t headerAndLoadCommandsSize(const NormalizedFile &file) {
236 MachOFileLayout layout(file);
237 return layout.headerAndLoadCommandsSize();
238}
239
240StringRef MachOFileLayout::dyldPath() {
241 return "/usr/lib/dyld";
242}
243
244uint32_t MachOFileLayout::pointerAlign(uint32_t value) {
245 return llvm::alignTo(value, _is64 ? 8 : 4);
246}
247
248
249size_t MachOFileLayout::headerAndLoadCommandsSize() const {
250 return _endOfLoadCommands;
251}
252
253MachOFileLayout::MachOFileLayout(const NormalizedFile &file)
254 : _file(file),
255 _is64(MachOLinkingContext::is64Bit(file.arch)),
256 _swap(!MachOLinkingContext::isHostEndian(file.arch)),
257 _bigEndianArch(MachOLinkingContext::isBigEndian(file.arch)),
258 _seg1addr(INT64_MAX) {
259 _startOfLoadCommands = _is64 ? sizeof(mach_header_64) : sizeof(mach_header);
260 const size_t segCommandBaseSize =
261 (_is64 ? sizeof(segment_command_64) : sizeof(segment_command));
262 const size_t sectsSize = (_is64 ? sizeof(section_64) : sizeof(section));
263 if (file.fileType == llvm::MachO::MH_OBJECT) {
264 // object files have just one segment load command containing all sections
265 _endOfLoadCommands = _startOfLoadCommands
266 + segCommandBaseSize
267 + file.sections.size() * sectsSize
268 + sizeof(symtab_command);
269 _countOfLoadCommands = 2;
270 if (file.hasMinVersionLoadCommand) {
271 _endOfLoadCommands += sizeof(version_min_command);
272 _countOfLoadCommands++;
273 }
274 if (!_file.functionStarts.empty()) {
275 _endOfLoadCommands += sizeof(linkedit_data_command);
276 _countOfLoadCommands++;
277 }
278 if (_file.generateDataInCodeLoadCommand) {
279 _endOfLoadCommands += sizeof(linkedit_data_command);
280 _countOfLoadCommands++;
281 }
282 // Assign file offsets to each section.
283 _startOfSectionsContent = _endOfLoadCommands;
284 unsigned relocCount = 0;
285 uint64_t offset = _startOfSectionsContent;
286 for (const Section &sect : file.sections) {
287 if (isZeroFillSection(sect.type))
288 _sectInfo[&sect].fileOffset = 0;
289 else {
290 offset = llvm::alignTo(offset, sect.alignment);
291 _sectInfo[&sect].fileOffset = offset;
292 offset += sect.content.size();
293 }
294 relocCount += sect.relocations.size();
295 }
296 _endOfSectionsContent = offset;
297
298 computeSymbolTableSizes();
299 computeFunctionStartsSize();
300 computeDataInCodeSize();
301
302 // Align start of relocations.
303 _startOfRelocations = pointerAlign(_endOfSectionsContent);
304 _startOfFunctionStarts = _startOfRelocations + relocCount * 8;
305 _startOfDataInCode = _startOfFunctionStarts + _functionStartsSize;
306 _startOfSymbols = _startOfDataInCode + _dataInCodeSize;
307 // Add Indirect symbol table.
308 _startOfIndirectSymbols = _startOfSymbols + _symbolTableSize;
309 // Align start of symbol table and symbol strings.
310 _startOfSymbolStrings = _startOfIndirectSymbols
311 + pointerAlign(_indirectSymbolTableCount * sizeof(uint32_t));
312 _endOfSymbolStrings = _startOfSymbolStrings
313 + pointerAlign(_symbolStringPoolSize);
314 _endOfLinkEdit = _endOfSymbolStrings;
315 DEBUG_WITH_TYPE("MachOFileLayout",
316 llvm::dbgs() << "MachOFileLayout()\n"
317 << " startOfLoadCommands=" << _startOfLoadCommands << "\n"
318 << " countOfLoadCommands=" << _countOfLoadCommands << "\n"
319 << " endOfLoadCommands=" << _endOfLoadCommands << "\n"
320 << " startOfRelocations=" << _startOfRelocations << "\n"
321 << " startOfSymbols=" << _startOfSymbols << "\n"
322 << " startOfSymbolStrings=" << _startOfSymbolStrings << "\n"
323 << " endOfSymbolStrings=" << _endOfSymbolStrings << "\n"
324 << " startOfSectionsContent=" << _startOfSectionsContent << "\n"
325 << " endOfSectionsContent=" << _endOfSectionsContent << "\n");
326 } else {
327 // Final linked images have one load command per segment.
328 _endOfLoadCommands = _startOfLoadCommands
329 + loadCommandsSize(_countOfLoadCommands);
330
331 // Assign section file offsets.
332 buildFileOffsets();
333 buildLinkEditInfo();
334
335 // LINKEDIT of final linked images has in order:
336 // rebase info, binding info, lazy binding info, weak binding info,
337 // data-in-code, symbol table, indirect symbol table, symbol table strings.
338 _startOfRebaseInfo = _startOfLinkEdit;
339 _endOfRebaseInfo = _startOfRebaseInfo + _rebaseInfo.size();
340 _startOfBindingInfo = _endOfRebaseInfo;
341 _endOfBindingInfo = _startOfBindingInfo + _bindingInfo.size();
342 _startOfLazyBindingInfo = _endOfBindingInfo;
343 _endOfLazyBindingInfo = _startOfLazyBindingInfo + _lazyBindingInfo.size();
344 _startOfExportTrie = _endOfLazyBindingInfo;
345 _endOfExportTrie = _startOfExportTrie + _exportTrie.size();
346 _startOfFunctionStarts = _endOfExportTrie;
347 _startOfDataInCode = _startOfFunctionStarts + _functionStartsSize;
348 _startOfSymbols = _startOfDataInCode + _dataInCodeSize;
349 _startOfIndirectSymbols = _startOfSymbols + _symbolTableSize;
350 _startOfSymbolStrings = _startOfIndirectSymbols
351 + pointerAlign(_indirectSymbolTableCount * sizeof(uint32_t));
352 _endOfSymbolStrings = _startOfSymbolStrings
353 + pointerAlign(_symbolStringPoolSize);
354 _endOfLinkEdit = _endOfSymbolStrings;
355 DEBUG_WITH_TYPE("MachOFileLayout",
356 llvm::dbgs() << "MachOFileLayout()\n"
357 << " startOfLoadCommands=" << _startOfLoadCommands << "\n"
358 << " countOfLoadCommands=" << _countOfLoadCommands << "\n"
359 << " endOfLoadCommands=" << _endOfLoadCommands << "\n"
360 << " startOfLinkEdit=" << _startOfLinkEdit << "\n"
361 << " startOfRebaseInfo=" << _startOfRebaseInfo << "\n"
362 << " endOfRebaseInfo=" << _endOfRebaseInfo << "\n"
363 << " startOfBindingInfo=" << _startOfBindingInfo << "\n"
364 << " endOfBindingInfo=" << _endOfBindingInfo << "\n"
365 << " startOfLazyBindingInfo=" << _startOfLazyBindingInfo << "\n"
366 << " endOfLazyBindingInfo=" << _endOfLazyBindingInfo << "\n"
367 << " startOfExportTrie=" << _startOfExportTrie << "\n"
368 << " endOfExportTrie=" << _endOfExportTrie << "\n"
369 << " startOfFunctionStarts=" << _startOfFunctionStarts << "\n"
370 << " startOfDataInCode=" << _startOfDataInCode << "\n"
371 << " startOfSymbols=" << _startOfSymbols << "\n"
372 << " startOfSymbolStrings=" << _startOfSymbolStrings << "\n"
373 << " endOfSymbolStrings=" << _endOfSymbolStrings << "\n"
374 << " addressOfLinkEdit=" << _addressOfLinkEdit << "\n");
375 }
376}
377
378uint32_t MachOFileLayout::loadCommandsSize(uint32_t &count) {
379 uint32_t size = 0;
380 count = 0;
381
382 const size_t segCommandSize =
383 (_is64 ? sizeof(segment_command_64) : sizeof(segment_command));
384 const size_t sectionSize = (_is64 ? sizeof(section_64) : sizeof(section));
385
386 // Add LC_SEGMENT for each segment.
387 size += _file.segments.size() * segCommandSize;
388 count += _file.segments.size();
389 // Add section record for each section.
390 size += _file.sections.size() * sectionSize;
391
392 // If creating a dylib, add LC_ID_DYLIB.
393 if (_file.fileType == llvm::MachO::MH_DYLIB) {
394 size += sizeof(dylib_command) + pointerAlign(_file.installName.size() + 1);
395 ++count;
396 }
397
398 // Add LC_DYLD_INFO
399 size += sizeof(dyld_info_command);
400 ++count;
401
402 // Add LC_SYMTAB
403 size += sizeof(symtab_command);
404 ++count;
405
406 // Add LC_DYSYMTAB
407 if (_file.fileType != llvm::MachO::MH_PRELOAD) {
408 size += sizeof(dysymtab_command);
409 ++count;
410 }
411
412 // If main executable add LC_LOAD_DYLINKER
413 if (_file.fileType == llvm::MachO::MH_EXECUTE) {
414 size += pointerAlign(sizeof(dylinker_command) + dyldPath().size()+1);
415 ++count;
416 }
417
418 // Add LC_VERSION_MIN_MACOSX, LC_VERSION_MIN_IPHONEOS, LC_VERSION_MIN_WATCHOS,
419 // LC_VERSION_MIN_TVOS
420 if (_file.hasMinVersionLoadCommand) {
421 size += sizeof(version_min_command);
422 ++count;
423 }
424
425 // Add LC_SOURCE_VERSION
426 size += sizeof(source_version_command);
427 ++count;
428
429 // If main executable add LC_MAIN
430 if (_file.fileType == llvm::MachO::MH_EXECUTE) {
431 size += sizeof(entry_point_command);
432 ++count;
433 }
434
435 // Add LC_LOAD_DYLIB for each dependent dylib.
436 for (const DependentDylib &dep : _file.dependentDylibs) {
437 size += sizeof(dylib_command) + pointerAlign(dep.path.size()+1);
438 ++count;
439 }
440
441 // Add LC_RPATH
442 for (const StringRef &path : _file.rpaths) {
443 size += pointerAlign(sizeof(rpath_command) + path.size() + 1);
444 ++count;
445 }
446
447 // Add LC_FUNCTION_STARTS if needed
448 if (!_file.functionStarts.empty()) {
449 size += sizeof(linkedit_data_command);
450 ++count;
451 }
452
453 // Add LC_DATA_IN_CODE if requested. Note, we do encode zero length entries.
454 // FIXME: Zero length entries is only to match ld64. Should we change this?
455 if (_file.generateDataInCodeLoadCommand) {
456 size += sizeof(linkedit_data_command);
457 ++count;
458 }
459
460 return size;
461}
462
463static bool overlaps(const Segment &s1, const Segment &s2) {
464 if (s2.address >= s1.address+s1.size)
465 return false;
466 if (s1.address >= s2.address+s2.size)
467 return false;
468 return true;
469}
470
471static bool overlaps(const Section &s1, const Section &s2) {
472 if (s2.address >= s1.address+s1.content.size())
473 return false;
474 if (s1.address >= s2.address+s2.content.size())
475 return false;
476 return true;
477}
478
479void MachOFileLayout::buildFileOffsets() {
480 // Verify no segments overlap
481 for (const Segment &sg1 : _file.segments) {
482 for (const Segment &sg2 : _file.segments) {
483 if (&sg1 == &sg2)
484 continue;
485 if (overlaps(sg1,sg2)) {
486 _ec = make_error_code(llvm::errc::executable_format_error);
487 return;
488 }
489 }
490 }
491
492 // Verify no sections overlap
493 for (const Section &s1 : _file.sections) {
494 for (const Section &s2 : _file.sections) {
495 if (&s1 == &s2)
496 continue;
497 if (overlaps(s1,s2)) {
498 _ec = make_error_code(llvm::errc::executable_format_error);
499 return;
500 }
501 }
502 }
503
504 // Build side table of extra info about segments and sections.
505 SegExtraInfo t;
506 t.fileOffset = 0;
507 for (const Segment &sg : _file.segments) {
508 _segInfo[&sg] = t;
509 }
510 SectionExtraInfo t2;
511 t2.fileOffset = 0;
512 // Assign sections to segments.
513 for (const Section &s : _file.sections) {
514 _sectInfo[&s] = t2;
515 bool foundSegment = false;
516 for (const Segment &sg : _file.segments) {
517 if (sg.name.equals(s.segmentName)) {
518 if ((s.address >= sg.address)
519 && (s.address+s.content.size() <= sg.address+sg.size)) {
520 _segInfo[&sg].sections.push_back(&s);
521 foundSegment = true;
522 break;
523 }
524 }
525 }
526 if (!foundSegment) {
527 _ec = make_error_code(llvm::errc::executable_format_error);
528 return;
529 }
530 }
531
532 // Assign file offsets.
533 uint32_t fileOffset = 0;
534 DEBUG_WITH_TYPE("MachOFileLayout",
535 llvm::dbgs() << "buildFileOffsets()\n");
536 for (const Segment &sg : _file.segments) {
537 _segInfo[&sg].fileOffset = fileOffset;
538 if ((_seg1addr == INT64_MAX) && sg.init_access)
539 _seg1addr = sg.address;
540 DEBUG_WITH_TYPE("MachOFileLayout",
541 llvm::dbgs() << " segment=" << sg.name
542 << ", fileOffset=" << _segInfo[&sg].fileOffset << "\n");
543
544 uint32_t segFileSize = 0;
545 // A segment that is not zero-fill must use a least one page of disk space.
546 if (sg.init_access)
547 segFileSize = _file.pageSize;
548 for (const Section *s : _segInfo[&sg].sections) {
549 uint32_t sectOffset = s->address - sg.address;
550 uint32_t sectFileSize =
551 isZeroFillSection(s->type) ? 0 : s->content.size();
552 segFileSize = std::max(segFileSize, sectOffset + sectFileSize);
553
554 _sectInfo[s].fileOffset = _segInfo[&sg].fileOffset + sectOffset;
555 DEBUG_WITH_TYPE("MachOFileLayout",
556 llvm::dbgs() << " section=" << s->sectionName
557 << ", fileOffset=" << fileOffset << "\n");
558 }
559
560 // round up all segments to page aligned, except __LINKEDIT
561 if (!sg.name.equals("__LINKEDIT")) {
562 _segInfo[&sg].fileSize = llvm::alignTo(segFileSize, _file.pageSize);
563 fileOffset = llvm::alignTo(fileOffset + segFileSize, _file.pageSize);
564 }
565 _addressOfLinkEdit = sg.address + sg.size;
566 }
567 _startOfLinkEdit = fileOffset;
568}
569
570size_t MachOFileLayout::size() const {
571 return _endOfSymbolStrings;
572}
573
574void MachOFileLayout::writeMachHeader() {
575 auto cpusubtype = MachOLinkingContext::cpuSubtypeFromArch(_file.arch);
576 // dynamic x86 executables on newer OS version should also set the
577 // CPU_SUBTYPE_LIB64 mask in the CPU subtype.
578 // FIXME: Check that this is a dynamic executable, not a static one.
579 if (_file.fileType == llvm::MachO::MH_EXECUTE &&
580 cpusubtype == CPU_SUBTYPE_X86_64_ALL &&
581 _file.os == MachOLinkingContext::OS::macOSX) {
582 uint32_t version;
583 bool failed = MachOLinkingContext::parsePackedVersion("10.5", version);
584 if (!failed && _file.minOSverson >= version)
585 cpusubtype |= CPU_SUBTYPE_LIB64;
586 }
587
588 mach_header *mh = reinterpret_cast<mach_header*>(_buffer);
589 mh->magic = _is64 ? llvm::MachO::MH_MAGIC_64 : llvm::MachO::MH_MAGIC;
590 mh->cputype = MachOLinkingContext::cpuTypeFromArch(_file.arch);
591 mh->cpusubtype = cpusubtype;
592 mh->filetype = _file.fileType;
593 mh->ncmds = _countOfLoadCommands;
594 mh->sizeofcmds = _endOfLoadCommands - _startOfLoadCommands;
595 mh->flags = _file.flags;
596 if (_swap)
597 swapStruct(*mh);
598}
599
600uint32_t MachOFileLayout::indirectSymbolIndex(const Section &sect,
601 uint32_t &index) {
602 if (sect.indirectSymbols.empty())
603 return 0;
604 uint32_t result = index;
605 index += sect.indirectSymbols.size();
606 return result;
607}
608
609uint32_t MachOFileLayout::indirectSymbolElementSize(const Section &sect) {
610 if (sect.indirectSymbols.empty())
611 return 0;
612 if (sect.type != S_SYMBOL_STUBS)
613 return 0;
614 return sect.content.size() / sect.indirectSymbols.size();
615}
616
617template <typename T>
618llvm::Error MachOFileLayout::writeSingleSegmentLoadCommand(uint8_t *&lc) {
619 typename T::command* seg = reinterpret_cast<typename T::command*>(lc);
620 seg->cmd = T::LC;
621 seg->cmdsize = sizeof(typename T::command)
622 + _file.sections.size() * sizeof(typename T::section);
623 uint8_t *next = lc + seg->cmdsize;
624 memset(seg->segname, 0, 16);
625 seg->vmaddr = 0;
626 seg->vmsize = _file.sections.back().address
627 + _file.sections.back().content.size();
628 seg->fileoff = _endOfLoadCommands;
629 seg->filesize = _sectInfo[&_file.sections.back()].fileOffset +
630 _file.sections.back().content.size() -
631 _sectInfo[&_file.sections.front()].fileOffset;
632 seg->maxprot = VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE;
633 seg->initprot = VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE;
634 seg->nsects = _file.sections.size();
635 seg->flags = 0;
636 if (_swap)
637 swapStruct(*seg);
638 typename T::section *sout = reinterpret_cast<typename T::section*>
639 (lc+sizeof(typename T::command));
640 uint32_t relOffset = _startOfRelocations;
641 uint32_t indirectSymRunningIndex = 0;
642 for (const Section &sin : _file.sections) {
643 setString16(sin.sectionName, sout->sectname);
644 setString16(sin.segmentName, sout->segname);
645 sout->addr = sin.address;
646 sout->size = sin.content.size();
647 sout->offset = _sectInfo[&sin].fileOffset;
648 sout->align = llvm::Log2_32(sin.alignment);
649 sout->reloff = sin.relocations.empty() ? 0 : relOffset;
650 sout->nreloc = sin.relocations.size();
651 sout->flags = sin.type | sin.attributes;
652 sout->reserved1 = indirectSymbolIndex(sin, indirectSymRunningIndex);
653 sout->reserved2 = indirectSymbolElementSize(sin);
654 relOffset += sin.relocations.size() * sizeof(any_relocation_info);
655 if (_swap)
656 swapStruct(*sout);
657 ++sout;
658 }
659 lc = next;
660 return llvm::Error::success();
661}
662
663template <typename T>
664llvm::Error MachOFileLayout::writeSegmentLoadCommands(uint8_t *&lc) {
665 uint32_t indirectSymRunningIndex = 0;
666 for (const Segment &seg : _file.segments) {
667 // Link edit has no sections and a custom range of address, so handle it
668 // specially.
669 SegExtraInfo &segInfo = _segInfo[&seg];
670 if (seg.name.equals("__LINKEDIT")) {
671 size_t linkeditSize = _endOfLinkEdit - _startOfLinkEdit;
672 typename T::command* cmd = reinterpret_cast<typename T::command*>(lc);
673 cmd->cmd = T::LC;
674 cmd->cmdsize = sizeof(typename T::command);
675 uint8_t *next = lc + cmd->cmdsize;
676 setString16("__LINKEDIT", cmd->segname);
677 cmd->vmaddr = _addressOfLinkEdit;
678 cmd->vmsize = llvm::alignTo(linkeditSize, _file.pageSize);
679 cmd->fileoff = _startOfLinkEdit;
680 cmd->filesize = linkeditSize;
681 cmd->initprot = seg.init_access;
682 cmd->maxprot = seg.max_access;
683 cmd->nsects = 0;
684 cmd->flags = 0;
685 if (_swap)
686 swapStruct(*cmd);
687 lc = next;
688 continue;
689 }
690 // Write segment command with trailing sections.
691 typename T::command* cmd = reinterpret_cast<typename T::command*>(lc);
692 cmd->cmd = T::LC;
693 cmd->cmdsize = sizeof(typename T::command)
694 + segInfo.sections.size() * sizeof(typename T::section);
695 uint8_t *next = lc + cmd->cmdsize;
696 setString16(seg.name, cmd->segname);
697 cmd->vmaddr = seg.address;
698 cmd->vmsize = seg.size;
699 cmd->fileoff = segInfo.fileOffset;
700 cmd->filesize = segInfo.fileSize;
701 cmd->initprot = seg.init_access;
702 cmd->maxprot = seg.max_access;
703 cmd->nsects = segInfo.sections.size();
704 cmd->flags = 0;
705 if (_swap)
706 swapStruct(*cmd);
707 typename T::section *sect = reinterpret_cast<typename T::section*>
708 (lc+sizeof(typename T::command));
709 for (const Section *section : segInfo.sections) {
710 setString16(section->sectionName, sect->sectname);
711 setString16(section->segmentName, sect->segname);
712 sect->addr = section->address;
713 sect->size = section->content.size();
714 if (isZeroFillSection(section->type))
715 sect->offset = 0;
716 else
717 sect->offset = section->address - seg.address + segInfo.fileOffset;
718 sect->align = llvm::Log2_32(section->alignment);
719 sect->reloff = 0;
720 sect->nreloc = 0;
721 sect->flags = section->type | section->attributes;
722 sect->reserved1 = indirectSymbolIndex(*section, indirectSymRunningIndex);
723 sect->reserved2 = indirectSymbolElementSize(*section);
724 if (_swap)
725 swapStruct(*sect);
726 ++sect;
727 }
728 lc = reinterpret_cast<uint8_t*>(next);
729 }
730 return llvm::Error::success();
731}
732
733static void writeVersionMinLoadCommand(const NormalizedFile &_file,
734 bool _swap,
735 uint8_t *&lc) {
736 if (!_file.hasMinVersionLoadCommand)
737 return;
738 version_min_command *vm = reinterpret_cast<version_min_command*>(lc);
739 switch (_file.os) {
740 case MachOLinkingContext::OS::unknown:
741 vm->cmd = _file.minOSVersionKind;
742 vm->cmdsize = sizeof(version_min_command);
743 vm->version = _file.minOSverson;
744 vm->sdk = 0;
745 break;
746 case MachOLinkingContext::OS::macOSX:
747 vm->cmd = LC_VERSION_MIN_MACOSX;
748 vm->cmdsize = sizeof(version_min_command);
749 vm->version = _file.minOSverson;
750 vm->sdk = _file.sdkVersion;
751 break;
752 case MachOLinkingContext::OS::iOS:
753 case MachOLinkingContext::OS::iOS_simulator:
754 vm->cmd = LC_VERSION_MIN_IPHONEOS;
755 vm->cmdsize = sizeof(version_min_command);
756 vm->version = _file.minOSverson;
757 vm->sdk = _file.sdkVersion;
758 break;
759 }
760 if (_swap)
761 swapStruct(*vm);
762 lc += sizeof(version_min_command);
763}
764
765llvm::Error MachOFileLayout::writeLoadCommands() {
766 uint8_t *lc = &_buffer[_startOfLoadCommands];
767 if (_file.fileType == llvm::MachO::MH_OBJECT) {
768 // Object files have one unnamed segment which holds all sections.
769 if (_is64) {
770 if (auto ec = writeSingleSegmentLoadCommand<MachO64Trait>(lc))
771 return ec;
772 } else {
773 if (auto ec = writeSingleSegmentLoadCommand<MachO32Trait>(lc))
774 return ec;
775 }
776 // Add LC_SYMTAB with symbol table info
777 symtab_command* st = reinterpret_cast<symtab_command*>(lc);
778 st->cmd = LC_SYMTAB;
779 st->cmdsize = sizeof(symtab_command);
780 st->symoff = _startOfSymbols;
781 st->nsyms = _file.stabsSymbols.size() + _file.localSymbols.size() +
782 _file.globalSymbols.size() + _file.undefinedSymbols.size();
783 st->stroff = _startOfSymbolStrings;
784 st->strsize = _endOfSymbolStrings - _startOfSymbolStrings;
785 if (_swap)
786 swapStruct(*st);
787 lc += sizeof(symtab_command);
788
789 // Add LC_VERSION_MIN_MACOSX, LC_VERSION_MIN_IPHONEOS,
790 // LC_VERSION_MIN_WATCHOS, LC_VERSION_MIN_TVOS
791 writeVersionMinLoadCommand(_file, _swap, lc);
792
793 // Add LC_FUNCTION_STARTS if needed.
794 if (_functionStartsSize != 0) {
795 linkedit_data_command* dl = reinterpret_cast<linkedit_data_command*>(lc);
796 dl->cmd = LC_FUNCTION_STARTS;
797 dl->cmdsize = sizeof(linkedit_data_command);
798 dl->dataoff = _startOfFunctionStarts;
799 dl->datasize = _functionStartsSize;
800 if (_swap)
801 swapStruct(*dl);
802 lc += sizeof(linkedit_data_command);
803 }
804
805 // Add LC_DATA_IN_CODE if requested.
806 if (_file.generateDataInCodeLoadCommand) {
807 linkedit_data_command* dl = reinterpret_cast<linkedit_data_command*>(lc);
808 dl->cmd = LC_DATA_IN_CODE;
809 dl->cmdsize = sizeof(linkedit_data_command);
810 dl->dataoff = _startOfDataInCode;
811 dl->datasize = _dataInCodeSize;
812 if (_swap)
813 swapStruct(*dl);
814 lc += sizeof(linkedit_data_command);
815 }
816 } else {
817 // Final linked images have sections under segments.
818 if (_is64) {
819 if (auto ec = writeSegmentLoadCommands<MachO64Trait>(lc))
820 return ec;
821 } else {
822 if (auto ec = writeSegmentLoadCommands<MachO32Trait>(lc))
823 return ec;
824 }
825
826 // Add LC_ID_DYLIB command for dynamic libraries.
827 if (_file.fileType == llvm::MachO::MH_DYLIB) {
828 dylib_command *dc = reinterpret_cast<dylib_command*>(lc);
829 StringRef path = _file.installName;
830 uint32_t size = sizeof(dylib_command) + pointerAlign(path.size() + 1);
831 dc->cmd = LC_ID_DYLIB;
832 dc->cmdsize = size;
833 dc->dylib.name = sizeof(dylib_command); // offset
834 // needs to be some constant value different than the one in LC_LOAD_DYLIB
835 dc->dylib.timestamp = 1;
836 dc->dylib.current_version = _file.currentVersion;
837 dc->dylib.compatibility_version = _file.compatVersion;
838 if (_swap)
839 swapStruct(*dc);
840 memcpy(lc + sizeof(dylib_command), path.begin(), path.size());
841 lc[sizeof(dylib_command) + path.size()] = '\0';
842 lc += size;
843 }
844
845 // Add LC_DYLD_INFO_ONLY.
846 dyld_info_command* di = reinterpret_cast<dyld_info_command*>(lc);
847 di->cmd = LC_DYLD_INFO_ONLY;
848 di->cmdsize = sizeof(dyld_info_command);
849 di->rebase_off = _rebaseInfo.size() ? _startOfRebaseInfo : 0;
850 di->rebase_size = _rebaseInfo.size();
851 di->bind_off = _bindingInfo.size() ? _startOfBindingInfo : 0;
852 di->bind_size = _bindingInfo.size();
853 di->weak_bind_off = 0;
854 di->weak_bind_size = 0;
855 di->lazy_bind_off = _lazyBindingInfo.size() ? _startOfLazyBindingInfo : 0;
856 di->lazy_bind_size = _lazyBindingInfo.size();
857 di->export_off = _exportTrie.size() ? _startOfExportTrie : 0;
858 di->export_size = _exportTrie.size();
859 if (_swap)
860 swapStruct(*di);
861 lc += sizeof(dyld_info_command);
862
863 // Add LC_SYMTAB with symbol table info.
864 symtab_command* st = reinterpret_cast<symtab_command*>(lc);
865 st->cmd = LC_SYMTAB;
866 st->cmdsize = sizeof(symtab_command);
867 st->symoff = _startOfSymbols;
868 st->nsyms = _file.stabsSymbols.size() + _file.localSymbols.size() +
869 _file.globalSymbols.size() + _file.undefinedSymbols.size();
870 st->stroff = _startOfSymbolStrings;
871 st->strsize = _endOfSymbolStrings - _startOfSymbolStrings;
872 if (_swap)
873 swapStruct(*st);
874 lc += sizeof(symtab_command);
875
876 // Add LC_DYSYMTAB
877 if (_file.fileType != llvm::MachO::MH_PRELOAD) {
878 dysymtab_command* dst = reinterpret_cast<dysymtab_command*>(lc);
879 dst->cmd = LC_DYSYMTAB;
880 dst->cmdsize = sizeof(dysymtab_command);
881 dst->ilocalsym = _symbolTableLocalsStartIndex;
882 dst->nlocalsym = _file.stabsSymbols.size() +
883 _file.localSymbols.size();
884 dst->iextdefsym = _symbolTableGlobalsStartIndex;
885 dst->nextdefsym = _file.globalSymbols.size();
886 dst->iundefsym = _symbolTableUndefinesStartIndex;
887 dst->nundefsym = _file.undefinedSymbols.size();
888 dst->tocoff = 0;
889 dst->ntoc = 0;
890 dst->modtaboff = 0;
891 dst->nmodtab = 0;
892 dst->extrefsymoff = 0;
893 dst->nextrefsyms = 0;
894 dst->indirectsymoff = _startOfIndirectSymbols;
895 dst->nindirectsyms = _indirectSymbolTableCount;
896 dst->extreloff = 0;
897 dst->nextrel = 0;
898 dst->locreloff = 0;
899 dst->nlocrel = 0;
900 if (_swap)
901 swapStruct(*dst);
902 lc += sizeof(dysymtab_command);
903 }
904
905 // If main executable, add LC_LOAD_DYLINKER
906 if (_file.fileType == llvm::MachO::MH_EXECUTE) {
907 // Build LC_LOAD_DYLINKER load command.
908 uint32_t size=pointerAlign(sizeof(dylinker_command)+dyldPath().size()+1);
909 dylinker_command* dl = reinterpret_cast<dylinker_command*>(lc);
910 dl->cmd = LC_LOAD_DYLINKER;
911 dl->cmdsize = size;
912 dl->name = sizeof(dylinker_command); // offset
913 if (_swap)
914 swapStruct(*dl);
915 memcpy(lc+sizeof(dylinker_command), dyldPath().data(), dyldPath().size());
916 lc[sizeof(dylinker_command)+dyldPath().size()] = '\0';
917 lc += size;
918 }
919
920 // Add LC_VERSION_MIN_MACOSX, LC_VERSION_MIN_IPHONEOS, LC_VERSION_MIN_WATCHOS,
921 // LC_VERSION_MIN_TVOS
922 writeVersionMinLoadCommand(_file, _swap, lc);
923
924 // Add LC_SOURCE_VERSION
925 {
926 // Note, using a temporary here to appease UB as we may not be aligned
927 // enough for a struct containing a uint64_t when emitting a 32-bit binary
928 source_version_command sv;
929 sv.cmd = LC_SOURCE_VERSION;
930 sv.cmdsize = sizeof(source_version_command);
931 sv.version = _file.sourceVersion;
932 if (_swap)
933 swapStruct(sv);
934 memcpy(lc, &sv, sizeof(source_version_command));
935 lc += sizeof(source_version_command);
936 }
937
938 // If main executable, add LC_MAIN.
939 if (_file.fileType == llvm::MachO::MH_EXECUTE) {
940 // Build LC_MAIN load command.
941 // Note, using a temporary here to appease UB as we may not be aligned
942 // enough for a struct containing a uint64_t when emitting a 32-bit binary
943 entry_point_command ep;
944 ep.cmd = LC_MAIN;
945 ep.cmdsize = sizeof(entry_point_command);
946 ep.entryoff = _file.entryAddress - _seg1addr;
947 ep.stacksize = _file.stackSize;
948 if (_swap)
949 swapStruct(ep);
950 memcpy(lc, &ep, sizeof(entry_point_command));
951 lc += sizeof(entry_point_command);
952 }
953
954 // Add LC_LOAD_DYLIB commands
955 for (const DependentDylib &dep : _file.dependentDylibs) {
956 dylib_command* dc = reinterpret_cast<dylib_command*>(lc);
957 uint32_t size = sizeof(dylib_command) + pointerAlign(dep.path.size()+1);
958 dc->cmd = dep.kind;
959 dc->cmdsize = size;
960 dc->dylib.name = sizeof(dylib_command); // offset
961 // needs to be some constant value different than the one in LC_ID_DYLIB
962 dc->dylib.timestamp = 2;
963 dc->dylib.current_version = dep.currentVersion;
964 dc->dylib.compatibility_version = dep.compatVersion;
965 if (_swap)
966 swapStruct(*dc);
967 memcpy(lc+sizeof(dylib_command), dep.path.begin(), dep.path.size());
968 lc[sizeof(dylib_command)+dep.path.size()] = '\0';
969 lc += size;
970 }
971
972 // Add LC_RPATH
973 for (const StringRef &path : _file.rpaths) {
974 rpath_command *rpc = reinterpret_cast<rpath_command *>(lc);
975 uint32_t size = pointerAlign(sizeof(rpath_command) + path.size() + 1);
976 rpc->cmd = LC_RPATH;
977 rpc->cmdsize = size;
978 rpc->path = sizeof(rpath_command); // offset
979 if (_swap)
980 swapStruct(*rpc);
981 memcpy(lc+sizeof(rpath_command), path.begin(), path.size());
982 lc[sizeof(rpath_command)+path.size()] = '\0';
983 lc += size;
984 }
985
986 // Add LC_FUNCTION_STARTS if needed.
987 if (_functionStartsSize != 0) {
988 linkedit_data_command* dl = reinterpret_cast<linkedit_data_command*>(lc);
989 dl->cmd = LC_FUNCTION_STARTS;
990 dl->cmdsize = sizeof(linkedit_data_command);
991 dl->dataoff = _startOfFunctionStarts;
992 dl->datasize = _functionStartsSize;
993 if (_swap)
994 swapStruct(*dl);
995 lc += sizeof(linkedit_data_command);
996 }
997
998 // Add LC_DATA_IN_CODE if requested.
999 if (_file.generateDataInCodeLoadCommand) {
1000 linkedit_data_command* dl = reinterpret_cast<linkedit_data_command*>(lc);
1001 dl->cmd = LC_DATA_IN_CODE;
1002 dl->cmdsize = sizeof(linkedit_data_command);
1003 dl->dataoff = _startOfDataInCode;
1004 dl->datasize = _dataInCodeSize;
1005 if (_swap)
1006 swapStruct(*dl);
1007 lc += sizeof(linkedit_data_command);
1008 }
1009 }
1010 return llvm::Error::success();
1011}
1012
1013void MachOFileLayout::writeSectionContent() {
1014 for (const Section &s : _file.sections) {
1015 // Copy all section content to output buffer.
1016 if (isZeroFillSection(s.type))
1017 continue;
1018 if (s.content.empty())
1019 continue;
1020 uint32_t offset = _sectInfo[&s].fileOffset;
1021 uint8_t *p = &_buffer[offset];
1022 memcpy(p, &s.content[0], s.content.size());
1023 p += s.content.size();
1024 }
1025}
1026
1027void MachOFileLayout::writeRelocations() {
1028 uint32_t relOffset = _startOfRelocations;
1029 for (Section sect : _file.sections) {
1030 for (Relocation r : sect.relocations) {
1031 any_relocation_info* rb = reinterpret_cast<any_relocation_info*>(
1032 &_buffer[relOffset]);
1033 *rb = packRelocation(r, _swap, _bigEndianArch);
1034 relOffset += sizeof(any_relocation_info);
1035 }
1036 }
1037}
1038
1039void MachOFileLayout::appendSymbols(const std::vector<Symbol> &symbols,
1040 uint32_t &symOffset, uint32_t &strOffset) {
1041 for (const Symbol &sym : symbols) {
1042 if (_is64) {
1043 nlist_64* nb = reinterpret_cast<nlist_64*>(&_buffer[symOffset]);
1044 nb->n_strx = strOffset - _startOfSymbolStrings;
1045 nb->n_type = sym.type | sym.scope;
1046 nb->n_sect = sym.sect;
1047 nb->n_desc = sym.desc;
1048 nb->n_value = sym.value;
1049 if (_swap)
1050 swapStruct(*nb);
1051 symOffset += sizeof(nlist_64);
1052 } else {
1053 nlist* nb = reinterpret_cast<nlist*>(&_buffer[symOffset]);
1054 nb->n_strx = strOffset - _startOfSymbolStrings;
1055 nb->n_type = sym.type | sym.scope;
1056 nb->n_sect = sym.sect;
1057 nb->n_desc = sym.desc;
1058 nb->n_value = sym.value;
1059 if (_swap)
1060 swapStruct(*nb);
1061 symOffset += sizeof(nlist);
1062 }
1063 memcpy(&_buffer[strOffset], sym.name.begin(), sym.name.size());
1064 strOffset += sym.name.size();
1065 _buffer[strOffset++] ='\0'; // Strings in table have nul terminator.
1066 }
1067}
1068
1069void MachOFileLayout::writeFunctionStartsInfo() {
1070 if (!_functionStartsSize)
1071 return;
1072 memcpy(&_buffer[_startOfFunctionStarts], _file.functionStarts.data(),
1073 _functionStartsSize);
1074}
1075
1076void MachOFileLayout::writeDataInCodeInfo() {
1077 uint32_t offset = _startOfDataInCode;
1078 for (const DataInCode &entry : _file.dataInCode) {
1079 data_in_code_entry *dst = reinterpret_cast<data_in_code_entry*>(
1080 &_buffer[offset]);
1081 dst->offset = entry.offset;
1082 dst->length = entry.length;
1083 dst->kind = entry.kind;
1084 if (_swap)
1085 swapStruct(*dst);
1086 offset += sizeof(data_in_code_entry);
1087 }
1088}
1089
1090void MachOFileLayout::writeSymbolTable() {
1091 // Write symbol table and symbol strings in parallel.
1092 uint32_t symOffset = _startOfSymbols;
1093 uint32_t strOffset = _startOfSymbolStrings;
1094 // Reserve n_strx offset of zero to mean no name.
1095 _buffer[strOffset++] = ' ';
1096 _buffer[strOffset++] = '\0';
1097 appendSymbols(_file.stabsSymbols, symOffset, strOffset);
1098 appendSymbols(_file.localSymbols, symOffset, strOffset);
1099 appendSymbols(_file.globalSymbols, symOffset, strOffset);
1100 appendSymbols(_file.undefinedSymbols, symOffset, strOffset);
1101 // Write indirect symbol table array.
1102 uint32_t *indirects = reinterpret_cast<uint32_t*>
1103 (&_buffer[_startOfIndirectSymbols]);
1104 if (_file.fileType == llvm::MachO::MH_OBJECT) {
1105 // Object files have sections in same order as input normalized file.
1106 for (const Section &section : _file.sections) {
1107 for (uint32_t index : section.indirectSymbols) {
1108 if (_swap)
1109 *indirects++ = llvm::sys::getSwappedBytes(index);
1110 else
1111 *indirects++ = index;
1112 }
1113 }
1114 } else {
1115 // Final linked images must sort sections from normalized file.
1116 for (const Segment &seg : _file.segments) {
1117 SegExtraInfo &segInfo = _segInfo[&seg];
1118 for (const Section *section : segInfo.sections) {
1119 for (uint32_t index : section->indirectSymbols) {
1120 if (_swap)
1121 *indirects++ = llvm::sys::getSwappedBytes(index);
1122 else
1123 *indirects++ = index;
1124 }
1125 }
1126 }
1127 }
1128}
1129
1130void MachOFileLayout::writeRebaseInfo() {
1131 memcpy(&_buffer[_startOfRebaseInfo], _rebaseInfo.bytes(), _rebaseInfo.size());
1132}
1133
1134void MachOFileLayout::writeBindingInfo() {
1135 memcpy(&_buffer[_startOfBindingInfo],
1136 _bindingInfo.bytes(), _bindingInfo.size());
1137}
1138
1139void MachOFileLayout::writeLazyBindingInfo() {
1140 memcpy(&_buffer[_startOfLazyBindingInfo],
1141 _lazyBindingInfo.bytes(), _lazyBindingInfo.size());
1142}
1143
1144void MachOFileLayout::writeExportInfo() {
1145 memcpy(&_buffer[_startOfExportTrie], _exportTrie.bytes(), _exportTrie.size());
1146}
1147
1148void MachOFileLayout::buildLinkEditInfo() {
1149 buildRebaseInfo();
1150 buildBindInfo();
1151 buildLazyBindInfo();
1152 buildExportTrie();
1153 computeSymbolTableSizes();
1154 computeFunctionStartsSize();
1155 computeDataInCodeSize();
1156}
1157
1158void MachOFileLayout::buildSectionRelocations() {
1159
1160}
1161
1162void MachOFileLayout::buildRebaseInfo() {
1163 // TODO: compress rebasing info.
1164 for (const RebaseLocation& entry : _file.rebasingInfo) {
1165 _rebaseInfo.append_byte(REBASE_OPCODE_SET_TYPE_IMM | entry.kind);
1166 _rebaseInfo.append_byte(REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
1167 | entry.segIndex);
1168 _rebaseInfo.append_uleb128(entry.segOffset);
1169 _rebaseInfo.append_uleb128(REBASE_OPCODE_DO_REBASE_IMM_TIMES | 1);
1170 }
1171 _rebaseInfo.append_byte(REBASE_OPCODE_DONE);
1172 _rebaseInfo.align(_is64 ? 8 : 4);
1173}
1174
1175void MachOFileLayout::buildBindInfo() {
1176 // TODO: compress bind info.
1177 uint64_t lastAddend = 0;
1178 int lastOrdinal = 0x80000000;
1179 StringRef lastSymbolName;
1180 BindType lastType = (BindType)0;
1181 Hex32 lastSegOffset = ~0U;
1182 uint8_t lastSegIndex = (uint8_t)~0U;
1183 for (const BindLocation& entry : _file.bindingInfo) {
1184 if (entry.ordinal != lastOrdinal) {
1185 if (entry.ordinal <= 0)
1186 _bindingInfo.append_byte(BIND_OPCODE_SET_DYLIB_SPECIAL_IMM |
1187 (entry.ordinal & BIND_IMMEDIATE_MASK));
1188 else if (entry.ordinal <= BIND_IMMEDIATE_MASK)
1189 _bindingInfo.append_byte(BIND_OPCODE_SET_DYLIB_ORDINAL_IMM |
1190 entry.ordinal);
1191 else {
1192 _bindingInfo.append_byte(BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB);
1193 _bindingInfo.append_uleb128(entry.ordinal);
1194 }
1195 lastOrdinal = entry.ordinal;
1196 }
1197
1198 if (lastSymbolName != entry.symbolName) {
1199 _bindingInfo.append_byte(BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM);
1200 _bindingInfo.append_string(entry.symbolName);
1201 lastSymbolName = entry.symbolName;
1202 }
1203
1204 if (lastType != entry.kind) {
1205 _bindingInfo.append_byte(BIND_OPCODE_SET_TYPE_IMM | entry.kind);
1206 lastType = entry.kind;
1207 }
1208
1209 if (lastSegIndex != entry.segIndex || lastSegOffset != entry.segOffset) {
1210 _bindingInfo.append_byte(BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
1211 | entry.segIndex);
1212 _bindingInfo.append_uleb128(entry.segOffset);
1213 lastSegIndex = entry.segIndex;
1214 lastSegOffset = entry.segOffset;
1215 }
1216 if (entry.addend != lastAddend) {
1217 _bindingInfo.append_byte(BIND_OPCODE_SET_ADDEND_SLEB);
1218 _bindingInfo.append_sleb128(entry.addend);
1219 lastAddend = entry.addend;
1220 }
1221 _bindingInfo.append_byte(BIND_OPCODE_DO_BIND);
1222 }
1223 _bindingInfo.append_byte(BIND_OPCODE_DONE);
1224 _bindingInfo.align(_is64 ? 8 : 4);
1225}
1226
1227void MachOFileLayout::buildLazyBindInfo() {
1228 for (const BindLocation& entry : _file.lazyBindingInfo) {
1229 _lazyBindingInfo.append_byte(BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
1230 | entry.segIndex);
1231 _lazyBindingInfo.append_uleb128(entry.segOffset);
1232 if (entry.ordinal <= 0)
1233 _lazyBindingInfo.append_byte(BIND_OPCODE_SET_DYLIB_SPECIAL_IMM |
1234 (entry.ordinal & BIND_IMMEDIATE_MASK));
1235 else if (entry.ordinal <= BIND_IMMEDIATE_MASK)
1236 _lazyBindingInfo.append_byte(BIND_OPCODE_SET_DYLIB_ORDINAL_IMM |
1237 entry.ordinal);
1238 else {
1239 _lazyBindingInfo.append_byte(BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB);
1240 _lazyBindingInfo.append_uleb128(entry.ordinal);
1241 }
1242 // FIXME: We need to | the opcode here with flags.
1243 _lazyBindingInfo.append_byte(BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM);
1244 _lazyBindingInfo.append_string(entry.symbolName);
1245 _lazyBindingInfo.append_byte(BIND_OPCODE_DO_BIND);
1246 _lazyBindingInfo.append_byte(BIND_OPCODE_DONE);
1247 }
1248 _lazyBindingInfo.align(_is64 ? 8 : 4);
1249}
1250
1251void TrieNode::addSymbol(const Export& entry,
1252 BumpPtrAllocator &allocator,
1253 std::vector<TrieNode*> &allNodes) {
1254 StringRef partialStr = entry.name.drop_front(_cummulativeString.size());
1255 for (TrieEdge &edge : _children) {
1256 StringRef edgeStr = edge._subString;
1257 if (partialStr.startswith(edgeStr)) {
1258 // Already have matching edge, go down that path.
1259 edge._child->addSymbol(entry, allocator, allNodes);
1260 return;
1261 }
1262 // See if string has commmon prefix with existing edge.
1263 for (int n=edgeStr.size()-1; n > 0; --n) {
1264 if (partialStr.substr(0, n).equals(edgeStr.substr(0, n))) {
1265 // Splice in new node: was A -> C, now A -> B -> C
1266 StringRef bNodeStr = edge._child->_cummulativeString;
1267 bNodeStr = bNodeStr.drop_back(edgeStr.size()-n).copy(allocator);
1268 auto *bNode = new (allocator) TrieNode(bNodeStr);
1269 allNodes.push_back(bNode);
1270 TrieNode* cNode = edge._child;
1271 StringRef abEdgeStr = edgeStr.substr(0,n).copy(allocator);
1272 StringRef bcEdgeStr = edgeStr.substr(n).copy(allocator);
1273 DEBUG_WITH_TYPE("trie-builder", llvm::dbgs()
1274 << "splice in TrieNode('" << bNodeStr
1275 << "') between edge '"
1276 << abEdgeStr << "' and edge='"
1277 << bcEdgeStr<< "'\n");
1278 TrieEdge& abEdge = edge;
1279 abEdge._subString = abEdgeStr;
1280 abEdge._child = bNode;
1281 auto *bcEdge = new (allocator) TrieEdge(bcEdgeStr, cNode);
1282 bNode->_children.insert(bNode->_children.end(), bcEdge);
1283 bNode->addSymbol(entry, allocator, allNodes);
1284 return;
1285 }
1286 }
1287 }
1288 if (entry.flags & EXPORT_SYMBOL_FLAGS_REEXPORT) {
1289 assert(entry.otherOffset != 0);
1290 }
1291 if (entry.flags & EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER) {
1292 assert(entry.otherOffset != 0);
1293 }
1294 // No commonality with any existing child, make a new edge.
1295 auto *newNode = new (allocator) TrieNode(entry.name.copy(allocator));
1296 auto *newEdge = new (allocator) TrieEdge(partialStr, newNode);
1297 _children.insert(_children.end(), newEdge);
1298 DEBUG_WITH_TYPE("trie-builder", llvm::dbgs()
1299 << "new TrieNode('" << entry.name << "') with edge '"
1300 << partialStr << "' from node='"
1301 << _cummulativeString << "'\n");
1302 newNode->_address = entry.offset;
1303 newNode->_flags = entry.flags | entry.kind;
1304 newNode->_other = entry.otherOffset;
1305 if ((entry.flags & EXPORT_SYMBOL_FLAGS_REEXPORT) && !entry.otherName.empty())
1306 newNode->_importedName = entry.otherName.copy(allocator);
1307 newNode->_hasExportInfo = true;
1308 allNodes.push_back(newNode);
1309}
1310
1311void TrieNode::addOrderedNodes(const Export& entry,
1312 std::vector<TrieNode*> &orderedNodes) {
1313 if (!_ordered) {
1314 orderedNodes.push_back(this);
1315 _ordered = true;
1316 }
1317
1318 StringRef partialStr = entry.name.drop_front(_cummulativeString.size());
1319 for (TrieEdge &edge : _children) {
1320 StringRef edgeStr = edge._subString;
1321 if (partialStr.startswith(edgeStr)) {
1322 // Already have matching edge, go down that path.
1323 edge._child->addOrderedNodes(entry, orderedNodes);
1324 return;
1325 }
1326 }
1327}
1328
1329bool TrieNode::updateOffset(uint32_t& offset) {
1330 uint32_t nodeSize = 1; // Length when no export info
1331 if (_hasExportInfo) {
1332 if (_flags & EXPORT_SYMBOL_FLAGS_REEXPORT) {
1333 nodeSize = llvm::getULEB128Size(_flags);
1334 nodeSize += llvm::getULEB128Size(_other); // Other contains ordinal.
1335 nodeSize += _importedName.size();
1336 ++nodeSize; // Trailing zero in imported name.
1337 } else {
1338 nodeSize = llvm::getULEB128Size(_flags) + llvm::getULEB128Size(_address);
1339 if (_flags & EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER)
1340 nodeSize += llvm::getULEB128Size(_other);
1341 }
1342 // Overall node size so far is uleb128 of export info + actual export info.
1343 nodeSize += llvm::getULEB128Size(nodeSize);
1344 }
1345 // Compute size of all child edges.
1346 ++nodeSize; // Byte for number of chidren.
1347 for (TrieEdge &edge : _children) {
1348 nodeSize += edge._subString.size() + 1 // String length.
1349 + llvm::getULEB128Size(edge._child->_trieOffset); // Offset len.
1350 }
1351 // On input, 'offset' is new prefered location for this node.
1352 bool result = (_trieOffset != offset);
1353 // Store new location in node object for use by parents.
1354 _trieOffset = offset;
1355 // Update offset for next iteration.
1356 offset += nodeSize;
1357 // Return true if _trieOffset was changed.
1358 return result;
1359}
1360
1361void TrieNode::appendToByteBuffer(ByteBuffer &out) {
1362 if (_hasExportInfo) {
1363 if (_flags & EXPORT_SYMBOL_FLAGS_REEXPORT) {
1364 if (!_importedName.empty()) {
1365 // nodes with re-export info: size, flags, ordinal, import-name
1366 uint32_t nodeSize = llvm::getULEB128Size(_flags)
1367 + llvm::getULEB128Size(_other)
1368 + _importedName.size() + 1;
1369 assert(nodeSize < 256);
1370 out.append_byte(nodeSize);
1371 out.append_uleb128(_flags);
1372 out.append_uleb128(_other);
1373 out.append_string(_importedName);
1374 } else {
1375 // nodes without re-export info: size, flags, ordinal, empty-string
1376 uint32_t nodeSize = llvm::getULEB128Size(_flags)
1377 + llvm::getULEB128Size(_other) + 1;
1378 assert(nodeSize < 256);
1379 out.append_byte(nodeSize);
1380 out.append_uleb128(_flags);
1381 out.append_uleb128(_other);
1382 out.append_byte(0);
1383 }
1384 } else if ( _flags & EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER ) {
1385 // Nodes with export info: size, flags, address, other
1386 uint32_t nodeSize = llvm::getULEB128Size(_flags)
1387 + llvm::getULEB128Size(_address)
1388 + llvm::getULEB128Size(_other);
1389 assert(nodeSize < 256);
1390 out.append_byte(nodeSize);
1391 out.append_uleb128(_flags);
1392 out.append_uleb128(_address);
1393 out.append_uleb128(_other);
1394 } else {
1395 // Nodes with export info: size, flags, address
1396 uint32_t nodeSize = llvm::getULEB128Size(_flags)
1397 + llvm::getULEB128Size(_address);
1398 assert(nodeSize < 256);
1399 out.append_byte(nodeSize);
1400 out.append_uleb128(_flags);
1401 out.append_uleb128(_address);
1402 }
1403 } else {
1404 // Node with no export info.
1405 uint32_t nodeSize = 0;
1406 out.append_byte(nodeSize);
1407 }
1408 // Add number of children.
1409 assert(_children.size() < 256);
1410 out.append_byte(_children.size());
1411 // Append each child edge substring and node offset.
1412 for (TrieEdge &edge : _children) {
1413 out.append_string(edge._subString);
1414 out.append_uleb128(edge._child->_trieOffset);
1415 }
1416}
1417
1418void MachOFileLayout::buildExportTrie() {
1419 if (_file.exportInfo.empty())
1420 return;
1421
1422 // For all temporary strings and objects used building trie.
1423 BumpPtrAllocator allocator;
1424
1425 // Build trie of all exported symbols.
1426 auto *rootNode = new (allocator) TrieNode(StringRef());
1427 std::vector<TrieNode*> allNodes;
1428 allNodes.reserve(_file.exportInfo.size()*2);
1429 allNodes.push_back(rootNode);
1430 for (const Export& entry : _file.exportInfo) {
1431 rootNode->addSymbol(entry, allocator, allNodes);
1432 }
1433
1434 std::vector<TrieNode*> orderedNodes;
1435 orderedNodes.reserve(allNodes.size());
1436
1437 for (const Export& entry : _file.exportInfo)
1438 rootNode->addOrderedNodes(entry, orderedNodes);
1439
1440 // Assign each node in the vector an offset in the trie stream, iterating
1441 // until all uleb128 sizes have stabilized.
1442 bool more;
1443 do {
1444 uint32_t offset = 0;
1445 more = false;
1446 for (TrieNode* node : orderedNodes) {
1447 if (node->updateOffset(offset))
1448 more = true;
1449 }
1450 } while (more);
1451
1452 // Serialize trie to ByteBuffer.
1453 for (TrieNode* node : orderedNodes) {
1454 node->appendToByteBuffer(_exportTrie);
1455 }
1456 _exportTrie.align(_is64 ? 8 : 4);
1457}
1458
1459void MachOFileLayout::computeSymbolTableSizes() {
1460 // MachO symbol tables have three ranges: locals, globals, and undefines
1461 const size_t nlistSize = (_is64 ? sizeof(nlist_64) : sizeof(nlist));
1462 _symbolTableSize = nlistSize * (_file.stabsSymbols.size()
1463 + _file.localSymbols.size()
1464 + _file.globalSymbols.size()
1465 + _file.undefinedSymbols.size());
1466 // Always reserve 1-byte for the empty string and 1-byte for its terminator.
1467 _symbolStringPoolSize = 2;
1468 for (const Symbol &sym : _file.stabsSymbols) {
1469 _symbolStringPoolSize += (sym.name.size()+1);
1470 }
1471 for (const Symbol &sym : _file.localSymbols) {
1472 _symbolStringPoolSize += (sym.name.size()+1);
1473 }
1474 for (const Symbol &sym : _file.globalSymbols) {
1475 _symbolStringPoolSize += (sym.name.size()+1);
1476 }
1477 for (const Symbol &sym : _file.undefinedSymbols) {
1478 _symbolStringPoolSize += (sym.name.size()+1);
1479 }
1480 _symbolTableLocalsStartIndex = 0;
1481 _symbolTableGlobalsStartIndex = _file.stabsSymbols.size() +
1482 _file.localSymbols.size();
1483 _symbolTableUndefinesStartIndex = _symbolTableGlobalsStartIndex
1484 + _file.globalSymbols.size();
1485
1486 _indirectSymbolTableCount = 0;
1487 for (const Section &sect : _file.sections) {
1488 _indirectSymbolTableCount += sect.indirectSymbols.size();
1489 }
1490}
1491
1492void MachOFileLayout::computeFunctionStartsSize() {
1493 _functionStartsSize = _file.functionStarts.size();
1494}
1495
1496void MachOFileLayout::computeDataInCodeSize() {
1497 _dataInCodeSize = _file.dataInCode.size() * sizeof(data_in_code_entry);
1498}
1499
1500void MachOFileLayout::writeLinkEditContent() {
1501 if (_file.fileType == llvm::MachO::MH_OBJECT) {
1502 writeRelocations();
1503 writeFunctionStartsInfo();
1504 writeDataInCodeInfo();
1505 writeSymbolTable();
1506 } else {
1507 writeRebaseInfo();
1508 writeBindingInfo();
1509 writeLazyBindingInfo();
1510 // TODO: add weak binding info
1511 writeExportInfo();
1512 writeFunctionStartsInfo();
1513 writeDataInCodeInfo();
1514 writeSymbolTable();
1515 }
1516}
1517
1518llvm::Error MachOFileLayout::writeBinary(StringRef path) {
1519 // Check for pending error from constructor.
1520 if (_ec)
1521 return llvm::errorCodeToError(_ec);
1522 // Create FileOutputBuffer with calculated size.
1523 unsigned flags = 0;
1524 if (_file.fileType != llvm::MachO::MH_OBJECT)
1525 flags = llvm::FileOutputBuffer::F_executable;
1526 ErrorOr<std::unique_ptr<llvm::FileOutputBuffer>> fobOrErr =
1527 llvm::FileOutputBuffer::create(path, size(), flags);
1528 if (std::error_code ec = fobOrErr.getError())
1529 return llvm::errorCodeToError(ec);
1530 std::unique_ptr<llvm::FileOutputBuffer> &fob = *fobOrErr;
1531 // Write content.
1532 _buffer = fob->getBufferStart();
1533 writeMachHeader();
1534 if (auto ec = writeLoadCommands())
1535 return ec;
1536 writeSectionContent();
1537 writeLinkEditContent();
1538 fob->commit();
1539
1540 return llvm::Error::success();
1541}
1542
1543/// Takes in-memory normalized view and writes a mach-o object file.
1544llvm::Error writeBinary(const NormalizedFile &file, StringRef path) {
1545 MachOFileLayout layout(file);
1546 return layout.writeBinary(path);
1547}
1548
1549} // namespace normalized
1550} // namespace mach_o
1551} // namespace lld
deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp created+1657
......@@ -0,0 +1,1657 @@
1//===- lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp ------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10///
11/// \file Converts from in-memory Atoms to in-memory normalized mach-o.
12///
13/// +------------+
14/// | normalized |
15/// +------------+
16/// ^
17/// |
18/// |
19/// +-------+
20/// | Atoms |
21/// +-------+
22
23#include "ArchHandler.h"
24#include "DebugInfo.h"
25#include "MachONormalizedFile.h"
26#include "MachONormalizedFileBinaryUtils.h"
27#include "lld/Core/Error.h"
28#include "lld/Core/LLVM.h"
29#include "llvm/ADT/StringRef.h"
30#include "llvm/ADT/StringSwitch.h"
31#include "llvm/BinaryFormat/MachO.h"
32#include "llvm/Support/Casting.h"
33#include "llvm/Support/Debug.h"
34#include "llvm/Support/ErrorHandling.h"
35#include "llvm/Support/Format.h"
36#include <map>
37#include <system_error>
38#include <unordered_set>
39
40using llvm::StringRef;
41using llvm::isa;
42using namespace llvm::MachO;
43using namespace lld::mach_o::normalized;
44using namespace lld;
45
46namespace {
47
48struct AtomInfo {
49 const DefinedAtom *atom;
50 uint64_t offsetInSection;
51};
52
53struct SectionInfo {
54 SectionInfo(StringRef seg, StringRef sect, SectionType type,
55 const MachOLinkingContext &ctxt, uint32_t attr,
56 bool relocsToDefinedCanBeImplicit);
57
58 StringRef segmentName;
59 StringRef sectionName;
60 SectionType type;
61 uint32_t attributes;
62 uint64_t address;
63 uint64_t size;
64 uint16_t alignment;
65
66 /// If this is set, the any relocs in this section which point to defined
67 /// addresses can be implicitly generated. This is the case for the
68 /// __eh_frame section where references to the function can be implicit if the
69 /// function is defined.
70 bool relocsToDefinedCanBeImplicit;
71
72
73 std::vector<AtomInfo> atomsAndOffsets;
74 uint32_t normalizedSectionIndex;
75 uint32_t finalSectionIndex;
76};
77
78SectionInfo::SectionInfo(StringRef sg, StringRef sct, SectionType t,
79 const MachOLinkingContext &ctxt, uint32_t attrs,
80 bool relocsToDefinedCanBeImplicit)
81 : segmentName(sg), sectionName(sct), type(t), attributes(attrs),
82 address(0), size(0), alignment(1),
83 relocsToDefinedCanBeImplicit(relocsToDefinedCanBeImplicit),
84 normalizedSectionIndex(0), finalSectionIndex(0) {
85 uint16_t align = 1;
86 if (ctxt.sectionAligned(segmentName, sectionName, align)) {
87 alignment = align;
88 }
89}
90
91struct SegmentInfo {
92 SegmentInfo(StringRef name);
93
94 StringRef name;
95 uint64_t address;
96 uint64_t size;
97 uint32_t init_access;
98 uint32_t max_access;
99 std::vector<SectionInfo*> sections;
100 uint32_t normalizedSegmentIndex;
101};
102
103SegmentInfo::SegmentInfo(StringRef n)
104 : name(n), address(0), size(0), init_access(0), max_access(0),
105 normalizedSegmentIndex(0) {
106}
107
108class Util {
109public:
110 Util(const MachOLinkingContext &ctxt)
111 : _ctx(ctxt), _archHandler(ctxt.archHandler()), _entryAtom(nullptr),
112 _hasTLVDescriptors(false), _subsectionsViaSymbols(true) {}
113 ~Util();
114
115 void processDefinedAtoms(const lld::File &atomFile);
116 void processAtomAttributes(const DefinedAtom *atom);
117 void assignAtomToSection(const DefinedAtom *atom);
118 void organizeSections();
119 void assignAddressesToSections(const NormalizedFile &file);
120 uint32_t fileFlags();
121 void copySegmentInfo(NormalizedFile &file);
122 void copySectionInfo(NormalizedFile &file);
123 void updateSectionInfo(NormalizedFile &file);
124 void buildAtomToAddressMap();
125 llvm::Error synthesizeDebugNotes(NormalizedFile &file);
126 llvm::Error addSymbols(const lld::File &atomFile, NormalizedFile &file);
127 void addIndirectSymbols(const lld::File &atomFile, NormalizedFile &file);
128 void addRebaseAndBindingInfo(const lld::File &, NormalizedFile &file);
129 void addExportInfo(const lld::File &, NormalizedFile &file);
130 void addSectionRelocs(const lld::File &, NormalizedFile &file);
131 void addFunctionStarts(const lld::File &, NormalizedFile &file);
132 void buildDataInCodeArray(const lld::File &, NormalizedFile &file);
133 void addDependentDylibs(const lld::File &, NormalizedFile &file);
134 void copyEntryPointAddress(NormalizedFile &file);
135 void copySectionContent(NormalizedFile &file);
136
137 bool allSourceFilesHaveMinVersions() const {
138 return _allSourceFilesHaveMinVersions;
139 }
140
141 uint32_t minVersion() const {
142 return _minVersion;
143 }
144
145 LoadCommandType minVersionCommandType() const {
146 return _minVersionCommandType;
147 }
148
149private:
150 typedef std::map<DefinedAtom::ContentType, SectionInfo*> TypeToSection;
151 typedef llvm::DenseMap<const Atom*, uint64_t> AtomToAddress;
152
153 struct DylibInfo { int ordinal; bool hasWeak; bool hasNonWeak; };
154 typedef llvm::StringMap<DylibInfo> DylibPathToInfo;
155
156 SectionInfo *sectionForAtom(const DefinedAtom*);
157 SectionInfo *getRelocatableSection(DefinedAtom::ContentType type);
158 SectionInfo *getFinalSection(DefinedAtom::ContentType type);
159 void appendAtom(SectionInfo *sect, const DefinedAtom *atom);
160 SegmentInfo *segmentForName(StringRef segName);
161 void layoutSectionsInSegment(SegmentInfo *seg, uint64_t &addr);
162 void layoutSectionsInTextSegment(size_t, SegmentInfo *, uint64_t &);
163 void copySectionContent(SectionInfo *si, ContentBytes &content);
164 uint16_t descBits(const DefinedAtom* atom);
165 int dylibOrdinal(const SharedLibraryAtom *sa);
166 void segIndexForSection(const SectionInfo *sect,
167 uint8_t &segmentIndex, uint64_t &segmentStartAddr);
168 const Atom *targetOfLazyPointer(const DefinedAtom *lpAtom);
169 const Atom *targetOfStub(const DefinedAtom *stubAtom);
170 llvm::Error getSymbolTableRegion(const DefinedAtom* atom,
171 bool &inGlobalsRegion,
172 SymbolScope &symbolScope);
173 void appendSection(SectionInfo *si, NormalizedFile &file);
174 uint32_t sectionIndexForAtom(const Atom *atom);
175 void fixLazyReferenceImm(const DefinedAtom *atom, uint32_t offset,
176 NormalizedFile &file);
177
178 typedef llvm::DenseMap<const Atom*, uint32_t> AtomToIndex;
179 struct AtomAndIndex { const Atom *atom; uint32_t index; SymbolScope scope; };
180 struct AtomSorter {
181 bool operator()(const AtomAndIndex &left, const AtomAndIndex &right);
182 };
183 struct SegmentSorter {
184 bool operator()(const SegmentInfo *left, const SegmentInfo *right);
185 static unsigned weight(const SegmentInfo *);
186 };
187 struct TextSectionSorter {
188 bool operator()(const SectionInfo *left, const SectionInfo *right);
189 static unsigned weight(const SectionInfo *);
190 };
191
192 const MachOLinkingContext &_ctx;
193 mach_o::ArchHandler &_archHandler;
194 llvm::BumpPtrAllocator _allocator;
195 std::vector<SectionInfo*> _sectionInfos;
196 std::vector<SegmentInfo*> _segmentInfos;
197 TypeToSection _sectionMap;
198 std::vector<SectionInfo*> _customSections;
199 AtomToAddress _atomToAddress;
200 DylibPathToInfo _dylibInfo;
201 const DefinedAtom *_entryAtom;
202 AtomToIndex _atomToSymbolIndex;
203 std::vector<const Atom *> _machHeaderAliasAtoms;
204 bool _hasTLVDescriptors;
205 bool _subsectionsViaSymbols;
206 bool _allSourceFilesHaveMinVersions = true;
207 LoadCommandType _minVersionCommandType = (LoadCommandType)0;
208 uint32_t _minVersion = 0;
209 std::vector<lld::mach_o::Stab> _stabs;
210};
211
212Util::~Util() {
213 // The SectionInfo structs are BumpPtr allocated, but atomsAndOffsets needs
214 // to be deleted.
215 for (SectionInfo *si : _sectionInfos) {
216 // clear() destroys vector elements, but does not deallocate.
217 // Instead use swap() to deallocate vector buffer.
218 std::vector<AtomInfo> empty;
219 si->atomsAndOffsets.swap(empty);
220 }
221 // The SegmentInfo structs are BumpPtr allocated, but sections needs
222 // to be deleted.
223 for (SegmentInfo *sgi : _segmentInfos) {
224 std::vector<SectionInfo*> empty2;
225 sgi->sections.swap(empty2);
226 }
227}
228
229SectionInfo *Util::getRelocatableSection(DefinedAtom::ContentType type) {
230 StringRef segmentName;
231 StringRef sectionName;
232 SectionType sectionType;
233 SectionAttr sectionAttrs;
234 bool relocsToDefinedCanBeImplicit;
235
236 // Use same table used by when parsing .o files.
237 relocatableSectionInfoForContentType(type, segmentName, sectionName,
238 sectionType, sectionAttrs,
239 relocsToDefinedCanBeImplicit);
240 // If we already have a SectionInfo with this name, re-use it.
241 // This can happen if two ContentType map to the same mach-o section.
242 for (auto sect : _sectionMap) {
243 if (sect.second->sectionName.equals(sectionName) &&
244 sect.second->segmentName.equals(segmentName)) {
245 return sect.second;
246 }
247 }
248 // Otherwise allocate new SectionInfo object.
249 auto *sect = new (_allocator)
250 SectionInfo(segmentName, sectionName, sectionType, _ctx, sectionAttrs,
251 relocsToDefinedCanBeImplicit);
252 _sectionInfos.push_back(sect);
253 _sectionMap[type] = sect;
254 return sect;
255}
256
257#define ENTRY(seg, sect, type, atomType) \
258 {seg, sect, type, DefinedAtom::atomType }
259
260struct MachOFinalSectionFromAtomType {
261 StringRef segmentName;
262 StringRef sectionName;
263 SectionType sectionType;
264 DefinedAtom::ContentType atomType;
265};
266
267const MachOFinalSectionFromAtomType sectsToAtomType[] = {
268 ENTRY("__TEXT", "__text", S_REGULAR, typeCode),
269 ENTRY("__TEXT", "__text", S_REGULAR, typeMachHeader),
270 ENTRY("__TEXT", "__cstring", S_CSTRING_LITERALS, typeCString),
271 ENTRY("__TEXT", "__ustring", S_REGULAR, typeUTF16String),
272 ENTRY("__TEXT", "__const", S_REGULAR, typeConstant),
273 ENTRY("__TEXT", "__const", S_4BYTE_LITERALS, typeLiteral4),
274 ENTRY("__TEXT", "__const", S_8BYTE_LITERALS, typeLiteral8),
275 ENTRY("__TEXT", "__const", S_16BYTE_LITERALS, typeLiteral16),
276 ENTRY("__TEXT", "__stubs", S_SYMBOL_STUBS, typeStub),
277 ENTRY("__TEXT", "__stub_helper", S_REGULAR, typeStubHelper),
278 ENTRY("__TEXT", "__gcc_except_tab", S_REGULAR, typeLSDA),
279 ENTRY("__TEXT", "__eh_frame", S_COALESCED, typeCFI),
280 ENTRY("__TEXT", "__unwind_info", S_REGULAR, typeProcessedUnwindInfo),
281 ENTRY("__DATA", "__data", S_REGULAR, typeData),
282 ENTRY("__DATA", "__const", S_REGULAR, typeConstData),
283 ENTRY("__DATA", "__cfstring", S_REGULAR, typeCFString),
284 ENTRY("__DATA", "__la_symbol_ptr", S_LAZY_SYMBOL_POINTERS,
285 typeLazyPointer),
286 ENTRY("__DATA", "__mod_init_func", S_MOD_INIT_FUNC_POINTERS,
287 typeInitializerPtr),
288 ENTRY("__DATA", "__mod_term_func", S_MOD_TERM_FUNC_POINTERS,
289 typeTerminatorPtr),
290 ENTRY("__DATA", "__got", S_NON_LAZY_SYMBOL_POINTERS,
291 typeGOT),
292 ENTRY("__DATA", "__nl_symbol_ptr", S_NON_LAZY_SYMBOL_POINTERS,
293 typeNonLazyPointer),
294 ENTRY("__DATA", "__thread_vars", S_THREAD_LOCAL_VARIABLES,
295 typeThunkTLV),
296 ENTRY("__DATA", "__thread_data", S_THREAD_LOCAL_REGULAR,
297 typeTLVInitialData),
298 ENTRY("__DATA", "__thread_ptrs", S_THREAD_LOCAL_VARIABLE_POINTERS,
299 typeTLVInitializerPtr),
300 ENTRY("__DATA", "__thread_bss", S_THREAD_LOCAL_ZEROFILL,
301 typeTLVInitialZeroFill),
302 ENTRY("__DATA", "__bss", S_ZEROFILL, typeZeroFill),
303 ENTRY("__DATA", "__interposing", S_INTERPOSING, typeInterposingTuples),
304};
305#undef ENTRY
306
307SectionInfo *Util::getFinalSection(DefinedAtom::ContentType atomType) {
308 for (auto &p : sectsToAtomType) {
309 if (p.atomType != atomType)
310 continue;
311 SectionAttr sectionAttrs = 0;
312 switch (atomType) {
313 case DefinedAtom::typeMachHeader:
314 case DefinedAtom::typeCode:
315 case DefinedAtom::typeStub:
316 case DefinedAtom::typeStubHelper:
317 sectionAttrs = S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SOME_INSTRUCTIONS;
318 break;
319 case DefinedAtom::typeThunkTLV:
320 _hasTLVDescriptors = true;
321 break;
322 default:
323 break;
324 }
325 // If we already have a SectionInfo with this name, re-use it.
326 // This can happen if two ContentType map to the same mach-o section.
327 for (auto sect : _sectionMap) {
328 if (sect.second->sectionName.equals(p.sectionName) &&
329 sect.second->segmentName.equals(p.segmentName)) {
330 return sect.second;
331 }
332 }
333 // Otherwise allocate new SectionInfo object.
334 auto *sect = new (_allocator) SectionInfo(
335 p.segmentName, p.sectionName, p.sectionType, _ctx, sectionAttrs,
336 /* relocsToDefinedCanBeImplicit */ false);
337 _sectionInfos.push_back(sect);
338 _sectionMap[atomType] = sect;
339 return sect;
340 }
341 llvm_unreachable("content type not yet supported");
342}
343
344SectionInfo *Util::sectionForAtom(const DefinedAtom *atom) {
345 if (atom->sectionChoice() == DefinedAtom::sectionBasedOnContent) {
346 // Section for this atom is derived from content type.
347 DefinedAtom::ContentType type = atom->contentType();
348 auto pos = _sectionMap.find(type);
349 if ( pos != _sectionMap.end() )
350 return pos->second;
351 bool rMode = (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT);
352 return rMode ? getRelocatableSection(type) : getFinalSection(type);
353 } else {
354 // This atom needs to be in a custom section.
355 StringRef customName = atom->customSectionName();
356 // Look to see if we have already allocated the needed custom section.
357 for(SectionInfo *sect : _customSections) {
358 const DefinedAtom *firstAtom = sect->atomsAndOffsets.front().atom;
359 if (firstAtom->customSectionName().equals(customName)) {
360 return sect;
361 }
362 }
363 // Not found, so need to create a new custom section.
364 size_t seperatorIndex = customName.find('/');
365 assert(seperatorIndex != StringRef::npos);
366 StringRef segName = customName.slice(0, seperatorIndex);
367 StringRef sectName = customName.drop_front(seperatorIndex + 1);
368 auto *sect =
369 new (_allocator) SectionInfo(segName, sectName, S_REGULAR, _ctx,
370 0, /* relocsToDefinedCanBeImplicit */ false);
371 _customSections.push_back(sect);
372 _sectionInfos.push_back(sect);
373 return sect;
374 }
375}
376
377void Util::appendAtom(SectionInfo *sect, const DefinedAtom *atom) {
378 // Figure out offset for atom in this section given alignment constraints.
379 uint64_t offset = sect->size;
380 DefinedAtom::Alignment atomAlign = atom->alignment();
381 uint64_t align = atomAlign.value;
382 uint64_t requiredModulus = atomAlign.modulus;
383 uint64_t currentModulus = (offset % align);
384 if ( currentModulus != requiredModulus ) {
385 if ( requiredModulus > currentModulus )
386 offset += requiredModulus-currentModulus;
387 else
388 offset += align+requiredModulus-currentModulus;
389 }
390 // Record max alignment of any atom in this section.
391 if (align > sect->alignment)
392 sect->alignment = atomAlign.value;
393 // Assign atom to this section with this offset.
394 AtomInfo ai = {atom, offset};
395 sect->atomsAndOffsets.push_back(ai);
396 // Update section size to include this atom.
397 sect->size = offset + atom->size();
398}
399
400void Util::processDefinedAtoms(const lld::File &atomFile) {
401 for (const DefinedAtom *atom : atomFile.defined()) {
402 processAtomAttributes(atom);
403 assignAtomToSection(atom);
404 }
405}
406
407void Util::processAtomAttributes(const DefinedAtom *atom) {
408 if (auto *machoFile = dyn_cast<mach_o::MachOFile>(&atom->file())) {
409 // If the file doesn't use subsections via symbols, then make sure we don't
410 // add that flag to the final output file if we have a relocatable file.
411 if (!machoFile->subsectionsViaSymbols())
412 _subsectionsViaSymbols = false;
413
414 // All the source files must have min versions for us to output an object
415 // file with a min version.
416 if (auto v = machoFile->minVersion())
417 _minVersion = std::max(_minVersion, v);
418 else
419 _allSourceFilesHaveMinVersions = false;
420
421 // If we don't have a platform load command, but one of the source files
422 // does, then take the one from the file.
423 if (!_minVersionCommandType)
424 if (auto v = machoFile->minVersionLoadCommandKind())
425 _minVersionCommandType = v;
426 }
427}
428
429void Util::assignAtomToSection(const DefinedAtom *atom) {
430 if (atom->contentType() == DefinedAtom::typeMachHeader) {
431 _machHeaderAliasAtoms.push_back(atom);
432 // Assign atom to this section with this offset.
433 AtomInfo ai = {atom, 0};
434 sectionForAtom(atom)->atomsAndOffsets.push_back(ai);
435 } else if (atom->contentType() == DefinedAtom::typeDSOHandle)
436 _machHeaderAliasAtoms.push_back(atom);
437 else
438 appendAtom(sectionForAtom(atom), atom);
439}
440
441SegmentInfo *Util::segmentForName(StringRef segName) {
442 for (SegmentInfo *si : _segmentInfos) {
443 if ( si->name.equals(segName) )
444 return si;
445 }
446 auto *info = new (_allocator) SegmentInfo(segName);
447
448 // Set the initial segment protection.
449 if (segName.equals("__TEXT"))
450 info->init_access = VM_PROT_READ | VM_PROT_EXECUTE;
451 else if (segName.equals("__PAGEZERO"))
452 info->init_access = 0;
453 else if (segName.equals("__LINKEDIT"))
454 info->init_access = VM_PROT_READ;
455 else {
456 // All others default to read-write
457 info->init_access = VM_PROT_READ | VM_PROT_WRITE;
458 }
459
460 // Set max segment protection
461 // Note, its overkill to use a switch statement here, but makes it so much
462 // easier to use switch coverage to catch new cases.
463 switch (_ctx.os()) {
464 case lld::MachOLinkingContext::OS::unknown:
465 case lld::MachOLinkingContext::OS::macOSX:
466 case lld::MachOLinkingContext::OS::iOS_simulator:
467 if (segName.equals("__PAGEZERO")) {
468 info->max_access = 0;
469 break;
470 }
471 // All others default to all
472 info->max_access = VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE;
473 break;
474 case lld::MachOLinkingContext::OS::iOS:
475 // iPhoneOS always uses same protection for max and initial
476 info->max_access = info->init_access;
477 break;
478 }
479 _segmentInfos.push_back(info);
480 return info;
481}
482
483unsigned Util::SegmentSorter::weight(const SegmentInfo *seg) {
484 return llvm::StringSwitch<unsigned>(seg->name)
485 .Case("__PAGEZERO", 1)
486 .Case("__TEXT", 2)
487 .Case("__DATA", 3)
488 .Default(100);
489}
490
491bool Util::SegmentSorter::operator()(const SegmentInfo *left,
492 const SegmentInfo *right) {
493 return (weight(left) < weight(right));
494}
495
496unsigned Util::TextSectionSorter::weight(const SectionInfo *sect) {
497 return llvm::StringSwitch<unsigned>(sect->sectionName)
498 .Case("__text", 1)
499 .Case("__stubs", 2)
500 .Case("__stub_helper", 3)
501 .Case("__const", 4)
502 .Case("__cstring", 5)
503 .Case("__unwind_info", 98)
504 .Case("__eh_frame", 99)
505 .Default(10);
506}
507
508bool Util::TextSectionSorter::operator()(const SectionInfo *left,
509 const SectionInfo *right) {
510 return (weight(left) < weight(right));
511}
512
513void Util::organizeSections() {
514 // NOTE!: Keep this in sync with assignAddressesToSections.
515 switch (_ctx.outputMachOType()) {
516 case llvm::MachO::MH_EXECUTE:
517 // Main executables, need a zero-page segment
518 segmentForName("__PAGEZERO");
519 // Fall into next case.
520 LLVM_FALLTHROUGH;
521 case llvm::MachO::MH_DYLIB:
522 case llvm::MachO::MH_BUNDLE:
523 // All dynamic code needs TEXT segment to hold the load commands.
524 segmentForName("__TEXT");
525 break;
526 default:
527 break;
528 }
529 segmentForName("__LINKEDIT");
530
531 // Group sections into segments.
532 for (SectionInfo *si : _sectionInfos) {
533 SegmentInfo *seg = segmentForName(si->segmentName);
534 seg->sections.push_back(si);
535 }
536 // Sort segments.
537 std::sort(_segmentInfos.begin(), _segmentInfos.end(), SegmentSorter());
538
539 // Sort sections within segments.
540 for (SegmentInfo *seg : _segmentInfos) {
541 if (seg->name.equals("__TEXT")) {
542 std::sort(seg->sections.begin(), seg->sections.end(),
543 TextSectionSorter());
544 }
545 }
546
547 // Record final section indexes.
548 uint32_t segmentIndex = 0;
549 uint32_t sectionIndex = 1;
550 for (SegmentInfo *seg : _segmentInfos) {
551 seg->normalizedSegmentIndex = segmentIndex++;
552 for (SectionInfo *sect : seg->sections)
553 sect->finalSectionIndex = sectionIndex++;
554 }
555}
556
557void Util::layoutSectionsInSegment(SegmentInfo *seg, uint64_t &addr) {
558 seg->address = addr;
559 for (SectionInfo *sect : seg->sections) {
560 sect->address = llvm::alignTo(addr, sect->alignment);
561 addr = sect->address + sect->size;
562 }
563 seg->size = llvm::alignTo(addr - seg->address, _ctx.pageSize());
564}
565
566// __TEXT segment lays out backwards so padding is at front after load commands.
567void Util::layoutSectionsInTextSegment(size_t hlcSize, SegmentInfo *seg,
568 uint64_t &addr) {
569 seg->address = addr;
570 // Walks sections starting at end to calculate padding for start.
571 int64_t taddr = 0;
572 for (auto it = seg->sections.rbegin(); it != seg->sections.rend(); ++it) {
573 SectionInfo *sect = *it;
574 taddr -= sect->size;
575 taddr = taddr & (0 - sect->alignment);
576 }
577 int64_t padding = taddr - hlcSize;
578 while (padding < 0)
579 padding += _ctx.pageSize();
580 // Start assigning section address starting at padded offset.
581 addr += (padding + hlcSize);
582 for (SectionInfo *sect : seg->sections) {
583 sect->address = llvm::alignTo(addr, sect->alignment);
584 addr = sect->address + sect->size;
585 }
586 seg->size = llvm::alignTo(addr - seg->address, _ctx.pageSize());
587}
588
589void Util::assignAddressesToSections(const NormalizedFile &file) {
590 // NOTE!: Keep this in sync with organizeSections.
591 size_t hlcSize = headerAndLoadCommandsSize(file);
592 uint64_t address = 0;
593 for (SegmentInfo *seg : _segmentInfos) {
594 if (seg->name.equals("__PAGEZERO")) {
595 seg->size = _ctx.pageZeroSize();
596 address += seg->size;
597 }
598 else if (seg->name.equals("__TEXT")) {
599 // _ctx.baseAddress() == 0 implies it was either unspecified or
600 // pageZeroSize is also 0. In either case resetting address is safe.
601 address = _ctx.baseAddress() ? _ctx.baseAddress() : address;
602 layoutSectionsInTextSegment(hlcSize, seg, address);
603 } else
604 layoutSectionsInSegment(seg, address);
605
606 address = llvm::alignTo(address, _ctx.pageSize());
607 }
608 DEBUG_WITH_TYPE("WriterMachO-norm",
609 llvm::dbgs() << "assignAddressesToSections()\n";
610 for (SegmentInfo *sgi : _segmentInfos) {
611 llvm::dbgs() << " address=" << llvm::format("0x%08llX", sgi->address)
612 << ", size=" << llvm::format("0x%08llX", sgi->size)
613 << ", segment-name='" << sgi->name
614 << "'\n";
615 for (SectionInfo *si : sgi->sections) {
616 llvm::dbgs()<< " addr=" << llvm::format("0x%08llX", si->address)
617 << ", size=" << llvm::format("0x%08llX", si->size)
618 << ", section-name='" << si->sectionName
619 << "\n";
620 }
621 }
622 );
623}
624
625void Util::copySegmentInfo(NormalizedFile &file) {
626 for (SegmentInfo *sgi : _segmentInfos) {
627 Segment seg;
628 seg.name = sgi->name;
629 seg.address = sgi->address;
630 seg.size = sgi->size;
631 seg.init_access = sgi->init_access;
632 seg.max_access = sgi->max_access;
633 file.segments.push_back(seg);
634 }
635}
636
637void Util::appendSection(SectionInfo *si, NormalizedFile &file) {
638 // Add new empty section to end of file.sections.
639 Section temp;
640 file.sections.push_back(std::move(temp));
641 Section* normSect = &file.sections.back();
642 // Copy fields to normalized section.
643 normSect->segmentName = si->segmentName;
644 normSect->sectionName = si->sectionName;
645 normSect->type = si->type;
646 normSect->attributes = si->attributes;
647 normSect->address = si->address;
648 normSect->alignment = si->alignment;
649 // Record where normalized section is.
650 si->normalizedSectionIndex = file.sections.size()-1;
651}
652
653void Util::copySectionContent(NormalizedFile &file) {
654 const bool r = (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT);
655
656 // Utility function for ArchHandler to find address of atom in output file.
657 auto addrForAtom = [&] (const Atom &atom) -> uint64_t {
658 auto pos = _atomToAddress.find(&atom);
659 assert(pos != _atomToAddress.end());
660 return pos->second;
661 };
662
663 auto sectionAddrForAtom = [&] (const Atom &atom) -> uint64_t {
664 for (const SectionInfo *sectInfo : _sectionInfos)
665 for (const AtomInfo &atomInfo : sectInfo->atomsAndOffsets)
666 if (atomInfo.atom == &atom)
667 return sectInfo->address;
668 llvm_unreachable("atom not assigned to section");
669 };
670
671 for (SectionInfo *si : _sectionInfos) {
672 Section *normSect = &file.sections[si->normalizedSectionIndex];
673 if (isZeroFillSection(si->type)) {
674 const uint8_t *empty = nullptr;
675 normSect->content = llvm::makeArrayRef(empty, si->size);
676 continue;
677 }
678 // Copy content from atoms to content buffer for section.
679 llvm::MutableArrayRef<uint8_t> sectionContent;
680 if (si->size) {
681 uint8_t *sectContent = file.ownedAllocations.Allocate<uint8_t>(si->size);
682 sectionContent = llvm::MutableArrayRef<uint8_t>(sectContent, si->size);
683 normSect->content = sectionContent;
684 }
685 for (AtomInfo &ai : si->atomsAndOffsets) {
686 if (!ai.atom->size()) {
687 assert(ai.atom->begin() == ai.atom->end() &&
688 "Cannot have references without content");
689 continue;
690 }
691 auto atomContent = sectionContent.slice(ai.offsetInSection,
692 ai.atom->size());
693 _archHandler.generateAtomContent(*ai.atom, r, addrForAtom,
694 sectionAddrForAtom, _ctx.baseAddress(),
695 atomContent);
696 }
697 }
698}
699
700void Util::copySectionInfo(NormalizedFile &file) {
701 file.sections.reserve(_sectionInfos.size());
702 // Write sections grouped by segment.
703 for (SegmentInfo *sgi : _segmentInfos) {
704 for (SectionInfo *si : sgi->sections) {
705 appendSection(si, file);
706 }
707 }
708}
709
710void Util::updateSectionInfo(NormalizedFile &file) {
711 file.sections.reserve(_sectionInfos.size());
712 // sections grouped by segment.
713 for (SegmentInfo *sgi : _segmentInfos) {
714 Segment *normSeg = &file.segments[sgi->normalizedSegmentIndex];
715 normSeg->address = sgi->address;
716 normSeg->size = sgi->size;
717 for (SectionInfo *si : sgi->sections) {
718 Section *normSect = &file.sections[si->normalizedSectionIndex];
719 normSect->address = si->address;
720 }
721 }
722}
723
724void Util::copyEntryPointAddress(NormalizedFile &nFile) {
725 if (!_entryAtom) {
726 nFile.entryAddress = 0;
727 return;
728 }
729
730 if (_ctx.outputTypeHasEntry()) {
731 if (_archHandler.isThumbFunction(*_entryAtom))
732 nFile.entryAddress = (_atomToAddress[_entryAtom] | 1);
733 else
734 nFile.entryAddress = _atomToAddress[_entryAtom];
735 }
736}
737
738void Util::buildAtomToAddressMap() {
739 DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
740 << "assign atom addresses:\n");
741 const bool lookForEntry = _ctx.outputTypeHasEntry();
742 for (SectionInfo *sect : _sectionInfos) {
743 for (const AtomInfo &info : sect->atomsAndOffsets) {
744 _atomToAddress[info.atom] = sect->address + info.offsetInSection;
745 if (lookForEntry && (info.atom->contentType() == DefinedAtom::typeCode) &&
746 (info.atom->size() != 0) &&
747 info.atom->name() == _ctx.entrySymbolName()) {
748 _entryAtom = info.atom;
749 }
750 DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
751 << " address="
752 << llvm::format("0x%016X", _atomToAddress[info.atom])
753 << llvm::format(" 0x%09lX", info.atom)
754 << ", file=#"
755 << info.atom->file().ordinal()
756 << ", atom=#"
757 << info.atom->ordinal()
758 << ", name="
759 << info.atom->name()
760 << ", type="
761 << info.atom->contentType()
762 << "\n");
763 }
764 }
765 DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
766 << "assign header alias atom addresses:\n");
767 for (const Atom *atom : _machHeaderAliasAtoms) {
768 _atomToAddress[atom] = _ctx.baseAddress();
769#ifndef NDEBUG
770 if (auto *definedAtom = dyn_cast<DefinedAtom>(atom)) {
771 DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
772 << " address="
773 << llvm::format("0x%016X", _atomToAddress[atom])
774 << llvm::format(" 0x%09lX", atom)
775 << ", file=#"
776 << definedAtom->file().ordinal()
777 << ", atom=#"
778 << definedAtom->ordinal()
779 << ", name="
780 << definedAtom->name()
781 << ", type="
782 << definedAtom->contentType()
783 << "\n");
784 } else {
785 DEBUG_WITH_TYPE("WriterMachO-address", llvm::dbgs()
786 << " address="
787 << llvm::format("0x%016X", _atomToAddress[atom])
788 << " atom=" << atom
789 << " name=" << atom->name() << "\n");
790 }
791#endif
792 }
793}
794
795llvm::Error Util::synthesizeDebugNotes(NormalizedFile &file) {
796
797 // Bail out early if we don't need to generate a debug map.
798 if (_ctx.debugInfoMode() == MachOLinkingContext::DebugInfoMode::noDebugMap)
799 return llvm::Error::success();
800
801 std::vector<const DefinedAtom*> atomsNeedingDebugNotes;
802 std::set<const mach_o::MachOFile*> filesWithStabs;
803 bool objFileHasDwarf = false;
804 const File *objFile = nullptr;
805
806 for (SectionInfo *sect : _sectionInfos) {
807 for (const AtomInfo &info : sect->atomsAndOffsets) {
808 if (const DefinedAtom *atom = dyn_cast<DefinedAtom>(info.atom)) {
809
810 // FIXME: No stabs/debug-notes for symbols that wouldn't be in the
811 // symbol table.
812 // FIXME: No stabs/debug-notes for kernel dtrace probes.
813
814 if (atom->contentType() == DefinedAtom::typeCFI ||
815 atom->contentType() == DefinedAtom::typeCString)
816 continue;
817
818 // Whenever we encounter a new file, update the 'objfileHasDwarf' flag.
819 if (&info.atom->file() != objFile) {
820 objFileHasDwarf = false;
821 if (const mach_o::MachOFile *atomFile =
822 dyn_cast<mach_o::MachOFile>(&info.atom->file())) {
823 if (atomFile->debugInfo()) {
824 if (isa<mach_o::DwarfDebugInfo>(atomFile->debugInfo()))
825 objFileHasDwarf = true;
826 else if (isa<mach_o::StabsDebugInfo>(atomFile->debugInfo()))
827 filesWithStabs.insert(atomFile);
828 }
829 }
830 }
831
832 // If this atom is from a file that needs dwarf, add it to the list.
833 if (objFileHasDwarf)
834 atomsNeedingDebugNotes.push_back(info.atom);
835 }
836 }
837 }
838
839 // Sort atoms needing debug notes by file ordinal, then atom ordinal.
840 std::sort(atomsNeedingDebugNotes.begin(), atomsNeedingDebugNotes.end(),
841 [](const DefinedAtom *lhs, const DefinedAtom *rhs) {
842 if (lhs->file().ordinal() != rhs->file().ordinal())
843 return (lhs->file().ordinal() < rhs->file().ordinal());
844 return (lhs->ordinal() < rhs->ordinal());
845 });
846
847 // FIXME: Handle <rdar://problem/17689030>: Add -add_ast_path option to \
848 // linker which add N_AST stab entry to output
849 // See OutputFile::synthesizeDebugNotes in ObjectFile.cpp in ld64.
850
851 StringRef oldFileName = "";
852 StringRef oldDirPath = "";
853 bool wroteStartSO = false;
854 std::unordered_set<std::string> seenFiles;
855 for (const DefinedAtom *atom : atomsNeedingDebugNotes) {
856 const auto &atomFile = cast<mach_o::MachOFile>(atom->file());
857 assert(dyn_cast_or_null<lld::mach_o::DwarfDebugInfo>(atomFile.debugInfo())
858 && "file for atom needing debug notes does not contain dwarf");
859 auto &dwarf = cast<lld::mach_o::DwarfDebugInfo>(*atomFile.debugInfo());
860
861 auto &tu = dwarf.translationUnitSource();
862 StringRef newFileName = tu.name;
863 StringRef newDirPath = tu.path;
864
865 // Add an SO whenever the TU source file changes.
866 if (newFileName != oldFileName || newDirPath != oldDirPath) {
867 // Translation unit change, emit ending SO
868 if (oldFileName != "")
869 _stabs.push_back(mach_o::Stab(nullptr, N_SO, 1, 0, 0, ""));
870
871 oldFileName = newFileName;
872 oldDirPath = newDirPath;
873
874 // If newDirPath doesn't end with a '/' we need to add one:
875 if (newDirPath.back() != '/') {
876 char *p =
877 file.ownedAllocations.Allocate<char>(newDirPath.size() + 2);
878 memcpy(p, newDirPath.data(), newDirPath.size());
879 p[newDirPath.size()] = '/';
880 p[newDirPath.size() + 1] = '\0';
881 newDirPath = p;
882 }
883
884 // New translation unit, emit start SOs:
885 _stabs.push_back(mach_o::Stab(nullptr, N_SO, 0, 0, 0, newDirPath));
886 _stabs.push_back(mach_o::Stab(nullptr, N_SO, 0, 0, 0, newFileName));
887
888 // Synthesize OSO for start of file.
889 char *fullPath = nullptr;
890 {
891 SmallString<1024> pathBuf(atomFile.path());
892 if (auto EC = llvm::sys::fs::make_absolute(pathBuf))
893 return llvm::errorCodeToError(EC);
894 fullPath = file.ownedAllocations.Allocate<char>(pathBuf.size() + 1);
895 memcpy(fullPath, pathBuf.c_str(), pathBuf.size() + 1);
896 }
897
898 // Get mod time.
899 uint32_t modTime = 0;
900 llvm::sys::fs::file_status stat;
901 if (!llvm::sys::fs::status(fullPath, stat))
902 if (llvm::sys::fs::exists(stat))
903 modTime = llvm::sys::toTimeT(stat.getLastModificationTime());
904
905 _stabs.push_back(mach_o::Stab(nullptr, N_OSO, _ctx.getCPUSubType(), 1,
906 modTime, fullPath));
907 // <rdar://problem/6337329> linker should put cpusubtype in n_sect field
908 // of nlist entry for N_OSO debug note entries.
909 wroteStartSO = true;
910 }
911
912 if (atom->contentType() == DefinedAtom::typeCode) {
913 // Synthesize BNSYM and start FUN stabs.
914 _stabs.push_back(mach_o::Stab(atom, N_BNSYM, 1, 0, 0, ""));
915 _stabs.push_back(mach_o::Stab(atom, N_FUN, 1, 0, 0, atom->name()));
916 // Synthesize any SOL stabs needed
917 // FIXME: add SOL stabs.
918 _stabs.push_back(mach_o::Stab(nullptr, N_FUN, 0, 0,
919 atom->rawContent().size(), ""));
920 _stabs.push_back(mach_o::Stab(nullptr, N_ENSYM, 1, 0,
921 atom->rawContent().size(), ""));
922 } else {
923 if (atom->scope() == Atom::scopeTranslationUnit)
924 _stabs.push_back(mach_o::Stab(atom, N_STSYM, 1, 0, 0, atom->name()));
925 else
926 _stabs.push_back(mach_o::Stab(nullptr, N_GSYM, 1, 0, 0, atom->name()));
927 }
928 }
929
930 // Emit ending SO if necessary.
931 if (wroteStartSO)
932 _stabs.push_back(mach_o::Stab(nullptr, N_SO, 1, 0, 0, ""));
933
934 // Copy any stabs from .o file.
935 for (const auto *objFile : filesWithStabs) {
936 const auto &stabsList =
937 cast<mach_o::StabsDebugInfo>(objFile->debugInfo())->stabs();
938 for (auto &stab : stabsList) {
939 // FIXME: Drop stabs whose atoms have been dead-stripped.
940 _stabs.push_back(stab);
941 }
942 }
943
944 return llvm::Error::success();
945}
946
947uint16_t Util::descBits(const DefinedAtom* atom) {
948 uint16_t desc = 0;
949 switch (atom->merge()) {
950 case lld::DefinedAtom::mergeNo:
951 case lld::DefinedAtom::mergeAsTentative:
952 break;
953 case lld::DefinedAtom::mergeAsWeak:
954 case lld::DefinedAtom::mergeAsWeakAndAddressUsed:
955 desc |= N_WEAK_DEF;
956 break;
957 case lld::DefinedAtom::mergeSameNameAndSize:
958 case lld::DefinedAtom::mergeByLargestSection:
959 case lld::DefinedAtom::mergeByContent:
960 llvm_unreachable("Unsupported DefinedAtom::merge()");
961 break;
962 }
963 if (atom->contentType() == lld::DefinedAtom::typeResolver)
964 desc |= N_SYMBOL_RESOLVER;
965 if (atom->contentType() == lld::DefinedAtom::typeMachHeader)
966 desc |= REFERENCED_DYNAMICALLY;
967 if (_archHandler.isThumbFunction(*atom))
968 desc |= N_ARM_THUMB_DEF;
969 if (atom->deadStrip() == DefinedAtom::deadStripNever &&
970 _ctx.outputMachOType() == llvm::MachO::MH_OBJECT) {
971 if ((atom->contentType() != DefinedAtom::typeInitializerPtr)
972 && (atom->contentType() != DefinedAtom::typeTerminatorPtr))
973 desc |= N_NO_DEAD_STRIP;
974 }
975 return desc;
976}
977
978bool Util::AtomSorter::operator()(const AtomAndIndex &left,
979 const AtomAndIndex &right) {
980 return (left.atom->name().compare(right.atom->name()) < 0);
981}
982
983llvm::Error Util::getSymbolTableRegion(const DefinedAtom* atom,
984 bool &inGlobalsRegion,
985 SymbolScope &scope) {
986 bool rMode = (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT);
987 switch (atom->scope()) {
988 case Atom::scopeTranslationUnit:
989 scope = 0;
990 inGlobalsRegion = false;
991 return llvm::Error::success();
992 case Atom::scopeLinkageUnit:
993 if ((_ctx.exportMode() == MachOLinkingContext::ExportMode::whiteList) &&
994 _ctx.exportSymbolNamed(atom->name())) {
995 return llvm::make_error<GenericError>(
996 Twine("cannot export hidden symbol ") + atom->name());
997 }
998 if (rMode) {
999 if (_ctx.keepPrivateExterns()) {
1000 // -keep_private_externs means keep in globals region as N_PEXT.
1001 scope = N_PEXT | N_EXT;
1002 inGlobalsRegion = true;
1003 return llvm::Error::success();
1004 }
1005 }
1006 // scopeLinkageUnit symbols are no longer global once linked.
1007 scope = N_PEXT;
1008 inGlobalsRegion = false;
1009 return llvm::Error::success();
1010 case Atom::scopeGlobal:
1011 if (_ctx.exportRestrictMode()) {
1012 if (_ctx.exportSymbolNamed(atom->name())) {
1013 scope = N_EXT;
1014 inGlobalsRegion = true;
1015 return llvm::Error::success();
1016 } else {
1017 scope = N_PEXT;
1018 inGlobalsRegion = false;
1019 return llvm::Error::success();
1020 }
1021 } else {
1022 scope = N_EXT;
1023 inGlobalsRegion = true;
1024 return llvm::Error::success();
1025 }
1026 break;
1027 }
1028 llvm_unreachable("atom->scope() unknown enum value");
1029}
1030
1031
1032
1033llvm::Error Util::addSymbols(const lld::File &atomFile,
1034 NormalizedFile &file) {
1035 bool rMode = (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT);
1036 // Mach-O symbol table has four regions: stabs, locals, globals, undefs.
1037
1038 // Add all stabs.
1039 for (auto &stab : _stabs) {
1040 Symbol sym;
1041 sym.type = static_cast<NListType>(stab.type);
1042 sym.scope = 0;
1043 sym.sect = stab.other;
1044 sym.desc = stab.desc;
1045 if (stab.atom)
1046 sym.value = _atomToAddress[stab.atom];
1047 else
1048 sym.value = stab.value;
1049 sym.name = stab.str;
1050 file.stabsSymbols.push_back(sym);
1051 }
1052
1053 // Add all local (non-global) symbols in address order
1054 std::vector<AtomAndIndex> globals;
1055 globals.reserve(512);
1056 for (SectionInfo *sect : _sectionInfos) {
1057 for (const AtomInfo &info : sect->atomsAndOffsets) {
1058 const DefinedAtom *atom = info.atom;
1059 if (!atom->name().empty()) {
1060 SymbolScope symbolScope;
1061 bool inGlobalsRegion;
1062 if (auto ec = getSymbolTableRegion(atom, inGlobalsRegion, symbolScope)){
1063 return ec;
1064 }
1065 if (inGlobalsRegion) {
1066 AtomAndIndex ai = { atom, sect->finalSectionIndex, symbolScope };
1067 globals.push_back(ai);
1068 } else {
1069 Symbol sym;
1070 sym.name = atom->name();
1071 sym.type = N_SECT;
1072 sym.scope = symbolScope;
1073 sym.sect = sect->finalSectionIndex;
1074 sym.desc = descBits(atom);
1075 sym.value = _atomToAddress[atom];
1076 _atomToSymbolIndex[atom] = file.localSymbols.size();
1077 file.localSymbols.push_back(sym);
1078 }
1079 } else if (rMode && _archHandler.needsLocalSymbolInRelocatableFile(atom)){
1080 // Create 'Lxxx' labels for anonymous atoms if archHandler says so.
1081 static unsigned tempNum = 1;
1082 char tmpName[16];
1083 sprintf(tmpName, "L%04u", tempNum++);
1084 StringRef tempRef(tmpName);
1085 Symbol sym;
1086 sym.name = tempRef.copy(file.ownedAllocations);
1087 sym.type = N_SECT;
1088 sym.scope = 0;
1089 sym.sect = sect->finalSectionIndex;
1090 sym.desc = 0;
1091 sym.value = _atomToAddress[atom];
1092 _atomToSymbolIndex[atom] = file.localSymbols.size();
1093 file.localSymbols.push_back(sym);
1094 }
1095 }
1096 }
1097
1098 // Sort global symbol alphabetically, then add to symbol table.
1099 std::sort(globals.begin(), globals.end(), AtomSorter());
1100 const uint32_t globalStartIndex = file.localSymbols.size();
1101 for (AtomAndIndex &ai : globals) {
1102 Symbol sym;
1103 sym.name = ai.atom->name();
1104 sym.type = N_SECT;
1105 sym.scope = ai.scope;
1106 sym.sect = ai.index;
1107 sym.desc = descBits(static_cast<const DefinedAtom*>(ai.atom));
1108 sym.value = _atomToAddress[ai.atom];
1109 _atomToSymbolIndex[ai.atom] = globalStartIndex + file.globalSymbols.size();
1110 file.globalSymbols.push_back(sym);
1111 }
1112
1113 // Sort undefined symbol alphabetically, then add to symbol table.
1114 std::vector<AtomAndIndex> undefs;
1115 undefs.reserve(128);
1116 for (const UndefinedAtom *atom : atomFile.undefined()) {
1117 AtomAndIndex ai = { atom, 0, N_EXT };
1118 undefs.push_back(ai);
1119 }
1120 for (const SharedLibraryAtom *atom : atomFile.sharedLibrary()) {
1121 AtomAndIndex ai = { atom, 0, N_EXT };
1122 undefs.push_back(ai);
1123 }
1124 std::sort(undefs.begin(), undefs.end(), AtomSorter());
1125 const uint32_t start = file.globalSymbols.size() + file.localSymbols.size();
1126 for (AtomAndIndex &ai : undefs) {
1127 Symbol sym;
1128 uint16_t desc = 0;
1129 if (!rMode) {
1130 uint8_t ordinal = 0;
1131 if (!_ctx.useFlatNamespace())
1132 ordinal = dylibOrdinal(dyn_cast<SharedLibraryAtom>(ai.atom));
1133 llvm::MachO::SET_LIBRARY_ORDINAL(desc, ordinal);
1134 }
1135 sym.name = ai.atom->name();
1136 sym.type = N_UNDF;
1137 sym.scope = ai.scope;
1138 sym.sect = 0;
1139 sym.desc = desc;
1140 sym.value = 0;
1141 _atomToSymbolIndex[ai.atom] = file.undefinedSymbols.size() + start;
1142 file.undefinedSymbols.push_back(sym);
1143 }
1144
1145 return llvm::Error::success();
1146}
1147
1148const Atom *Util::targetOfLazyPointer(const DefinedAtom *lpAtom) {
1149 for (const Reference *ref : *lpAtom) {
1150 if (_archHandler.isLazyPointer(*ref)) {
1151 return ref->target();
1152 }
1153 }
1154 return nullptr;
1155}
1156
1157const Atom *Util::targetOfStub(const DefinedAtom *stubAtom) {
1158 for (const Reference *ref : *stubAtom) {
1159 if (const Atom *ta = ref->target()) {
1160 if (const DefinedAtom *lpAtom = dyn_cast<DefinedAtom>(ta)) {
1161 const Atom *target = targetOfLazyPointer(lpAtom);
1162 if (target)
1163 return target;
1164 }
1165 }
1166 }
1167 return nullptr;
1168}
1169
1170void Util::addIndirectSymbols(const lld::File &atomFile, NormalizedFile &file) {
1171 for (SectionInfo *si : _sectionInfos) {
1172 Section &normSect = file.sections[si->normalizedSectionIndex];
1173 switch (si->type) {
1174 case llvm::MachO::S_NON_LAZY_SYMBOL_POINTERS:
1175 for (const AtomInfo &info : si->atomsAndOffsets) {
1176 bool foundTarget = false;
1177 for (const Reference *ref : *info.atom) {
1178 const Atom *target = ref->target();
1179 if (target) {
1180 if (isa<const SharedLibraryAtom>(target)) {
1181 uint32_t index = _atomToSymbolIndex[target];
1182 normSect.indirectSymbols.push_back(index);
1183 foundTarget = true;
1184 } else {
1185 normSect.indirectSymbols.push_back(
1186 llvm::MachO::INDIRECT_SYMBOL_LOCAL);
1187 }
1188 }
1189 }
1190 if (!foundTarget) {
1191 normSect.indirectSymbols.push_back(
1192 llvm::MachO::INDIRECT_SYMBOL_ABS);
1193 }
1194 }
1195 break;
1196 case llvm::MachO::S_LAZY_SYMBOL_POINTERS:
1197 for (const AtomInfo &info : si->atomsAndOffsets) {
1198 const Atom *target = targetOfLazyPointer(info.atom);
1199 if (target) {
1200 uint32_t index = _atomToSymbolIndex[target];
1201 normSect.indirectSymbols.push_back(index);
1202 }
1203 }
1204 break;
1205 case llvm::MachO::S_SYMBOL_STUBS:
1206 for (const AtomInfo &info : si->atomsAndOffsets) {
1207 const Atom *target = targetOfStub(info.atom);
1208 if (target) {
1209 uint32_t index = _atomToSymbolIndex[target];
1210 normSect.indirectSymbols.push_back(index);
1211 }
1212 }
1213 break;
1214 default:
1215 break;
1216 }
1217 }
1218}
1219
1220void Util::addDependentDylibs(const lld::File &atomFile,
1221 NormalizedFile &nFile) {
1222 // Scan all imported symbols and build up list of dylibs they are from.
1223 int ordinal = 1;
1224 for (const auto *dylib : _ctx.allDylibs()) {
1225 DylibPathToInfo::iterator pos = _dylibInfo.find(dylib->installName());
1226 if (pos == _dylibInfo.end()) {
1227 DylibInfo info;
1228 bool flatNamespaceAtom = dylib == _ctx.flatNamespaceFile();
1229
1230 // If we're in -flat_namespace mode (or this atom came from the flat
1231 // namespace file under -undefined dynamic_lookup) then use the flat
1232 // lookup ordinal.
1233 if (flatNamespaceAtom || _ctx.useFlatNamespace())
1234 info.ordinal = BIND_SPECIAL_DYLIB_FLAT_LOOKUP;
1235 else
1236 info.ordinal = ordinal++;
1237 info.hasWeak = false;
1238 info.hasNonWeak = !info.hasWeak;
1239 _dylibInfo[dylib->installName()] = info;
1240
1241 // Unless this was a flat_namespace atom, record the source dylib.
1242 if (!flatNamespaceAtom) {
1243 DependentDylib depInfo;
1244 depInfo.path = dylib->installName();
1245 depInfo.kind = llvm::MachO::LC_LOAD_DYLIB;
1246 depInfo.currentVersion = _ctx.dylibCurrentVersion(dylib->path());
1247 depInfo.compatVersion = _ctx.dylibCompatVersion(dylib->path());
1248 nFile.dependentDylibs.push_back(depInfo);
1249 }
1250 } else {
1251 pos->second.hasWeak = false;
1252 pos->second.hasNonWeak = !pos->second.hasWeak;
1253 }
1254 }
1255 // Automatically weak link dylib in which all symbols are weak (canBeNull).
1256 for (DependentDylib &dep : nFile.dependentDylibs) {
1257 DylibInfo &info = _dylibInfo[dep.path];
1258 if (info.hasWeak && !info.hasNonWeak)
1259 dep.kind = llvm::MachO::LC_LOAD_WEAK_DYLIB;
1260 else if (_ctx.isUpwardDylib(dep.path))
1261 dep.kind = llvm::MachO::LC_LOAD_UPWARD_DYLIB;
1262 }
1263}
1264
1265int Util::dylibOrdinal(const SharedLibraryAtom *sa) {
1266 return _dylibInfo[sa->loadName()].ordinal;
1267}
1268
1269void Util::segIndexForSection(const SectionInfo *sect, uint8_t &segmentIndex,
1270 uint64_t &segmentStartAddr) {
1271 segmentIndex = 0;
1272 for (const SegmentInfo *seg : _segmentInfos) {
1273 if ((seg->address <= sect->address)
1274 && (seg->address+seg->size >= sect->address+sect->size)) {
1275 segmentStartAddr = seg->address;
1276 return;
1277 }
1278 ++segmentIndex;
1279 }
1280 llvm_unreachable("section not in any segment");
1281}
1282
1283uint32_t Util::sectionIndexForAtom(const Atom *atom) {
1284 uint64_t address = _atomToAddress[atom];
1285 for (const SectionInfo *si : _sectionInfos) {
1286 if ((si->address <= address) && (address < si->address+si->size))
1287 return si->finalSectionIndex;
1288 }
1289 llvm_unreachable("atom not in any section");
1290}
1291
1292void Util::addSectionRelocs(const lld::File &, NormalizedFile &file) {
1293 if (_ctx.outputMachOType() != llvm::MachO::MH_OBJECT)
1294 return;
1295
1296 // Utility function for ArchHandler to find symbol index for an atom.
1297 auto symIndexForAtom = [&] (const Atom &atom) -> uint32_t {
1298 auto pos = _atomToSymbolIndex.find(&atom);
1299 assert(pos != _atomToSymbolIndex.end());
1300 return pos->second;
1301 };
1302
1303 // Utility function for ArchHandler to find section index for an atom.
1304 auto sectIndexForAtom = [&] (const Atom &atom) -> uint32_t {
1305 return sectionIndexForAtom(&atom);
1306 };
1307
1308 // Utility function for ArchHandler to find address of atom in output file.
1309 auto addressForAtom = [&] (const Atom &atom) -> uint64_t {
1310 auto pos = _atomToAddress.find(&atom);
1311 assert(pos != _atomToAddress.end());
1312 return pos->second;
1313 };
1314
1315 for (SectionInfo *si : _sectionInfos) {
1316 Section &normSect = file.sections[si->normalizedSectionIndex];
1317 for (const AtomInfo &info : si->atomsAndOffsets) {
1318 const DefinedAtom *atom = info.atom;
1319 for (const Reference *ref : *atom) {
1320 // Skip emitting relocs for sections which are always able to be
1321 // implicitly regenerated and where the relocation targets an address
1322 // which is defined.
1323 if (si->relocsToDefinedCanBeImplicit && isa<DefinedAtom>(ref->target()))
1324 continue;
1325 _archHandler.appendSectionRelocations(*atom, info.offsetInSection, *ref,
1326 symIndexForAtom,
1327 sectIndexForAtom,
1328 addressForAtom,
1329 normSect.relocations);
1330 }
1331 }
1332 }
1333}
1334
1335void Util::addFunctionStarts(const lld::File &, NormalizedFile &file) {
1336 if (!_ctx.generateFunctionStartsLoadCommand())
1337 return;
1338 file.functionStarts.reserve(8192);
1339 // Delta compress function starts, starting with the mach header symbol.
1340 const uint64_t badAddress = ~0ULL;
1341 uint64_t addr = badAddress;
1342 for (SectionInfo *si : _sectionInfos) {
1343 for (const AtomInfo &info : si->atomsAndOffsets) {
1344 auto type = info.atom->contentType();
1345 if (type == DefinedAtom::typeMachHeader) {
1346 addr = _atomToAddress[info.atom];
1347 continue;
1348 }
1349 if (type != DefinedAtom::typeCode)
1350 continue;
1351 assert(addr != badAddress && "Missing mach header symbol");
1352 // Skip atoms which have 0 size. This is so that LC_FUNCTION_STARTS
1353 // can't spill in to the next section.
1354 if (!info.atom->size())
1355 continue;
1356 uint64_t nextAddr = _atomToAddress[info.atom];
1357 if (_archHandler.isThumbFunction(*info.atom))
1358 nextAddr |= 1;
1359 uint64_t delta = nextAddr - addr;
1360 if (delta) {
1361 ByteBuffer buffer;
1362 buffer.append_uleb128(delta);
1363 file.functionStarts.insert(file.functionStarts.end(), buffer.bytes(),
1364 buffer.bytes() + buffer.size());
1365 }
1366 addr = nextAddr;
1367 }
1368 }
1369
1370 // Null terminate, and pad to pointer size for this arch.
1371 file.functionStarts.push_back(0);
1372
1373 auto size = file.functionStarts.size();
1374 for (unsigned i = size, e = llvm::alignTo(size, _ctx.is64Bit() ? 8 : 4);
1375 i != e; ++i)
1376 file.functionStarts.push_back(0);
1377}
1378
1379void Util::buildDataInCodeArray(const lld::File &, NormalizedFile &file) {
1380 if (!_ctx.generateDataInCodeLoadCommand())
1381 return;
1382 for (SectionInfo *si : _sectionInfos) {
1383 for (const AtomInfo &info : si->atomsAndOffsets) {
1384 // Atoms that contain data-in-code have "transition" references
1385 // which mark a point where the embedded data starts of ends.
1386 // This needs to be converted to the mach-o format which is an array
1387 // of data-in-code ranges.
1388 uint32_t startOffset = 0;
1389 DataRegionType mode = DataRegionType(0);
1390 for (const Reference *ref : *info.atom) {
1391 if (ref->kindNamespace() != Reference::KindNamespace::mach_o)
1392 continue;
1393 if (_archHandler.isDataInCodeTransition(ref->kindValue())) {
1394 DataRegionType nextMode = (DataRegionType)ref->addend();
1395 if (mode != nextMode) {
1396 if (mode != 0) {
1397 // Found end data range, so make range entry.
1398 DataInCode entry;
1399 entry.offset = si->address + info.offsetInSection + startOffset;
1400 entry.length = ref->offsetInAtom() - startOffset;
1401 entry.kind = mode;
1402 file.dataInCode.push_back(entry);
1403 }
1404 }
1405 mode = nextMode;
1406 startOffset = ref->offsetInAtom();
1407 }
1408 }
1409 if (mode != 0) {
1410 // Function ends with data (no end transition).
1411 DataInCode entry;
1412 entry.offset = si->address + info.offsetInSection + startOffset;
1413 entry.length = info.atom->size() - startOffset;
1414 entry.kind = mode;
1415 file.dataInCode.push_back(entry);
1416 }
1417 }
1418 }
1419}
1420
1421void Util::addRebaseAndBindingInfo(const lld::File &atomFile,
1422 NormalizedFile &nFile) {
1423 if (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT)
1424 return;
1425
1426 uint8_t segmentIndex;
1427 uint64_t segmentStartAddr;
1428 uint32_t offsetInBindInfo = 0;
1429
1430 for (SectionInfo *sect : _sectionInfos) {
1431 segIndexForSection(sect, segmentIndex, segmentStartAddr);
1432 for (const AtomInfo &info : sect->atomsAndOffsets) {
1433 const DefinedAtom *atom = info.atom;
1434 for (const Reference *ref : *atom) {
1435 uint64_t segmentOffset = _atomToAddress[atom] + ref->offsetInAtom()
1436 - segmentStartAddr;
1437 const Atom* targ = ref->target();
1438 if (_archHandler.isPointer(*ref)) {
1439 // A pointer to a DefinedAtom requires rebasing.
1440 if (isa<DefinedAtom>(targ)) {
1441 RebaseLocation rebase;
1442 rebase.segIndex = segmentIndex;
1443 rebase.segOffset = segmentOffset;
1444 rebase.kind = llvm::MachO::REBASE_TYPE_POINTER;
1445 nFile.rebasingInfo.push_back(rebase);
1446 }
1447 // A pointer to an SharedLibraryAtom requires binding.
1448 if (const SharedLibraryAtom *sa = dyn_cast<SharedLibraryAtom>(targ)) {
1449 BindLocation bind;
1450 bind.segIndex = segmentIndex;
1451 bind.segOffset = segmentOffset;
1452 bind.kind = llvm::MachO::BIND_TYPE_POINTER;
1453 bind.canBeNull = sa->canBeNullAtRuntime();
1454 bind.ordinal = dylibOrdinal(sa);
1455 bind.symbolName = targ->name();
1456 bind.addend = ref->addend();
1457 nFile.bindingInfo.push_back(bind);
1458 }
1459 }
1460 else if (_archHandler.isLazyPointer(*ref)) {
1461 BindLocation bind;
1462 if (const SharedLibraryAtom *sa = dyn_cast<SharedLibraryAtom>(targ)) {
1463 bind.ordinal = dylibOrdinal(sa);
1464 } else {
1465 bind.ordinal = llvm::MachO::BIND_SPECIAL_DYLIB_SELF;
1466 }
1467 bind.segIndex = segmentIndex;
1468 bind.segOffset = segmentOffset;
1469 bind.kind = llvm::MachO::BIND_TYPE_POINTER;
1470 bind.canBeNull = false; //sa->canBeNullAtRuntime();
1471 bind.symbolName = targ->name();
1472 bind.addend = ref->addend();
1473 nFile.lazyBindingInfo.push_back(bind);
1474
1475 // Now that we know the segmentOffset and the ordinal attribute,
1476 // we can fix the helper's code
1477
1478 fixLazyReferenceImm(atom, offsetInBindInfo, nFile);
1479
1480 // 5 bytes for opcodes + variable sizes (target name + \0 and offset
1481 // encode's size)
1482 offsetInBindInfo +=
1483 6 + targ->name().size() + llvm::getULEB128Size(bind.segOffset);
1484 if (bind.ordinal > BIND_IMMEDIATE_MASK)
1485 offsetInBindInfo += llvm::getULEB128Size(bind.ordinal);
1486 }
1487 }
1488 }
1489 }
1490}
1491
1492void Util::fixLazyReferenceImm(const DefinedAtom *atom, uint32_t offset,
1493 NormalizedFile &file) {
1494 for (const auto &ref : *atom) {
1495 const DefinedAtom *da = dyn_cast<DefinedAtom>(ref->target());
1496 if (da == nullptr)
1497 return;
1498
1499 const Reference *helperRef = nullptr;
1500 for (const Reference *hr : *da) {
1501 if (hr->kindValue() == _archHandler.lazyImmediateLocationKind()) {
1502 helperRef = hr;
1503 break;
1504 }
1505 }
1506 if (helperRef == nullptr)
1507 continue;
1508
1509 // TODO: maybe get the fixed atom content from _archHandler ?
1510 for (SectionInfo *sectInfo : _sectionInfos) {
1511 for (const AtomInfo &atomInfo : sectInfo->atomsAndOffsets) {
1512 if (atomInfo.atom == helperRef->target()) {
1513 auto sectionContent =
1514 file.sections[sectInfo->normalizedSectionIndex].content;
1515 uint8_t *rawb =
1516 file.ownedAllocations.Allocate<uint8_t>(sectionContent.size());
1517 llvm::MutableArrayRef<uint8_t> newContent{rawb,
1518 sectionContent.size()};
1519 std::copy(sectionContent.begin(), sectionContent.end(),
1520 newContent.begin());
1521 llvm::support::ulittle32_t *loc =
1522 reinterpret_cast<llvm::support::ulittle32_t *>(
1523 &newContent[atomInfo.offsetInSection +
1524 helperRef->offsetInAtom()]);
1525 *loc = offset;
1526 file.sections[sectInfo->normalizedSectionIndex].content = newContent;
1527 }
1528 }
1529 }
1530 }
1531}
1532
1533void Util::addExportInfo(const lld::File &atomFile, NormalizedFile &nFile) {
1534 if (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT)
1535 return;
1536
1537 for (SectionInfo *sect : _sectionInfos) {
1538 for (const AtomInfo &info : sect->atomsAndOffsets) {
1539 const DefinedAtom *atom = info.atom;
1540 if (atom->scope() != Atom::scopeGlobal)
1541 continue;
1542 if (_ctx.exportRestrictMode()) {
1543 if (!_ctx.exportSymbolNamed(atom->name()))
1544 continue;
1545 }
1546 Export exprt;
1547 exprt.name = atom->name();
1548 exprt.offset = _atomToAddress[atom] - _ctx.baseAddress();
1549 exprt.kind = EXPORT_SYMBOL_FLAGS_KIND_REGULAR;
1550 if (atom->merge() == DefinedAtom::mergeAsWeak)
1551 exprt.flags = EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION;
1552 else
1553 exprt.flags = 0;
1554 exprt.otherOffset = 0;
1555 exprt.otherName = StringRef();
1556 nFile.exportInfo.push_back(exprt);
1557 }
1558 }
1559}
1560
1561uint32_t Util::fileFlags() {
1562 // FIXME: these need to determined at runtime.
1563 if (_ctx.outputMachOType() == MH_OBJECT) {
1564 return _subsectionsViaSymbols ? MH_SUBSECTIONS_VIA_SYMBOLS : 0;
1565 } else {
1566 uint32_t flags = MH_DYLDLINK;
1567 if (!_ctx.useFlatNamespace())
1568 flags |= MH_TWOLEVEL | MH_NOUNDEFS;
1569 if ((_ctx.outputMachOType() == MH_EXECUTE) && _ctx.PIE())
1570 flags |= MH_PIE;
1571 if (_hasTLVDescriptors)
1572 flags |= (MH_PIE | MH_HAS_TLV_DESCRIPTORS);
1573 return flags;
1574 }
1575}
1576
1577} // end anonymous namespace
1578
1579namespace lld {
1580namespace mach_o {
1581namespace normalized {
1582
1583/// Convert a set of Atoms into a normalized mach-o file.
1584llvm::Expected<std::unique_ptr<NormalizedFile>>
1585normalizedFromAtoms(const lld::File &atomFile,
1586 const MachOLinkingContext &context) {
1587 // The util object buffers info until the normalized file can be made.
1588 Util util(context);
1589 util.processDefinedAtoms(atomFile);
1590 util.organizeSections();
1591
1592 std::unique_ptr<NormalizedFile> f(new NormalizedFile());
1593 NormalizedFile &normFile = *f.get();
1594 normFile.arch = context.arch();
1595 normFile.fileType = context.outputMachOType();
1596 normFile.flags = util.fileFlags();
1597 normFile.stackSize = context.stackSize();
1598 normFile.installName = context.installName();
1599 normFile.currentVersion = context.currentVersion();
1600 normFile.compatVersion = context.compatibilityVersion();
1601 normFile.os = context.os();
1602
1603 // If we are emitting an object file, then the min version is the maximum
1604 // of the min's of all the source files and the cmdline.
1605 if (normFile.fileType == llvm::MachO::MH_OBJECT)
1606 normFile.minOSverson = std::max(context.osMinVersion(), util.minVersion());
1607 else
1608 normFile.minOSverson = context.osMinVersion();
1609
1610 normFile.minOSVersionKind = util.minVersionCommandType();
1611
1612 normFile.sdkVersion = context.sdkVersion();
1613 normFile.sourceVersion = context.sourceVersion();
1614
1615 if (context.generateVersionLoadCommand() &&
1616 context.os() != MachOLinkingContext::OS::unknown)
1617 normFile.hasMinVersionLoadCommand = true;
1618 else if (normFile.fileType == llvm::MachO::MH_OBJECT &&
1619 util.allSourceFilesHaveMinVersions() &&
1620 ((normFile.os != MachOLinkingContext::OS::unknown) ||
1621 util.minVersionCommandType())) {
1622 // If we emit an object file, then it should contain a min version load
1623 // command if all of the source files also contained min version commands.
1624 // Also, we either need to have a platform, or found a platform from the
1625 // source object files.
1626 normFile.hasMinVersionLoadCommand = true;
1627 }
1628 normFile.generateDataInCodeLoadCommand =
1629 context.generateDataInCodeLoadCommand();
1630 normFile.pageSize = context.pageSize();
1631 normFile.rpaths = context.rpaths();
1632 util.addDependentDylibs(atomFile, normFile);
1633 util.copySegmentInfo(normFile);
1634 util.copySectionInfo(normFile);
1635 util.assignAddressesToSections(normFile);
1636 util.buildAtomToAddressMap();
1637 if (auto err = util.synthesizeDebugNotes(normFile))
1638 return std::move(err);
1639 util.updateSectionInfo(normFile);
1640 util.copySectionContent(normFile);
1641 if (auto ec = util.addSymbols(atomFile, normFile)) {
1642 return std::move(ec);
1643 }
1644 util.addIndirectSymbols(atomFile, normFile);
1645 util.addRebaseAndBindingInfo(atomFile, normFile);
1646 util.addExportInfo(atomFile, normFile);
1647 util.addSectionRelocs(atomFile, normFile);
1648 util.addFunctionStarts(atomFile, normFile);
1649 util.buildDataInCodeArray(atomFile, normFile);
1650 util.copyEntryPointAddress(normFile);
1651
1652 return std::move(f);
1653}
1654
1655} // namespace normalized
1656} // namespace mach_o
1657} // namespace lld
deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp created+1635
......@@ -0,0 +1,1635 @@
1//===- lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp --------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10///
11/// \file Converts from in-memory normalized mach-o to in-memory Atoms.
12///
13/// +------------+
14/// | normalized |
15/// +------------+
16/// |
17/// |
18/// v
19/// +-------+
20/// | Atoms |
21/// +-------+
22
23#include "ArchHandler.h"
24#include "Atoms.h"
25#include "File.h"
26#include "MachONormalizedFile.h"
27#include "MachONormalizedFileBinaryUtils.h"
28#include "lld/Core/Error.h"
29#include "lld/Core/LLVM.h"
30#include "llvm/BinaryFormat/Dwarf.h"
31#include "llvm/BinaryFormat/MachO.h"
32#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
33#include "llvm/Support/DataExtractor.h"
34#include "llvm/Support/Debug.h"
35#include "llvm/Support/Error.h"
36#include "llvm/Support/Format.h"
37#include "llvm/Support/LEB128.h"
38#include "llvm/Support/raw_ostream.h"
39
40using namespace llvm::MachO;
41using namespace lld::mach_o::normalized;
42
43#define DEBUG_TYPE "normalized-file-to-atoms"
44
45namespace lld {
46namespace mach_o {
47
48
49namespace { // anonymous
50
51
52#define ENTRY(seg, sect, type, atomType) \
53 {seg, sect, type, DefinedAtom::atomType }
54
55struct MachORelocatableSectionToAtomType {
56 StringRef segmentName;
57 StringRef sectionName;
58 SectionType sectionType;
59 DefinedAtom::ContentType atomType;
60};
61
62const MachORelocatableSectionToAtomType sectsToAtomType[] = {
63 ENTRY("__TEXT", "__text", S_REGULAR, typeCode),
64 ENTRY("__TEXT", "__text", S_REGULAR, typeResolver),
65 ENTRY("__TEXT", "__cstring", S_CSTRING_LITERALS, typeCString),
66 ENTRY("", "", S_CSTRING_LITERALS, typeCString),
67 ENTRY("__TEXT", "__ustring", S_REGULAR, typeUTF16String),
68 ENTRY("__TEXT", "__const", S_REGULAR, typeConstant),
69 ENTRY("__TEXT", "__const_coal", S_COALESCED, typeConstant),
70 ENTRY("__TEXT", "__eh_frame", S_COALESCED, typeCFI),
71 ENTRY("__TEXT", "__eh_frame", S_REGULAR, typeCFI),
72 ENTRY("__TEXT", "__literal4", S_4BYTE_LITERALS, typeLiteral4),
73 ENTRY("__TEXT", "__literal8", S_8BYTE_LITERALS, typeLiteral8),
74 ENTRY("__TEXT", "__literal16", S_16BYTE_LITERALS, typeLiteral16),
75 ENTRY("__TEXT", "__gcc_except_tab", S_REGULAR, typeLSDA),
76 ENTRY("__DATA", "__data", S_REGULAR, typeData),
77 ENTRY("__DATA", "__datacoal_nt", S_COALESCED, typeData),
78 ENTRY("__DATA", "__const", S_REGULAR, typeConstData),
79 ENTRY("__DATA", "__cfstring", S_REGULAR, typeCFString),
80 ENTRY("__DATA", "__mod_init_func", S_MOD_INIT_FUNC_POINTERS,
81 typeInitializerPtr),
82 ENTRY("__DATA", "__mod_term_func", S_MOD_TERM_FUNC_POINTERS,
83 typeTerminatorPtr),
84 ENTRY("__DATA", "__got", S_NON_LAZY_SYMBOL_POINTERS,
85 typeGOT),
86 ENTRY("__DATA", "__bss", S_ZEROFILL, typeZeroFill),
87 ENTRY("", "", S_NON_LAZY_SYMBOL_POINTERS,
88 typeGOT),
89 ENTRY("__DATA", "__interposing", S_INTERPOSING, typeInterposingTuples),
90 ENTRY("__DATA", "__thread_vars", S_THREAD_LOCAL_VARIABLES,
91 typeThunkTLV),
92 ENTRY("__DATA", "__thread_data", S_THREAD_LOCAL_REGULAR, typeTLVInitialData),
93 ENTRY("__DATA", "__thread_bss", S_THREAD_LOCAL_ZEROFILL,
94 typeTLVInitialZeroFill),
95 ENTRY("__DATA", "__objc_imageinfo", S_REGULAR, typeObjCImageInfo),
96 ENTRY("__DATA", "__objc_catlist", S_REGULAR, typeObjC2CategoryList),
97 ENTRY("", "", S_INTERPOSING, typeInterposingTuples),
98 ENTRY("__LD", "__compact_unwind", S_REGULAR,
99 typeCompactUnwindInfo),
100 ENTRY("", "", S_REGULAR, typeUnknown)
101};
102#undef ENTRY
103
104
105/// Figures out ContentType of a mach-o section.
106DefinedAtom::ContentType atomTypeFromSection(const Section &section,
107 bool &customSectionName) {
108 // First look for match of name and type. Empty names in table are wildcards.
109 customSectionName = false;
110 for (const MachORelocatableSectionToAtomType *p = sectsToAtomType ;
111 p->atomType != DefinedAtom::typeUnknown; ++p) {
112 if (p->sectionType != section.type)
113 continue;
114 if (!p->segmentName.equals(section.segmentName) && !p->segmentName.empty())
115 continue;
116 if (!p->sectionName.equals(section.sectionName) && !p->sectionName.empty())
117 continue;
118 customSectionName = p->segmentName.empty() && p->sectionName.empty();
119 return p->atomType;
120 }
121 // Look for code denoted by section attributes
122 if (section.attributes & S_ATTR_PURE_INSTRUCTIONS)
123 return DefinedAtom::typeCode;
124
125 return DefinedAtom::typeUnknown;
126}
127
128enum AtomizeModel {
129 atomizeAtSymbols,
130 atomizeFixedSize,
131 atomizePointerSize,
132 atomizeUTF8,
133 atomizeUTF16,
134 atomizeCFI,
135 atomizeCU,
136 atomizeCFString
137};
138
139/// Returns info on how to atomize a section of the specified ContentType.
140void sectionParseInfo(DefinedAtom::ContentType atomType,
141 unsigned int &sizeMultiple,
142 DefinedAtom::Scope &scope,
143 DefinedAtom::Merge &merge,
144 AtomizeModel &atomizeModel) {
145 struct ParseInfo {
146 DefinedAtom::ContentType atomType;
147 unsigned int sizeMultiple;
148 DefinedAtom::Scope scope;
149 DefinedAtom::Merge merge;
150 AtomizeModel atomizeModel;
151 };
152
153 #define ENTRY(type, size, scope, merge, model) \
154 {DefinedAtom::type, size, DefinedAtom::scope, DefinedAtom::merge, model }
155
156 static const ParseInfo parseInfo[] = {
157 ENTRY(typeCode, 1, scopeGlobal, mergeNo,
158 atomizeAtSymbols),
159 ENTRY(typeData, 1, scopeGlobal, mergeNo,
160 atomizeAtSymbols),
161 ENTRY(typeConstData, 1, scopeGlobal, mergeNo,
162 atomizeAtSymbols),
163 ENTRY(typeZeroFill, 1, scopeGlobal, mergeNo,
164 atomizeAtSymbols),
165 ENTRY(typeConstant, 1, scopeGlobal, mergeNo,
166 atomizeAtSymbols),
167 ENTRY(typeCString, 1, scopeLinkageUnit, mergeByContent,
168 atomizeUTF8),
169 ENTRY(typeUTF16String, 1, scopeLinkageUnit, mergeByContent,
170 atomizeUTF16),
171 ENTRY(typeCFI, 4, scopeTranslationUnit, mergeNo,
172 atomizeCFI),
173 ENTRY(typeLiteral4, 4, scopeLinkageUnit, mergeByContent,
174 atomizeFixedSize),
175 ENTRY(typeLiteral8, 8, scopeLinkageUnit, mergeByContent,
176 atomizeFixedSize),
177 ENTRY(typeLiteral16, 16, scopeLinkageUnit, mergeByContent,
178 atomizeFixedSize),
179 ENTRY(typeCFString, 4, scopeLinkageUnit, mergeByContent,
180 atomizeCFString),
181 ENTRY(typeInitializerPtr, 4, scopeTranslationUnit, mergeNo,
182 atomizePointerSize),
183 ENTRY(typeTerminatorPtr, 4, scopeTranslationUnit, mergeNo,
184 atomizePointerSize),
185 ENTRY(typeCompactUnwindInfo, 4, scopeTranslationUnit, mergeNo,
186 atomizeCU),
187 ENTRY(typeGOT, 4, scopeLinkageUnit, mergeByContent,
188 atomizePointerSize),
189 ENTRY(typeObjC2CategoryList, 4, scopeTranslationUnit, mergeByContent,
190 atomizePointerSize),
191 ENTRY(typeUnknown, 1, scopeGlobal, mergeNo,
192 atomizeAtSymbols)
193 };
194 #undef ENTRY
195 const int tableLen = sizeof(parseInfo) / sizeof(ParseInfo);
196 for (int i=0; i < tableLen; ++i) {
197 if (parseInfo[i].atomType == atomType) {
198 sizeMultiple = parseInfo[i].sizeMultiple;
199 scope = parseInfo[i].scope;
200 merge = parseInfo[i].merge;
201 atomizeModel = parseInfo[i].atomizeModel;
202 return;
203 }
204 }
205
206 // Unknown type is atomized by symbols.
207 sizeMultiple = 1;
208 scope = DefinedAtom::scopeGlobal;
209 merge = DefinedAtom::mergeNo;
210 atomizeModel = atomizeAtSymbols;
211}
212
213
214Atom::Scope atomScope(uint8_t scope) {
215 switch (scope) {
216 case N_EXT:
217 return Atom::scopeGlobal;
218 case N_PEXT:
219 case N_PEXT | N_EXT:
220 return Atom::scopeLinkageUnit;
221 case 0:
222 return Atom::scopeTranslationUnit;
223 }
224 llvm_unreachable("unknown scope value!");
225}
226
227void appendSymbolsInSection(const std::vector<Symbol> &inSymbols,
228 uint32_t sectionIndex,
229 SmallVector<const Symbol *, 64> &outSyms) {
230 for (const Symbol &sym : inSymbols) {
231 // Only look at definition symbols.
232 if ((sym.type & N_TYPE) != N_SECT)
233 continue;
234 if (sym.sect != sectionIndex)
235 continue;
236 outSyms.push_back(&sym);
237 }
238}
239
240void atomFromSymbol(DefinedAtom::ContentType atomType, const Section &section,
241 MachOFile &file, uint64_t symbolAddr, StringRef symbolName,
242 uint16_t symbolDescFlags, Atom::Scope symbolScope,
243 uint64_t nextSymbolAddr, bool scatterable, bool copyRefs) {
244 // Mach-O symbol table does have size in it. Instead the size is the
245 // difference between this and the next symbol.
246 uint64_t size = nextSymbolAddr - symbolAddr;
247 uint64_t offset = symbolAddr - section.address;
248 bool noDeadStrip = (symbolDescFlags & N_NO_DEAD_STRIP) || !scatterable;
249 if (isZeroFillSection(section.type)) {
250 file.addZeroFillDefinedAtom(symbolName, symbolScope, offset, size,
251 noDeadStrip, copyRefs, &section);
252 } else {
253 DefinedAtom::Merge merge = (symbolDescFlags & N_WEAK_DEF)
254 ? DefinedAtom::mergeAsWeak : DefinedAtom::mergeNo;
255 bool thumb = (symbolDescFlags & N_ARM_THUMB_DEF);
256 if (atomType == DefinedAtom::typeUnknown) {
257 // Mach-O needs a segment and section name. Concatentate those two
258 // with a / separator (e.g. "seg/sect") to fit into the lld model
259 // of just a section name.
260 std::string segSectName = section.segmentName.str()
261 + "/" + section.sectionName.str();
262 file.addDefinedAtomInCustomSection(symbolName, symbolScope, atomType,
263 merge, thumb, noDeadStrip, offset,
264 size, segSectName, true, &section);
265 } else {
266 if ((atomType == lld::DefinedAtom::typeCode) &&
267 (symbolDescFlags & N_SYMBOL_RESOLVER)) {
268 atomType = lld::DefinedAtom::typeResolver;
269 }
270 file.addDefinedAtom(symbolName, symbolScope, atomType, merge,
271 offset, size, thumb, noDeadStrip, copyRefs, &section);
272 }
273 }
274}
275
276llvm::Error processSymboledSection(DefinedAtom::ContentType atomType,
277 const Section &section,
278 const NormalizedFile &normalizedFile,
279 MachOFile &file, bool scatterable,
280 bool copyRefs) {
281 // Find section's index.
282 uint32_t sectIndex = 1;
283 for (auto &sect : normalizedFile.sections) {
284 if (&sect == &section)
285 break;
286 ++sectIndex;
287 }
288
289 // Find all symbols in this section.
290 SmallVector<const Symbol *, 64> symbols;
291 appendSymbolsInSection(normalizedFile.globalSymbols, sectIndex, symbols);
292 appendSymbolsInSection(normalizedFile.localSymbols, sectIndex, symbols);
293
294 // Sort symbols.
295 std::sort(symbols.begin(), symbols.end(),
296 [](const Symbol *lhs, const Symbol *rhs) -> bool {
297 if (lhs == rhs)
298 return false;
299 // First by address.
300 uint64_t lhsAddr = lhs->value;
301 uint64_t rhsAddr = rhs->value;
302 if (lhsAddr != rhsAddr)
303 return lhsAddr < rhsAddr;
304 // If same address, one is an alias so sort by scope.
305 Atom::Scope lScope = atomScope(lhs->scope);
306 Atom::Scope rScope = atomScope(rhs->scope);
307 if (lScope != rScope)
308 return lScope < rScope;
309 // If same address and scope, see if one might be better as
310 // the alias.
311 bool lPrivate = (lhs->name.front() == 'l');
312 bool rPrivate = (rhs->name.front() == 'l');
313 if (lPrivate != rPrivate)
314 return lPrivate;
315 // If same address and scope, sort by name.
316 return lhs->name < rhs->name;
317 });
318
319 // Debug logging of symbols.
320 //for (const Symbol *sym : symbols)
321 // llvm::errs() << " sym: "
322 // << llvm::format("0x%08llx ", (uint64_t)sym->value)
323 // << ", " << sym->name << "\n";
324
325 // If section has no symbols and no content, there are no atoms.
326 if (symbols.empty() && section.content.empty())
327 return llvm::Error::success();
328
329 if (symbols.empty()) {
330 // Section has no symbols, put all content in one anoymous atom.
331 atomFromSymbol(atomType, section, file, section.address, StringRef(),
332 0, Atom::scopeTranslationUnit,
333 section.address + section.content.size(),
334 scatterable, copyRefs);
335 }
336 else if (symbols.front()->value != section.address) {
337 // Section has anonymous content before first symbol.
338 atomFromSymbol(atomType, section, file, section.address, StringRef(),
339 0, Atom::scopeTranslationUnit, symbols.front()->value,
340 scatterable, copyRefs);
341 }
342
343 const Symbol *lastSym = nullptr;
344 for (const Symbol *sym : symbols) {
345 if (lastSym != nullptr) {
346 // Ignore any assembler added "ltmpNNN" symbol at start of section
347 // if there is another symbol at the start.
348 if ((lastSym->value != sym->value)
349 || lastSym->value != section.address
350 || !lastSym->name.startswith("ltmp")) {
351 atomFromSymbol(atomType, section, file, lastSym->value, lastSym->name,
352 lastSym->desc, atomScope(lastSym->scope), sym->value,
353 scatterable, copyRefs);
354 }
355 }
356 lastSym = sym;
357 }
358 if (lastSym != nullptr) {
359 atomFromSymbol(atomType, section, file, lastSym->value, lastSym->name,
360 lastSym->desc, atomScope(lastSym->scope),
361 section.address + section.content.size(),
362 scatterable, copyRefs);
363 }
364
365 // If object built without .subsections_via_symbols, add reference chain.
366 if (!scatterable) {
367 MachODefinedAtom *prevAtom = nullptr;
368 file.eachAtomInSection(section,
369 [&](MachODefinedAtom *atom, uint64_t offset)->void {
370 if (prevAtom)
371 prevAtom->addReference(Reference::KindNamespace::all,
372 Reference::KindArch::all,
373 Reference::kindLayoutAfter, 0, atom, 0);
374 prevAtom = atom;
375 });
376 }
377
378 return llvm::Error::success();
379}
380
381llvm::Error processSection(DefinedAtom::ContentType atomType,
382 const Section &section,
383 bool customSectionName,
384 const NormalizedFile &normalizedFile,
385 MachOFile &file, bool scatterable,
386 bool copyRefs) {
387 const bool is64 = MachOLinkingContext::is64Bit(normalizedFile.arch);
388 const bool isBig = MachOLinkingContext::isBigEndian(normalizedFile.arch);
389
390 // Get info on how to atomize section.
391 unsigned int sizeMultiple;
392 DefinedAtom::Scope scope;
393 DefinedAtom::Merge merge;
394 AtomizeModel atomizeModel;
395 sectionParseInfo(atomType, sizeMultiple, scope, merge, atomizeModel);
396
397 // Validate section size.
398 if ((section.content.size() % sizeMultiple) != 0)
399 return llvm::make_error<GenericError>(Twine("Section ")
400 + section.segmentName
401 + "/" + section.sectionName
402 + " has size ("
403 + Twine(section.content.size())
404 + ") which is not a multiple of "
405 + Twine(sizeMultiple));
406
407 if (atomizeModel == atomizeAtSymbols) {
408 // Break section up into atoms each with a fixed size.
409 return processSymboledSection(atomType, section, normalizedFile, file,
410 scatterable, copyRefs);
411 } else {
412 unsigned int size;
413 for (unsigned int offset = 0, e = section.content.size(); offset != e;) {
414 switch (atomizeModel) {
415 case atomizeFixedSize:
416 // Break section up into atoms each with a fixed size.
417 size = sizeMultiple;
418 break;
419 case atomizePointerSize:
420 // Break section up into atoms each the size of a pointer.
421 size = is64 ? 8 : 4;
422 break;
423 case atomizeUTF8:
424 // Break section up into zero terminated c-strings.
425 size = 0;
426 for (unsigned int i = offset; i < e; ++i) {
427 if (section.content[i] == 0) {
428 size = i + 1 - offset;
429 break;
430 }
431 }
432 break;
433 case atomizeUTF16:
434 // Break section up into zero terminated UTF16 strings.
435 size = 0;
436 for (unsigned int i = offset; i < e; i += 2) {
437 if ((section.content[i] == 0) && (section.content[i + 1] == 0)) {
438 size = i + 2 - offset;
439 break;
440 }
441 }
442 break;
443 case atomizeCFI:
444 // Break section up into dwarf unwind CFIs (FDE or CIE).
445 size = read32(&section.content[offset], isBig) + 4;
446 if (offset+size > section.content.size()) {
447 return llvm::make_error<GenericError>(Twine("Section ")
448 + section.segmentName
449 + "/" + section.sectionName
450 + " is malformed. Size of CFI "
451 "starting at offset ("
452 + Twine(offset)
453 + ") is past end of section.");
454 }
455 break;
456 case atomizeCU:
457 // Break section up into compact unwind entries.
458 size = is64 ? 32 : 20;
459 break;
460 case atomizeCFString:
461 // Break section up into NS/CFString objects.
462 size = is64 ? 32 : 16;
463 break;
464 case atomizeAtSymbols:
465 break;
466 }
467 if (size == 0) {
468 return llvm::make_error<GenericError>(Twine("Section ")
469 + section.segmentName
470 + "/" + section.sectionName
471 + " is malformed. The last atom "
472 "is not zero terminated.");
473 }
474 if (customSectionName) {
475 // Mach-O needs a segment and section name. Concatentate those two
476 // with a / separator (e.g. "seg/sect") to fit into the lld model
477 // of just a section name.
478 std::string segSectName = section.segmentName.str()
479 + "/" + section.sectionName.str();
480 file.addDefinedAtomInCustomSection(StringRef(), scope, atomType,
481 merge, false, false, offset,
482 size, segSectName, true, &section);
483 } else {
484 file.addDefinedAtom(StringRef(), scope, atomType, merge, offset, size,
485 false, false, copyRefs, &section);
486 }
487 offset += size;
488 }
489 }
490 return llvm::Error::success();
491}
492
493const Section* findSectionCoveringAddress(const NormalizedFile &normalizedFile,
494 uint64_t address) {
495 for (const Section &s : normalizedFile.sections) {
496 uint64_t sAddr = s.address;
497 if ((sAddr <= address) && (address < sAddr+s.content.size())) {
498 return &s;
499 }
500 }
501 return nullptr;
502}
503
504const MachODefinedAtom *
505findAtomCoveringAddress(const NormalizedFile &normalizedFile, MachOFile &file,
506 uint64_t addr, Reference::Addend &addend) {
507 const Section *sect = nullptr;
508 sect = findSectionCoveringAddress(normalizedFile, addr);
509 if (!sect)
510 return nullptr;
511
512 uint32_t offsetInTarget;
513 uint64_t offsetInSect = addr - sect->address;
514 auto atom =
515 file.findAtomCoveringAddress(*sect, offsetInSect, &offsetInTarget);
516 addend = offsetInTarget;
517 return atom;
518}
519
520// Walks all relocations for a section in a normalized .o file and
521// creates corresponding lld::Reference objects.
522llvm::Error convertRelocs(const Section &section,
523 const NormalizedFile &normalizedFile,
524 bool scatterable,
525 MachOFile &file,
526 ArchHandler &handler) {
527 // Utility function for ArchHandler to find atom by its address.
528 auto atomByAddr = [&] (uint32_t sectIndex, uint64_t addr,
529 const lld::Atom **atom, Reference::Addend *addend)
530 -> llvm::Error {
531 if (sectIndex > normalizedFile.sections.size())
532 return llvm::make_error<GenericError>(Twine("out of range section "
533 "index (") + Twine(sectIndex) + ")");
534 const Section *sect = nullptr;
535 if (sectIndex == 0) {
536 sect = findSectionCoveringAddress(normalizedFile, addr);
537 if (!sect)
538 return llvm::make_error<GenericError>(Twine("address (" + Twine(addr)
539 + ") is not in any section"));
540 } else {
541 sect = &normalizedFile.sections[sectIndex-1];
542 }
543 uint32_t offsetInTarget;
544 uint64_t offsetInSect = addr - sect->address;
545 *atom = file.findAtomCoveringAddress(*sect, offsetInSect, &offsetInTarget);
546 *addend = offsetInTarget;
547 return llvm::Error::success();
548 };
549
550 // Utility function for ArchHandler to find atom by its symbol index.
551 auto atomBySymbol = [&] (uint32_t symbolIndex, const lld::Atom **result)
552 -> llvm::Error {
553 // Find symbol from index.
554 const Symbol *sym = nullptr;
555 uint32_t numStabs = normalizedFile.stabsSymbols.size();
556 uint32_t numLocal = normalizedFile.localSymbols.size();
557 uint32_t numGlobal = normalizedFile.globalSymbols.size();
558 uint32_t numUndef = normalizedFile.undefinedSymbols.size();
559 assert(symbolIndex >= numStabs && "Searched for stab via atomBySymbol?");
560 if (symbolIndex < numStabs+numLocal) {
561 sym = &normalizedFile.localSymbols[symbolIndex-numStabs];
562 } else if (symbolIndex < numStabs+numLocal+numGlobal) {
563 sym = &normalizedFile.globalSymbols[symbolIndex-numStabs-numLocal];
564 } else if (symbolIndex < numStabs+numLocal+numGlobal+numUndef) {
565 sym = &normalizedFile.undefinedSymbols[symbolIndex-numStabs-numLocal-
566 numGlobal];
567 } else {
568 return llvm::make_error<GenericError>(Twine("symbol index (")
569 + Twine(symbolIndex) + ") out of range");
570 }
571
572 // Find atom from symbol.
573 if ((sym->type & N_TYPE) == N_SECT) {
574 if (sym->sect > normalizedFile.sections.size())
575 return llvm::make_error<GenericError>(Twine("symbol section index (")
576 + Twine(sym->sect) + ") out of range ");
577 const Section &symSection = normalizedFile.sections[sym->sect-1];
578 uint64_t targetOffsetInSect = sym->value - symSection.address;
579 MachODefinedAtom *target = file.findAtomCoveringAddress(symSection,
580 targetOffsetInSect);
581 if (target) {
582 *result = target;
583 return llvm::Error::success();
584 }
585 return llvm::make_error<GenericError>("no atom found for defined symbol");
586 } else if ((sym->type & N_TYPE) == N_UNDF) {
587 const lld::Atom *target = file.findUndefAtom(sym->name);
588 if (target) {
589 *result = target;
590 return llvm::Error::success();
591 }
592 return llvm::make_error<GenericError>("no undefined atom found for sym");
593 } else {
594 // Search undefs
595 return llvm::make_error<GenericError>("no atom found for symbol");
596 }
597 };
598
599 const bool isBig = MachOLinkingContext::isBigEndian(normalizedFile.arch);
600 // Use old-school iterator so that paired relocations can be grouped.
601 for (auto it=section.relocations.begin(), e=section.relocations.end();
602 it != e; ++it) {
603 const Relocation &reloc = *it;
604 // Find atom this relocation is in.
605 if (reloc.offset > section.content.size())
606 return llvm::make_error<GenericError>(
607 Twine("r_address (") + Twine(reloc.offset)
608 + ") is larger than section size ("
609 + Twine(section.content.size()) + ")");
610 uint32_t offsetInAtom;
611 MachODefinedAtom *inAtom = file.findAtomCoveringAddress(section,
612 reloc.offset,
613 &offsetInAtom);
614 assert(inAtom && "r_address in range, should have found atom");
615 uint64_t fixupAddress = section.address + reloc.offset;
616
617 const lld::Atom *target = nullptr;
618 Reference::Addend addend = 0;
619 Reference::KindValue kind;
620 if (handler.isPairedReloc(reloc)) {
621 // Handle paired relocations together.
622 const Relocation &reloc2 = *++it;
623 auto relocErr = handler.getPairReferenceInfo(
624 reloc, reloc2, inAtom, offsetInAtom, fixupAddress, isBig, scatterable,
625 atomByAddr, atomBySymbol, &kind, &target, &addend);
626 if (relocErr) {
627 return handleErrors(std::move(relocErr),
628 [&](std::unique_ptr<GenericError> GE) {
629 return llvm::make_error<GenericError>(
630 Twine("bad relocation (") + GE->getMessage()
631 + ") in section "
632 + section.segmentName + "/" + section.sectionName
633 + " (r1_address=" + Twine::utohexstr(reloc.offset)
634 + ", r1_type=" + Twine(reloc.type)
635 + ", r1_extern=" + Twine(reloc.isExtern)
636 + ", r1_length=" + Twine((int)reloc.length)
637 + ", r1_pcrel=" + Twine(reloc.pcRel)
638 + (!reloc.scattered ? (Twine(", r1_symbolnum=")
639 + Twine(reloc.symbol))
640 : (Twine(", r1_scattered=1, r1_value=")
641 + Twine(reloc.value)))
642 + ")"
643 + ", (r2_address=" + Twine::utohexstr(reloc2.offset)
644 + ", r2_type=" + Twine(reloc2.type)
645 + ", r2_extern=" + Twine(reloc2.isExtern)
646 + ", r2_length=" + Twine((int)reloc2.length)
647 + ", r2_pcrel=" + Twine(reloc2.pcRel)
648 + (!reloc2.scattered ? (Twine(", r2_symbolnum=")
649 + Twine(reloc2.symbol))
650 : (Twine(", r2_scattered=1, r2_value=")
651 + Twine(reloc2.value)))
652 + ")" );
653 });
654 }
655 }
656 else {
657 // Use ArchHandler to convert relocation record into information
658 // needed to instantiate an lld::Reference object.
659 auto relocErr = handler.getReferenceInfo(
660 reloc, inAtom, offsetInAtom, fixupAddress, isBig, atomByAddr,
661 atomBySymbol, &kind, &target, &addend);
662 if (relocErr) {
663 return handleErrors(std::move(relocErr),
664 [&](std::unique_ptr<GenericError> GE) {
665 return llvm::make_error<GenericError>(
666 Twine("bad relocation (") + GE->getMessage()
667 + ") in section "
668 + section.segmentName + "/" + section.sectionName
669 + " (r_address=" + Twine::utohexstr(reloc.offset)
670 + ", r_type=" + Twine(reloc.type)
671 + ", r_extern=" + Twine(reloc.isExtern)
672 + ", r_length=" + Twine((int)reloc.length)
673 + ", r_pcrel=" + Twine(reloc.pcRel)
674 + (!reloc.scattered ? (Twine(", r_symbolnum=") + Twine(reloc.symbol))
675 : (Twine(", r_scattered=1, r_value=")
676 + Twine(reloc.value)))
677 + ")" );
678 });
679 }
680 }
681 // Instantiate an lld::Reference object and add to its atom.
682 inAtom->addReference(Reference::KindNamespace::mach_o,
683 handler.kindArch(),
684 kind, offsetInAtom, target, addend);
685 }
686
687 return llvm::Error::success();
688}
689
690bool isDebugInfoSection(const Section &section) {
691 if ((section.attributes & S_ATTR_DEBUG) == 0)
692 return false;
693 return section.segmentName.equals("__DWARF");
694}
695
696static const Atom* findDefinedAtomByName(MachOFile &file, Twine name) {
697 std::string strName = name.str();
698 for (auto *atom : file.defined())
699 if (atom->name() == strName)
700 return atom;
701 return nullptr;
702}
703
704static StringRef copyDebugString(StringRef str, BumpPtrAllocator &alloc) {
705 char *strCopy = alloc.Allocate<char>(str.size() + 1);
706 memcpy(strCopy, str.data(), str.size());
707 strCopy[str.size()] = '\0';
708 return strCopy;
709}
710
711llvm::Error parseStabs(MachOFile &file,
712 const NormalizedFile &normalizedFile,
713 bool copyRefs) {
714
715 if (normalizedFile.stabsSymbols.empty())
716 return llvm::Error::success();
717
718 // FIXME: Kill this off when we can move to sane yaml parsing.
719 std::unique_ptr<BumpPtrAllocator> allocator;
720 if (copyRefs)
721 allocator = llvm::make_unique<BumpPtrAllocator>();
722
723 enum { start, inBeginEnd } state = start;
724
725 const Atom *currentAtom = nullptr;
726 uint64_t currentAtomAddress = 0;
727 StabsDebugInfo::StabsList stabsList;
728 for (const auto &stabSym : normalizedFile.stabsSymbols) {
729 Stab stab(nullptr, stabSym.type, stabSym.sect, stabSym.desc,
730 stabSym.value, stabSym.name);
731 switch (state) {
732 case start:
733 switch (static_cast<StabType>(stabSym.type)) {
734 case N_BNSYM:
735 state = inBeginEnd;
736 currentAtomAddress = stabSym.value;
737 Reference::Addend addend;
738 currentAtom = findAtomCoveringAddress(normalizedFile, file,
739 currentAtomAddress, addend);
740 if (addend != 0)
741 return llvm::make_error<GenericError>(
742 "Non-zero addend for BNSYM '" + stabSym.name + "' in " +
743 file.path());
744 if (currentAtom)
745 stab.atom = currentAtom;
746 else {
747 // FIXME: ld64 just issues a warning here - should we match that?
748 return llvm::make_error<GenericError>(
749 "can't find atom for stabs BNSYM at " +
750 Twine::utohexstr(stabSym.value) + " in " + file.path());
751 }
752 break;
753 case N_SO:
754 case N_OSO:
755 // Not associated with an atom, just copy.
756 if (copyRefs)
757 stab.str = copyDebugString(stabSym.name, *allocator);
758 else
759 stab.str = stabSym.name;
760 break;
761 case N_GSYM: {
762 auto colonIdx = stabSym.name.find(':');
763 if (colonIdx != StringRef::npos) {
764 StringRef name = stabSym.name.substr(0, colonIdx);
765 currentAtom = findDefinedAtomByName(file, "_" + name);
766 stab.atom = currentAtom;
767 if (copyRefs)
768 stab.str = copyDebugString(stabSym.name, *allocator);
769 else
770 stab.str = stabSym.name;
771 } else {
772 currentAtom = findDefinedAtomByName(file, stabSym.name);
773 stab.atom = currentAtom;
774 if (copyRefs)
775 stab.str = copyDebugString(stabSym.name, *allocator);
776 else
777 stab.str = stabSym.name;
778 }
779 if (stab.atom == nullptr)
780 return llvm::make_error<GenericError>(
781 "can't find atom for N_GSYM stabs" + stabSym.name +
782 " in " + file.path());
783 break;
784 }
785 case N_FUN:
786 return llvm::make_error<GenericError>(
787 "old-style N_FUN stab '" + stabSym.name + "' unsupported");
788 default:
789 return llvm::make_error<GenericError>(
790 "unrecognized stab symbol '" + stabSym.name + "'");
791 }
792 break;
793 case inBeginEnd:
794 stab.atom = currentAtom;
795 switch (static_cast<StabType>(stabSym.type)) {
796 case N_ENSYM:
797 state = start;
798 currentAtom = nullptr;
799 break;
800 case N_FUN:
801 // Just copy the string.
802 if (copyRefs)
803 stab.str = copyDebugString(stabSym.name, *allocator);
804 else
805 stab.str = stabSym.name;
806 break;
807 default:
808 return llvm::make_error<GenericError>(
809 "unrecognized stab symbol '" + stabSym.name + "'");
810 }
811 }
812 llvm::dbgs() << "Adding to stabsList: " << stab << "\n";
813 stabsList.push_back(stab);
814 }
815
816 file.setDebugInfo(llvm::make_unique<StabsDebugInfo>(std::move(stabsList)));
817
818 // FIXME: Kill this off when we fix YAML memory ownership.
819 file.debugInfo()->setAllocator(std::move(allocator));
820
821 return llvm::Error::success();
822}
823
824static llvm::DataExtractor
825dataExtractorFromSection(const NormalizedFile &normalizedFile,
826 const Section &S) {
827 const bool is64 = MachOLinkingContext::is64Bit(normalizedFile.arch);
828 const bool isBig = MachOLinkingContext::isBigEndian(normalizedFile.arch);
829 StringRef SecData(reinterpret_cast<const char*>(S.content.data()),
830 S.content.size());
831 return llvm::DataExtractor(SecData, !isBig, is64 ? 8 : 4);
832}
833
834// FIXME: Cribbed from llvm-dwp -- should share "lightweight CU DIE
835// inspection" code if possible.
836static uint32_t getCUAbbrevOffset(llvm::DataExtractor abbrevData,
837 uint64_t abbrCode) {
838 uint64_t curCode;
839 uint32_t offset = 0;
840 while ((curCode = abbrevData.getULEB128(&offset)) != abbrCode) {
841 // Tag
842 abbrevData.getULEB128(&offset);
843 // DW_CHILDREN
844 abbrevData.getU8(&offset);
845 // Attributes
846 while (abbrevData.getULEB128(&offset) | abbrevData.getULEB128(&offset))
847 ;
848 }
849 return offset;
850}
851
852// FIXME: Cribbed from llvm-dwp -- should share "lightweight CU DIE
853// inspection" code if possible.
854static Expected<const char *>
855getIndexedString(const NormalizedFile &normalizedFile,
856 llvm::dwarf::Form form, llvm::DataExtractor infoData,
857 uint32_t &infoOffset, const Section &stringsSection) {
858 if (form == llvm::dwarf::DW_FORM_string)
859 return infoData.getCStr(&infoOffset);
860 if (form != llvm::dwarf::DW_FORM_strp)
861 return llvm::make_error<GenericError>(
862 "string field encoded without DW_FORM_strp");
863 uint32_t stringOffset = infoData.getU32(&infoOffset);
864 llvm::DataExtractor stringsData =
865 dataExtractorFromSection(normalizedFile, stringsSection);
866 return stringsData.getCStr(&stringOffset);
867}
868
869// FIXME: Cribbed from llvm-dwp -- should share "lightweight CU DIE
870// inspection" code if possible.
871static llvm::Expected<TranslationUnitSource>
872readCompUnit(const NormalizedFile &normalizedFile,
873 const Section &info,
874 const Section &abbrev,
875 const Section &strings,
876 StringRef path) {
877 // FIXME: Cribbed from llvm-dwp -- should share "lightweight CU DIE
878 // inspection" code if possible.
879 uint32_t offset = 0;
880 llvm::dwarf::DwarfFormat Format = llvm::dwarf::DwarfFormat::DWARF32;
881 auto infoData = dataExtractorFromSection(normalizedFile, info);
882 uint32_t length = infoData.getU32(&offset);
883 if (length == 0xffffffff) {
884 Format = llvm::dwarf::DwarfFormat::DWARF64;
885 infoData.getU64(&offset);
886 }
887 else if (length > 0xffffff00)
888 return llvm::make_error<GenericError>("Malformed DWARF in " + path);
889
890 uint16_t version = infoData.getU16(&offset);
891
892 if (version < 2 || version > 4)
893 return llvm::make_error<GenericError>("Unsupported DWARF version in " +
894 path);
895
896 infoData.getU32(&offset); // Abbrev offset (should be zero)
897 uint8_t addrSize = infoData.getU8(&offset);
898
899 uint32_t abbrCode = infoData.getULEB128(&offset);
900 auto abbrevData = dataExtractorFromSection(normalizedFile, abbrev);
901 uint32_t abbrevOffset = getCUAbbrevOffset(abbrevData, abbrCode);
902 uint64_t tag = abbrevData.getULEB128(&abbrevOffset);
903 if (tag != llvm::dwarf::DW_TAG_compile_unit)
904 return llvm::make_error<GenericError>("top level DIE is not a compile unit");
905 // DW_CHILDREN
906 abbrevData.getU8(&abbrevOffset);
907 uint32_t name;
908 llvm::dwarf::Form form;
909 llvm::DWARFFormParams formParams = {version, addrSize, Format};
910 TranslationUnitSource tu;
911 while ((name = abbrevData.getULEB128(&abbrevOffset)) |
912 (form = static_cast<llvm::dwarf::Form>(
913 abbrevData.getULEB128(&abbrevOffset))) &&
914 (name != 0 || form != 0)) {
915 switch (name) {
916 case llvm::dwarf::DW_AT_name: {
917 if (auto eName = getIndexedString(normalizedFile, form, infoData, offset,
918 strings))
919 tu.name = *eName;
920 else
921 return eName.takeError();
922 break;
923 }
924 case llvm::dwarf::DW_AT_comp_dir: {
925 if (auto eName = getIndexedString(normalizedFile, form, infoData, offset,
926 strings))
927 tu.path = *eName;
928 else
929 return eName.takeError();
930 break;
931 }
932 default:
933 llvm::DWARFFormValue::skipValue(form, infoData, &offset, formParams);
934 }
935 }
936 return tu;
937}
938
939llvm::Error parseDebugInfo(MachOFile &file,
940 const NormalizedFile &normalizedFile, bool copyRefs) {
941
942 // Find the interesting debug info sections.
943 const Section *debugInfo = nullptr;
944 const Section *debugAbbrev = nullptr;
945 const Section *debugStrings = nullptr;
946
947 for (auto &s : normalizedFile.sections) {
948 if (s.segmentName == "__DWARF") {
949 if (s.sectionName == "__debug_info")
950 debugInfo = &s;
951 else if (s.sectionName == "__debug_abbrev")
952 debugAbbrev = &s;
953 else if (s.sectionName == "__debug_str")
954 debugStrings = &s;
955 }
956 }
957
958 if (!debugInfo)
959 return parseStabs(file, normalizedFile, copyRefs);
960
961 if (debugInfo->content.size() == 0)
962 return llvm::Error::success();
963
964 if (debugInfo->content.size() < 12)
965 return llvm::make_error<GenericError>("Malformed __debug_info section in " +
966 file.path() + ": too small");
967
968 if (!debugAbbrev)
969 return llvm::make_error<GenericError>("Missing __dwarf_abbrev section in " +
970 file.path());
971
972 if (auto tuOrErr = readCompUnit(normalizedFile, *debugInfo, *debugAbbrev,
973 *debugStrings, file.path())) {
974 // FIXME: Kill of allocator and code under 'copyRefs' when we fix YAML
975 // memory ownership.
976 std::unique_ptr<BumpPtrAllocator> allocator;
977 if (copyRefs) {
978 allocator = llvm::make_unique<BumpPtrAllocator>();
979 tuOrErr->name = copyDebugString(tuOrErr->name, *allocator);
980 tuOrErr->path = copyDebugString(tuOrErr->path, *allocator);
981 }
982 file.setDebugInfo(llvm::make_unique<DwarfDebugInfo>(std::move(*tuOrErr)));
983 if (copyRefs)
984 file.debugInfo()->setAllocator(std::move(allocator));
985 } else
986 return tuOrErr.takeError();
987
988 return llvm::Error::success();
989}
990
991static int64_t readSPtr(bool is64, bool isBig, const uint8_t *addr) {
992 if (is64)
993 return read64(addr, isBig);
994
995 int32_t res = read32(addr, isBig);
996 return res;
997}
998
999/// --- Augmentation String Processing ---
1000
1001struct CIEInfo {
1002 bool _augmentationDataPresent = false;
1003 bool _mayHaveEH = false;
1004 uint32_t _offsetOfLSDA = ~0U;
1005 uint32_t _offsetOfPersonality = ~0U;
1006 uint32_t _offsetOfFDEPointerEncoding = ~0U;
1007 uint32_t _augmentationDataLength = ~0U;
1008};
1009
1010typedef llvm::DenseMap<const MachODefinedAtom*, CIEInfo> CIEInfoMap;
1011
1012static llvm::Error processAugmentationString(const uint8_t *augStr,
1013 CIEInfo &cieInfo,
1014 unsigned &len) {
1015
1016 if (augStr[0] == '\0') {
1017 len = 1;
1018 return llvm::Error::success();
1019 }
1020
1021 if (augStr[0] != 'z')
1022 return llvm::make_error<GenericError>("expected 'z' at start of "
1023 "augmentation string");
1024
1025 cieInfo._augmentationDataPresent = true;
1026 uint64_t idx = 1;
1027
1028 uint32_t offsetInAugmentationData = 0;
1029 while (augStr[idx] != '\0') {
1030 if (augStr[idx] == 'L') {
1031 cieInfo._offsetOfLSDA = offsetInAugmentationData;
1032 // This adds a single byte to the augmentation data.
1033 ++offsetInAugmentationData;
1034 ++idx;
1035 continue;
1036 }
1037 if (augStr[idx] == 'P') {
1038 cieInfo._offsetOfPersonality = offsetInAugmentationData;
1039 // This adds a single byte to the augmentation data for the encoding,
1040 // then a number of bytes for the pointer data.
1041 // FIXME: We are assuming 4 is correct here for the pointer size as we
1042 // always currently use delta32ToGOT.
1043 offsetInAugmentationData += 5;
1044 ++idx;
1045 continue;
1046 }
1047 if (augStr[idx] == 'R') {
1048 cieInfo._offsetOfFDEPointerEncoding = offsetInAugmentationData;
1049 // This adds a single byte to the augmentation data.
1050 ++offsetInAugmentationData;
1051 ++idx;
1052 continue;
1053 }
1054 if (augStr[idx] == 'e') {
1055 if (augStr[idx + 1] != 'h')
1056 return llvm::make_error<GenericError>("expected 'eh' in "
1057 "augmentation string");
1058 cieInfo._mayHaveEH = true;
1059 idx += 2;
1060 continue;
1061 }
1062 ++idx;
1063 }
1064
1065 cieInfo._augmentationDataLength = offsetInAugmentationData;
1066
1067 len = idx + 1;
1068 return llvm::Error::success();
1069}
1070
1071static llvm::Error processCIE(const NormalizedFile &normalizedFile,
1072 MachOFile &file,
1073 mach_o::ArchHandler &handler,
1074 const Section *ehFrameSection,
1075 MachODefinedAtom *atom,
1076 uint64_t offset,
1077 CIEInfoMap &cieInfos) {
1078 const bool isBig = MachOLinkingContext::isBigEndian(normalizedFile.arch);
1079 const uint8_t *frameData = atom->rawContent().data();
1080
1081 CIEInfo cieInfo;
1082
1083 uint32_t size = read32(frameData, isBig);
1084 uint64_t cieIDField = size == 0xffffffffU
1085 ? sizeof(uint32_t) + sizeof(uint64_t)
1086 : sizeof(uint32_t);
1087 uint64_t versionField = cieIDField + sizeof(uint32_t);
1088 uint64_t augmentationStringField = versionField + sizeof(uint8_t);
1089
1090 unsigned augmentationStringLength = 0;
1091 if (auto err = processAugmentationString(frameData + augmentationStringField,
1092 cieInfo, augmentationStringLength))
1093 return err;
1094
1095 if (cieInfo._offsetOfPersonality != ~0U) {
1096 // If we have augmentation data for the personality function, then we may
1097 // need to implicitly generate its relocation.
1098
1099 // Parse the EH Data field which is pointer sized.
1100 uint64_t EHDataField = augmentationStringField + augmentationStringLength;
1101 const bool is64 = MachOLinkingContext::is64Bit(normalizedFile.arch);
1102 unsigned EHDataFieldSize = (cieInfo._mayHaveEH ? (is64 ? 8 : 4) : 0);
1103
1104 // Parse Code Align Factor which is a ULEB128.
1105 uint64_t CodeAlignField = EHDataField + EHDataFieldSize;
1106 unsigned lengthFieldSize = 0;
1107 llvm::decodeULEB128(frameData + CodeAlignField, &lengthFieldSize);
1108
1109 // Parse Data Align Factor which is a SLEB128.
1110 uint64_t DataAlignField = CodeAlignField + lengthFieldSize;
1111 llvm::decodeSLEB128(frameData + DataAlignField, &lengthFieldSize);
1112
1113 // Parse Return Address Register which is a byte.
1114 uint64_t ReturnAddressField = DataAlignField + lengthFieldSize;
1115
1116 // Parse the augmentation length which is a ULEB128.
1117 uint64_t AugmentationLengthField = ReturnAddressField + 1;
1118 uint64_t AugmentationLength =
1119 llvm::decodeULEB128(frameData + AugmentationLengthField,
1120 &lengthFieldSize);
1121
1122 if (AugmentationLength != cieInfo._augmentationDataLength)
1123 return llvm::make_error<GenericError>("CIE augmentation data length "
1124 "mismatch");
1125
1126 // Get the start address of the augmentation data.
1127 uint64_t AugmentationDataField = AugmentationLengthField + lengthFieldSize;
1128
1129 // Parse the personality function from the augmentation data.
1130 uint64_t PersonalityField =
1131 AugmentationDataField + cieInfo._offsetOfPersonality;
1132
1133 // Parse the personality encoding.
1134 // FIXME: Verify that this is a 32-bit pcrel offset.
1135 uint64_t PersonalityFunctionField = PersonalityField + 1;
1136
1137 if (atom->begin() != atom->end()) {
1138 // If we have an explicit relocation, then make sure it matches this
1139 // offset as this is where we'd expect it to be applied to.
1140 DefinedAtom::reference_iterator CurrentRef = atom->begin();
1141 if (CurrentRef->offsetInAtom() != PersonalityFunctionField)
1142 return llvm::make_error<GenericError>("CIE personality reloc at "
1143 "wrong offset");
1144
1145 if (++CurrentRef != atom->end())
1146 return llvm::make_error<GenericError>("CIE contains too many relocs");
1147 } else {
1148 // Implicitly generate the personality function reloc. It's assumed to
1149 // be a delta32 offset to a GOT entry.
1150 // FIXME: Parse the encoding and check this.
1151 int32_t funcDelta = read32(frameData + PersonalityFunctionField, isBig);
1152 uint64_t funcAddress = ehFrameSection->address + offset +
1153 PersonalityFunctionField;
1154 funcAddress += funcDelta;
1155
1156 const MachODefinedAtom *func = nullptr;
1157 Reference::Addend addend;
1158 func = findAtomCoveringAddress(normalizedFile, file, funcAddress,
1159 addend);
1160 atom->addReference(Reference::KindNamespace::mach_o, handler.kindArch(),
1161 handler.unwindRefToPersonalityFunctionKind(),
1162 PersonalityFunctionField, func, addend);
1163 }
1164 } else if (atom->begin() != atom->end()) {
1165 // Otherwise, we expect there to be no relocations in this atom as the only
1166 // relocation would have been to the personality function.
1167 return llvm::make_error<GenericError>("unexpected relocation in CIE");
1168 }
1169
1170
1171 cieInfos[atom] = std::move(cieInfo);
1172
1173 return llvm::Error::success();
1174}
1175
1176static llvm::Error processFDE(const NormalizedFile &normalizedFile,
1177 MachOFile &file,
1178 mach_o::ArchHandler &handler,
1179 const Section *ehFrameSection,
1180 MachODefinedAtom *atom,
1181 uint64_t offset,
1182 const CIEInfoMap &cieInfos) {
1183
1184 const bool isBig = MachOLinkingContext::isBigEndian(normalizedFile.arch);
1185 const bool is64 = MachOLinkingContext::is64Bit(normalizedFile.arch);
1186
1187 // Compiler wasn't lazy and actually told us what it meant.
1188 // Unfortunately, the compiler may not have generated references for all of
1189 // [cie, func, lsda] and so we still need to parse the FDE and add references
1190 // for any the compiler didn't generate.
1191 if (atom->begin() != atom->end())
1192 atom->sortReferences();
1193
1194 DefinedAtom::reference_iterator CurrentRef = atom->begin();
1195
1196 // This helper returns the reference (if one exists) at the offset we are
1197 // currently processing. It automatically increments the ref iterator if we
1198 // do return a ref, and throws an error if we pass over a ref without
1199 // comsuming it.
1200 auto currentRefGetter = [&CurrentRef,
1201 &atom](uint64_t Offset)->const Reference* {
1202 // If there are no more refs found, then we are done.
1203 if (CurrentRef == atom->end())
1204 return nullptr;
1205
1206 const Reference *Ref = *CurrentRef;
1207
1208 // If we haven't reached the offset for this reference, then return that
1209 // we don't yet have a reference to process.
1210 if (Offset < Ref->offsetInAtom())
1211 return nullptr;
1212
1213 // If the offset is equal, then we want to process this ref.
1214 if (Offset == Ref->offsetInAtom()) {
1215 ++CurrentRef;
1216 return Ref;
1217 }
1218
1219 // The current ref is at an offset which is earlier than the current
1220 // offset, then we failed to consume it when we should have. In this case
1221 // throw an error.
1222 llvm::report_fatal_error("Skipped reference when processing FDE");
1223 };
1224
1225 // Helper to either get the reference at this current location, and verify
1226 // that it is of the expected type, or add a reference of that type.
1227 // Returns the reference target.
1228 auto verifyOrAddReference = [&](uint64_t targetAddress,
1229 Reference::KindValue refKind,
1230 uint64_t refAddress,
1231 bool allowsAddend)->const Atom* {
1232 if (auto *ref = currentRefGetter(refAddress)) {
1233 // The compiler already emitted a relocation for the CIE ref. This should
1234 // have been converted to the correct type of reference in
1235 // get[Pair]ReferenceInfo().
1236 assert(ref->kindValue() == refKind &&
1237 "Incorrect EHFrame reference kind");
1238 return ref->target();
1239 }
1240 Reference::Addend addend;
1241 auto *target = findAtomCoveringAddress(normalizedFile, file,
1242 targetAddress, addend);
1243 atom->addReference(Reference::KindNamespace::mach_o, handler.kindArch(),
1244 refKind, refAddress, target, addend);
1245
1246 if (!allowsAddend)
1247 assert(!addend && "EHFrame reference cannot have addend");
1248 return target;
1249 };
1250
1251 const uint8_t *startFrameData = atom->rawContent().data();
1252 const uint8_t *frameData = startFrameData;
1253
1254 uint32_t size = read32(frameData, isBig);
1255 uint64_t cieFieldInFDE = size == 0xffffffffU
1256 ? sizeof(uint32_t) + sizeof(uint64_t)
1257 : sizeof(uint32_t);
1258
1259 // Linker needs to fixup a reference from the FDE to its parent CIE (a
1260 // 32-bit byte offset backwards in the __eh_frame section).
1261 uint32_t cieDelta = read32(frameData + cieFieldInFDE, isBig);
1262 uint64_t cieAddress = ehFrameSection->address + offset + cieFieldInFDE;
1263 cieAddress -= cieDelta;
1264
1265 auto *cieRefTarget = verifyOrAddReference(cieAddress,
1266 handler.unwindRefToCIEKind(),
1267 cieFieldInFDE, false);
1268 const MachODefinedAtom *cie = dyn_cast<MachODefinedAtom>(cieRefTarget);
1269 assert(cie && cie->contentType() == DefinedAtom::typeCFI &&
1270 "FDE's CIE field does not point at the start of a CIE.");
1271
1272 const CIEInfo &cieInfo = cieInfos.find(cie)->second;
1273
1274 // Linker needs to fixup reference from the FDE to the function it's
1275 // describing. FIXME: there are actually different ways to do this, and the
1276 // particular method used is specified in the CIE's augmentation fields
1277 // (hopefully)
1278 uint64_t rangeFieldInFDE = cieFieldInFDE + sizeof(uint32_t);
1279
1280 int64_t functionFromFDE = readSPtr(is64, isBig,
1281 frameData + rangeFieldInFDE);
1282 uint64_t rangeStart = ehFrameSection->address + offset + rangeFieldInFDE;
1283 rangeStart += functionFromFDE;
1284
1285 verifyOrAddReference(rangeStart,
1286 handler.unwindRefToFunctionKind(),
1287 rangeFieldInFDE, true);
1288
1289 // Handle the augmentation data if there is any.
1290 if (cieInfo._augmentationDataPresent) {
1291 // First process the augmentation data length field.
1292 uint64_t augmentationDataLengthFieldInFDE =
1293 rangeFieldInFDE + 2 * (is64 ? sizeof(uint64_t) : sizeof(uint32_t));
1294 unsigned lengthFieldSize = 0;
1295 uint64_t augmentationDataLength =
1296 llvm::decodeULEB128(frameData + augmentationDataLengthFieldInFDE,
1297 &lengthFieldSize);
1298
1299 if (cieInfo._offsetOfLSDA != ~0U && augmentationDataLength > 0) {
1300
1301 // Look at the augmentation data field.
1302 uint64_t augmentationDataFieldInFDE =
1303 augmentationDataLengthFieldInFDE + lengthFieldSize;
1304
1305 int64_t lsdaFromFDE = readSPtr(is64, isBig,
1306 frameData + augmentationDataFieldInFDE);
1307 uint64_t lsdaStart =
1308 ehFrameSection->address + offset + augmentationDataFieldInFDE +
1309 lsdaFromFDE;
1310
1311 verifyOrAddReference(lsdaStart,
1312 handler.unwindRefToFunctionKind(),
1313 augmentationDataFieldInFDE, true);
1314 }
1315 }
1316
1317 return llvm::Error::success();
1318}
1319
1320llvm::Error addEHFrameReferences(const NormalizedFile &normalizedFile,
1321 MachOFile &file,
1322 mach_o::ArchHandler &handler) {
1323
1324 const Section *ehFrameSection = nullptr;
1325 for (auto &section : normalizedFile.sections)
1326 if (section.segmentName == "__TEXT" &&
1327 section.sectionName == "__eh_frame") {
1328 ehFrameSection = &section;
1329 break;
1330 }
1331
1332 // No __eh_frame so nothing to do.
1333 if (!ehFrameSection)
1334 return llvm::Error::success();
1335
1336 llvm::Error ehFrameErr = llvm::Error::success();
1337 CIEInfoMap cieInfos;
1338
1339 file.eachAtomInSection(*ehFrameSection,
1340 [&](MachODefinedAtom *atom, uint64_t offset) -> void {
1341 assert(atom->contentType() == DefinedAtom::typeCFI);
1342
1343 // Bail out if we've encountered an error.
1344 if (ehFrameErr)
1345 return;
1346
1347 const bool isBig = MachOLinkingContext::isBigEndian(normalizedFile.arch);
1348 if (ArchHandler::isDwarfCIE(isBig, atom))
1349 ehFrameErr = processCIE(normalizedFile, file, handler, ehFrameSection,
1350 atom, offset, cieInfos);
1351 else
1352 ehFrameErr = processFDE(normalizedFile, file, handler, ehFrameSection,
1353 atom, offset, cieInfos);
1354 });
1355
1356 return ehFrameErr;
1357}
1358
1359llvm::Error parseObjCImageInfo(const Section &sect,
1360 const NormalizedFile &normalizedFile,
1361 MachOFile &file) {
1362
1363 // struct objc_image_info {
1364 // uint32_t version; // initially 0
1365 // uint32_t flags;
1366 // };
1367
1368 ArrayRef<uint8_t> content = sect.content;
1369 if (content.size() != 8)
1370 return llvm::make_error<GenericError>(sect.segmentName + "/" +
1371 sect.sectionName +
1372 " in file " + file.path() +
1373 " should be 8 bytes in size");
1374
1375 const bool isBig = MachOLinkingContext::isBigEndian(normalizedFile.arch);
1376 uint32_t version = read32(content.data(), isBig);
1377 if (version)
1378 return llvm::make_error<GenericError>(sect.segmentName + "/" +
1379 sect.sectionName +
1380 " in file " + file.path() +
1381 " should have version=0");
1382
1383 uint32_t flags = read32(content.data() + 4, isBig);
1384 if (flags & (MachOLinkingContext::objc_supports_gc |
1385 MachOLinkingContext::objc_gc_only))
1386 return llvm::make_error<GenericError>(sect.segmentName + "/" +
1387 sect.sectionName +
1388 " in file " + file.path() +
1389 " uses GC. This is not supported");
1390
1391 if (flags & MachOLinkingContext::objc_retainReleaseForSimulator)
1392 file.setObjcConstraint(MachOLinkingContext::objc_retainReleaseForSimulator);
1393 else
1394 file.setObjcConstraint(MachOLinkingContext::objc_retainRelease);
1395
1396 file.setSwiftVersion((flags >> 8) & 0xFF);
1397
1398 return llvm::Error::success();
1399}
1400
1401/// Converts normalized mach-o file into an lld::File and lld::Atoms.
1402llvm::Expected<std::unique_ptr<lld::File>>
1403objectToAtoms(const NormalizedFile &normalizedFile, StringRef path,
1404 bool copyRefs) {
1405 std::unique_ptr<MachOFile> file(new MachOFile(path));
1406 if (auto ec = normalizedObjectToAtoms(file.get(), normalizedFile, copyRefs))
1407 return std::move(ec);
1408 return std::unique_ptr<File>(std::move(file));
1409}
1410
1411llvm::Expected<std::unique_ptr<lld::File>>
1412dylibToAtoms(const NormalizedFile &normalizedFile, StringRef path,
1413 bool copyRefs) {
1414 // Instantiate SharedLibraryFile object.
1415 std::unique_ptr<MachODylibFile> file(new MachODylibFile(path));
1416 if (auto ec = normalizedDylibToAtoms(file.get(), normalizedFile, copyRefs))
1417 return std::move(ec);
1418 return std::unique_ptr<File>(std::move(file));
1419}
1420
1421} // anonymous namespace
1422
1423namespace normalized {
1424
1425static bool isObjCImageInfo(const Section &sect) {
1426 return (sect.segmentName == "__OBJC" && sect.sectionName == "__image_info") ||
1427 (sect.segmentName == "__DATA" && sect.sectionName == "__objc_imageinfo");
1428}
1429
1430llvm::Error
1431normalizedObjectToAtoms(MachOFile *file,
1432 const NormalizedFile &normalizedFile,
1433 bool copyRefs) {
1434 DEBUG(llvm::dbgs() << "******** Normalizing file to atoms: "
1435 << file->path() << "\n");
1436 bool scatterable = ((normalizedFile.flags & MH_SUBSECTIONS_VIA_SYMBOLS) != 0);
1437
1438 // Create atoms from each section.
1439 for (auto &sect : normalizedFile.sections) {
1440
1441 // If this is a debug-info section parse it specially.
1442 if (isDebugInfoSection(sect))
1443 continue;
1444
1445 // If the file contains an objc_image_info struct, then we should parse the
1446 // ObjC flags and Swift version.
1447 if (isObjCImageInfo(sect)) {
1448 if (auto ec = parseObjCImageInfo(sect, normalizedFile, *file))
1449 return ec;
1450 // We then skip adding atoms for this section as we use the ObjCPass to
1451 // re-emit this data after it has been aggregated for all files.
1452 continue;
1453 }
1454
1455 bool customSectionName;
1456 DefinedAtom::ContentType atomType = atomTypeFromSection(sect,
1457 customSectionName);
1458 if (auto ec = processSection(atomType, sect, customSectionName,
1459 normalizedFile, *file, scatterable, copyRefs))
1460 return ec;
1461 }
1462 // Create atoms from undefined symbols.
1463 for (auto &sym : normalizedFile.undefinedSymbols) {
1464 // Undefinded symbols with n_value != 0 are actually tentative definitions.
1465 if (sym.value == Hex64(0)) {
1466 file->addUndefinedAtom(sym.name, copyRefs);
1467 } else {
1468 file->addTentativeDefAtom(sym.name, atomScope(sym.scope), sym.value,
1469 DefinedAtom::Alignment(1 << (sym.desc >> 8)),
1470 copyRefs);
1471 }
1472 }
1473
1474 // Convert mach-o relocations to References
1475 std::unique_ptr<mach_o::ArchHandler> handler
1476 = ArchHandler::create(normalizedFile.arch);
1477 for (auto &sect : normalizedFile.sections) {
1478 if (isDebugInfoSection(sect))
1479 continue;
1480 if (llvm::Error ec = convertRelocs(sect, normalizedFile, scatterable,
1481 *file, *handler))
1482 return ec;
1483 }
1484
1485 // Add additional arch-specific References
1486 file->eachDefinedAtom([&](MachODefinedAtom* atom) -> void {
1487 handler->addAdditionalReferences(*atom);
1488 });
1489
1490 // Each __eh_frame section needs references to both __text (the function we're
1491 // providing unwind info for) and itself (FDE -> CIE). These aren't
1492 // represented in the relocations on some architectures, so we have to add
1493 // them back in manually there.
1494 if (auto ec = addEHFrameReferences(normalizedFile, *file, *handler))
1495 return ec;
1496
1497 // Process mach-o data-in-code regions array. That information is encoded in
1498 // atoms as References at each transition point.
1499 unsigned nextIndex = 0;
1500 for (const DataInCode &entry : normalizedFile.dataInCode) {
1501 ++nextIndex;
1502 const Section* s = findSectionCoveringAddress(normalizedFile, entry.offset);
1503 if (!s) {
1504 return llvm::make_error<GenericError>(Twine("LC_DATA_IN_CODE address ("
1505 + Twine(entry.offset)
1506 + ") is not in any section"));
1507 }
1508 uint64_t offsetInSect = entry.offset - s->address;
1509 uint32_t offsetInAtom;
1510 MachODefinedAtom *atom = file->findAtomCoveringAddress(*s, offsetInSect,
1511 &offsetInAtom);
1512 if (offsetInAtom + entry.length > atom->size()) {
1513 return llvm::make_error<GenericError>(Twine("LC_DATA_IN_CODE entry "
1514 "(offset="
1515 + Twine(entry.offset)
1516 + ", length="
1517 + Twine(entry.length)
1518 + ") crosses atom boundary."));
1519 }
1520 // Add reference that marks start of data-in-code.
1521 atom->addReference(Reference::KindNamespace::mach_o, handler->kindArch(),
1522 handler->dataInCodeTransitionStart(*atom),
1523 offsetInAtom, atom, entry.kind);
1524
1525 // Peek at next entry, if it starts where this one ends, skip ending ref.
1526 if (nextIndex < normalizedFile.dataInCode.size()) {
1527 const DataInCode &nextEntry = normalizedFile.dataInCode[nextIndex];
1528 if (nextEntry.offset == (entry.offset + entry.length))
1529 continue;
1530 }
1531
1532 // If data goes to end of function, skip ending ref.
1533 if ((offsetInAtom + entry.length) == atom->size())
1534 continue;
1535
1536 // Add reference that marks end of data-in-code.
1537 atom->addReference(Reference::KindNamespace::mach_o, handler->kindArch(),
1538 handler->dataInCodeTransitionEnd(*atom),
1539 offsetInAtom+entry.length, atom, 0);
1540 }
1541
1542 // Cache some attributes on the file for use later.
1543 file->setFlags(normalizedFile.flags);
1544 file->setArch(normalizedFile.arch);
1545 file->setOS(normalizedFile.os);
1546 file->setMinVersion(normalizedFile.minOSverson);
1547 file->setMinVersionLoadCommandKind(normalizedFile.minOSVersionKind);
1548
1549 // Sort references in each atom to their canonical order.
1550 for (const DefinedAtom* defAtom : file->defined()) {
1551 reinterpret_cast<const SimpleDefinedAtom*>(defAtom)->sortReferences();
1552 }
1553
1554 if (auto err = parseDebugInfo(*file, normalizedFile, copyRefs))
1555 return err;
1556
1557 return llvm::Error::success();
1558}
1559
1560llvm::Error
1561normalizedDylibToAtoms(MachODylibFile *file,
1562 const NormalizedFile &normalizedFile,
1563 bool copyRefs) {
1564 file->setInstallName(normalizedFile.installName);
1565 file->setCompatVersion(normalizedFile.compatVersion);
1566 file->setCurrentVersion(normalizedFile.currentVersion);
1567
1568 // Tell MachODylibFile object about all symbols it exports.
1569 if (!normalizedFile.exportInfo.empty()) {
1570 // If exports trie exists, use it instead of traditional symbol table.
1571 for (const Export &exp : normalizedFile.exportInfo) {
1572 bool weakDef = (exp.flags & EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION);
1573 // StringRefs from export iterator are ephemeral, so force copy.
1574 file->addExportedSymbol(exp.name, weakDef, true);
1575 }
1576 } else {
1577 for (auto &sym : normalizedFile.globalSymbols) {
1578 assert((sym.scope & N_EXT) && "only expect external symbols here");
1579 bool weakDef = (sym.desc & N_WEAK_DEF);
1580 file->addExportedSymbol(sym.name, weakDef, copyRefs);
1581 }
1582 }
1583 // Tell MachODylibFile object about all dylibs it re-exports.
1584 for (const DependentDylib &dep : normalizedFile.dependentDylibs) {
1585 if (dep.kind == llvm::MachO::LC_REEXPORT_DYLIB)
1586 file->addReExportedDylib(dep.path);
1587 }
1588 return llvm::Error::success();
1589}
1590
1591void relocatableSectionInfoForContentType(DefinedAtom::ContentType atomType,
1592 StringRef &segmentName,
1593 StringRef &sectionName,
1594 SectionType &sectionType,
1595 SectionAttr &sectionAttrs,
1596 bool &relocsToDefinedCanBeImplicit) {
1597
1598 for (const MachORelocatableSectionToAtomType *p = sectsToAtomType ;
1599 p->atomType != DefinedAtom::typeUnknown; ++p) {
1600 if (p->atomType != atomType)
1601 continue;
1602 // Wild carded entries are ignored for reverse lookups.
1603 if (p->segmentName.empty() || p->sectionName.empty())
1604 continue;
1605 segmentName = p->segmentName;
1606 sectionName = p->sectionName;
1607 sectionType = p->sectionType;
1608 sectionAttrs = 0;
1609 relocsToDefinedCanBeImplicit = false;
1610 if (atomType == DefinedAtom::typeCode)
1611 sectionAttrs = S_ATTR_PURE_INSTRUCTIONS;
1612 if (atomType == DefinedAtom::typeCFI)
1613 relocsToDefinedCanBeImplicit = true;
1614 return;
1615 }
1616 llvm_unreachable("content type not yet supported");
1617}
1618
1619llvm::Expected<std::unique_ptr<lld::File>>
1620normalizedToAtoms(const NormalizedFile &normalizedFile, StringRef path,
1621 bool copyRefs) {
1622 switch (normalizedFile.fileType) {
1623 case MH_DYLIB:
1624 case MH_DYLIB_STUB:
1625 return dylibToAtoms(normalizedFile, path, copyRefs);
1626 case MH_OBJECT:
1627 return objectToAtoms(normalizedFile, path, copyRefs);
1628 default:
1629 llvm_unreachable("unhandled MachO file type!");
1630 }
1631}
1632
1633} // namespace normalized
1634} // namespace mach_o
1635} // namespace lld
deps/lld/lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp created+843
......@@ -0,0 +1,843 @@
1//===- lib/ReaderWriter/MachO/MachONormalizedFileYAML.cpp -----------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10///
11/// \file For mach-o object files, this implementation uses YAML I/O to
12/// provide the convert between YAML and the normalized mach-o (NM).
13///
14/// +------------+ +------+
15/// | normalized | <-> | yaml |
16/// +------------+ +------+
17
18#include "MachONormalizedFile.h"
19#include "lld/Core/Error.h"
20#include "lld/Core/LLVM.h"
21#include "lld/ReaderWriter/YamlContext.h"
22#include "llvm/ADT/SmallString.h"
23#include "llvm/ADT/StringRef.h"
24#include "llvm/ADT/StringSwitch.h"
25#include "llvm/ADT/Twine.h"
26#include "llvm/BinaryFormat/MachO.h"
27#include "llvm/Support/Casting.h"
28#include "llvm/Support/ErrorHandling.h"
29#include "llvm/Support/Format.h"
30#include "llvm/Support/MemoryBuffer.h"
31#include "llvm/Support/SourceMgr.h"
32#include "llvm/Support/YAMLTraits.h"
33#include "llvm/Support/raw_ostream.h"
34#include <system_error>
35
36using llvm::StringRef;
37using namespace llvm::yaml;
38using namespace llvm::MachO;
39using namespace lld::mach_o::normalized;
40using lld::YamlContext;
41
42LLVM_YAML_IS_SEQUENCE_VECTOR(Segment)
43LLVM_YAML_IS_SEQUENCE_VECTOR(DependentDylib)
44LLVM_YAML_IS_SEQUENCE_VECTOR(RebaseLocation)
45LLVM_YAML_IS_SEQUENCE_VECTOR(BindLocation)
46LLVM_YAML_IS_SEQUENCE_VECTOR(Export)
47LLVM_YAML_IS_SEQUENCE_VECTOR(DataInCode)
48
49
50// for compatibility with gcc-4.7 in C++11 mode, add extra namespace
51namespace llvm {
52namespace yaml {
53
54// A vector of Sections is a sequence.
55template<>
56struct SequenceTraits< std::vector<Section> > {
57 static size_t size(IO &io, std::vector<Section> &seq) {
58 return seq.size();
59 }
60 static Section& element(IO &io, std::vector<Section> &seq, size_t index) {
61 if ( index >= seq.size() )
62 seq.resize(index+1);
63 return seq[index];
64 }
65};
66
67template<>
68struct SequenceTraits< std::vector<Symbol> > {
69 static size_t size(IO &io, std::vector<Symbol> &seq) {
70 return seq.size();
71 }
72 static Symbol& element(IO &io, std::vector<Symbol> &seq, size_t index) {
73 if ( index >= seq.size() )
74 seq.resize(index+1);
75 return seq[index];
76 }
77};
78
79// A vector of Relocations is a sequence.
80template<>
81struct SequenceTraits< Relocations > {
82 static size_t size(IO &io, Relocations &seq) {
83 return seq.size();
84 }
85 static Relocation& element(IO &io, Relocations &seq, size_t index) {
86 if ( index >= seq.size() )
87 seq.resize(index+1);
88 return seq[index];
89 }
90};
91
92// The content for a section is represented as a flow sequence of hex bytes.
93template<>
94struct SequenceTraits< ContentBytes > {
95 static size_t size(IO &io, ContentBytes &seq) {
96 return seq.size();
97 }
98 static Hex8& element(IO &io, ContentBytes &seq, size_t index) {
99 if ( index >= seq.size() )
100 seq.resize(index+1);
101 return seq[index];
102 }
103 static const bool flow = true;
104};
105
106// The indirect symbols for a section is represented as a flow sequence
107// of numbers (symbol table indexes).
108template<>
109struct SequenceTraits< IndirectSymbols > {
110 static size_t size(IO &io, IndirectSymbols &seq) {
111 return seq.size();
112 }
113 static uint32_t& element(IO &io, IndirectSymbols &seq, size_t index) {
114 if ( index >= seq.size() )
115 seq.resize(index+1);
116 return seq[index];
117 }
118 static const bool flow = true;
119};
120
121template <>
122struct ScalarEnumerationTraits<lld::MachOLinkingContext::Arch> {
123 static void enumeration(IO &io, lld::MachOLinkingContext::Arch &value) {
124 io.enumCase(value, "unknown",lld::MachOLinkingContext::arch_unknown);
125 io.enumCase(value, "ppc", lld::MachOLinkingContext::arch_ppc);
126 io.enumCase(value, "x86", lld::MachOLinkingContext::arch_x86);
127 io.enumCase(value, "x86_64", lld::MachOLinkingContext::arch_x86_64);
128 io.enumCase(value, "armv6", lld::MachOLinkingContext::arch_armv6);
129 io.enumCase(value, "armv7", lld::MachOLinkingContext::arch_armv7);
130 io.enumCase(value, "armv7s", lld::MachOLinkingContext::arch_armv7s);
131 io.enumCase(value, "arm64", lld::MachOLinkingContext::arch_arm64);
132 }
133};
134
135template <>
136struct ScalarEnumerationTraits<lld::MachOLinkingContext::OS> {
137 static void enumeration(IO &io, lld::MachOLinkingContext::OS &value) {
138 io.enumCase(value, "unknown",
139 lld::MachOLinkingContext::OS::unknown);
140 io.enumCase(value, "Mac OS X",
141 lld::MachOLinkingContext::OS::macOSX);
142 io.enumCase(value, "iOS",
143 lld::MachOLinkingContext::OS::iOS);
144 io.enumCase(value, "iOS Simulator",
145 lld::MachOLinkingContext::OS::iOS_simulator);
146 }
147};
148
149
150template <>
151struct ScalarEnumerationTraits<HeaderFileType> {
152 static void enumeration(IO &io, HeaderFileType &value) {
153 io.enumCase(value, "MH_OBJECT", llvm::MachO::MH_OBJECT);
154 io.enumCase(value, "MH_DYLIB", llvm::MachO::MH_DYLIB);
155 io.enumCase(value, "MH_EXECUTE", llvm::MachO::MH_EXECUTE);
156 io.enumCase(value, "MH_BUNDLE", llvm::MachO::MH_BUNDLE);
157 }
158};
159
160
161template <>
162struct ScalarBitSetTraits<FileFlags> {
163 static void bitset(IO &io, FileFlags &value) {
164 io.bitSetCase(value, "MH_TWOLEVEL",
165 llvm::MachO::MH_TWOLEVEL);
166 io.bitSetCase(value, "MH_SUBSECTIONS_VIA_SYMBOLS",
167 llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);
168 }
169};
170
171
172template <>
173struct ScalarEnumerationTraits<SectionType> {
174 static void enumeration(IO &io, SectionType &value) {
175 io.enumCase(value, "S_REGULAR",
176 llvm::MachO::S_REGULAR);
177 io.enumCase(value, "S_ZEROFILL",
178 llvm::MachO::S_ZEROFILL);
179 io.enumCase(value, "S_CSTRING_LITERALS",
180 llvm::MachO::S_CSTRING_LITERALS);
181 io.enumCase(value, "S_4BYTE_LITERALS",
182 llvm::MachO::S_4BYTE_LITERALS);
183 io.enumCase(value, "S_8BYTE_LITERALS",
184 llvm::MachO::S_8BYTE_LITERALS);
185 io.enumCase(value, "S_LITERAL_POINTERS",
186 llvm::MachO::S_LITERAL_POINTERS);
187 io.enumCase(value, "S_NON_LAZY_SYMBOL_POINTERS",
188 llvm::MachO::S_NON_LAZY_SYMBOL_POINTERS);
189 io.enumCase(value, "S_LAZY_SYMBOL_POINTERS",
190 llvm::MachO::S_LAZY_SYMBOL_POINTERS);
191 io.enumCase(value, "S_SYMBOL_STUBS",
192 llvm::MachO::S_SYMBOL_STUBS);
193 io.enumCase(value, "S_MOD_INIT_FUNC_POINTERS",
194 llvm::MachO::S_MOD_INIT_FUNC_POINTERS);
195 io.enumCase(value, "S_MOD_TERM_FUNC_POINTERS",
196 llvm::MachO::S_MOD_TERM_FUNC_POINTERS);
197 io.enumCase(value, "S_COALESCED",
198 llvm::MachO::S_COALESCED);
199 io.enumCase(value, "S_GB_ZEROFILL",
200 llvm::MachO::S_GB_ZEROFILL);
201 io.enumCase(value, "S_INTERPOSING",
202 llvm::MachO::S_INTERPOSING);
203 io.enumCase(value, "S_16BYTE_LITERALS",
204 llvm::MachO::S_16BYTE_LITERALS);
205 io.enumCase(value, "S_DTRACE_DOF",
206 llvm::MachO::S_DTRACE_DOF);
207 io.enumCase(value, "S_LAZY_DYLIB_SYMBOL_POINTERS",
208 llvm::MachO::S_LAZY_DYLIB_SYMBOL_POINTERS);
209 io.enumCase(value, "S_THREAD_LOCAL_REGULAR",
210 llvm::MachO::S_THREAD_LOCAL_REGULAR);
211 io.enumCase(value, "S_THREAD_LOCAL_ZEROFILL",
212 llvm::MachO::S_THREAD_LOCAL_ZEROFILL);
213 io.enumCase(value, "S_THREAD_LOCAL_VARIABLES",
214 llvm::MachO::S_THREAD_LOCAL_VARIABLES);
215 io.enumCase(value, "S_THREAD_LOCAL_VARIABLE_POINTERS",
216 llvm::MachO::S_THREAD_LOCAL_VARIABLE_POINTERS);
217 io.enumCase(value, "S_THREAD_LOCAL_INIT_FUNCTION_POINTERS",
218 llvm::MachO::S_THREAD_LOCAL_INIT_FUNCTION_POINTERS);
219 }
220};
221
222template <>
223struct ScalarBitSetTraits<SectionAttr> {
224 static void bitset(IO &io, SectionAttr &value) {
225 io.bitSetCase(value, "S_ATTR_PURE_INSTRUCTIONS",
226 llvm::MachO::S_ATTR_PURE_INSTRUCTIONS);
227 io.bitSetCase(value, "S_ATTR_SOME_INSTRUCTIONS",
228 llvm::MachO::S_ATTR_SOME_INSTRUCTIONS);
229 io.bitSetCase(value, "S_ATTR_NO_DEAD_STRIP",
230 llvm::MachO::S_ATTR_NO_DEAD_STRIP);
231 io.bitSetCase(value, "S_ATTR_EXT_RELOC",
232 llvm::MachO::S_ATTR_EXT_RELOC);
233 io.bitSetCase(value, "S_ATTR_LOC_RELOC",
234 llvm::MachO::S_ATTR_LOC_RELOC);
235 io.bitSetCase(value, "S_ATTR_DEBUG",
236 llvm::MachO::S_ATTR_DEBUG);
237 }
238};
239
240/// This is a custom formatter for SectionAlignment. Values are
241/// the power to raise by, ie, the n in 2^n.
242template <> struct ScalarTraits<SectionAlignment> {
243 static void output(const SectionAlignment &value, void *ctxt,
244 raw_ostream &out) {
245 out << llvm::format("%d", (uint32_t)value);
246 }
247
248 static StringRef input(StringRef scalar, void *ctxt,
249 SectionAlignment &value) {
250 uint32_t alignment;
251 if (scalar.getAsInteger(0, alignment)) {
252 return "malformed alignment value";
253 }
254 if (!llvm::isPowerOf2_32(alignment))
255 return "alignment must be a power of 2";
256 value = alignment;
257 return StringRef(); // returning empty string means success
258 }
259
260 static bool mustQuote(StringRef) { return false; }
261};
262
263template <>
264struct ScalarEnumerationTraits<NListType> {
265 static void enumeration(IO &io, NListType &value) {
266 io.enumCase(value, "N_UNDF", llvm::MachO::N_UNDF);
267 io.enumCase(value, "N_ABS", llvm::MachO::N_ABS);
268 io.enumCase(value, "N_SECT", llvm::MachO::N_SECT);
269 io.enumCase(value, "N_PBUD", llvm::MachO::N_PBUD);
270 io.enumCase(value, "N_INDR", llvm::MachO::N_INDR);
271 }
272};
273
274template <>
275struct ScalarBitSetTraits<SymbolScope> {
276 static void bitset(IO &io, SymbolScope &value) {
277 io.bitSetCase(value, "N_EXT", llvm::MachO::N_EXT);
278 io.bitSetCase(value, "N_PEXT", llvm::MachO::N_PEXT);
279 }
280};
281
282template <>
283struct ScalarBitSetTraits<SymbolDesc> {
284 static void bitset(IO &io, SymbolDesc &value) {
285 io.bitSetCase(value, "N_NO_DEAD_STRIP", llvm::MachO::N_NO_DEAD_STRIP);
286 io.bitSetCase(value, "N_WEAK_REF", llvm::MachO::N_WEAK_REF);
287 io.bitSetCase(value, "N_WEAK_DEF", llvm::MachO::N_WEAK_DEF);
288 io.bitSetCase(value, "N_ARM_THUMB_DEF", llvm::MachO::N_ARM_THUMB_DEF);
289 io.bitSetCase(value, "N_SYMBOL_RESOLVER", llvm::MachO::N_SYMBOL_RESOLVER);
290 }
291};
292
293
294template <>
295struct MappingTraits<Section> {
296 struct NormalizedContentBytes;
297 static void mapping(IO &io, Section &sect) {
298 io.mapRequired("segment", sect.segmentName);
299 io.mapRequired("section", sect.sectionName);
300 io.mapRequired("type", sect.type);
301 io.mapOptional("attributes", sect.attributes);
302 io.mapOptional("alignment", sect.alignment, (SectionAlignment)1);
303 io.mapRequired("address", sect.address);
304 if (isZeroFillSection(sect.type)) {
305 // S_ZEROFILL sections use "size:" instead of "content:"
306 uint64_t size = sect.content.size();
307 io.mapOptional("size", size);
308 if (!io.outputting()) {
309 uint8_t *bytes = nullptr;
310 sect.content = makeArrayRef(bytes, size);
311 }
312 } else {
313 MappingNormalization<NormalizedContent, ArrayRef<uint8_t>> content(
314 io, sect.content);
315 io.mapOptional("content", content->_normalizedContent);
316 }
317 io.mapOptional("relocations", sect.relocations);
318 io.mapOptional("indirect-syms", sect.indirectSymbols);
319 }
320
321 struct NormalizedContent {
322 NormalizedContent(IO &io) : _io(io) {}
323 NormalizedContent(IO &io, ArrayRef<uint8_t> content) : _io(io) {
324 // When writing yaml, copy content byte array to Hex8 vector.
325 for (auto &c : content) {
326 _normalizedContent.push_back(c);
327 }
328 }
329 ArrayRef<uint8_t> denormalize(IO &io) {
330 // When reading yaml, allocate byte array owned by NormalizedFile and
331 // copy Hex8 vector to byte array.
332 YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
333 assert(info != nullptr);
334 NormalizedFile *file = info->_normalizeMachOFile;
335 assert(file != nullptr);
336 size_t size = _normalizedContent.size();
337 if (!size)
338 return None;
339 uint8_t *bytes = file->ownedAllocations.Allocate<uint8_t>(size);
340 std::copy(_normalizedContent.begin(), _normalizedContent.end(), bytes);
341 return makeArrayRef(bytes, size);
342 }
343
344 IO &_io;
345 ContentBytes _normalizedContent;
346 };
347};
348
349
350template <>
351struct MappingTraits<Relocation> {
352 static void mapping(IO &io, Relocation &reloc) {
353 io.mapRequired("offset", reloc.offset);
354 io.mapOptional("scattered", reloc.scattered, false);
355 io.mapRequired("type", reloc.type);
356 io.mapRequired("length", reloc.length);
357 io.mapRequired("pc-rel", reloc.pcRel);
358 if ( !reloc.scattered )
359 io.mapRequired("extern", reloc.isExtern);
360 if ( reloc.scattered )
361 io.mapRequired("value", reloc.value);
362 if ( !reloc.scattered )
363 io.mapRequired("symbol", reloc.symbol);
364 }
365};
366
367
368template <>
369struct ScalarEnumerationTraits<RelocationInfoType> {
370 static void enumeration(IO &io, RelocationInfoType &value) {
371 YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
372 assert(info != nullptr);
373 NormalizedFile *file = info->_normalizeMachOFile;
374 assert(file != nullptr);
375 switch (file->arch) {
376 case lld::MachOLinkingContext::arch_x86_64:
377 io.enumCase(value, "X86_64_RELOC_UNSIGNED",
378 llvm::MachO::X86_64_RELOC_UNSIGNED);
379 io.enumCase(value, "X86_64_RELOC_SIGNED",
380 llvm::MachO::X86_64_RELOC_SIGNED);
381 io.enumCase(value, "X86_64_RELOC_BRANCH",
382 llvm::MachO::X86_64_RELOC_BRANCH);
383 io.enumCase(value, "X86_64_RELOC_GOT_LOAD",
384 llvm::MachO::X86_64_RELOC_GOT_LOAD);
385 io.enumCase(value, "X86_64_RELOC_GOT",
386 llvm::MachO::X86_64_RELOC_GOT);
387 io.enumCase(value, "X86_64_RELOC_SUBTRACTOR",
388 llvm::MachO::X86_64_RELOC_SUBTRACTOR);
389 io.enumCase(value, "X86_64_RELOC_SIGNED_1",
390 llvm::MachO::X86_64_RELOC_SIGNED_1);
391 io.enumCase(value, "X86_64_RELOC_SIGNED_2",
392 llvm::MachO::X86_64_RELOC_SIGNED_2);
393 io.enumCase(value, "X86_64_RELOC_SIGNED_4",
394 llvm::MachO::X86_64_RELOC_SIGNED_4);
395 io.enumCase(value, "X86_64_RELOC_TLV",
396 llvm::MachO::X86_64_RELOC_TLV);
397 break;
398 case lld::MachOLinkingContext::arch_x86:
399 io.enumCase(value, "GENERIC_RELOC_VANILLA",
400 llvm::MachO::GENERIC_RELOC_VANILLA);
401 io.enumCase(value, "GENERIC_RELOC_PAIR",
402 llvm::MachO::GENERIC_RELOC_PAIR);
403 io.enumCase(value, "GENERIC_RELOC_SECTDIFF",
404 llvm::MachO::GENERIC_RELOC_SECTDIFF);
405 io.enumCase(value, "GENERIC_RELOC_LOCAL_SECTDIFF",
406 llvm::MachO::GENERIC_RELOC_LOCAL_SECTDIFF);
407 io.enumCase(value, "GENERIC_RELOC_TLV",
408 llvm::MachO::GENERIC_RELOC_TLV);
409 break;
410 case lld::MachOLinkingContext::arch_armv6:
411 case lld::MachOLinkingContext::arch_armv7:
412 case lld::MachOLinkingContext::arch_armv7s:
413 io.enumCase(value, "ARM_RELOC_VANILLA",
414 llvm::MachO::ARM_RELOC_VANILLA);
415 io.enumCase(value, "ARM_RELOC_PAIR",
416 llvm::MachO::ARM_RELOC_PAIR);
417 io.enumCase(value, "ARM_RELOC_SECTDIFF",
418 llvm::MachO::ARM_RELOC_SECTDIFF);
419 io.enumCase(value, "ARM_RELOC_LOCAL_SECTDIFF",
420 llvm::MachO::ARM_RELOC_LOCAL_SECTDIFF);
421 io.enumCase(value, "ARM_RELOC_BR24",
422 llvm::MachO::ARM_RELOC_BR24);
423 io.enumCase(value, "ARM_THUMB_RELOC_BR22",
424 llvm::MachO::ARM_THUMB_RELOC_BR22);
425 io.enumCase(value, "ARM_RELOC_HALF",
426 llvm::MachO::ARM_RELOC_HALF);
427 io.enumCase(value, "ARM_RELOC_HALF_SECTDIFF",
428 llvm::MachO::ARM_RELOC_HALF_SECTDIFF);
429 break;
430 case lld::MachOLinkingContext::arch_arm64:
431 io.enumCase(value, "ARM64_RELOC_UNSIGNED",
432 llvm::MachO::ARM64_RELOC_UNSIGNED);
433 io.enumCase(value, "ARM64_RELOC_SUBTRACTOR",
434 llvm::MachO::ARM64_RELOC_SUBTRACTOR);
435 io.enumCase(value, "ARM64_RELOC_BRANCH26",
436 llvm::MachO::ARM64_RELOC_BRANCH26);
437 io.enumCase(value, "ARM64_RELOC_PAGE21",
438 llvm::MachO::ARM64_RELOC_PAGE21);
439 io.enumCase(value, "ARM64_RELOC_PAGEOFF12",
440 llvm::MachO::ARM64_RELOC_PAGEOFF12);
441 io.enumCase(value, "ARM64_RELOC_GOT_LOAD_PAGE21",
442 llvm::MachO::ARM64_RELOC_GOT_LOAD_PAGE21);
443 io.enumCase(value, "ARM64_RELOC_GOT_LOAD_PAGEOFF12",
444 llvm::MachO::ARM64_RELOC_GOT_LOAD_PAGEOFF12);
445 io.enumCase(value, "ARM64_RELOC_POINTER_TO_GOT",
446 llvm::MachO::ARM64_RELOC_POINTER_TO_GOT);
447 io.enumCase(value, "ARM64_RELOC_TLVP_LOAD_PAGE21",
448 llvm::MachO::ARM64_RELOC_TLVP_LOAD_PAGE21);
449 io.enumCase(value, "ARM64_RELOC_TLVP_LOAD_PAGEOFF12",
450 llvm::MachO::ARM64_RELOC_TLVP_LOAD_PAGEOFF12);
451 io.enumCase(value, "ARM64_RELOC_ADDEND",
452 llvm::MachO::ARM64_RELOC_ADDEND);
453 break;
454 default:
455 llvm_unreachable("unknown architecture");
456 }
457 }
458};
459
460
461template <>
462struct MappingTraits<Symbol> {
463 static void mapping(IO &io, Symbol& sym) {
464 io.mapRequired("name", sym.name);
465 io.mapRequired("type", sym.type);
466 io.mapOptional("scope", sym.scope, SymbolScope(0));
467 io.mapOptional("sect", sym.sect, (uint8_t)0);
468 if (sym.type == llvm::MachO::N_UNDF) {
469 // In undef symbols, desc field contains alignment/ordinal info
470 // which is better represented as a hex vaule.
471 uint16_t t1 = sym.desc;
472 Hex16 t2 = t1;
473 io.mapOptional("desc", t2, Hex16(0));
474 sym.desc = t2;
475 } else {
476 // In defined symbols, desc fit is a set of option bits.
477 io.mapOptional("desc", sym.desc, SymbolDesc(0));
478 }
479 io.mapRequired("value", sym.value);
480 }
481};
482
483// Custom mapping for VMProtect (e.g. "r-x").
484template <>
485struct ScalarTraits<VMProtect> {
486 static void output(const VMProtect &value, void*, raw_ostream &out) {
487 out << ( (value & llvm::MachO::VM_PROT_READ) ? 'r' : '-');
488 out << ( (value & llvm::MachO::VM_PROT_WRITE) ? 'w' : '-');
489 out << ( (value & llvm::MachO::VM_PROT_EXECUTE) ? 'x' : '-');
490 }
491 static StringRef input(StringRef scalar, void*, VMProtect &value) {
492 value = 0;
493 if (scalar.size() != 3)
494 return "segment access protection must be three chars (e.g. \"r-x\")";
495 switch (scalar[0]) {
496 case 'r':
497 value = llvm::MachO::VM_PROT_READ;
498 break;
499 case '-':
500 break;
501 default:
502 return "segment access protection first char must be 'r' or '-'";
503 }
504 switch (scalar[1]) {
505 case 'w':
506 value = value | llvm::MachO::VM_PROT_WRITE;
507 break;
508 case '-':
509 break;
510 default:
511 return "segment access protection second char must be 'w' or '-'";
512 }
513 switch (scalar[2]) {
514 case 'x':
515 value = value | llvm::MachO::VM_PROT_EXECUTE;
516 break;
517 case '-':
518 break;
519 default:
520 return "segment access protection third char must be 'x' or '-'";
521 }
522 // Return the empty string on success,
523 return StringRef();
524 }
525 static bool mustQuote(StringRef) { return false; }
526};
527
528
529template <>
530struct MappingTraits<Segment> {
531 static void mapping(IO &io, Segment& seg) {
532 io.mapRequired("name", seg.name);
533 io.mapRequired("address", seg.address);
534 io.mapRequired("size", seg.size);
535 io.mapRequired("init-access", seg.init_access);
536 io.mapRequired("max-access", seg.max_access);
537 }
538};
539
540template <>
541struct ScalarEnumerationTraits<LoadCommandType> {
542 static void enumeration(IO &io, LoadCommandType &value) {
543 io.enumCase(value, "LC_LOAD_DYLIB",
544 llvm::MachO::LC_LOAD_DYLIB);
545 io.enumCase(value, "LC_LOAD_WEAK_DYLIB",
546 llvm::MachO::LC_LOAD_WEAK_DYLIB);
547 io.enumCase(value, "LC_REEXPORT_DYLIB",
548 llvm::MachO::LC_REEXPORT_DYLIB);
549 io.enumCase(value, "LC_LOAD_UPWARD_DYLIB",
550 llvm::MachO::LC_LOAD_UPWARD_DYLIB);
551 io.enumCase(value, "LC_LAZY_LOAD_DYLIB",
552 llvm::MachO::LC_LAZY_LOAD_DYLIB);
553 io.enumCase(value, "LC_VERSION_MIN_MACOSX",
554 llvm::MachO::LC_VERSION_MIN_MACOSX);
555 io.enumCase(value, "LC_VERSION_MIN_IPHONEOS",
556 llvm::MachO::LC_VERSION_MIN_IPHONEOS);
557 io.enumCase(value, "LC_VERSION_MIN_TVOS",
558 llvm::MachO::LC_VERSION_MIN_TVOS);
559 io.enumCase(value, "LC_VERSION_MIN_WATCHOS",
560 llvm::MachO::LC_VERSION_MIN_WATCHOS);
561 }
562};
563
564template <>
565struct MappingTraits<DependentDylib> {
566 static void mapping(IO &io, DependentDylib& dylib) {
567 io.mapRequired("path", dylib.path);
568 io.mapOptional("kind", dylib.kind,
569 llvm::MachO::LC_LOAD_DYLIB);
570 io.mapOptional("compat-version", dylib.compatVersion,
571 PackedVersion(0x10000));
572 io.mapOptional("current-version", dylib.currentVersion,
573 PackedVersion(0x10000));
574 }
575};
576
577template <>
578struct ScalarEnumerationTraits<RebaseType> {
579 static void enumeration(IO &io, RebaseType &value) {
580 io.enumCase(value, "REBASE_TYPE_POINTER",
581 llvm::MachO::REBASE_TYPE_POINTER);
582 io.enumCase(value, "REBASE_TYPE_TEXT_PCREL32",
583 llvm::MachO::REBASE_TYPE_TEXT_PCREL32);
584 io.enumCase(value, "REBASE_TYPE_TEXT_ABSOLUTE32",
585 llvm::MachO::REBASE_TYPE_TEXT_ABSOLUTE32);
586 }
587};
588
589
590template <>
591struct MappingTraits<RebaseLocation> {
592 static void mapping(IO &io, RebaseLocation& rebase) {
593 io.mapRequired("segment-index", rebase.segIndex);
594 io.mapRequired("segment-offset", rebase.segOffset);
595 io.mapOptional("kind", rebase.kind,
596 llvm::MachO::REBASE_TYPE_POINTER);
597 }
598};
599
600
601
602template <>
603struct ScalarEnumerationTraits<BindType> {
604 static void enumeration(IO &io, BindType &value) {
605 io.enumCase(value, "BIND_TYPE_POINTER",
606 llvm::MachO::BIND_TYPE_POINTER);
607 io.enumCase(value, "BIND_TYPE_TEXT_ABSOLUTE32",
608 llvm::MachO::BIND_TYPE_TEXT_ABSOLUTE32);
609 io.enumCase(value, "BIND_TYPE_TEXT_PCREL32",
610 llvm::MachO::BIND_TYPE_TEXT_PCREL32);
611 }
612};
613
614template <>
615struct MappingTraits<BindLocation> {
616 static void mapping(IO &io, BindLocation &bind) {
617 io.mapRequired("segment-index", bind.segIndex);
618 io.mapRequired("segment-offset", bind.segOffset);
619 io.mapOptional("kind", bind.kind,
620 llvm::MachO::BIND_TYPE_POINTER);
621 io.mapOptional("can-be-null", bind.canBeNull, false);
622 io.mapRequired("ordinal", bind.ordinal);
623 io.mapRequired("symbol-name", bind.symbolName);
624 io.mapOptional("addend", bind.addend, Hex64(0));
625 }
626};
627
628
629template <>
630struct ScalarEnumerationTraits<ExportSymbolKind> {
631 static void enumeration(IO &io, ExportSymbolKind &value) {
632 io.enumCase(value, "EXPORT_SYMBOL_FLAGS_KIND_REGULAR",
633 llvm::MachO::EXPORT_SYMBOL_FLAGS_KIND_REGULAR);
634 io.enumCase(value, "EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL",
635 llvm::MachO::EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL);
636 io.enumCase(value, "EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE",
637 llvm::MachO::EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE);
638 }
639};
640
641template <>
642struct ScalarBitSetTraits<ExportFlags> {
643 static void bitset(IO &io, ExportFlags &value) {
644 io.bitSetCase(value, "EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION",
645 llvm::MachO::EXPORT_SYMBOL_FLAGS_WEAK_DEFINITION);
646 io.bitSetCase(value, "EXPORT_SYMBOL_FLAGS_REEXPORT",
647 llvm::MachO::EXPORT_SYMBOL_FLAGS_REEXPORT);
648 io.bitSetCase(value, "EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER",
649 llvm::MachO::EXPORT_SYMBOL_FLAGS_STUB_AND_RESOLVER);
650 }
651};
652
653
654template <>
655struct MappingTraits<Export> {
656 static void mapping(IO &io, Export &exp) {
657 io.mapRequired("name", exp.name);
658 io.mapOptional("offset", exp.offset);
659 io.mapOptional("kind", exp.kind,
660 llvm::MachO::EXPORT_SYMBOL_FLAGS_KIND_REGULAR);
661 if (!io.outputting() || exp.flags)
662 io.mapOptional("flags", exp.flags);
663 io.mapOptional("other", exp.otherOffset, Hex32(0));
664 io.mapOptional("other-name", exp.otherName, StringRef());
665 }
666};
667
668template <>
669struct ScalarEnumerationTraits<DataRegionType> {
670 static void enumeration(IO &io, DataRegionType &value) {
671 io.enumCase(value, "DICE_KIND_DATA",
672 llvm::MachO::DICE_KIND_DATA);
673 io.enumCase(value, "DICE_KIND_JUMP_TABLE8",
674 llvm::MachO::DICE_KIND_JUMP_TABLE8);
675 io.enumCase(value, "DICE_KIND_JUMP_TABLE16",
676 llvm::MachO::DICE_KIND_JUMP_TABLE16);
677 io.enumCase(value, "DICE_KIND_JUMP_TABLE32",
678 llvm::MachO::DICE_KIND_JUMP_TABLE32);
679 io.enumCase(value, "DICE_KIND_ABS_JUMP_TABLE32",
680 llvm::MachO::DICE_KIND_ABS_JUMP_TABLE32);
681 }
682};
683
684template <>
685struct MappingTraits<DataInCode> {
686 static void mapping(IO &io, DataInCode &entry) {
687 io.mapRequired("offset", entry.offset);
688 io.mapRequired("length", entry.length);
689 io.mapRequired("kind", entry.kind);
690 }
691};
692
693template <>
694struct ScalarTraits<PackedVersion> {
695 static void output(const PackedVersion &value, void*, raw_ostream &out) {
696 out << llvm::format("%d.%d", (value >> 16), (value >> 8) & 0xFF);
697 if (value & 0xFF) {
698 out << llvm::format(".%d", (value & 0xFF));
699 }
700 }
701 static StringRef input(StringRef scalar, void*, PackedVersion &result) {
702 uint32_t value;
703 if (lld::MachOLinkingContext::parsePackedVersion(scalar, value))
704 return "malformed version number";
705 result = value;
706 // Return the empty string on success,
707 return StringRef();
708 }
709 static bool mustQuote(StringRef) { return false; }
710};
711
712template <>
713struct MappingTraits<NormalizedFile> {
714 static void mapping(IO &io, NormalizedFile &file) {
715 io.mapRequired("arch", file.arch);
716 io.mapRequired("file-type", file.fileType);
717 io.mapOptional("flags", file.flags);
718 io.mapOptional("dependents", file.dependentDylibs);
719 io.mapOptional("install-name", file.installName, StringRef());
720 io.mapOptional("compat-version", file.compatVersion, PackedVersion(0x10000));
721 io.mapOptional("current-version", file.currentVersion, PackedVersion(0x10000));
722 io.mapOptional("has-UUID", file.hasUUID, true);
723 io.mapOptional("rpaths", file.rpaths);
724 io.mapOptional("entry-point", file.entryAddress, Hex64(0));
725 io.mapOptional("stack-size", file.stackSize, Hex64(0));
726 io.mapOptional("source-version", file.sourceVersion, Hex64(0));
727 io.mapOptional("OS", file.os);
728 io.mapOptional("min-os-version", file.minOSverson, PackedVersion(0));
729 io.mapOptional("min-os-version-kind", file.minOSVersionKind, (LoadCommandType)0);
730 io.mapOptional("sdk-version", file.sdkVersion, PackedVersion(0));
731 io.mapOptional("segments", file.segments);
732 io.mapOptional("sections", file.sections);
733 io.mapOptional("local-symbols", file.localSymbols);
734 io.mapOptional("global-symbols", file.globalSymbols);
735 io.mapOptional("undefined-symbols",file.undefinedSymbols);
736 io.mapOptional("page-size", file.pageSize, Hex32(4096));
737 io.mapOptional("rebasings", file.rebasingInfo);
738 io.mapOptional("bindings", file.bindingInfo);
739 io.mapOptional("weak-bindings", file.weakBindingInfo);
740 io.mapOptional("lazy-bindings", file.lazyBindingInfo);
741 io.mapOptional("exports", file.exportInfo);
742 io.mapOptional("dataInCode", file.dataInCode);
743 }
744 static StringRef validate(IO &io, NormalizedFile &file) {
745 return StringRef();
746 }
747};
748
749} // namespace llvm
750} // namespace yaml
751
752
753namespace lld {
754namespace mach_o {
755
756/// Handles !mach-o tagged yaml documents.
757bool MachOYamlIOTaggedDocumentHandler::handledDocTag(llvm::yaml::IO &io,
758 const lld::File *&file) const {
759 if (!io.mapTag("!mach-o"))
760 return false;
761 // Step 1: parse yaml into normalized mach-o struct.
762 NormalizedFile nf;
763 YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
764 assert(info != nullptr);
765 assert(info->_normalizeMachOFile == nullptr);
766 info->_normalizeMachOFile = &nf;
767 MappingTraits<NormalizedFile>::mapping(io, nf);
768 // Step 2: parse normalized mach-o struct into atoms.
769 auto fileOrError = normalizedToAtoms(nf, info->_path, true);
770
771 // Check that we parsed successfully.
772 if (!fileOrError) {
773 std::string buffer;
774 llvm::raw_string_ostream stream(buffer);
775 handleAllErrors(fileOrError.takeError(),
776 [&](const llvm::ErrorInfoBase &EI) {
777 EI.log(stream);
778 stream << "\n";
779 });
780 io.setError(stream.str());
781 return false;
782 }
783
784 if (nf.arch != _arch) {
785 io.setError(Twine("file is wrong architecture. Expected ("
786 + MachOLinkingContext::nameFromArch(_arch)
787 + ") found ("
788 + MachOLinkingContext::nameFromArch(nf.arch)
789 + ")"));
790 return false;
791 }
792 info->_normalizeMachOFile = nullptr;
793 file = fileOrError->release();
794 return true;
795}
796
797
798
799namespace normalized {
800
801/// Parses a yaml encoded mach-o file to produce an in-memory normalized view.
802llvm::Expected<std::unique_ptr<NormalizedFile>>
803readYaml(std::unique_ptr<MemoryBuffer> &mb) {
804 // Make empty NormalizedFile.
805 std::unique_ptr<NormalizedFile> f(new NormalizedFile());
806
807 // Create YAML Input parser.
808 YamlContext yamlContext;
809 yamlContext._normalizeMachOFile = f.get();
810 llvm::yaml::Input yin(mb->getBuffer(), &yamlContext);
811
812 // Fill NormalizedFile by parsing yaml.
813 yin >> *f;
814
815 // Return error if there were parsing problems.
816 if (auto ec = yin.error())
817 return llvm::make_error<GenericError>(Twine("YAML parsing error: ")
818 + ec.message());
819
820 // Hand ownership of instantiated NormalizedFile to caller.
821 return std::move(f);
822}
823
824
825/// Writes a yaml encoded mach-o files from an in-memory normalized view.
826std::error_code writeYaml(const NormalizedFile &file, raw_ostream &out) {
827 // YAML I/O is not const aware, so need to cast away ;-(
828 NormalizedFile *f = const_cast<NormalizedFile*>(&file);
829
830 // Create yaml Output writer, using yaml options for context.
831 YamlContext yamlContext;
832 yamlContext._normalizeMachOFile = f;
833 llvm::yaml::Output yout(out, &yamlContext);
834
835 // Stream out yaml.
836 yout << *f;
837
838 return std::error_code();
839}
840
841} // namespace normalized
842} // namespace mach_o
843} // namespace lld
deps/lld/lib/ReaderWriter/MachO/MachOPasses.h created+30
......@@ -0,0 +1,30 @@
1//===- lib/ReaderWriter/MachO/MachOPasses.h -------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_READER_WRITER_MACHO_PASSES_H
11#define LLD_READER_WRITER_MACHO_PASSES_H
12
13#include "lld/Core/PassManager.h"
14#include "lld/ReaderWriter/MachOLinkingContext.h"
15
16namespace lld {
17namespace mach_o {
18
19void addLayoutPass(PassManager &pm, const MachOLinkingContext &ctx);
20void addStubsPass(PassManager &pm, const MachOLinkingContext &ctx);
21void addGOTPass(PassManager &pm, const MachOLinkingContext &ctx);
22void addTLVPass(PassManager &pm, const MachOLinkingContext &ctx);
23void addCompactUnwindPass(PassManager &pm, const MachOLinkingContext &ctx);
24void addObjCPass(PassManager &pm, const MachOLinkingContext &ctx);
25void addShimPass(PassManager &pm, const MachOLinkingContext &ctx);
26
27} // namespace mach_o
28} // namespace lld
29
30#endif // LLD_READER_WRITER_MACHO_PASSES_H
deps/lld/lib/ReaderWriter/MachO/ObjCPass.cpp created+132
......@@ -0,0 +1,132 @@
1//===- lib/ReaderWriter/MachO/ObjCPass.cpp -------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10//===----------------------------------------------------------------------===//
11
12#include "ArchHandler.h"
13#include "File.h"
14#include "MachONormalizedFileBinaryUtils.h"
15#include "MachOPasses.h"
16#include "lld/Core/DefinedAtom.h"
17#include "lld/Core/File.h"
18#include "lld/Core/LLVM.h"
19#include "lld/Core/Reference.h"
20#include "lld/Core/Simple.h"
21#include "lld/ReaderWriter/MachOLinkingContext.h"
22#include "llvm/ADT/DenseMap.h"
23#include "llvm/ADT/STLExtras.h"
24
25namespace lld {
26namespace mach_o {
27
28///
29/// ObjC Image Info Atom created by the ObjC pass.
30///
31class ObjCImageInfoAtom : public SimpleDefinedAtom {
32public:
33 ObjCImageInfoAtom(const File &file, bool isBig,
34 MachOLinkingContext::ObjCConstraint objCConstraint,
35 uint32_t swiftVersion)
36 : SimpleDefinedAtom(file) {
37
38 Data.info.version = 0;
39
40 switch (objCConstraint) {
41 case MachOLinkingContext::objc_unknown:
42 llvm_unreachable("Shouldn't run the objc pass without a constraint");
43 case MachOLinkingContext::objc_supports_gc:
44 case MachOLinkingContext::objc_gc_only:
45 llvm_unreachable("GC is not supported");
46 case MachOLinkingContext::objc_retainReleaseForSimulator:
47 // The retain/release for simulator flag is already the correct
48 // encoded value for the data so just set it here.
49 Data.info.flags = (uint32_t)objCConstraint;
50 break;
51 case MachOLinkingContext::objc_retainRelease:
52 // We don't need to encode this flag, so just leave the flags as 0.
53 Data.info.flags = 0;
54 break;
55 }
56
57 Data.info.flags |= (swiftVersion << 8);
58
59 normalized::write32(Data.bytes + 4, Data.info.flags, isBig);
60 }
61
62 ~ObjCImageInfoAtom() override = default;
63
64 ContentType contentType() const override {
65 return DefinedAtom::typeObjCImageInfo;
66 }
67
68 Alignment alignment() const override {
69 return 4;
70 }
71
72 uint64_t size() const override {
73 return 8;
74 }
75
76 ContentPermissions permissions() const override {
77 return DefinedAtom::permR__;
78 }
79
80 ArrayRef<uint8_t> rawContent() const override {
81 return llvm::makeArrayRef(Data.bytes, size());
82 }
83
84private:
85
86 struct objc_image_info {
87 uint32_t version;
88 uint32_t flags;
89 };
90
91 union {
92 objc_image_info info;
93 uint8_t bytes[8];
94 } Data;
95};
96
97class ObjCPass : public Pass {
98public:
99 ObjCPass(const MachOLinkingContext &context)
100 : _ctx(context),
101 _file(*_ctx.make_file<MachOFile>("<mach-o objc pass>")) {
102 _file.setOrdinal(_ctx.getNextOrdinalAndIncrement());
103 }
104
105 llvm::Error perform(SimpleFile &mergedFile) override {
106 // Add the image info.
107 mergedFile.addAtom(*getImageInfo());
108
109 return llvm::Error::success();
110 }
111
112private:
113
114 const DefinedAtom* getImageInfo() {
115 bool IsBig = MachOLinkingContext::isBigEndian(_ctx.arch());
116 return new (_file.allocator()) ObjCImageInfoAtom(_file, IsBig,
117 _ctx.objcConstraint(),
118 _ctx.swiftVersion());
119 }
120
121 const MachOLinkingContext &_ctx;
122 MachOFile &_file;
123};
124
125
126
127void addObjCPass(PassManager &pm, const MachOLinkingContext &ctx) {
128 pm.add(llvm::make_unique<ObjCPass>(ctx));
129}
130
131} // end namespace mach_o
132} // end namespace lld
deps/lld/lib/ReaderWriter/MachO/SectCreateFile.h created+102
......@@ -0,0 +1,102 @@
1//===---- lib/ReaderWriter/MachO/SectCreateFile.h ---------------*- c++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLD_READER_WRITER_MACHO_SECTCREATE_FILE_H
11#define LLD_READER_WRITER_MACHO_SECTCREATE_FILE_H
12
13#include "lld/Core/DefinedAtom.h"
14#include "lld/Core/Simple.h"
15#include "lld/ReaderWriter/MachOLinkingContext.h"
16
17namespace lld {
18namespace mach_o {
19
20//
21// A FlateNamespaceFile instance may be added as a resolution source of last
22// resort, depending on how -flat_namespace and -undefined are set.
23//
24class SectCreateFile : public File {
25public:
26 class SectCreateAtom : public SimpleDefinedAtom {
27 public:
28 SectCreateAtom(const File &file, StringRef segName, StringRef sectName,
29 std::unique_ptr<MemoryBuffer> content)
30 : SimpleDefinedAtom(file),
31 _combinedName((segName + "/" + sectName).str()),
32 _content(std::move(content)) {}
33
34 ~SectCreateAtom() override = default;
35
36 uint64_t size() const override { return _content->getBufferSize(); }
37
38 Scope scope() const override { return scopeGlobal; }
39
40 ContentType contentType() const override { return typeSectCreate; }
41
42 SectionChoice sectionChoice() const override { return sectionCustomRequired; }
43
44 StringRef customSectionName() const override { return _combinedName; }
45
46 DeadStripKind deadStrip() const override { return deadStripNever; }
47
48 ArrayRef<uint8_t> rawContent() const override {
49 const uint8_t *data =
50 reinterpret_cast<const uint8_t*>(_content->getBufferStart());
51 return ArrayRef<uint8_t>(data, _content->getBufferSize());
52 }
53
54 StringRef segmentName() const { return _segName; }
55 StringRef sectionName() const { return _sectName; }
56
57 private:
58 std::string _combinedName;
59 StringRef _segName;
60 StringRef _sectName;
61 std::unique_ptr<MemoryBuffer> _content;
62 };
63
64 SectCreateFile() : File("sectcreate", kindSectCreateObject) {}
65
66 void addSection(StringRef seg, StringRef sect,
67 std::unique_ptr<MemoryBuffer> content) {
68 _definedAtoms.push_back(
69 new (allocator()) SectCreateAtom(*this, seg, sect, std::move(content)));
70 }
71
72 const AtomRange<DefinedAtom> defined() const override {
73 return _definedAtoms;
74 }
75
76 const AtomRange<UndefinedAtom> undefined() const override {
77 return _noUndefinedAtoms;
78 }
79
80 const AtomRange<SharedLibraryAtom> sharedLibrary() const override {
81 return _noSharedLibraryAtoms;
82 }
83
84 const AtomRange<AbsoluteAtom> absolute() const override {
85 return _noAbsoluteAtoms;
86 }
87
88 void clearAtoms() override {
89 _definedAtoms.clear();
90 _noUndefinedAtoms.clear();
91 _noSharedLibraryAtoms.clear();
92 _noAbsoluteAtoms.clear();
93 }
94
95private:
96 AtomVector<DefinedAtom> _definedAtoms;
97};
98
99} // namespace mach_o
100} // namespace lld
101
102#endif // LLD_READER_WRITER_MACHO_SECTCREATE_FILE_H
deps/lld/lib/ReaderWriter/MachO/ShimPass.cpp created+129
......@@ -0,0 +1,129 @@
1//===- lib/ReaderWriter/MachO/ShimPass.cpp -------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This linker pass updates branch-sites whose target is a different mode
11// (thumb vs arm).
12//
13// Arm code has two instruction encodings thumb and arm. When branching from
14// one code encoding to another, you need to use an instruction that switches
15// the instruction mode. Usually the transition only happens at call sites, and
16// the linker can transform a BL instruction in BLX (or vice versa). But if the
17// compiler did a tail call optimization and a function ends with a branch (not
18// branch and link), there is no pc-rel BX instruction.
19//
20// The ShimPass looks for pc-rel B instructions that will need to switch mode.
21// For those cases it synthesizes a shim which does the transition, then
22// modifies the original atom with the B instruction to target to the shim atom.
23//
24//===----------------------------------------------------------------------===//
25
26#include "ArchHandler.h"
27#include "File.h"
28#include "MachOPasses.h"
29#include "lld/Core/DefinedAtom.h"
30#include "lld/Core/File.h"
31#include "lld/Core/LLVM.h"
32#include "lld/Core/Reference.h"
33#include "lld/Core/Simple.h"
34#include "lld/ReaderWriter/MachOLinkingContext.h"
35#include "llvm/ADT/DenseMap.h"
36#include "llvm/ADT/STLExtras.h"
37
38namespace lld {
39namespace mach_o {
40
41class ShimPass : public Pass {
42public:
43 ShimPass(const MachOLinkingContext &context)
44 : _ctx(context), _archHandler(_ctx.archHandler()),
45 _stubInfo(_archHandler.stubInfo()),
46 _file(*_ctx.make_file<MachOFile>("<mach-o shim pass>")) {
47 _file.setOrdinal(_ctx.getNextOrdinalAndIncrement());
48 }
49
50 llvm::Error perform(SimpleFile &mergedFile) override {
51 // Scan all references in all atoms.
52 for (const DefinedAtom *atom : mergedFile.defined()) {
53 for (const Reference *ref : *atom) {
54 // Look at non-call branches.
55 if (!_archHandler.isNonCallBranch(*ref))
56 continue;
57 const Atom *target = ref->target();
58 assert(target != nullptr);
59 if (const lld::DefinedAtom *daTarget = dyn_cast<DefinedAtom>(target)) {
60 bool atomIsThumb = _archHandler.isThumbFunction(*atom);
61 bool targetIsThumb = _archHandler.isThumbFunction(*daTarget);
62 if (atomIsThumb != targetIsThumb)
63 updateBranchToUseShim(atomIsThumb, *daTarget, ref);
64 }
65 }
66 }
67 // Exit early if no shims needed.
68 if (_targetToShim.empty())
69 return llvm::Error::success();
70
71 // Sort shim atoms so the layout order is stable.
72 std::vector<const DefinedAtom *> shims;
73 shims.reserve(_targetToShim.size());
74 for (auto element : _targetToShim) {
75 shims.push_back(element.second);
76 }
77 std::sort(shims.begin(), shims.end(),
78 [](const DefinedAtom *l, const DefinedAtom *r) {
79 return (l->name() < r->name());
80 });
81
82 // Add all shims to master file.
83 for (const DefinedAtom *shim : shims)
84 mergedFile.addAtom(*shim);
85
86 return llvm::Error::success();
87 }
88
89private:
90
91 void updateBranchToUseShim(bool thumbToArm, const DefinedAtom& target,
92 const Reference *ref) {
93 // Make file-format specific stub and other support atoms.
94 const DefinedAtom *shim = this->getShim(thumbToArm, target);
95 assert(shim != nullptr);
96 // Switch branch site to target shim atom.
97 const_cast<Reference *>(ref)->setTarget(shim);
98 }
99
100 const DefinedAtom* getShim(bool thumbToArm, const DefinedAtom& target) {
101 auto pos = _targetToShim.find(&target);
102 if ( pos != _targetToShim.end() ) {
103 // Reuse an existing shim.
104 assert(pos->second != nullptr);
105 return pos->second;
106 } else {
107 // There is no existing shim, so create a new one.
108 const DefinedAtom *shim = _archHandler.createShim(_file, thumbToArm,
109 target);
110 _targetToShim[&target] = shim;
111 return shim;
112 }
113 }
114
115 const MachOLinkingContext &_ctx;
116 mach_o::ArchHandler &_archHandler;
117 const ArchHandler::StubInfo &_stubInfo;
118 MachOFile &_file;
119 llvm::DenseMap<const Atom*, const DefinedAtom*> _targetToShim;
120};
121
122
123
124void addShimPass(PassManager &pm, const MachOLinkingContext &ctx) {
125 pm.add(llvm::make_unique<ShimPass>(ctx));
126}
127
128} // end namespace mach_o
129} // end namespace lld
deps/lld/lib/ReaderWriter/MachO/StubsPass.cpp created+379
......@@ -0,0 +1,379 @@
1//===- lib/ReaderWriter/MachO/StubsPass.cpp ---------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This linker pass updates call-sites which have references to shared library
11// atoms to instead have a reference to a stub (PLT entry) for the specified
12// symbol. Each file format defines a subclass of StubsPass which implements
13// the abstract methods for creating the file format specific StubAtoms.
14//
15//===----------------------------------------------------------------------===//
16
17#include "ArchHandler.h"
18#include "File.h"
19#include "MachOPasses.h"
20#include "lld/Core/DefinedAtom.h"
21#include "lld/Core/File.h"
22#include "lld/Core/LLVM.h"
23#include "lld/Core/Reference.h"
24#include "lld/Core/Simple.h"
25#include "lld/ReaderWriter/MachOLinkingContext.h"
26#include "llvm/ADT/DenseMap.h"
27#include "llvm/ADT/SmallVector.h"
28
29namespace lld {
30namespace mach_o {
31
32//
33// Lazy Pointer Atom created by the stubs pass.
34//
35class LazyPointerAtom : public SimpleDefinedAtom {
36public:
37 LazyPointerAtom(const File &file, bool is64)
38 : SimpleDefinedAtom(file), _is64(is64) { }
39
40 ~LazyPointerAtom() override = default;
41
42 ContentType contentType() const override {
43 return DefinedAtom::typeLazyPointer;
44 }
45
46 Alignment alignment() const override {
47 return _is64 ? 8 : 4;
48 }
49
50 uint64_t size() const override {
51 return _is64 ? 8 : 4;
52 }
53
54 ContentPermissions permissions() const override {
55 return DefinedAtom::permRW_;
56 }
57
58 ArrayRef<uint8_t> rawContent() const override {
59 static const uint8_t zeros[] =
60 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
61 return llvm::makeArrayRef(zeros, size());
62 }
63
64private:
65 const bool _is64;
66};
67
68//
69// NonLazyPointer (GOT) Atom created by the stubs pass.
70//
71class NonLazyPointerAtom : public SimpleDefinedAtom {
72public:
73 NonLazyPointerAtom(const File &file, bool is64, ContentType contentType)
74 : SimpleDefinedAtom(file), _is64(is64), _contentType(contentType) { }
75
76 ~NonLazyPointerAtom() override = default;
77
78 ContentType contentType() const override {
79 return _contentType;
80 }
81
82 Alignment alignment() const override {
83 return _is64 ? 8 : 4;
84 }
85
86 uint64_t size() const override {
87 return _is64 ? 8 : 4;
88 }
89
90 ContentPermissions permissions() const override {
91 return DefinedAtom::permRW_;
92 }
93
94 ArrayRef<uint8_t> rawContent() const override {
95 static const uint8_t zeros[] =
96 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
97 return llvm::makeArrayRef(zeros, size());
98 }
99
100private:
101 const bool _is64;
102 const ContentType _contentType;
103};
104
105//
106// Stub Atom created by the stubs pass.
107//
108class StubAtom : public SimpleDefinedAtom {
109public:
110 StubAtom(const File &file, const ArchHandler::StubInfo &stubInfo)
111 : SimpleDefinedAtom(file), _stubInfo(stubInfo){ }
112
113 ~StubAtom() override = default;
114
115 ContentType contentType() const override {
116 return DefinedAtom::typeStub;
117 }
118
119 Alignment alignment() const override {
120 return 1 << _stubInfo.codeAlignment;
121 }
122
123 uint64_t size() const override {
124 return _stubInfo.stubSize;
125 }
126
127 ContentPermissions permissions() const override {
128 return DefinedAtom::permR_X;
129 }
130
131 ArrayRef<uint8_t> rawContent() const override {
132 return llvm::makeArrayRef(_stubInfo.stubBytes, _stubInfo.stubSize);
133 }
134
135private:
136 const ArchHandler::StubInfo &_stubInfo;
137};
138
139//
140// Stub Helper Atom created by the stubs pass.
141//
142class StubHelperAtom : public SimpleDefinedAtom {
143public:
144 StubHelperAtom(const File &file, const ArchHandler::StubInfo &stubInfo)
145 : SimpleDefinedAtom(file), _stubInfo(stubInfo) { }
146
147 ~StubHelperAtom() override = default;
148
149 ContentType contentType() const override {
150 return DefinedAtom::typeStubHelper;
151 }
152
153 Alignment alignment() const override {
154 return 1 << _stubInfo.codeAlignment;
155 }
156
157 uint64_t size() const override {
158 return _stubInfo.stubHelperSize;
159 }
160
161 ContentPermissions permissions() const override {
162 return DefinedAtom::permR_X;
163 }
164
165 ArrayRef<uint8_t> rawContent() const override {
166 return llvm::makeArrayRef(_stubInfo.stubHelperBytes,
167 _stubInfo.stubHelperSize);
168 }
169
170private:
171 const ArchHandler::StubInfo &_stubInfo;
172};
173
174//
175// Stub Helper Common Atom created by the stubs pass.
176//
177class StubHelperCommonAtom : public SimpleDefinedAtom {
178public:
179 StubHelperCommonAtom(const File &file, const ArchHandler::StubInfo &stubInfo)
180 : SimpleDefinedAtom(file), _stubInfo(stubInfo) { }
181
182 ~StubHelperCommonAtom() override = default;
183
184 ContentType contentType() const override {
185 return DefinedAtom::typeStubHelper;
186 }
187
188 Alignment alignment() const override {
189 return 1 << _stubInfo.stubHelperCommonAlignment;
190 }
191
192 uint64_t size() const override {
193 return _stubInfo.stubHelperCommonSize;
194 }
195
196 ContentPermissions permissions() const override {
197 return DefinedAtom::permR_X;
198 }
199
200 ArrayRef<uint8_t> rawContent() const override {
201 return llvm::makeArrayRef(_stubInfo.stubHelperCommonBytes,
202 _stubInfo.stubHelperCommonSize);
203 }
204
205private:
206 const ArchHandler::StubInfo &_stubInfo;
207};
208
209class StubsPass : public Pass {
210public:
211 StubsPass(const MachOLinkingContext &context)
212 : _ctx(context), _archHandler(_ctx.archHandler()),
213 _stubInfo(_archHandler.stubInfo()),
214 _file(*_ctx.make_file<MachOFile>("<mach-o Stubs pass>")) {
215 _file.setOrdinal(_ctx.getNextOrdinalAndIncrement());
216 }
217
218 llvm::Error perform(SimpleFile &mergedFile) override {
219 // Skip this pass if output format uses text relocations instead of stubs.
220 if (!this->noTextRelocs())
221 return llvm::Error::success();
222
223 // Scan all references in all atoms.
224 for (const DefinedAtom *atom : mergedFile.defined()) {
225 for (const Reference *ref : *atom) {
226 // Look at call-sites.
227 if (!this->isCallSite(*ref))
228 continue;
229 const Atom *target = ref->target();
230 assert(target != nullptr);
231 if (isa<SharedLibraryAtom>(target)) {
232 // Calls to shared libraries go through stubs.
233 _targetToUses[target].push_back(ref);
234 continue;
235 }
236 const DefinedAtom *defTarget = dyn_cast<DefinedAtom>(target);
237 if (defTarget && defTarget->interposable() != DefinedAtom::interposeNo){
238 // Calls to interposable functions in same linkage unit must also go
239 // through a stub.
240 assert(defTarget->scope() != DefinedAtom::scopeTranslationUnit);
241 _targetToUses[target].push_back(ref);
242 }
243 }
244 }
245
246 // Exit early if no stubs needed.
247 if (_targetToUses.empty())
248 return llvm::Error::success();
249
250 // First add help-common and GOT slots used by lazy binding.
251 SimpleDefinedAtom *helperCommonAtom =
252 new (_file.allocator()) StubHelperCommonAtom(_file, _stubInfo);
253 SimpleDefinedAtom *helperCacheNLPAtom =
254 new (_file.allocator()) NonLazyPointerAtom(_file, _ctx.is64Bit(),
255 _stubInfo.stubHelperImageCacheContentType);
256 SimpleDefinedAtom *helperBinderNLPAtom =
257 new (_file.allocator()) NonLazyPointerAtom(_file, _ctx.is64Bit(),
258 _stubInfo.stubHelperImageCacheContentType);
259 addReference(helperCommonAtom, _stubInfo.stubHelperCommonReferenceToCache,
260 helperCacheNLPAtom);
261 addOptReference(
262 helperCommonAtom, _stubInfo.stubHelperCommonReferenceToCache,
263 _stubInfo.optStubHelperCommonReferenceToCache, helperCacheNLPAtom);
264 addReference(helperCommonAtom, _stubInfo.stubHelperCommonReferenceToBinder,
265 helperBinderNLPAtom);
266 addOptReference(
267 helperCommonAtom, _stubInfo.stubHelperCommonReferenceToBinder,
268 _stubInfo.optStubHelperCommonReferenceToBinder, helperBinderNLPAtom);
269 mergedFile.addAtom(*helperCommonAtom);
270 mergedFile.addAtom(*helperBinderNLPAtom);
271 mergedFile.addAtom(*helperCacheNLPAtom);
272
273 // Add reference to dyld_stub_binder in libSystem.dylib
274 auto I = std::find_if(
275 mergedFile.sharedLibrary().begin(), mergedFile.sharedLibrary().end(),
276 [&](const SharedLibraryAtom *atom) {
277 return atom->name().equals(_stubInfo.binderSymbolName);
278 });
279 assert(I != mergedFile.sharedLibrary().end() &&
280 "dyld_stub_binder not found");
281 addReference(helperBinderNLPAtom, _stubInfo.nonLazyPointerReferenceToBinder, *I);
282
283 // Sort targets by name, so stubs and lazy pointers are consistent
284 std::vector<const Atom *> targetsNeedingStubs;
285 for (auto it : _targetToUses)
286 targetsNeedingStubs.push_back(it.first);
287 std::sort(targetsNeedingStubs.begin(), targetsNeedingStubs.end(),
288 [](const Atom * left, const Atom * right) {
289 return (left->name().compare(right->name()) < 0);
290 });
291
292 // Make and append stubs, lazy pointers, and helpers in alphabetical order.
293 unsigned lazyOffset = 0;
294 for (const Atom *target : targetsNeedingStubs) {
295 auto *stub = new (_file.allocator()) StubAtom(_file, _stubInfo);
296 auto *lp =
297 new (_file.allocator()) LazyPointerAtom(_file, _ctx.is64Bit());
298 auto *helper = new (_file.allocator()) StubHelperAtom(_file, _stubInfo);
299
300 addReference(stub, _stubInfo.stubReferenceToLP, lp);
301 addOptReference(stub, _stubInfo.stubReferenceToLP,
302 _stubInfo.optStubReferenceToLP, lp);
303 addReference(lp, _stubInfo.lazyPointerReferenceToHelper, helper);
304 addReference(lp, _stubInfo.lazyPointerReferenceToFinal, target);
305 addReference(helper, _stubInfo.stubHelperReferenceToImm, helper);
306 addReferenceAddend(helper, _stubInfo.stubHelperReferenceToImm, helper,
307 lazyOffset);
308 addReference(helper, _stubInfo.stubHelperReferenceToHelperCommon,
309 helperCommonAtom);
310
311 mergedFile.addAtom(*stub);
312 mergedFile.addAtom(*lp);
313 mergedFile.addAtom(*helper);
314
315 // Update each reference to use stub.
316 for (const Reference *ref : _targetToUses[target]) {
317 assert(ref->target() == target);
318 // Switch call site to reference stub atom instead.
319 const_cast<Reference *>(ref)->setTarget(stub);
320 }
321
322 // Calculate new offset
323 lazyOffset += target->name().size() + 12;
324 }
325
326 return llvm::Error::success();
327 }
328
329private:
330 bool noTextRelocs() {
331 return true;
332 }
333
334 bool isCallSite(const Reference &ref) {
335 return _archHandler.isCallSite(ref);
336 }
337
338 void addReference(SimpleDefinedAtom* atom,
339 const ArchHandler::ReferenceInfo &refInfo,
340 const lld::Atom* target) {
341 atom->addReference(Reference::KindNamespace::mach_o,
342 refInfo.arch, refInfo.kind, refInfo.offset,
343 target, refInfo.addend);
344 }
345
346 void addReferenceAddend(SimpleDefinedAtom *atom,
347 const ArchHandler::ReferenceInfo &refInfo,
348 const lld::Atom *target, uint64_t addend) {
349 atom->addReference(Reference::KindNamespace::mach_o, refInfo.arch,
350 refInfo.kind, refInfo.offset, target, addend);
351 }
352
353 void addOptReference(SimpleDefinedAtom* atom,
354 const ArchHandler::ReferenceInfo &refInfo,
355 const ArchHandler::OptionalRefInfo &optRef,
356 const lld::Atom* target) {
357 if (!optRef.used)
358 return;
359 atom->addReference(Reference::KindNamespace::mach_o,
360 refInfo.arch, optRef.kind, optRef.offset,
361 target, optRef.addend);
362 }
363
364 typedef llvm::DenseMap<const Atom*,
365 llvm::SmallVector<const Reference *, 8>> TargetToUses;
366
367 const MachOLinkingContext &_ctx;
368 mach_o::ArchHandler &_archHandler;
369 const ArchHandler::StubInfo &_stubInfo;
370 MachOFile &_file;
371 TargetToUses _targetToUses;
372};
373
374void addStubsPass(PassManager &pm, const MachOLinkingContext &ctx) {
375 pm.add(std::unique_ptr<Pass>(new StubsPass(ctx)));
376}
377
378} // end namespace mach_o
379} // end namespace lld
deps/lld/lib/ReaderWriter/MachO/TLVPass.cpp created+141
......@@ -0,0 +1,141 @@
1//===- lib/ReaderWriter/MachO/TLVPass.cpp -----------------------*- C++ -*-===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11/// This linker pass transforms all TLV references to real references.
12///
13//===----------------------------------------------------------------------===//
14
15#include "ArchHandler.h"
16#include "File.h"
17#include "MachOPasses.h"
18#include "lld/Core/Simple.h"
19#include "llvm/ADT/STLExtras.h"
20#include "llvm/Support/Debug.h"
21
22namespace lld {
23namespace mach_o {
24
25//
26// TLVP Entry Atom created by the TLV pass.
27//
28class TLVPEntryAtom : public SimpleDefinedAtom {
29public:
30 TLVPEntryAtom(const File &file, bool is64, StringRef name)
31 : SimpleDefinedAtom(file), _is64(is64), _name(name) {}
32
33 ~TLVPEntryAtom() override = default;
34
35 ContentType contentType() const override {
36 return DefinedAtom::typeTLVInitializerPtr;
37 }
38
39 Alignment alignment() const override {
40 return _is64 ? 8 : 4;
41 }
42
43 uint64_t size() const override {
44 return _is64 ? 8 : 4;
45 }
46
47 ContentPermissions permissions() const override {
48 return DefinedAtom::permRW_;
49 }
50
51 ArrayRef<uint8_t> rawContent() const override {
52 static const uint8_t zeros[] =
53 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
54 return llvm::makeArrayRef(zeros, size());
55 }
56
57 StringRef slotName() const {
58 return _name;
59 }
60
61private:
62 const bool _is64;
63 StringRef _name;
64};
65
66class TLVPass : public Pass {
67public:
68 TLVPass(const MachOLinkingContext &context)
69 : _ctx(context), _archHandler(_ctx.archHandler()),
70 _file(*_ctx.make_file<MachOFile>("<mach-o TLV pass>")) {
71 _file.setOrdinal(_ctx.getNextOrdinalAndIncrement());
72 }
73
74private:
75 llvm::Error perform(SimpleFile &mergedFile) override {
76 bool allowTLV = _ctx.minOS("10.7", "1.0");
77
78 for (const DefinedAtom *atom : mergedFile.defined()) {
79 for (const Reference *ref : *atom) {
80 if (!_archHandler.isTLVAccess(*ref))
81 continue;
82
83 if (!allowTLV)
84 return llvm::make_error<GenericError>(
85 "targeted OS version does not support use of thread local "
86 "variables in " + atom->name() + " for architecture " +
87 _ctx.archName());
88
89 const Atom *target = ref->target();
90 assert(target != nullptr);
91
92 const DefinedAtom *tlvpEntry = makeTLVPEntry(target);
93 const_cast<Reference*>(ref)->setTarget(tlvpEntry);
94 _archHandler.updateReferenceToTLV(ref);
95 }
96 }
97
98 std::vector<const TLVPEntryAtom*> entries;
99 entries.reserve(_targetToTLVP.size());
100 for (auto &it : _targetToTLVP)
101 entries.push_back(it.second);
102 std::sort(entries.begin(), entries.end(),
103 [](const TLVPEntryAtom *lhs, const TLVPEntryAtom *rhs) {
104 return (lhs->slotName().compare(rhs->slotName()) < 0);
105 });
106
107 for (const TLVPEntryAtom *slot : entries)
108 mergedFile.addAtom(*slot);
109
110 return llvm::Error::success();
111 }
112
113 const DefinedAtom *makeTLVPEntry(const Atom *target) {
114 auto pos = _targetToTLVP.find(target);
115
116 if (pos != _targetToTLVP.end())
117 return pos->second;
118
119 auto *tlvpEntry = new (_file.allocator())
120 TLVPEntryAtom(_file, _ctx.is64Bit(), target->name());
121 _targetToTLVP[target] = tlvpEntry;
122 const ArchHandler::ReferenceInfo &nlInfo =
123 _archHandler.stubInfo().nonLazyPointerReferenceToBinder;
124 tlvpEntry->addReference(Reference::KindNamespace::mach_o, nlInfo.arch,
125 nlInfo.kind, 0, target, 0);
126 return tlvpEntry;
127 }
128
129 const MachOLinkingContext &_ctx;
130 mach_o::ArchHandler &_archHandler;
131 MachOFile &_file;
132 llvm::DenseMap<const Atom*, const TLVPEntryAtom*> _targetToTLVP;
133};
134
135void addTLVPass(PassManager &pm, const MachOLinkingContext &ctx) {
136 assert(ctx.needsTLVPass());
137 pm.add(llvm::make_unique<TLVPass>(ctx));
138}
139
140} // end namesapce mach_o
141} // end namesapce lld
deps/lld/lib/ReaderWriter/MachO/WriterMachO.cpp created+71
......@@ -0,0 +1,71 @@
1//===- lib/ReaderWriter/MachO/WriterMachO.cpp -----------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "ExecutableAtoms.h"
11#include "MachONormalizedFile.h"
12#include "lld/Core/File.h"
13#include "lld/Core/Writer.h"
14#include "lld/ReaderWriter/MachOLinkingContext.h"
15#include "llvm/BinaryFormat/MachO.h"
16#include "llvm/Support/Debug.h"
17#include "llvm/Support/ErrorHandling.h"
18#include "llvm/Support/FileOutputBuffer.h"
19#include "llvm/Support/raw_ostream.h"
20#include <system_error>
21
22using lld::mach_o::normalized::NormalizedFile;
23
24namespace lld {
25namespace mach_o {
26
27class MachOWriter : public Writer {
28public:
29 MachOWriter(const MachOLinkingContext &ctxt) : _ctx(ctxt) {}
30
31 llvm::Error writeFile(const lld::File &file, StringRef path) override {
32 // Construct empty normalized file from atoms.
33 llvm::Expected<std::unique_ptr<NormalizedFile>> nFile =
34 normalized::normalizedFromAtoms(file, _ctx);
35 if (auto ec = nFile.takeError())
36 return ec;
37
38 // For testing, write out yaml form of normalized file.
39 if (_ctx.printAtoms()) {
40 std::unique_ptr<Writer> yamlWriter = createWriterYAML(_ctx);
41 if (auto ec = yamlWriter->writeFile(file, "-"))
42 return ec;
43 }
44
45 // Write normalized file as mach-o binary.
46 return writeBinary(*nFile->get(), path);
47 }
48
49 void createImplicitFiles(std::vector<std::unique_ptr<File>> &r) override {
50 // When building main executables, add _main as required entry point.
51 if (_ctx.outputTypeHasEntry())
52 r.emplace_back(new CEntryFile(_ctx));
53 // If this can link with dylibs, need helper function (dyld_stub_binder).
54 if (_ctx.needsStubsPass())
55 r.emplace_back(new StubHelperFile(_ctx));
56 // Final linked images can access a symbol for their mach_header.
57 if (_ctx.outputMachOType() != llvm::MachO::MH_OBJECT)
58 r.emplace_back(new MachHeaderAliasFile(_ctx));
59 }
60private:
61 const MachOLinkingContext &_ctx;
62 };
63
64
65} // namespace mach_o
66
67std::unique_ptr<Writer> createWriterMachO(const MachOLinkingContext &context) {
68 return std::unique_ptr<Writer>(new lld::mach_o::MachOWriter(context));
69}
70
71} // namespace lld
deps/lld/lib/ReaderWriter/YAML/CMakeLists.txt created+9
......@@ -0,0 +1,9 @@
1add_lld_library(lldYAML
2 ReaderWriterYAML.cpp
3
4 LINK_COMPONENTS
5 Support
6
7 LINK_LIBS
8 lldCore
9 )
deps/lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp created+1404
......@@ -0,0 +1,1404 @@
1//===- lib/ReaderWriter/YAML/ReaderWriterYAML.cpp -------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "lld/Core/AbsoluteAtom.h"
11#include "lld/Core/ArchiveLibraryFile.h"
12#include "lld/Core/Atom.h"
13#include "lld/Core/DefinedAtom.h"
14#include "lld/Core/Error.h"
15#include "lld/Core/File.h"
16#include "lld/Core/LinkingContext.h"
17#include "lld/Core/Reader.h"
18#include "lld/Core/Reference.h"
19#include "lld/Core/SharedLibraryAtom.h"
20#include "lld/Core/Simple.h"
21#include "lld/Core/UndefinedAtom.h"
22#include "lld/Core/Writer.h"
23#include "lld/ReaderWriter/YamlContext.h"
24#include "llvm/ADT/ArrayRef.h"
25#include "llvm/ADT/DenseMap.h"
26#include "llvm/ADT/StringMap.h"
27#include "llvm/ADT/StringRef.h"
28#include "llvm/ADT/Twine.h"
29#include "llvm/BinaryFormat/Magic.h"
30#include "llvm/Support/Allocator.h"
31#include "llvm/Support/Debug.h"
32#include "llvm/Support/Error.h"
33#include "llvm/Support/ErrorOr.h"
34#include "llvm/Support/FileSystem.h"
35#include "llvm/Support/Format.h"
36#include "llvm/Support/MemoryBuffer.h"
37#include "llvm/Support/YAMLTraits.h"
38#include "llvm/Support/raw_ostream.h"
39#include <cassert>
40#include <cstdint>
41#include <cstring>
42#include <memory>
43#include <string>
44#include <system_error>
45#include <vector>
46
47using llvm::file_magic;
48using llvm::yaml::MappingTraits;
49using llvm::yaml::ScalarEnumerationTraits;
50using llvm::yaml::ScalarTraits;
51using llvm::yaml::IO;
52using llvm::yaml::SequenceTraits;
53using llvm::yaml::DocumentListTraits;
54
55using namespace lld;
56
57/// The conversion of Atoms to and from YAML uses LLVM's YAML I/O. This
58/// file just defines template specializations on the lld types which control
59/// how the mapping is done to and from YAML.
60
61namespace {
62
63/// Used when writing yaml files.
64/// In most cases, atoms names are unambiguous, so references can just
65/// use the atom name as the target (e.g. target: foo). But in a few
66/// cases that does not work, so ref-names are added. These are labels
67/// used only in yaml. The labels do not exist in the Atom model.
68///
69/// One need for ref-names are when atoms have no user supplied name
70/// (e.g. c-string literal). Another case is when two object files with
71/// identically named static functions are merged (ld -r) into one object file.
72/// In that case referencing the function by name is ambiguous, so a unique
73/// ref-name is added.
74class RefNameBuilder {
75public:
76 RefNameBuilder(const lld::File &file)
77 : _collisionCount(0), _unnamedCounter(0) {
78 // visit all atoms
79 for (const lld::DefinedAtom *atom : file.defined()) {
80 // Build map of atoms names to detect duplicates
81 if (!atom->name().empty())
82 buildDuplicateNameMap(*atom);
83
84 // Find references to unnamed atoms and create ref-names for them.
85 for (const lld::Reference *ref : *atom) {
86 // create refname for any unnamed reference target
87 const lld::Atom *target = ref->target();
88 if ((target != nullptr) && target->name().empty()) {
89 std::string storage;
90 llvm::raw_string_ostream buffer(storage);
91 buffer << llvm::format("L%03d", _unnamedCounter++);
92 StringRef newName = copyString(buffer.str());
93 _refNames[target] = newName;
94 DEBUG_WITH_TYPE("WriterYAML",
95 llvm::dbgs() << "unnamed atom: creating ref-name: '"
96 << newName << "' ("
97 << (const void *)newName.data() << ", "
98 << newName.size() << ")\n");
99 }
100 }
101 }
102 for (const lld::UndefinedAtom *undefAtom : file.undefined()) {
103 buildDuplicateNameMap(*undefAtom);
104 }
105 for (const lld::SharedLibraryAtom *shlibAtom : file.sharedLibrary()) {
106 buildDuplicateNameMap(*shlibAtom);
107 }
108 for (const lld::AbsoluteAtom *absAtom : file.absolute()) {
109 if (!absAtom->name().empty())
110 buildDuplicateNameMap(*absAtom);
111 }
112 }
113
114 void buildDuplicateNameMap(const lld::Atom &atom) {
115 assert(!atom.name().empty());
116 NameToAtom::iterator pos = _nameMap.find(atom.name());
117 if (pos != _nameMap.end()) {
118 // Found name collision, give each a unique ref-name.
119 std::string Storage;
120 llvm::raw_string_ostream buffer(Storage);
121 buffer << atom.name() << llvm::format(".%03d", ++_collisionCount);
122 StringRef newName = copyString(buffer.str());
123 _refNames[&atom] = newName;
124 DEBUG_WITH_TYPE("WriterYAML",
125 llvm::dbgs() << "name collsion: creating ref-name: '"
126 << newName << "' ("
127 << (const void *)newName.data()
128 << ", " << newName.size() << ")\n");
129 const lld::Atom *prevAtom = pos->second;
130 AtomToRefName::iterator pos2 = _refNames.find(prevAtom);
131 if (pos2 == _refNames.end()) {
132 // Only create ref-name for previous if none already created.
133 std::string Storage2;
134 llvm::raw_string_ostream buffer2(Storage2);
135 buffer2 << prevAtom->name() << llvm::format(".%03d", ++_collisionCount);
136 StringRef newName2 = copyString(buffer2.str());
137 _refNames[prevAtom] = newName2;
138 DEBUG_WITH_TYPE("WriterYAML",
139 llvm::dbgs() << "name collsion: creating ref-name: '"
140 << newName2 << "' ("
141 << (const void *)newName2.data() << ", "
142 << newName2.size() << ")\n");
143 }
144 } else {
145 // First time we've seen this name, just add it to map.
146 _nameMap[atom.name()] = &atom;
147 DEBUG_WITH_TYPE("WriterYAML", llvm::dbgs()
148 << "atom name seen for first time: '"
149 << atom.name() << "' ("
150 << (const void *)atom.name().data()
151 << ", " << atom.name().size() << ")\n");
152 }
153 }
154
155 bool hasRefName(const lld::Atom *atom) { return _refNames.count(atom); }
156
157 StringRef refName(const lld::Atom *atom) {
158 return _refNames.find(atom)->second;
159 }
160
161private:
162 typedef llvm::StringMap<const lld::Atom *> NameToAtom;
163 typedef llvm::DenseMap<const lld::Atom *, std::string> AtomToRefName;
164
165 // Allocate a new copy of this string in _storage, so the strings
166 // can be freed when RefNameBuilder is destroyed.
167 StringRef copyString(StringRef str) {
168 char *s = _storage.Allocate<char>(str.size());
169 memcpy(s, str.data(), str.size());
170 return StringRef(s, str.size());
171 }
172
173 unsigned int _collisionCount;
174 unsigned int _unnamedCounter;
175 NameToAtom _nameMap;
176 AtomToRefName _refNames;
177 llvm::BumpPtrAllocator _storage;
178};
179
180/// Used when reading yaml files to find the target of a reference
181/// that could be a name or ref-name.
182class RefNameResolver {
183public:
184 RefNameResolver(const lld::File *file, IO &io);
185
186 const lld::Atom *lookup(StringRef name) const {
187 NameToAtom::const_iterator pos = _nameMap.find(name);
188 if (pos != _nameMap.end())
189 return pos->second;
190 _io.setError(Twine("no such atom name: ") + name);
191 return nullptr;
192 }
193
194private:
195 typedef llvm::StringMap<const lld::Atom *> NameToAtom;
196
197 void add(StringRef name, const lld::Atom *atom) {
198 if (_nameMap.count(name)) {
199 _io.setError(Twine("duplicate atom name: ") + name);
200 } else {
201 _nameMap[name] = atom;
202 }
203 }
204
205 IO &_io;
206 NameToAtom _nameMap;
207};
208
209/// Mapping of Atoms.
210template <typename T> class AtomList {
211 using Ty = std::vector<OwningAtomPtr<T>>;
212
213public:
214 typename Ty::iterator begin() { return _atoms.begin(); }
215 typename Ty::iterator end() { return _atoms.end(); }
216 Ty _atoms;
217};
218
219/// Mapping of kind: field in yaml files.
220enum FileKinds {
221 fileKindObjectAtoms, // atom based object file encoded in yaml
222 fileKindArchive, // static archive library encoded in yaml
223 fileKindObjectMachO // mach-o object files encoded in yaml
224};
225
226struct ArchMember {
227 FileKinds _kind;
228 StringRef _name;
229 const lld::File *_content;
230};
231
232// The content bytes in a DefinedAtom are just uint8_t but we want
233// special formatting, so define a strong type.
234LLVM_YAML_STRONG_TYPEDEF(uint8_t, ImplicitHex8)
235
236// SharedLibraryAtoms have a bool canBeNull() method which we'd like to be
237// more readable than just true/false.
238LLVM_YAML_STRONG_TYPEDEF(bool, ShlibCanBeNull)
239
240// lld::Reference::Kind is a tuple of <namespace, arch, value>.
241// For yaml, we just want one string that encapsulates the tuple.
242struct RefKind {
243 Reference::KindNamespace ns;
244 Reference::KindArch arch;
245 Reference::KindValue value;
246};
247
248} // end anonymous namespace
249
250LLVM_YAML_IS_SEQUENCE_VECTOR(ArchMember)
251LLVM_YAML_IS_SEQUENCE_VECTOR(const lld::Reference *)
252// Always write DefinedAtoms content bytes as a flow sequence.
253LLVM_YAML_IS_FLOW_SEQUENCE_VECTOR(ImplicitHex8)
254
255// for compatibility with gcc-4.7 in C++11 mode, add extra namespace
256namespace llvm {
257namespace yaml {
258
259// This is a custom formatter for RefKind
260template <> struct ScalarTraits<RefKind> {
261 static void output(const RefKind &kind, void *ctxt, raw_ostream &out) {
262 assert(ctxt != nullptr);
263 YamlContext *info = reinterpret_cast<YamlContext *>(ctxt);
264 assert(info->_registry);
265 StringRef str;
266 if (info->_registry->referenceKindToString(kind.ns, kind.arch, kind.value,
267 str))
268 out << str;
269 else
270 out << (int)(kind.ns) << "-" << (int)(kind.arch) << "-" << kind.value;
271 }
272
273 static StringRef input(StringRef scalar, void *ctxt, RefKind &kind) {
274 assert(ctxt != nullptr);
275 YamlContext *info = reinterpret_cast<YamlContext *>(ctxt);
276 assert(info->_registry);
277 if (info->_registry->referenceKindFromString(scalar, kind.ns, kind.arch,
278 kind.value))
279 return StringRef();
280 return StringRef("unknown reference kind");
281 }
282
283 static bool mustQuote(StringRef) { return false; }
284};
285
286template <> struct ScalarEnumerationTraits<lld::File::Kind> {
287 static void enumeration(IO &io, lld::File::Kind &value) {
288 io.enumCase(value, "error-object", lld::File::kindErrorObject);
289 io.enumCase(value, "object", lld::File::kindMachObject);
290 io.enumCase(value, "shared-library", lld::File::kindSharedLibrary);
291 io.enumCase(value, "static-library", lld::File::kindArchiveLibrary);
292 }
293};
294
295template <> struct ScalarEnumerationTraits<lld::Atom::Scope> {
296 static void enumeration(IO &io, lld::Atom::Scope &value) {
297 io.enumCase(value, "global", lld::Atom::scopeGlobal);
298 io.enumCase(value, "hidden", lld::Atom::scopeLinkageUnit);
299 io.enumCase(value, "static", lld::Atom::scopeTranslationUnit);
300 }
301};
302
303template <> struct ScalarEnumerationTraits<lld::DefinedAtom::SectionChoice> {
304 static void enumeration(IO &io, lld::DefinedAtom::SectionChoice &value) {
305 io.enumCase(value, "content", lld::DefinedAtom::sectionBasedOnContent);
306 io.enumCase(value, "custom", lld::DefinedAtom::sectionCustomPreferred);
307 io.enumCase(value, "custom-required",
308 lld::DefinedAtom::sectionCustomRequired);
309 }
310};
311
312template <> struct ScalarEnumerationTraits<lld::DefinedAtom::Interposable> {
313 static void enumeration(IO &io, lld::DefinedAtom::Interposable &value) {
314 io.enumCase(value, "no", DefinedAtom::interposeNo);
315 io.enumCase(value, "yes", DefinedAtom::interposeYes);
316 io.enumCase(value, "yes-and-weak", DefinedAtom::interposeYesAndRuntimeWeak);
317 }
318};
319
320template <> struct ScalarEnumerationTraits<lld::DefinedAtom::Merge> {
321 static void enumeration(IO &io, lld::DefinedAtom::Merge &value) {
322 io.enumCase(value, "no", lld::DefinedAtom::mergeNo);
323 io.enumCase(value, "as-tentative", lld::DefinedAtom::mergeAsTentative);
324 io.enumCase(value, "as-weak", lld::DefinedAtom::mergeAsWeak);
325 io.enumCase(value, "as-addressed-weak",
326 lld::DefinedAtom::mergeAsWeakAndAddressUsed);
327 io.enumCase(value, "by-content", lld::DefinedAtom::mergeByContent);
328 io.enumCase(value, "same-name-and-size",
329 lld::DefinedAtom::mergeSameNameAndSize);
330 io.enumCase(value, "largest", lld::DefinedAtom::mergeByLargestSection);
331 }
332};
333
334template <> struct ScalarEnumerationTraits<lld::DefinedAtom::DeadStripKind> {
335 static void enumeration(IO &io, lld::DefinedAtom::DeadStripKind &value) {
336 io.enumCase(value, "normal", lld::DefinedAtom::deadStripNormal);
337 io.enumCase(value, "never", lld::DefinedAtom::deadStripNever);
338 io.enumCase(value, "always", lld::DefinedAtom::deadStripAlways);
339 }
340};
341
342template <> struct ScalarEnumerationTraits<lld::DefinedAtom::DynamicExport> {
343 static void enumeration(IO &io, lld::DefinedAtom::DynamicExport &value) {
344 io.enumCase(value, "normal", lld::DefinedAtom::dynamicExportNormal);
345 io.enumCase(value, "always", lld::DefinedAtom::dynamicExportAlways);
346 }
347};
348
349template <> struct ScalarEnumerationTraits<lld::DefinedAtom::CodeModel> {
350 static void enumeration(IO &io, lld::DefinedAtom::CodeModel &value) {
351 io.enumCase(value, "none", lld::DefinedAtom::codeNA);
352 io.enumCase(value, "mips-pic", lld::DefinedAtom::codeMipsPIC);
353 io.enumCase(value, "mips-micro", lld::DefinedAtom::codeMipsMicro);
354 io.enumCase(value, "mips-micro-pic", lld::DefinedAtom::codeMipsMicroPIC);
355 io.enumCase(value, "mips-16", lld::DefinedAtom::codeMips16);
356 io.enumCase(value, "arm-thumb", lld::DefinedAtom::codeARMThumb);
357 io.enumCase(value, "arm-a", lld::DefinedAtom::codeARM_a);
358 io.enumCase(value, "arm-d", lld::DefinedAtom::codeARM_d);
359 io.enumCase(value, "arm-t", lld::DefinedAtom::codeARM_t);
360 }
361};
362
363template <>
364struct ScalarEnumerationTraits<lld::DefinedAtom::ContentPermissions> {
365 static void enumeration(IO &io, lld::DefinedAtom::ContentPermissions &value) {
366 io.enumCase(value, "---", lld::DefinedAtom::perm___);
367 io.enumCase(value, "r--", lld::DefinedAtom::permR__);
368 io.enumCase(value, "r-x", lld::DefinedAtom::permR_X);
369 io.enumCase(value, "rw-", lld::DefinedAtom::permRW_);
370 io.enumCase(value, "rwx", lld::DefinedAtom::permRWX);
371 io.enumCase(value, "rw-l", lld::DefinedAtom::permRW_L);
372 io.enumCase(value, "unknown", lld::DefinedAtom::permUnknown);
373 }
374};
375
376template <> struct ScalarEnumerationTraits<lld::DefinedAtom::ContentType> {
377 static void enumeration(IO &io, lld::DefinedAtom::ContentType &value) {
378 io.enumCase(value, "unknown", DefinedAtom::typeUnknown);
379 io.enumCase(value, "code", DefinedAtom::typeCode);
380 io.enumCase(value, "stub", DefinedAtom::typeStub);
381 io.enumCase(value, "constant", DefinedAtom::typeConstant);
382 io.enumCase(value, "data", DefinedAtom::typeData);
383 io.enumCase(value, "quick-data", DefinedAtom::typeDataFast);
384 io.enumCase(value, "zero-fill", DefinedAtom::typeZeroFill);
385 io.enumCase(value, "zero-fill-quick", DefinedAtom::typeZeroFillFast);
386 io.enumCase(value, "const-data", DefinedAtom::typeConstData);
387 io.enumCase(value, "got", DefinedAtom::typeGOT);
388 io.enumCase(value, "resolver", DefinedAtom::typeResolver);
389 io.enumCase(value, "branch-island", DefinedAtom::typeBranchIsland);
390 io.enumCase(value, "branch-shim", DefinedAtom::typeBranchShim);
391 io.enumCase(value, "stub-helper", DefinedAtom::typeStubHelper);
392 io.enumCase(value, "c-string", DefinedAtom::typeCString);
393 io.enumCase(value, "utf16-string", DefinedAtom::typeUTF16String);
394 io.enumCase(value, "unwind-cfi", DefinedAtom::typeCFI);
395 io.enumCase(value, "unwind-lsda", DefinedAtom::typeLSDA);
396 io.enumCase(value, "const-4-byte", DefinedAtom::typeLiteral4);
397 io.enumCase(value, "const-8-byte", DefinedAtom::typeLiteral8);
398 io.enumCase(value, "const-16-byte", DefinedAtom::typeLiteral16);
399 io.enumCase(value, "lazy-pointer", DefinedAtom::typeLazyPointer);
400 io.enumCase(value, "lazy-dylib-pointer",
401 DefinedAtom::typeLazyDylibPointer);
402 io.enumCase(value, "cfstring", DefinedAtom::typeCFString);
403 io.enumCase(value, "initializer-pointer",
404 DefinedAtom::typeInitializerPtr);
405 io.enumCase(value, "terminator-pointer",
406 DefinedAtom::typeTerminatorPtr);
407 io.enumCase(value, "c-string-pointer",DefinedAtom::typeCStringPtr);
408 io.enumCase(value, "objc-class-pointer",
409 DefinedAtom::typeObjCClassPtr);
410 io.enumCase(value, "objc-category-list",
411 DefinedAtom::typeObjC2CategoryList);
412 io.enumCase(value, "objc-image-info",
413 DefinedAtom::typeObjCImageInfo);
414 io.enumCase(value, "objc-method-list",
415 DefinedAtom::typeObjCMethodList);
416 io.enumCase(value, "objc-class1", DefinedAtom::typeObjC1Class);
417 io.enumCase(value, "dtraceDOF", DefinedAtom::typeDTraceDOF);
418 io.enumCase(value, "interposing-tuples",
419 DefinedAtom::typeInterposingTuples);
420 io.enumCase(value, "lto-temp", DefinedAtom::typeTempLTO);
421 io.enumCase(value, "compact-unwind", DefinedAtom::typeCompactUnwindInfo);
422 io.enumCase(value, "unwind-info", DefinedAtom::typeProcessedUnwindInfo);
423 io.enumCase(value, "tlv-thunk", DefinedAtom::typeThunkTLV);
424 io.enumCase(value, "tlv-data", DefinedAtom::typeTLVInitialData);
425 io.enumCase(value, "tlv-zero-fill", DefinedAtom::typeTLVInitialZeroFill);
426 io.enumCase(value, "tlv-initializer-ptr",
427 DefinedAtom::typeTLVInitializerPtr);
428 io.enumCase(value, "mach_header", DefinedAtom::typeMachHeader);
429 io.enumCase(value, "dso_handle", DefinedAtom::typeDSOHandle);
430 io.enumCase(value, "sectcreate", DefinedAtom::typeSectCreate);
431 }
432};
433
434template <> struct ScalarEnumerationTraits<lld::UndefinedAtom::CanBeNull> {
435 static void enumeration(IO &io, lld::UndefinedAtom::CanBeNull &value) {
436 io.enumCase(value, "never", lld::UndefinedAtom::canBeNullNever);
437 io.enumCase(value, "at-runtime", lld::UndefinedAtom::canBeNullAtRuntime);
438 io.enumCase(value, "at-buildtime",lld::UndefinedAtom::canBeNullAtBuildtime);
439 }
440};
441
442template <> struct ScalarEnumerationTraits<ShlibCanBeNull> {
443 static void enumeration(IO &io, ShlibCanBeNull &value) {
444 io.enumCase(value, "never", false);
445 io.enumCase(value, "at-runtime", true);
446 }
447};
448
449template <>
450struct ScalarEnumerationTraits<lld::SharedLibraryAtom::Type> {
451 static void enumeration(IO &io, lld::SharedLibraryAtom::Type &value) {
452 io.enumCase(value, "code", lld::SharedLibraryAtom::Type::Code);
453 io.enumCase(value, "data", lld::SharedLibraryAtom::Type::Data);
454 io.enumCase(value, "unknown", lld::SharedLibraryAtom::Type::Unknown);
455 }
456};
457
458/// This is a custom formatter for lld::DefinedAtom::Alignment. Values look
459/// like:
460/// 8 # 8-byte aligned
461/// 7 mod 16 # 16-byte aligned plus 7 bytes
462template <> struct ScalarTraits<lld::DefinedAtom::Alignment> {
463 static void output(const lld::DefinedAtom::Alignment &value, void *ctxt,
464 raw_ostream &out) {
465 if (value.modulus == 0) {
466 out << llvm::format("%d", value.value);
467 } else {
468 out << llvm::format("%d mod %d", value.modulus, value.value);
469 }
470 }
471
472 static StringRef input(StringRef scalar, void *ctxt,
473 lld::DefinedAtom::Alignment &value) {
474 value.modulus = 0;
475 size_t modStart = scalar.find("mod");
476 if (modStart != StringRef::npos) {
477 StringRef modStr = scalar.slice(0, modStart);
478 modStr = modStr.rtrim();
479 unsigned int modulus;
480 if (modStr.getAsInteger(0, modulus)) {
481 return "malformed alignment modulus";
482 }
483 value.modulus = modulus;
484 scalar = scalar.drop_front(modStart + 3);
485 scalar = scalar.ltrim();
486 }
487 unsigned int power;
488 if (scalar.getAsInteger(0, power)) {
489 return "malformed alignment power";
490 }
491 value.value = power;
492 if (value.modulus >= power) {
493 return "malformed alignment, modulus too large for power";
494 }
495 return StringRef(); // returning empty string means success
496 }
497
498 static bool mustQuote(StringRef) { return false; }
499};
500
501template <> struct ScalarEnumerationTraits<FileKinds> {
502 static void enumeration(IO &io, FileKinds &value) {
503 io.enumCase(value, "object", fileKindObjectAtoms);
504 io.enumCase(value, "archive", fileKindArchive);
505 io.enumCase(value, "object-mach-o", fileKindObjectMachO);
506 }
507};
508
509template <> struct MappingTraits<ArchMember> {
510 static void mapping(IO &io, ArchMember &member) {
511 io.mapOptional("kind", member._kind, fileKindObjectAtoms);
512 io.mapOptional("name", member._name);
513 io.mapRequired("content", member._content);
514 }
515};
516
517// Declare that an AtomList is a yaml sequence.
518template <typename T> struct SequenceTraits<AtomList<T> > {
519 static size_t size(IO &io, AtomList<T> &seq) { return seq._atoms.size(); }
520 static T *&element(IO &io, AtomList<T> &seq, size_t index) {
521 if (index >= seq._atoms.size())
522 seq._atoms.resize(index + 1);
523 return seq._atoms[index].get();
524 }
525};
526
527// Declare that an AtomRange is a yaml sequence.
528template <typename T> struct SequenceTraits<File::AtomRange<T> > {
529 static size_t size(IO &io, File::AtomRange<T> &seq) { return seq.size(); }
530 static T *&element(IO &io, File::AtomRange<T> &seq, size_t index) {
531 assert(io.outputting() && "AtomRange only used when outputting");
532 assert(index < seq.size() && "Out of range access");
533 return seq[index].get();
534 }
535};
536
537// Used to allow DefinedAtom content bytes to be a flow sequence of
538// two-digit hex numbers without the leading 0x (e.g. FF, 04, 0A)
539template <> struct ScalarTraits<ImplicitHex8> {
540 static void output(const ImplicitHex8 &val, void *, raw_ostream &out) {
541 uint8_t num = val;
542 out << llvm::format("%02X", num);
543 }
544
545 static StringRef input(StringRef str, void *, ImplicitHex8 &val) {
546 unsigned long long n;
547 if (getAsUnsignedInteger(str, 16, n))
548 return "invalid two-digit-hex number";
549 if (n > 0xFF)
550 return "out of range two-digit-hex number";
551 val = n;
552 return StringRef(); // returning empty string means success
553 }
554
555 static bool mustQuote(StringRef) { return false; }
556};
557
558// YAML conversion for std::vector<const lld::File*>
559template <> struct DocumentListTraits<std::vector<const lld::File *> > {
560 static size_t size(IO &io, std::vector<const lld::File *> &seq) {
561 return seq.size();
562 }
563 static const lld::File *&element(IO &io, std::vector<const lld::File *> &seq,
564 size_t index) {
565 if (index >= seq.size())
566 seq.resize(index + 1);
567 return seq[index];
568 }
569};
570
571// YAML conversion for const lld::File*
572template <> struct MappingTraits<const lld::File *> {
573 class NormArchiveFile : public lld::ArchiveLibraryFile {
574 public:
575 NormArchiveFile(IO &io) : ArchiveLibraryFile("") {}
576
577 NormArchiveFile(IO &io, const lld::File *file)
578 : ArchiveLibraryFile(file->path()), _path(file->path()) {
579 // If we want to support writing archives, this constructor would
580 // need to populate _members.
581 }
582
583 const lld::File *denormalize(IO &io) { return this; }
584
585 const AtomRange<lld::DefinedAtom> defined() const override {
586 return _noDefinedAtoms;
587 }
588
589 const AtomRange<lld::UndefinedAtom> undefined() const override {
590 return _noUndefinedAtoms;
591 }
592
593 const AtomRange<lld::SharedLibraryAtom> sharedLibrary() const override {
594 return _noSharedLibraryAtoms;
595 }
596
597 const AtomRange<lld::AbsoluteAtom> absolute() const override {
598 return _noAbsoluteAtoms;
599 }
600
601 void clearAtoms() override {
602 _noDefinedAtoms.clear();
603 _noUndefinedAtoms.clear();
604 _noSharedLibraryAtoms.clear();
605 _noAbsoluteAtoms.clear();
606 }
607
608 File *find(StringRef name) override {
609 for (const ArchMember &member : _members)
610 for (const lld::DefinedAtom *atom : member._content->defined())
611 if (name == atom->name())
612 return const_cast<File *>(member._content);
613 return nullptr;
614 }
615
616 std::error_code
617 parseAllMembers(std::vector<std::unique_ptr<File>> &result) override {
618 return std::error_code();
619 }
620
621 StringRef _path;
622 std::vector<ArchMember> _members;
623 };
624
625 class NormalizedFile : public lld::File {
626 public:
627 NormalizedFile(IO &io)
628 : File("", kindNormalizedObject), _io(io), _rnb(nullptr),
629 _definedAtomsRef(_definedAtoms._atoms),
630 _undefinedAtomsRef(_undefinedAtoms._atoms),
631 _sharedLibraryAtomsRef(_sharedLibraryAtoms._atoms),
632 _absoluteAtomsRef(_absoluteAtoms._atoms) {}
633
634 NormalizedFile(IO &io, const lld::File *file)
635 : File(file->path(), kindNormalizedObject), _io(io),
636 _rnb(new RefNameBuilder(*file)), _path(file->path()),
637 _definedAtomsRef(file->defined()),
638 _undefinedAtomsRef(file->undefined()),
639 _sharedLibraryAtomsRef(file->sharedLibrary()),
640 _absoluteAtomsRef(file->absolute()) {
641 }
642
643 ~NormalizedFile() override {
644 }
645
646 const lld::File *denormalize(IO &io);
647
648 const AtomRange<lld::DefinedAtom> defined() const override {
649 return _definedAtomsRef;
650 }
651
652 const AtomRange<lld::UndefinedAtom> undefined() const override {
653 return _undefinedAtomsRef;
654 }
655
656 const AtomRange<lld::SharedLibraryAtom> sharedLibrary() const override {
657 return _sharedLibraryAtomsRef;
658 }
659
660 const AtomRange<lld::AbsoluteAtom> absolute() const override {
661 return _absoluteAtomsRef;
662 }
663
664 void clearAtoms() override {
665 _definedAtoms._atoms.clear();
666 _undefinedAtoms._atoms.clear();
667 _sharedLibraryAtoms._atoms.clear();
668 _absoluteAtoms._atoms.clear();
669 }
670
671 // Allocate a new copy of this string in _storage, so the strings
672 // can be freed when File is destroyed.
673 StringRef copyString(StringRef str) {
674 char *s = _storage.Allocate<char>(str.size());
675 memcpy(s, str.data(), str.size());
676 return StringRef(s, str.size());
677 }
678
679 IO &_io;
680 std::unique_ptr<RefNameBuilder> _rnb;
681 StringRef _path;
682 AtomList<lld::DefinedAtom> _definedAtoms;
683 AtomList<lld::UndefinedAtom> _undefinedAtoms;
684 AtomList<lld::SharedLibraryAtom> _sharedLibraryAtoms;
685 AtomList<lld::AbsoluteAtom> _absoluteAtoms;
686 AtomRange<lld::DefinedAtom> _definedAtomsRef;
687 AtomRange<lld::UndefinedAtom> _undefinedAtomsRef;
688 AtomRange<lld::SharedLibraryAtom> _sharedLibraryAtomsRef;
689 AtomRange<lld::AbsoluteAtom> _absoluteAtomsRef;
690 llvm::BumpPtrAllocator _storage;
691 };
692
693 static void mapping(IO &io, const lld::File *&file) {
694 YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
695 assert(info != nullptr);
696 // Let any register tag handler process this.
697 if (info->_registry && info->_registry->handleTaggedDoc(io, file))
698 return;
699 // If no registered handler claims this tag and there is no tag,
700 // grandfather in as "!native".
701 if (io.mapTag("!native", true) || io.mapTag("tag:yaml.org,2002:map"))
702 mappingAtoms(io, file);
703 }
704
705 static void mappingAtoms(IO &io, const lld::File *&file) {
706 YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
707 MappingNormalizationHeap<NormalizedFile, const lld::File *>
708 keys(io, file, nullptr);
709 assert(info != nullptr);
710 info->_file = keys.operator->();
711
712 io.mapOptional("path", keys->_path);
713
714 if (io.outputting()) {
715 io.mapOptional("defined-atoms", keys->_definedAtomsRef);
716 io.mapOptional("undefined-atoms", keys->_undefinedAtomsRef);
717 io.mapOptional("shared-library-atoms", keys->_sharedLibraryAtomsRef);
718 io.mapOptional("absolute-atoms", keys->_absoluteAtomsRef);
719 } else {
720 io.mapOptional("defined-atoms", keys->_definedAtoms);
721 io.mapOptional("undefined-atoms", keys->_undefinedAtoms);
722 io.mapOptional("shared-library-atoms", keys->_sharedLibraryAtoms);
723 io.mapOptional("absolute-atoms", keys->_absoluteAtoms);
724 }
725 }
726
727 static void mappingArchive(IO &io, const lld::File *&file) {
728 YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
729 MappingNormalizationHeap<NormArchiveFile, const lld::File *>
730 keys(io, file, &info->_file->allocator());
731
732 io.mapOptional("path", keys->_path);
733 io.mapOptional("members", keys->_members);
734 }
735};
736
737// YAML conversion for const lld::Reference*
738template <> struct MappingTraits<const lld::Reference *> {
739 class NormalizedReference : public lld::Reference {
740 public:
741 NormalizedReference(IO &io)
742 : lld::Reference(lld::Reference::KindNamespace::all,
743 lld::Reference::KindArch::all, 0),
744 _target(nullptr), _offset(0), _addend(0), _tag(0) {}
745
746 NormalizedReference(IO &io, const lld::Reference *ref)
747 : lld::Reference(ref->kindNamespace(), ref->kindArch(),
748 ref->kindValue()),
749 _target(nullptr), _targetName(targetName(io, ref)),
750 _offset(ref->offsetInAtom()), _addend(ref->addend()),
751 _tag(ref->tag()) {
752 _mappedKind.ns = ref->kindNamespace();
753 _mappedKind.arch = ref->kindArch();
754 _mappedKind.value = ref->kindValue();
755 }
756
757 const lld::Reference *denormalize(IO &io) {
758 YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
759 assert(info != nullptr);
760 typedef MappingTraits<const lld::File *>::NormalizedFile NormalizedFile;
761 NormalizedFile *f = reinterpret_cast<NormalizedFile *>(info->_file);
762 if (!_targetName.empty())
763 _targetName = f->copyString(_targetName);
764 DEBUG_WITH_TYPE("WriterYAML", llvm::dbgs()
765 << "created Reference to name: '"
766 << _targetName << "' ("
767 << (const void *)_targetName.data()
768 << ", " << _targetName.size() << ")\n");
769 setKindNamespace(_mappedKind.ns);
770 setKindArch(_mappedKind.arch);
771 setKindValue(_mappedKind.value);
772 return this;
773 }
774
775 void bind(const RefNameResolver &);
776 static StringRef targetName(IO &io, const lld::Reference *ref);
777
778 uint64_t offsetInAtom() const override { return _offset; }
779 const lld::Atom *target() const override { return _target; }
780 Addend addend() const override { return _addend; }
781 void setAddend(Addend a) override { _addend = a; }
782 void setTarget(const lld::Atom *a) override { _target = a; }
783
784 const lld::Atom *_target;
785 StringRef _targetName;
786 uint32_t _offset;
787 Addend _addend;
788 RefKind _mappedKind;
789 uint32_t _tag;
790 };
791
792 static void mapping(IO &io, const lld::Reference *&ref) {
793 YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
794 MappingNormalizationHeap<NormalizedReference, const lld::Reference *> keys(
795 io, ref, &info->_file->allocator());
796
797 io.mapRequired("kind", keys->_mappedKind);
798 io.mapOptional("offset", keys->_offset);
799 io.mapOptional("target", keys->_targetName);
800 io.mapOptional("addend", keys->_addend, (lld::Reference::Addend)0);
801 io.mapOptional("tag", keys->_tag, 0u);
802 }
803};
804
805// YAML conversion for const lld::DefinedAtom*
806template <> struct MappingTraits<const lld::DefinedAtom *> {
807
808 class NormalizedAtom : public lld::DefinedAtom {
809 public:
810 NormalizedAtom(IO &io)
811 : _file(fileFromContext(io)), _contentType(), _alignment(1) {
812 static uint32_t ordinalCounter = 1;
813 _ordinal = ordinalCounter++;
814 }
815
816 NormalizedAtom(IO &io, const lld::DefinedAtom *atom)
817 : _file(fileFromContext(io)), _name(atom->name()),
818 _scope(atom->scope()), _interpose(atom->interposable()),
819 _merge(atom->merge()), _contentType(atom->contentType()),
820 _alignment(atom->alignment()), _sectionChoice(atom->sectionChoice()),
821 _deadStrip(atom->deadStrip()), _dynamicExport(atom->dynamicExport()),
822 _codeModel(atom->codeModel()),
823 _permissions(atom->permissions()), _size(atom->size()),
824 _sectionName(atom->customSectionName()),
825 _sectionSize(atom->sectionSize()) {
826 for (const lld::Reference *r : *atom)
827 _references.push_back(r);
828 if (!atom->occupiesDiskSpace())
829 return;
830 ArrayRef<uint8_t> cont = atom->rawContent();
831 _content.reserve(cont.size());
832 for (uint8_t x : cont)
833 _content.push_back(x);
834 }
835
836 ~NormalizedAtom() override = default;
837
838 const lld::DefinedAtom *denormalize(IO &io) {
839 YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
840 assert(info != nullptr);
841 typedef MappingTraits<const lld::File *>::NormalizedFile NormalizedFile;
842 NormalizedFile *f = reinterpret_cast<NormalizedFile *>(info->_file);
843 if (!_name.empty())
844 _name = f->copyString(_name);
845 if (!_refName.empty())
846 _refName = f->copyString(_refName);
847 if (!_sectionName.empty())
848 _sectionName = f->copyString(_sectionName);
849 DEBUG_WITH_TYPE("WriterYAML",
850 llvm::dbgs() << "created DefinedAtom named: '" << _name
851 << "' (" << (const void *)_name.data()
852 << ", " << _name.size() << ")\n");
853 return this;
854 }
855
856 void bind(const RefNameResolver &);
857
858 // Extract current File object from YAML I/O parsing context
859 const lld::File &fileFromContext(IO &io) {
860 YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
861 assert(info != nullptr);
862 assert(info->_file != nullptr);
863 return *info->_file;
864 }
865
866 const lld::File &file() const override { return _file; }
867 StringRef name() const override { return _name; }
868 uint64_t size() const override { return _size; }
869 Scope scope() const override { return _scope; }
870 Interposable interposable() const override { return _interpose; }
871 Merge merge() const override { return _merge; }
872 ContentType contentType() const override { return _contentType; }
873 Alignment alignment() const override { return _alignment; }
874 SectionChoice sectionChoice() const override { return _sectionChoice; }
875 StringRef customSectionName() const override { return _sectionName; }
876 uint64_t sectionSize() const override { return _sectionSize; }
877 DeadStripKind deadStrip() const override { return _deadStrip; }
878 DynamicExport dynamicExport() const override { return _dynamicExport; }
879 CodeModel codeModel() const override { return _codeModel; }
880 ContentPermissions permissions() const override { return _permissions; }
881 ArrayRef<uint8_t> rawContent() const override {
882 if (!occupiesDiskSpace())
883 return ArrayRef<uint8_t>();
884 return ArrayRef<uint8_t>(
885 reinterpret_cast<const uint8_t *>(_content.data()), _content.size());
886 }
887
888 uint64_t ordinal() const override { return _ordinal; }
889
890 reference_iterator begin() const override {
891 uintptr_t index = 0;
892 const void *it = reinterpret_cast<const void *>(index);
893 return reference_iterator(*this, it);
894 }
895 reference_iterator end() const override {
896 uintptr_t index = _references.size();
897 const void *it = reinterpret_cast<const void *>(index);
898 return reference_iterator(*this, it);
899 }
900 const lld::Reference *derefIterator(const void *it) const override {
901 uintptr_t index = reinterpret_cast<uintptr_t>(it);
902 assert(index < _references.size());
903 return _references[index];
904 }
905 void incrementIterator(const void *&it) const override {
906 uintptr_t index = reinterpret_cast<uintptr_t>(it);
907 ++index;
908 it = reinterpret_cast<const void *>(index);
909 }
910
911 void addReference(Reference::KindNamespace ns,
912 Reference::KindArch arch,
913 Reference::KindValue kindValue, uint64_t off,
914 const Atom *target, Reference::Addend a) override {
915 assert(target && "trying to create reference to nothing");
916 auto node = new (file().allocator()) SimpleReference(ns, arch, kindValue,
917 off, target, a);
918 _references.push_back(node);
919 }
920
921 const lld::File &_file;
922 StringRef _name;
923 StringRef _refName;
924 Scope _scope;
925 Interposable _interpose;
926 Merge _merge;
927 ContentType _contentType;
928 Alignment _alignment;
929 SectionChoice _sectionChoice;
930 DeadStripKind _deadStrip;
931 DynamicExport _dynamicExport;
932 CodeModel _codeModel;
933 ContentPermissions _permissions;
934 uint32_t _ordinal;
935 std::vector<ImplicitHex8> _content;
936 uint64_t _size;
937 StringRef _sectionName;
938 uint64_t _sectionSize;
939 std::vector<const lld::Reference *> _references;
940 };
941
942 static void mapping(IO &io, const lld::DefinedAtom *&atom) {
943 YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
944 MappingNormalizationHeap<NormalizedAtom, const lld::DefinedAtom *> keys(
945 io, atom, &info->_file->allocator());
946 if (io.outputting()) {
947 // If writing YAML, check if atom needs a ref-name.
948 typedef MappingTraits<const lld::File *>::NormalizedFile NormalizedFile;
949 assert(info != nullptr);
950 NormalizedFile *f = reinterpret_cast<NormalizedFile *>(info->_file);
951 assert(f);
952 assert(f->_rnb);
953 if (f->_rnb->hasRefName(atom)) {
954 keys->_refName = f->_rnb->refName(atom);
955 }
956 }
957
958 io.mapOptional("name", keys->_name, StringRef());
959 io.mapOptional("ref-name", keys->_refName, StringRef());
960 io.mapOptional("scope", keys->_scope,
961 DefinedAtom::scopeTranslationUnit);
962 io.mapOptional("type", keys->_contentType,
963 DefinedAtom::typeCode);
964 io.mapOptional("content", keys->_content);
965 io.mapOptional("size", keys->_size, (uint64_t)keys->_content.size());
966 io.mapOptional("interposable", keys->_interpose,
967 DefinedAtom::interposeNo);
968 io.mapOptional("merge", keys->_merge, DefinedAtom::mergeNo);
969 io.mapOptional("alignment", keys->_alignment,
970 DefinedAtom::Alignment(1));
971 io.mapOptional("section-choice", keys->_sectionChoice,
972 DefinedAtom::sectionBasedOnContent);
973 io.mapOptional("section-name", keys->_sectionName, StringRef());
974 io.mapOptional("section-size", keys->_sectionSize, (uint64_t)0);
975 io.mapOptional("dead-strip", keys->_deadStrip,
976 DefinedAtom::deadStripNormal);
977 io.mapOptional("dynamic-export", keys->_dynamicExport,
978 DefinedAtom::dynamicExportNormal);
979 io.mapOptional("code-model", keys->_codeModel, DefinedAtom::codeNA);
980 // default permissions based on content type
981 io.mapOptional("permissions", keys->_permissions,
982 DefinedAtom::permissions(
983 keys->_contentType));
984 io.mapOptional("references", keys->_references);
985 }
986};
987
988template <> struct MappingTraits<lld::DefinedAtom *> {
989 static void mapping(IO &io, lld::DefinedAtom *&atom) {
990 const lld::DefinedAtom *atomPtr = atom;
991 MappingTraits<const lld::DefinedAtom *>::mapping(io, atomPtr);
992 atom = const_cast<lld::DefinedAtom *>(atomPtr);
993 }
994};
995
996// YAML conversion for const lld::UndefinedAtom*
997template <> struct MappingTraits<const lld::UndefinedAtom *> {
998 class NormalizedAtom : public lld::UndefinedAtom {
999 public:
1000 NormalizedAtom(IO &io)
1001 : _file(fileFromContext(io)), _canBeNull(canBeNullNever) {}
1002
1003 NormalizedAtom(IO &io, const lld::UndefinedAtom *atom)
1004 : _file(fileFromContext(io)), _name(atom->name()),
1005 _canBeNull(atom->canBeNull()) {}
1006
1007 ~NormalizedAtom() override = default;
1008
1009 const lld::UndefinedAtom *denormalize(IO &io) {
1010 YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
1011 assert(info != nullptr);
1012 typedef MappingTraits<const lld::File *>::NormalizedFile NormalizedFile;
1013 NormalizedFile *f = reinterpret_cast<NormalizedFile *>(info->_file);
1014 if (!_name.empty())
1015 _name = f->copyString(_name);
1016
1017 DEBUG_WITH_TYPE("WriterYAML",
1018 llvm::dbgs() << "created UndefinedAtom named: '" << _name
1019 << "' (" << (const void *)_name.data() << ", "
1020 << _name.size() << ")\n");
1021 return this;
1022 }
1023
1024 // Extract current File object from YAML I/O parsing context
1025 const lld::File &fileFromContext(IO &io) {
1026 YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
1027 assert(info != nullptr);
1028 assert(info->_file != nullptr);
1029 return *info->_file;
1030 }
1031
1032 const lld::File &file() const override { return _file; }
1033 StringRef name() const override { return _name; }
1034 CanBeNull canBeNull() const override { return _canBeNull; }
1035
1036 const lld::File &_file;
1037 StringRef _name;
1038 CanBeNull _canBeNull;
1039 };
1040
1041 static void mapping(IO &io, const lld::UndefinedAtom *&atom) {
1042 YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
1043 MappingNormalizationHeap<NormalizedAtom, const lld::UndefinedAtom *> keys(
1044 io, atom, &info->_file->allocator());
1045
1046 io.mapRequired("name", keys->_name);
1047 io.mapOptional("can-be-null", keys->_canBeNull,
1048 lld::UndefinedAtom::canBeNullNever);
1049 }
1050};
1051
1052template <> struct MappingTraits<lld::UndefinedAtom *> {
1053 static void mapping(IO &io, lld::UndefinedAtom *&atom) {
1054 const lld::UndefinedAtom *atomPtr = atom;
1055 MappingTraits<const lld::UndefinedAtom *>::mapping(io, atomPtr);
1056 atom = const_cast<lld::UndefinedAtom *>(atomPtr);
1057 }
1058};
1059
1060// YAML conversion for const lld::SharedLibraryAtom*
1061template <> struct MappingTraits<const lld::SharedLibraryAtom *> {
1062 class NormalizedAtom : public lld::SharedLibraryAtom {
1063 public:
1064 NormalizedAtom(IO &io)
1065 : _file(fileFromContext(io)), _canBeNull(false),
1066 _type(Type::Unknown), _size(0) {}
1067
1068 NormalizedAtom(IO &io, const lld::SharedLibraryAtom *atom)
1069 : _file(fileFromContext(io)), _name(atom->name()),
1070 _loadName(atom->loadName()), _canBeNull(atom->canBeNullAtRuntime()),
1071 _type(atom->type()), _size(atom->size()) {}
1072
1073 ~NormalizedAtom() override = default;
1074
1075 const lld::SharedLibraryAtom *denormalize(IO &io) {
1076 YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
1077 assert(info != nullptr);
1078 typedef MappingTraits<const lld::File *>::NormalizedFile NormalizedFile;
1079 NormalizedFile *f = reinterpret_cast<NormalizedFile *>(info->_file);
1080 if (!_name.empty())
1081 _name = f->copyString(_name);
1082 if (!_loadName.empty())
1083 _loadName = f->copyString(_loadName);
1084
1085 DEBUG_WITH_TYPE("WriterYAML",
1086 llvm::dbgs() << "created SharedLibraryAtom named: '"
1087 << _name << "' ("
1088 << (const void *)_name.data()
1089 << ", " << _name.size() << ")\n");
1090 return this;
1091 }
1092
1093 // Extract current File object from YAML I/O parsing context
1094 const lld::File &fileFromContext(IO &io) {
1095 YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
1096 assert(info != nullptr);
1097 assert(info->_file != nullptr);
1098 return *info->_file;
1099 }
1100
1101 const lld::File &file() const override { return _file; }
1102 StringRef name() const override { return _name; }
1103 StringRef loadName() const override { return _loadName; }
1104 bool canBeNullAtRuntime() const override { return _canBeNull; }
1105 Type type() const override { return _type; }
1106 uint64_t size() const override { return _size; }
1107
1108 const lld::File &_file;
1109 StringRef _name;
1110 StringRef _loadName;
1111 ShlibCanBeNull _canBeNull;
1112 Type _type;
1113 uint64_t _size;
1114 };
1115
1116 static void mapping(IO &io, const lld::SharedLibraryAtom *&atom) {
1117
1118 YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
1119 MappingNormalizationHeap<NormalizedAtom, const lld::SharedLibraryAtom *>
1120 keys(io, atom, &info->_file->allocator());
1121
1122 io.mapRequired("name", keys->_name);
1123 io.mapOptional("load-name", keys->_loadName);
1124 io.mapOptional("can-be-null", keys->_canBeNull, (ShlibCanBeNull) false);
1125 io.mapOptional("type", keys->_type, SharedLibraryAtom::Type::Code);
1126 io.mapOptional("size", keys->_size, uint64_t(0));
1127 }
1128};
1129
1130template <> struct MappingTraits<lld::SharedLibraryAtom *> {
1131 static void mapping(IO &io, lld::SharedLibraryAtom *&atom) {
1132 const lld::SharedLibraryAtom *atomPtr = atom;
1133 MappingTraits<const lld::SharedLibraryAtom *>::mapping(io, atomPtr);
1134 atom = const_cast<lld::SharedLibraryAtom *>(atomPtr);
1135 }
1136};
1137
1138// YAML conversion for const lld::AbsoluteAtom*
1139template <> struct MappingTraits<const lld::AbsoluteAtom *> {
1140 class NormalizedAtom : public lld::AbsoluteAtom {
1141 public:
1142 NormalizedAtom(IO &io)
1143 : _file(fileFromContext(io)), _scope(), _value(0) {}
1144
1145 NormalizedAtom(IO &io, const lld::AbsoluteAtom *atom)
1146 : _file(fileFromContext(io)), _name(atom->name()),
1147 _scope(atom->scope()), _value(atom->value()) {}
1148
1149 ~NormalizedAtom() override = default;
1150
1151 const lld::AbsoluteAtom *denormalize(IO &io) {
1152 YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
1153 assert(info != nullptr);
1154 typedef MappingTraits<const lld::File *>::NormalizedFile NormalizedFile;
1155 NormalizedFile *f = reinterpret_cast<NormalizedFile *>(info->_file);
1156 if (!_name.empty())
1157 _name = f->copyString(_name);
1158
1159 DEBUG_WITH_TYPE("WriterYAML",
1160 llvm::dbgs() << "created AbsoluteAtom named: '" << _name
1161 << "' (" << (const void *)_name.data()
1162 << ", " << _name.size() << ")\n");
1163 return this;
1164 }
1165
1166 // Extract current File object from YAML I/O parsing context
1167 const lld::File &fileFromContext(IO &io) {
1168 YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
1169 assert(info != nullptr);
1170 assert(info->_file != nullptr);
1171 return *info->_file;
1172 }
1173
1174 const lld::File &file() const override { return _file; }
1175 StringRef name() const override { return _name; }
1176 uint64_t value() const override { return _value; }
1177 Scope scope() const override { return _scope; }
1178
1179 const lld::File &_file;
1180 StringRef _name;
1181 StringRef _refName;
1182 Scope _scope;
1183 Hex64 _value;
1184 };
1185
1186 static void mapping(IO &io, const lld::AbsoluteAtom *&atom) {
1187 YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
1188 MappingNormalizationHeap<NormalizedAtom, const lld::AbsoluteAtom *> keys(
1189 io, atom, &info->_file->allocator());
1190
1191 if (io.outputting()) {
1192 typedef MappingTraits<const lld::File *>::NormalizedFile NormalizedFile;
1193 YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
1194 assert(info != nullptr);
1195 NormalizedFile *f = reinterpret_cast<NormalizedFile *>(info->_file);
1196 assert(f);
1197 assert(f->_rnb);
1198 if (f->_rnb->hasRefName(atom)) {
1199 keys->_refName = f->_rnb->refName(atom);
1200 }
1201 }
1202
1203 io.mapRequired("name", keys->_name);
1204 io.mapOptional("ref-name", keys->_refName, StringRef());
1205 io.mapOptional("scope", keys->_scope);
1206 io.mapRequired("value", keys->_value);
1207 }
1208};
1209
1210template <> struct MappingTraits<lld::AbsoluteAtom *> {
1211 static void mapping(IO &io, lld::AbsoluteAtom *&atom) {
1212 const lld::AbsoluteAtom *atomPtr = atom;
1213 MappingTraits<const lld::AbsoluteAtom *>::mapping(io, atomPtr);
1214 atom = const_cast<lld::AbsoluteAtom *>(atomPtr);
1215 }
1216};
1217
1218} // end namespace llvm
1219} // end namespace yaml
1220
1221RefNameResolver::RefNameResolver(const lld::File *file, IO &io) : _io(io) {
1222 typedef MappingTraits<const lld::DefinedAtom *>::NormalizedAtom
1223 NormalizedAtom;
1224 for (const lld::DefinedAtom *a : file->defined()) {
1225 const auto *na = (const NormalizedAtom *)a;
1226 if (!na->_refName.empty())
1227 add(na->_refName, a);
1228 else if (!na->_name.empty())
1229 add(na->_name, a);
1230 }
1231
1232 for (const lld::UndefinedAtom *a : file->undefined())
1233 add(a->name(), a);
1234
1235 for (const lld::SharedLibraryAtom *a : file->sharedLibrary())
1236 add(a->name(), a);
1237
1238 typedef MappingTraits<const lld::AbsoluteAtom *>::NormalizedAtom NormAbsAtom;
1239 for (const lld::AbsoluteAtom *a : file->absolute()) {
1240 const auto *na = (const NormAbsAtom *)a;
1241 if (na->_refName.empty())
1242 add(na->_name, a);
1243 else
1244 add(na->_refName, a);
1245 }
1246}
1247
1248inline const lld::File *
1249MappingTraits<const lld::File *>::NormalizedFile::denormalize(IO &io) {
1250 typedef MappingTraits<const lld::DefinedAtom *>::NormalizedAtom
1251 NormalizedAtom;
1252
1253 RefNameResolver nameResolver(this, io);
1254 // Now that all atoms are parsed, references can be bound.
1255 for (const lld::DefinedAtom *a : this->defined()) {
1256 auto *normAtom = (NormalizedAtom *)const_cast<DefinedAtom *>(a);
1257 normAtom->bind(nameResolver);
1258 }
1259
1260 return this;
1261}
1262
1263inline void MappingTraits<const lld::DefinedAtom *>::NormalizedAtom::bind(
1264 const RefNameResolver &resolver) {
1265 typedef MappingTraits<const lld::Reference *>::NormalizedReference
1266 NormalizedReference;
1267 for (const lld::Reference *ref : _references) {
1268 auto *normRef = (NormalizedReference *)const_cast<Reference *>(ref);
1269 normRef->bind(resolver);
1270 }
1271}
1272
1273inline void MappingTraits<const lld::Reference *>::NormalizedReference::bind(
1274 const RefNameResolver &resolver) {
1275 _target = resolver.lookup(_targetName);
1276}
1277
1278inline StringRef
1279MappingTraits<const lld::Reference *>::NormalizedReference::targetName(
1280 IO &io, const lld::Reference *ref) {
1281 if (ref->target() == nullptr)
1282 return StringRef();
1283 YamlContext *info = reinterpret_cast<YamlContext *>(io.getContext());
1284 assert(info != nullptr);
1285 typedef MappingTraits<const lld::File *>::NormalizedFile NormalizedFile;
1286 NormalizedFile *f = reinterpret_cast<NormalizedFile *>(info->_file);
1287 RefNameBuilder &rnb = *f->_rnb;
1288 if (rnb.hasRefName(ref->target()))
1289 return rnb.refName(ref->target());
1290 return ref->target()->name();
1291}
1292
1293namespace lld {
1294namespace yaml {
1295
1296class Writer : public lld::Writer {
1297public:
1298 Writer(const LinkingContext &context) : _ctx(context) {}
1299
1300 llvm::Error writeFile(const lld::File &file, StringRef outPath) override {
1301 // Create stream to path.
1302 std::error_code ec;
1303 llvm::raw_fd_ostream out(outPath, ec, llvm::sys::fs::F_Text);
1304 if (ec)
1305 return llvm::errorCodeToError(ec);
1306
1307 // Create yaml Output writer, using yaml options for context.
1308 YamlContext yamlContext;
1309 yamlContext._ctx = &_ctx;
1310 yamlContext._registry = &_ctx.registry();
1311 llvm::yaml::Output yout(out, &yamlContext);
1312
1313 // Write yaml output.
1314 const lld::File *fileRef = &file;
1315 yout << fileRef;
1316
1317 return llvm::Error::success();
1318 }
1319
1320private:
1321 const LinkingContext &_ctx;
1322};
1323
1324} // end namespace yaml
1325
1326namespace {
1327
1328/// Handles !native tagged yaml documents.
1329class NativeYamlIOTaggedDocumentHandler : public YamlIOTaggedDocumentHandler {
1330 bool handledDocTag(llvm::yaml::IO &io, const lld::File *&file) const override {
1331 if (io.mapTag("!native")) {
1332 MappingTraits<const lld::File *>::mappingAtoms(io, file);
1333 return true;
1334 }
1335 return false;
1336 }
1337};
1338
1339/// Handles !archive tagged yaml documents.
1340class ArchiveYamlIOTaggedDocumentHandler : public YamlIOTaggedDocumentHandler {
1341 bool handledDocTag(llvm::yaml::IO &io, const lld::File *&file) const override {
1342 if (io.mapTag("!archive")) {
1343 MappingTraits<const lld::File *>::mappingArchive(io, file);
1344 return true;
1345 }
1346 return false;
1347 }
1348};
1349
1350class YAMLReader : public Reader {
1351public:
1352 YAMLReader(const Registry &registry) : _registry(registry) {}
1353
1354 bool canParse(file_magic magic, MemoryBufferRef mb) const override {
1355 StringRef name = mb.getBufferIdentifier();
1356 return name.endswith(".objtxt") || name.endswith(".yaml");
1357 }
1358
1359 ErrorOr<std::unique_ptr<File>>
1360 loadFile(std::unique_ptr<MemoryBuffer> mb,
1361 const class Registry &) const override {
1362 // Create YAML Input Reader.
1363 YamlContext yamlContext;
1364 yamlContext._registry = &_registry;
1365 yamlContext._path = mb->getBufferIdentifier();
1366 llvm::yaml::Input yin(mb->getBuffer(), &yamlContext);
1367
1368 // Fill vector with File objects created by parsing yaml.
1369 std::vector<const lld::File *> createdFiles;
1370 yin >> createdFiles;
1371 assert(createdFiles.size() == 1);
1372
1373 // Error out now if there were parsing errors.
1374 if (yin.error())
1375 return make_error_code(lld::YamlReaderError::illegal_value);
1376
1377 std::shared_ptr<MemoryBuffer> smb(mb.release());
1378 const File *file = createdFiles[0];
1379 // Note: loadFile() should return vector of *const* File
1380 File *f = const_cast<File *>(file);
1381 f->setLastError(std::error_code());
1382 f->setSharedMemoryBuffer(smb);
1383 return std::unique_ptr<File>(f);
1384 }
1385
1386private:
1387 const Registry &_registry;
1388};
1389
1390} // end anonymous namespace
1391
1392void Registry::addSupportYamlFiles() {
1393 add(std::unique_ptr<Reader>(new YAMLReader(*this)));
1394 add(std::unique_ptr<YamlIOTaggedDocumentHandler>(
1395 new NativeYamlIOTaggedDocumentHandler()));
1396 add(std::unique_ptr<YamlIOTaggedDocumentHandler>(
1397 new ArchiveYamlIOTaggedDocumentHandler()));
1398}
1399
1400std::unique_ptr<Writer> createWriterYAML(const LinkingContext &context) {
1401 return std::unique_ptr<Writer>(new lld::yaml::Writer(context));
1402}
1403
1404} // end namespace lld
deps/lld/test/CMakeLists.txt created+56
......@@ -0,0 +1,56 @@
1set(LLVM_SOURCE_DIR "${LLVM_MAIN_SRC_DIR}")
2set(LLVM_BINARY_DIR "${LLVM_BINARY_DIR}")
3set(LLVM_BUILD_MODE "%(build_mode)s")
4set(LLVM_TOOLS_DIR "${LLVM_TOOLS_BINARY_DIR}/%(build_config)s")
5set(LLVM_LIBS_DIR "${LLVM_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}/%(build_config)s")
6
7if(LLD_BUILT_STANDALONE)
8 # Set HAVE_LIBZ according to recorded LLVM_ENABLE_ZLIB value. This
9 # value is forced to 0 if zlib was not found, so it is fine to use it
10 # instead of HAVE_LIBZ (not recorded).
11 if(LLVM_ENABLE_ZLIB)
12 set(HAVE_LIBZ 1)
13 endif()
14endif()
15
16llvm_canonicalize_cmake_booleans(
17 HAVE_LIBZ)
18
19configure_lit_site_cfg(
20 ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
21 ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg)
22configure_lit_site_cfg(
23 ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.in
24 ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg
25 )
26
27set(LLD_TEST_DEPS lld)
28if (NOT LLD_BUILT_STANDALONE)
29 list(APPEND LLD_TEST_DEPS
30 FileCheck count not llvm-ar llvm-as llvm-dis llvm-dwarfdump llvm-nm
31 llc llvm-config llvm-objdump llvm-readobj yaml2obj obj2yaml
32 llvm-mc llvm-lib llvm-pdbutil opt
33 )
34endif()
35
36if (LLVM_INCLUDE_TESTS)
37 list(APPEND LLD_TEST_DEPS LLDUnitTests)
38endif()
39
40set(LLD_TEST_PARAMS
41 lld_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
42 )
43
44add_lit_testsuite(check-lld "Running lld test suite"
45 ${CMAKE_CURRENT_BINARY_DIR}
46 PARAMS lld_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
47 lld_unit_site_config=${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg
48 DEPENDS ${LLD_TEST_DEPS}
49 )
50
51set_target_properties(check-lld PROPERTIES FOLDER "lld tests")
52
53# Add a legacy target spelling: lld-test
54add_custom_target(lld-test)
55add_dependencies(lld-test check-lld)
56set_target_properties(lld-test PROPERTIES FOLDER "lld tests")
deps/lld/test/COFF/Inputs/armnt-executable.obj.yaml created+29
......@@ -0,0 +1,29 @@
1--- !COFF
2header:
3 Machine: IMAGE_FILE_MACHINE_ARMNT
4 Characteristics: []
5sections:
6 - Name: .text
7 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_PURGEABLE, IMAGE_SCN_MEM_16BIT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
8 Alignment: 4
9 SectionData: '7047'
10symbols:
11 - Name: .text
12 Value: 0
13 SectionNumber: 1
14 SimpleType: IMAGE_SYM_TYPE_NULL
15 ComplexType: IMAGE_SYM_DTYPE_NULL
16 StorageClass: IMAGE_SYM_CLASS_STATIC
17 SectionDefinition:
18 Length: 2
19 NumberOfRelocations: 0
20 NumberOfLinenumbers: 0
21 CheckSum: 0
22 Number: 1
23 - Name: mainCRTStartup
24 Value: 0
25 SectionNumber: 1
26 SimpleType: IMAGE_SYM_TYPE_NULL
27 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
28 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
29...
deps/lld/test/COFF/Inputs/armnt-executable.s created+13
......@@ -0,0 +1,13 @@
1# void mainCRTStartup() {}
2 .syntax unified
3 .thumb
4 .text
5 .def mainCRTStartup
6 .scl 2
7 .type 32
8 .endef
9 .global mainCRTStartup
10 .align 2
11 .thumb_func
12mainCRTStartup:
13 bx lr
deps/lld/test/COFF/Inputs/associative-comdat-2.s created+13
......@@ -0,0 +1,13 @@
1# Defines foo and foo_assoc globals. foo is comdat, and foo_assoc is comdat
2# associative with it. foo_assoc should be discarded iff foo is discarded,
3# either by linker GC or normal comdat merging.
4
5 .section .rdata,"dr",associative,foo
6 .p2align 3
7 .quad foo
8
9 .section .data,"dw",discard,foo
10 .globl foo # @foo
11 .p2align 2
12foo:
13 .long 42
deps/lld/test/COFF/Inputs/bar.ll created+6
......@@ -0,0 +1,6 @@
1target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-pc-windows-msvc"
3
4define void @bar() {
5 ret void
6}
deps/lld/test/COFF/Inputs/cl-gl.obj created
Binary files /dev/null and b/deps/lld/test/COFF/Inputs/cl-gl.obj differ
deps/lld/test/COFF/Inputs/combined-resources-2.rc created+36
......@@ -0,0 +1,36 @@
1#include "windows.h"
2
3LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
4randomdat RCDATA
5{
6 "this is a random bit of data that means nothing\0",
7 0x23a9,
8 0x140e,
9 194292,
10}
11
12LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
13randomdat RCDATA
14{
15 "zhe4 shi4 yi1ge4 sui2ji1 de shu4ju4, zhe4 yi4wei4zhe shen2me\0",
16 0x23a9,
17 0x140e,
18 194292,
19}
20
21LANGUAGE LANG_GERMAN, SUBLANG_GERMAN_LUXEMBOURG
22randomdat RCDATA
23{
24 "Dies ist ein zufälliges Bit von Daten, die nichts bedeutet\0",
25 0x23a9,
26 0x140e,
27 194292,
28}
29
30LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
31myaccelerators ACCELERATORS
32{
33 "^C", 999, VIRTKEY, ALT
34 "D", 1100, VIRTKEY, CONTROL, SHIFT
35 "^R", 444, ASCII, NOINVERT
36}
deps/lld/test/COFF/Inputs/combined-resources-2.res created
Binary files /dev/null and b/deps/lld/test/COFF/Inputs/combined-resources-2.res differ
deps/lld/test/COFF/Inputs/combined-resources-cursor.bmp created
Binary files /dev/null and b/deps/lld/test/COFF/Inputs/combined-resources-cursor.bmp differ
deps/lld/test/COFF/Inputs/combined-resources-okay.bmp created
Binary files /dev/null and b/deps/lld/test/COFF/Inputs/combined-resources-okay.bmp differ
deps/lld/test/COFF/Inputs/combined-resources.rc created+50
......@@ -0,0 +1,50 @@
1#include "windows.h"
2
3LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
4
5myaccelerators ACCELERATORS
6{
7 "^C", 999, VIRTKEY, ALT
8 "D", 1100, VIRTKEY, CONTROL, SHIFT
9 "^R", 444, ASCII, NOINVERT
10}
11
12cursor BITMAP "combined-resources-cursor.bmp"
13okay BITMAP "combined-resources-okay.bmp"
14
1514432 MENU
16LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
17{
18 MENUITEM "yu", 100
19 MENUITEM "shala", 101
20 MENUITEM "kaoya", 102
21}
22
23testdialog DIALOG 10, 10, 200, 300
24STYLE WS_POPUP | WS_BORDER
25CAPTION "Test"
26{
27 CTEXT "Continue:", 1, 10, 10, 230, 14
28 PUSHBUTTON "&OK", 2, 66, 134, 161, 13
29}
30
3112 ACCELERATORS
32{
33 "X", 164, VIRTKEY, ALT
34 "H", 5678, VIRTKEY, CONTROL, SHIFT
35 "^R", 444, ASCII, NOINVERT
36}
37
38"eat" MENU
39LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS
40{
41 MENUITEM "fish", 100
42 MENUITEM "salad", 101
43 MENUITEM "duck", 102
44}
45
46
47myresource stringarray {
48 "this is a user defined resource\0",
49 "it contains many strings\0",
50}
deps/lld/test/COFF/Inputs/combined-resources.res created
Binary files /dev/null and b/deps/lld/test/COFF/Inputs/combined-resources.res differ
deps/lld/test/COFF/Inputs/conflict.ll created+6
......@@ -0,0 +1,6 @@
1target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-pc-windows-msvc"
3
4define void @foo() {
5 ret void
6}
deps/lld/test/COFF/Inputs/constant-export.ll created+7
......@@ -0,0 +1,7 @@
1target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
2target triple = "i686-unknown-windows-msvc18.0.0"
3
4@__CFConstantStringClassReference = common global [32 x i32] zeroinitializer, align 4
5
6!llvm.linker.options = !{!0}
7!0 = !{!" -export:___CFConstantStringClassReference,CONSTANT"}
deps/lld/test/COFF/Inputs/constant-import.s created+21
......@@ -0,0 +1,21 @@
1
2 .def __DllMainCRTStartup@12
3 .type 32
4 .scl 2
5 .endef
6 .global __DllMainCRTStartup@12
7__DllMainCRTStartup@12:
8 ret
9
10 .data
11 .def _Data
12 .type 0
13 .scl 2
14 .endef
15 .global _Data
16_Data:
17 .long ___CFConstantStringClassReference
18
19 .section .drectve
20 .ascii " -export:_Data"
21
deps/lld/test/COFF/Inputs/default.def created+2
......@@ -0,0 +1,2 @@
1EXPORTS
2 f
deps/lld/test/COFF/Inputs/delayimports-error.yaml created+29
......@@ -0,0 +1,29 @@
1--- !COFF
2header:
3 Machine: IMAGE_FILE_MACHINE_AMD64
4 Characteristics: []
5sections:
6 - Name: .data
7 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
8 Alignment: 4
9 SectionData: 0000000000000000
10symbols:
11 - Name: .data
12 Value: 0
13 SectionNumber: 1
14 SimpleType: IMAGE_SYM_TYPE_NULL
15 ComplexType: IMAGE_SYM_DTYPE_NULL
16 StorageClass: IMAGE_SYM_CLASS_STATIC
17 SectionDefinition:
18 Length: 8
19 NumberOfRelocations: 0
20 NumberOfLinenumbers: 0
21 CheckSum: 0
22 Number: 0
23 - Name: datasym
24 Value: 0
25 SectionNumber: 1
26 SimpleType: IMAGE_SYM_TYPE_NULL
27 ComplexType: IMAGE_SYM_DTYPE_NULL
28 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
29...
deps/lld/test/COFF/Inputs/entry-mangled.ll created+6
......@@ -0,0 +1,6 @@
1target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-pc-windows-msvc18.0.0"
3
4define void @"\01?main@@YAHXZ"() {
5 ret void
6}
deps/lld/test/COFF/Inputs/export.ll created+18
......@@ -0,0 +1,18 @@
1target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-pc-windows-msvc"
3
4define void @_DllMainCRTStartup() {
5 ret void
6}
7
8define void @exportfn1() {
9 ret void
10}
11
12define void @exportfn2() {
13 ret void
14}
15
16define dllexport void @exportfn3() {
17 ret void
18}
deps/lld/test/COFF/Inputs/export.yaml created+57
......@@ -0,0 +1,57 @@
1--- !COFF
2header:
3 Machine: IMAGE_FILE_MACHINE_AMD64
4 Characteristics: []
5sections:
6 - Name: .text
7 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
8 Alignment: 4
9 SectionData: B800000000506800000000680000000050E80000000050E800000000
10 - Name: .drectve
11 Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
12 Alignment: 1
13 SectionData: 2f6578706f72743a6578706f7274666e3300 # /export:exportfn3
14symbols:
15 - Name: .text
16 Value: 0
17 SectionNumber: 1
18 SimpleType: IMAGE_SYM_TYPE_NULL
19 ComplexType: IMAGE_SYM_DTYPE_NULL
20 StorageClass: IMAGE_SYM_CLASS_STATIC
21 SectionDefinition:
22 Length: 28
23 NumberOfRelocations: 4
24 NumberOfLinenumbers: 0
25 CheckSum: 0
26 Number: 0
27 - Name: _DllMainCRTStartup
28 Value: 0
29 SectionNumber: 1
30 SimpleType: IMAGE_SYM_TYPE_NULL
31 ComplexType: IMAGE_SYM_DTYPE_NULL
32 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
33 - Name: exportfn1
34 Value: 8
35 SectionNumber: 1
36 SimpleType: IMAGE_SYM_TYPE_NULL
37 ComplexType: IMAGE_SYM_DTYPE_NULL
38 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
39 - Name: exportfn2
40 Value: 16
41 SectionNumber: 1
42 SimpleType: IMAGE_SYM_TYPE_NULL
43 ComplexType: IMAGE_SYM_DTYPE_NULL
44 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
45 - Name: exportfn3
46 Value: 16
47 SectionNumber: 1
48 SimpleType: IMAGE_SYM_TYPE_NULL
49 ComplexType: IMAGE_SYM_DTYPE_NULL
50 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
51 - Name: '?mangled@@YAHXZ'
52 Value: 16
53 SectionNumber: 1
54 SimpleType: IMAGE_SYM_TYPE_NULL
55 ComplexType: IMAGE_SYM_DTYPE_NULL
56 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
57...
deps/lld/test/COFF/Inputs/export2.yaml created+29
......@@ -0,0 +1,29 @@
1--- !COFF
2header:
3 Machine: IMAGE_FILE_MACHINE_AMD64
4 Characteristics: []
5sections:
6 - Name: .text
7 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
8 Alignment: 4
9 SectionData: B800000000506800000000680000000050E80000000050E800000000
10symbols:
11 - Name: .text
12 Value: 0
13 SectionNumber: 1
14 SimpleType: IMAGE_SYM_TYPE_NULL
15 ComplexType: IMAGE_SYM_DTYPE_NULL
16 StorageClass: IMAGE_SYM_CLASS_STATIC
17 SectionDefinition:
18 Length: 28
19 NumberOfRelocations: 4
20 NumberOfLinenumbers: 0
21 CheckSum: 0
22 Number: 0
23 - Name: '?mangled2@@YAHXZ'
24 Value: 0
25 SectionNumber: 1
26 SimpleType: IMAGE_SYM_TYPE_NULL
27 ComplexType: IMAGE_SYM_DTYPE_NULL
28 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
29...
deps/lld/test/COFF/Inputs/extension.def created+3
......@@ -0,0 +1,3 @@
1LIBRARY library.ext
2EXPORTS
3 f
deps/lld/test/COFF/Inputs/far-arm-thumb-abs.s created+2
......@@ -0,0 +1,2 @@
1.global too_far1
2too_far1 = 0x1401004
deps/lld/test/COFF/Inputs/hello32.yaml created+82
......@@ -0,0 +1,82 @@
1--- !COFF
2header:
3 Machine: IMAGE_FILE_MACHINE_I386
4 Characteristics: []
5sections:
6 - Name: .text
7 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
8 Alignment: 16
9 SectionData: 33DB538D0500000000508D05000000005053E80000000050E800000000
10 Relocations:
11 - VirtualAddress: 5
12 SymbolName: caption
13 Type: IMAGE_REL_I386_DIR32
14 - VirtualAddress: 12
15 SymbolName: message
16 Type: IMAGE_REL_I386_DIR32
17 - VirtualAddress: 19
18 SymbolName: '_MessageBoxA@16'
19 Type: IMAGE_REL_I386_REL32
20 - VirtualAddress: 25
21 SymbolName: '_ExitProcess@4'
22 Type: IMAGE_REL_I386_REL32
23 - Name: .data
24 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
25 Alignment: 16
26 SectionData: 48656C6C6F0048656C6C6F20576F726C642100
27symbols:
28 - Name: .text
29 Value: 0
30 SectionNumber: 1
31 SimpleType: IMAGE_SYM_TYPE_NULL
32 ComplexType: IMAGE_SYM_DTYPE_NULL
33 StorageClass: IMAGE_SYM_CLASS_STATIC
34 SectionDefinition:
35 Length: 29
36 NumberOfRelocations: 4
37 NumberOfLinenumbers: 0
38 CheckSum: 0
39 Number: 0
40 - Name: .data
41 Value: 0
42 SectionNumber: 2
43 SimpleType: IMAGE_SYM_TYPE_NULL
44 ComplexType: IMAGE_SYM_DTYPE_NULL
45 StorageClass: IMAGE_SYM_CLASS_STATIC
46 SectionDefinition:
47 Length: 19
48 NumberOfRelocations: 0
49 NumberOfLinenumbers: 0
50 CheckSum: 0
51 Number: 0
52 - Name: '_ExitProcess@4'
53 Value: 0
54 SectionNumber: 0
55 SimpleType: IMAGE_SYM_TYPE_NULL
56 ComplexType: IMAGE_SYM_DTYPE_NULL
57 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
58 - Name: '_MessageBoxA@16'
59 Value: 0
60 SectionNumber: 0
61 SimpleType: IMAGE_SYM_TYPE_NULL
62 ComplexType: IMAGE_SYM_DTYPE_NULL
63 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
64 - Name: message
65 Value: 6
66 SectionNumber: 2
67 SimpleType: IMAGE_SYM_TYPE_NULL
68 ComplexType: IMAGE_SYM_DTYPE_NULL
69 StorageClass: IMAGE_SYM_CLASS_STATIC
70 - Name: caption
71 Value: 0
72 SectionNumber: 2
73 SimpleType: IMAGE_SYM_TYPE_NULL
74 ComplexType: IMAGE_SYM_DTYPE_NULL
75 StorageClass: IMAGE_SYM_CLASS_STATIC
76 - Name: '_main@0'
77 Value: 0
78 SectionNumber: 1
79 SimpleType: IMAGE_SYM_TYPE_NULL
80 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
81 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
82...
deps/lld/test/COFF/Inputs/hello64.asm created+24
......@@ -0,0 +1,24 @@
1;; ml64 hello64.asm /link /subsystem:windows /defaultlib:kernel32 \
2;; /defaultlib:user32 /out:hello64.exe /entry:main
3
4extern ExitProcess : PROC
5extern MessageBoxA : PROC
6extern ImportByOrdinal: PROC
7
8.data
9 caption db 'Hello', 0
10 message db 'Hello World!', 0
11
12.code
13main PROC
14 sub rsp,28h
15 mov rcx, 0
16 lea rdx, message
17 lea r8, caption
18 mov r9d, 0
19 call MessageBoxA
20 mov ecx, 0
21 call ExitProcess
22 call ImportByOrdinal
23main ENDP
24END
deps/lld/test/COFF/Inputs/hello64.obj created
Binary files /dev/null and b/deps/lld/test/COFF/Inputs/hello64.obj differ
deps/lld/test/COFF/Inputs/import.yaml created+48
......@@ -0,0 +1,48 @@
1--- !COFF
2header:
3 Machine: IMAGE_FILE_MACHINE_AMD64
4 Characteristics: []
5sections:
6 - Name: .text
7 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
8 Alignment: 4
9 SectionData: 0000000000000000
10 Relocations:
11 - VirtualAddress: 0
12 SymbolName: exportfn1
13 Type: IMAGE_REL_AMD64_ADDR32NB
14 - VirtualAddress: 4
15 SymbolName: exportfn2
16 Type: IMAGE_REL_AMD64_ADDR32NB
17symbols:
18 - Name: .text
19 Value: 0
20 SectionNumber: 1
21 SimpleType: IMAGE_SYM_TYPE_NULL
22 ComplexType: IMAGE_SYM_DTYPE_NULL
23 StorageClass: IMAGE_SYM_CLASS_STATIC
24 SectionDefinition:
25 Length: 8
26 NumberOfRelocations: 2
27 NumberOfLinenumbers: 0
28 CheckSum: 0
29 Number: 0
30 - Name: main
31 Value: 0
32 SectionNumber: 1
33 SimpleType: IMAGE_SYM_TYPE_NULL
34 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
35 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
36 - Name: exportfn1
37 Value: 0
38 SectionNumber: 0
39 SimpleType: IMAGE_SYM_TYPE_NULL
40 ComplexType: IMAGE_SYM_DTYPE_NULL
41 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
42 - Name: exportfn2
43 Value: 0
44 SectionNumber: 0
45 SimpleType: IMAGE_SYM_TYPE_NULL
46 ComplexType: IMAGE_SYM_DTYPE_NULL
47 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
48...
deps/lld/test/COFF/Inputs/imports-mangle.lib created
Binary files /dev/null and b/deps/lld/test/COFF/Inputs/imports-mangle.lib differ
deps/lld/test/COFF/Inputs/include1a.yaml created+33
......@@ -0,0 +1,33 @@
1--- !COFF
2header:
3 Machine: IMAGE_FILE_MACHINE_AMD64
4 Characteristics: []
5sections:
6 - Name: .text
7 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
8 Alignment: 4
9 SectionData: B800000000506800000000680000000050E80000000050E800000000
10 - Name: .drectve
11 Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
12 Alignment: 1
13 SectionData: 2f696e636c7564653a666f6f00 # /include:foo
14symbols:
15 - Name: .text
16 Value: 0
17 SectionNumber: 1
18 SimpleType: IMAGE_SYM_TYPE_NULL
19 ComplexType: IMAGE_SYM_DTYPE_NULL
20 StorageClass: IMAGE_SYM_CLASS_STATIC
21 SectionDefinition:
22 Length: 28
23 NumberOfRelocations: 4
24 NumberOfLinenumbers: 0
25 CheckSum: 0
26 Number: 0
27 - Name: main
28 Value: 0
29 SectionNumber: 1
30 SimpleType: IMAGE_SYM_TYPE_NULL
31 ComplexType: IMAGE_SYM_DTYPE_NULL
32 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
33...
deps/lld/test/COFF/Inputs/include1b.yaml created+33
......@@ -0,0 +1,33 @@
1--- !COFF
2header:
3 Machine: IMAGE_FILE_MACHINE_AMD64
4 Characteristics: []
5sections:
6 - Name: .text
7 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
8 Alignment: 4
9 SectionData: B800000000506800000000680000000050E80000000050E800000000
10 - Name: .drectve
11 Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
12 Alignment: 1
13 SectionData: 2f696e636c7564653a62617200 # /include:bar
14symbols:
15 - Name: .text
16 Value: 0
17 SectionNumber: 1
18 SimpleType: IMAGE_SYM_TYPE_NULL
19 ComplexType: IMAGE_SYM_DTYPE_NULL
20 StorageClass: IMAGE_SYM_CLASS_STATIC
21 SectionDefinition:
22 Length: 28
23 NumberOfRelocations: 4
24 NumberOfLinenumbers: 0
25 CheckSum: 0
26 Number: 0
27 - Name: foo
28 Value: 0
29 SectionNumber: 1
30 SimpleType: IMAGE_SYM_TYPE_NULL
31 ComplexType: IMAGE_SYM_DTYPE_NULL
32 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
33...
deps/lld/test/COFF/Inputs/include1c.yaml created+29
......@@ -0,0 +1,29 @@
1--- !COFF
2header:
3 Machine: IMAGE_FILE_MACHINE_AMD64
4 Characteristics: []
5sections:
6 - Name: .text
7 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
8 Alignment: 4
9 SectionData: B800000000506800000000680000000050E80000000050E800000000
10symbols:
11 - Name: .text
12 Value: 0
13 SectionNumber: 1
14 SimpleType: IMAGE_SYM_TYPE_NULL
15 ComplexType: IMAGE_SYM_DTYPE_NULL
16 StorageClass: IMAGE_SYM_CLASS_STATIC
17 SectionDefinition:
18 Length: 28
19 NumberOfRelocations: 4
20 NumberOfLinenumbers: 0
21 CheckSum: 0
22 Number: 0
23 - Name: bar
24 Value: 0
25 SectionNumber: 1
26 SimpleType: IMAGE_SYM_TYPE_NULL
27 ComplexType: IMAGE_SYM_DTYPE_NULL
28 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
29...
deps/lld/test/COFF/Inputs/library-arm64.lib created
Binary files /dev/null and b/deps/lld/test/COFF/Inputs/library-arm64.lib differ
deps/lld/test/COFF/Inputs/library.def created+5
......@@ -0,0 +1,5 @@
1LIBRARY library
2EXPORTS
3 function
4 data DATA
5 constant CONSTANT
deps/lld/test/COFF/Inputs/library.lib created
Binary files /dev/null and b/deps/lld/test/COFF/Inputs/library.lib differ
deps/lld/test/COFF/Inputs/lto-chkstk-chkstk.s created+3
......@@ -0,0 +1,3 @@
1.globl __chkstk
2__chkstk:
3ret
deps/lld/test/COFF/Inputs/lto-chkstk-foo.s created+3
......@@ -0,0 +1,3 @@
1.globl foo
2foo:
3ret
deps/lld/test/COFF/Inputs/lto-comdat1.ll created+13
......@@ -0,0 +1,13 @@
1target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-pc-windows-msvc"
3
4$comdat = comdat any
5
6define void @f1() {
7 call void @comdat()
8 ret void
9}
10
11define linkonce_odr void @comdat() comdat {
12 ret void
13}
deps/lld/test/COFF/Inputs/lto-comdat2.ll created+13
......@@ -0,0 +1,13 @@
1target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-pc-windows-msvc"
3
4$comdat = comdat any
5
6define void @f2() {
7 call void @comdat()
8 ret void
9}
10
11define linkonce_odr void @comdat() comdat {
12 ret void
13}
deps/lld/test/COFF/Inputs/lto-dep.ll created+10
......@@ -0,0 +1,10 @@
1target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-pc-windows-msvc"
3
4define void @foo() {
5 ret void
6}
7
8define internal void @internal() {
9 ret void
10}
deps/lld/test/COFF/Inputs/lto-lazy-reference-dummy.ll created+6
......@@ -0,0 +1,6 @@
1target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
2target triple = "i686-pc-windows-msvc18.0.0"
3
4define void @dummy() {
5 ret void
6}
deps/lld/test/COFF/Inputs/lto-lazy-reference-quadruple.ll created+16
......@@ -0,0 +1,16 @@
1target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
2target triple = "i686-pc-windows-msvc18.0.0"
3
4define double @quadruple(double %x) {
5entry:
6 ; The symbol __real@40800000 is used to materialize the 4.0 constant.
7 %mul = fmul double %x, 4.0
8 ret double %mul
9}
10
11
12declare void @dummy()
13define void @f() {
14 call void @dummy()
15 ret void
16}
deps/lld/test/COFF/Inputs/machine-x64.yaml created+29
......@@ -0,0 +1,29 @@
1--- !COFF
2header:
3 Machine: IMAGE_FILE_MACHINE_AMD64
4 Characteristics: []
5sections:
6 - Name: .text
7 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
8 Alignment: 4
9 SectionData: 000000000000
10symbols:
11 - Name: .text
12 Value: 0
13 SectionNumber: 1
14 SimpleType: IMAGE_SYM_TYPE_NULL
15 ComplexType: IMAGE_SYM_DTYPE_NULL
16 StorageClass: IMAGE_SYM_CLASS_STATIC
17 SectionDefinition:
18 Length: 6
19 NumberOfRelocations: 0
20 NumberOfLinenumbers: 0
21 CheckSum: 0
22 Number: 0
23 - Name: main
24 Value: 0
25 SectionNumber: 1
26 SimpleType: IMAGE_SYM_TYPE_NULL
27 ComplexType: IMAGE_SYM_DTYPE_NULL
28 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
29...
deps/lld/test/COFF/Inputs/machine-x86.yaml created+29
......@@ -0,0 +1,29 @@
1--- !COFF
2header:
3 Machine: IMAGE_FILE_MACHINE_I386
4 Characteristics: []
5sections:
6 - Name: .text
7 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
8 Alignment: 4
9 SectionData: 000000000000
10symbols:
11 - Name: .text
12 Value: 0
13 SectionNumber: 1
14 SimpleType: IMAGE_SYM_TYPE_NULL
15 ComplexType: IMAGE_SYM_DTYPE_NULL
16 StorageClass: IMAGE_SYM_CLASS_STATIC
17 SectionDefinition:
18 Length: 6
19 NumberOfRelocations: 0
20 NumberOfLinenumbers: 0
21 CheckSum: 0
22 Number: 0
23 - Name: _main
24 Value: 0
25 SectionNumber: 1
26 SimpleType: IMAGE_SYM_TYPE_NULL
27 ComplexType: IMAGE_SYM_DTYPE_NULL
28 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
29...
deps/lld/test/COFF/Inputs/manifestinput.test created+13
......@@ -0,0 +1,13 @@
1<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
2<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
3 <dependency>
4 <dependentAssembly>
5 <assemblyIdentity type='win32'
6 name='Microsoft.Windows.Common-Controls'
7 version='6.0.0.0'
8 processorArchitecture='*'
9 publicKeyToken='6595b64144ccf1df'
10 language='*' />
11 </dependentAssembly>
12 </dependency>
13</assembly>
deps/lld/test/COFF/Inputs/msvclto-order-a.ll created+7
......@@ -0,0 +1,7 @@
1target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-pc-windows-msvc"
3
4define void @foo() {
5 ret void
6}
7
deps/lld/test/COFF/Inputs/msvclto-order-b.ll created+10
......@@ -0,0 +1,10 @@
1target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-pc-windows-msvc"
3
4declare void @doesntexist()
5
6define void @foo() {
7 call void @doesntexist()
8 ret void
9}
10
deps/lld/test/COFF/Inputs/msvclto.s created+3
......@@ -0,0 +1,3 @@
1.globl foo
2foo:
3ret
deps/lld/test/COFF/Inputs/named.def created+3
......@@ -0,0 +1,3 @@
1LIBRARY library
2EXPORTS
3 f
deps/lld/test/COFF/Inputs/object.s created+13
......@@ -0,0 +1,13 @@
1
2 .text
3
4 .def f
5 .scl 2
6 .type 32
7 .endef
8 .global f
9f:
10 retq $0
11
12 .section .drectve,"rd"
13 .ascii " /EXPORT:f"
deps/lld/test/COFF/Inputs/oldname.yaml created+26
......@@ -0,0 +1,26 @@
1--- !COFF
2header:
3 Machine: IMAGE_FILE_MACHINE_UNKNOWN
4 Characteristics: [ ]
5sections:
6 - Name: .drectve
7 Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
8 Alignment: 1
9 SectionData: ''
10symbols:
11 - Name: exportfn1
12 Value: 0
13 SectionNumber: 0
14 SimpleType: IMAGE_SYM_TYPE_NULL
15 ComplexType: IMAGE_SYM_DTYPE_NULL
16 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
17 - Name: exportfn1_alias
18 Value: 0
19 SectionNumber: 0
20 SimpleType: IMAGE_SYM_TYPE_NULL
21 ComplexType: IMAGE_SYM_DTYPE_NULL
22 StorageClass: IMAGE_SYM_CLASS_WEAK_EXTERNAL
23 WeakExternal:
24 TagIndex: 0
25 Characteristics: IMAGE_WEAK_EXTERN_SEARCH_ALIAS
26...
deps/lld/test/COFF/Inputs/pdb-diff-cl.pdb created
Binary files /dev/null and b/deps/lld/test/COFF/Inputs/pdb-diff-cl.pdb differ
deps/lld/test/COFF/Inputs/pdb-diff.cpp created+10
......@@ -0,0 +1,10 @@
1// Build with cl:
2// cl.exe /Z7 pdb-diff.cpp /link /debug /pdb:pdb-diff-cl.pdb
3// /nodefaultlib /entry:main
4// Build with lld (after running the above cl command):
5// lld-link.exe /debug /pdb:pdb-diff-lld.pdb /nodefaultlib
6// /entry:main pdb-diff.obj
7
8void *__purecall = 0;
9
10int main() { return 42; }
deps/lld/test/COFF/Inputs/pdb-diff.obj created
Binary files /dev/null and b/deps/lld/test/COFF/Inputs/pdb-diff.obj differ
deps/lld/test/COFF/Inputs/pdb-global-gc.s created+4
......@@ -0,0 +1,4 @@
1.section .data,"dw",one_only,__wc_mb_cur
2.global __wc_mb_cur
3__wc_mb_cur:
4.long 42
deps/lld/test/COFF/Inputs/pdb-import-gc.lib created
Binary files /dev/null and b/deps/lld/test/COFF/Inputs/pdb-import-gc.lib differ
deps/lld/test/COFF/Inputs/pdb-scopes-a.yaml created+425
......@@ -0,0 +1,425 @@
1--- !COFF
2header:
3 Machine: IMAGE_FILE_MACHINE_AMD64
4 Characteristics: [ ]
5sections:
6 - Name: .drectve
7 Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
8 Alignment: 1
9 SectionData: 2020202F44454641554C544C49423A224C4942434D5422202F44454641554C544C49423A224F4C444E414D45532220
10 - Name: '.debug$S'
11 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
12 Alignment: 1
13 Subsections:
14 - !Symbols
15 Records:
16 - Kind: S_OBJNAME
17 ObjNameSym:
18 Signature: 0
19 ObjectName: 'C:\src\llvm-project\build\a.obj'
20 - Kind: S_COMPILE3
21 Compile3Sym:
22 Flags: [ SecurityChecks, HotPatch ]
23 Machine: X64
24 FrontendMajor: 19
25 FrontendMinor: 0
26 FrontendBuild: 24215
27 FrontendQFE: 1
28 BackendMajor: 19
29 BackendMinor: 0
30 BackendBuild: 24215
31 BackendQFE: 1
32 Version: 'Microsoft (R) Optimizing Compiler'
33 - !Symbols
34 Records:
35 - Kind: S_GPROC32_ID
36 ProcSym:
37 CodeSize: 5
38 DbgStart: 4
39 DbgEnd: 4
40 FunctionType: 4099
41 Flags: [ ]
42 DisplayName: g
43 - Kind: S_FRAMEPROC
44 FrameProcSym:
45 TotalFrameBytes: 0
46 PaddingFrameBytes: 0
47 OffsetToPadding: 0
48 BytesOfCalleeSavedRegisters: 0
49 OffsetOfExceptionHandler: 0
50 SectionIdOfExceptionHandler: 0
51 Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ]
52 - Kind: S_REGREL32
53 RegRelativeSym:
54 Offset: 8
55 Type: 116
56 Register: RSP
57 VarName: x
58 - Kind: S_PROC_ID_END
59 ScopeEndSym:
60 - !Lines
61 CodeSize: 5
62 Flags: [ ]
63 RelocOffset: 0
64 RelocSegment: 0
65 Blocks:
66 - FileName: 'c:\src\llvm-project\build\a.c'
67 Lines:
68 - Offset: 0
69 LineStart: 1
70 IsStatement: true
71 EndDelta: 0
72 Columns:
73 - !Symbols
74 Records:
75 - Kind: S_GPROC32_ID
76 ProcSym:
77 CodeSize: 58
78 DbgStart: 8
79 DbgEnd: 53
80 FunctionType: 4101
81 Flags: [ ]
82 DisplayName: main
83 - Kind: S_FRAMEPROC
84 FrameProcSym:
85 TotalFrameBytes: 56
86 PaddingFrameBytes: 0
87 OffsetToPadding: 0
88 BytesOfCalleeSavedRegisters: 0
89 OffsetOfExceptionHandler: 0
90 SectionIdOfExceptionHandler: 0
91 Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ]
92 - Kind: S_REGREL32
93 RegRelativeSym:
94 Offset: 64
95 Type: 116
96 Register: RSP
97 VarName: argc
98 - Kind: S_BLOCK32
99 BlockSym:
100 CodeSize: 17
101 Offset: 15
102 BlockName: ''
103 - Kind: S_REGREL32
104 RegRelativeSym:
105 Offset: 32
106 Type: 116
107 Register: RSP
108 VarName: x
109 - Kind: S_END
110 ScopeEndSym:
111 - Kind: S_BLOCK32
112 BlockSym:
113 CodeSize: 17
114 Offset: 34
115 BlockName: ''
116 - Kind: S_REGREL32
117 RegRelativeSym:
118 Offset: 36
119 Type: 116
120 Register: RSP
121 VarName: y
122 - Kind: S_END
123 ScopeEndSym:
124 - Kind: S_PROC_ID_END
125 ScopeEndSym:
126 - !Lines
127 CodeSize: 58
128 Flags: [ ]
129 RelocOffset: 0
130 RelocSegment: 0
131 Blocks:
132 - FileName: 'c:\src\llvm-project\build\a.c'
133 Lines:
134 - Offset: 0
135 LineStart: 3
136 IsStatement: true
137 EndDelta: 0
138 - Offset: 8
139 LineStart: 4
140 IsStatement: true
141 EndDelta: 0
142 - Offset: 15
143 LineStart: 5
144 IsStatement: true
145 EndDelta: 0
146 - Offset: 23
147 LineStart: 6
148 IsStatement: true
149 EndDelta: 0
150 - Offset: 32
151 LineStart: 7
152 IsStatement: true
153 EndDelta: 0
154 - Offset: 34
155 LineStart: 8
156 IsStatement: true
157 EndDelta: 0
158 - Offset: 42
159 LineStart: 9
160 IsStatement: true
161 EndDelta: 0
162 - Offset: 51
163 LineStart: 11
164 IsStatement: true
165 EndDelta: 0
166 Columns:
167 - !FileChecksums
168 Checksums:
169 - FileName: 'c:\src\llvm-project\build\a.c'
170 Kind: MD5
171 Checksum: 7FA72225C3F5630316383BD8BCC3EF72
172 - !StringTable
173 Strings:
174 - 'c:\src\llvm-project\build\a.c'
175 - !Symbols
176 Records:
177 - Kind: S_BUILDINFO
178 BuildInfoSym:
179 BuildId: 4110
180 Relocations:
181 - VirtualAddress: 152
182 SymbolName: g
183 Type: IMAGE_REL_AMD64_SECREL
184 - VirtualAddress: 156
185 SymbolName: g
186 Type: IMAGE_REL_AMD64_SECTION
187 - VirtualAddress: 220
188 SymbolName: g
189 Type: IMAGE_REL_AMD64_SECREL
190 - VirtualAddress: 224
191 SymbolName: g
192 Type: IMAGE_REL_AMD64_SECTION
193 - VirtualAddress: 292
194 SymbolName: main
195 Type: IMAGE_REL_AMD64_SECREL
196 - VirtualAddress: 296
197 SymbolName: main
198 Type: IMAGE_REL_AMD64_SECTION
199 - VirtualAddress: 369
200 SymbolName: main
201 Type: IMAGE_REL_AMD64_SECREL
202 - VirtualAddress: 373
203 SymbolName: main
204 Type: IMAGE_REL_AMD64_SECTION
205 - VirtualAddress: 412
206 SymbolName: main
207 Type: IMAGE_REL_AMD64_SECREL
208 - VirtualAddress: 416
209 SymbolName: main
210 Type: IMAGE_REL_AMD64_SECTION
211 - VirtualAddress: 452
212 SymbolName: main
213 Type: IMAGE_REL_AMD64_SECREL
214 - VirtualAddress: 456
215 SymbolName: main
216 Type: IMAGE_REL_AMD64_SECTION
217 - Name: '.debug$T'
218 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
219 Alignment: 1
220 Types:
221 - Kind: LF_ARGLIST
222 ArgList:
223 ArgIndices: [ 116 ]
224 - Kind: LF_PROCEDURE
225 Procedure:
226 ReturnType: 3
227 CallConv: NearC
228 Options: [ None ]
229 ParameterCount: 1
230 ArgumentList: 4096
231 - Kind: LF_POINTER
232 Pointer:
233 ReferentType: 4097
234 Attrs: 65548
235 - Kind: LF_FUNC_ID
236 FuncId:
237 ParentScope: 0
238 FunctionType: 4097
239 Name: g
240 - Kind: LF_PROCEDURE
241 Procedure:
242 ReturnType: 116
243 CallConv: NearC
244 Options: [ None ]
245 ParameterCount: 1
246 ArgumentList: 4096
247 - Kind: LF_FUNC_ID
248 FuncId:
249 ParentScope: 0
250 FunctionType: 4100
251 Name: main
252 - Kind: LF_FUNC_ID
253 FuncId:
254 ParentScope: 0
255 FunctionType: 4097
256 Name: f
257 - Kind: LF_STRING_ID
258 StringId:
259 Id: 0
260 String: 'C:\src\llvm-project\build'
261 - Kind: LF_STRING_ID
262 StringId:
263 Id: 0
264 String: 'C:\PROGRA~2\MICROS~1.0\VC\Bin\amd64\cl.exe'
265 - Kind: LF_STRING_ID
266 StringId:
267 Id: 0
268 String: '-c -Z7 -MT -IC:\PROGRA~2\MICROS~1.0\VC\include -IC:\PROGRA~2\MICROS~1.0\VC\atlmfc\include -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\ucrt -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\shared -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\um'
269 - Kind: LF_SUBSTR_LIST
270 StringList:
271 StringIndices: [ 4105 ]
272 - Kind: LF_STRING_ID
273 StringId:
274 Id: 4106
275 String: ' -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\winrt -TC -X'
276 - Kind: LF_STRING_ID
277 StringId:
278 Id: 0
279 String: a.c
280 - Kind: LF_STRING_ID
281 StringId:
282 Id: 0
283 String: 'C:\src\llvm-project\build\vc140.pdb'
284 - Kind: LF_BUILDINFO
285 BuildInfo:
286 ArgIndices: [ 4103, 4104, 4108, 4109, 4107 ]
287 - Name: '.text$mn'
288 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
289 Alignment: 16
290 SectionData: 894C2408C3CCCCCCCCCCCCCCCCCCCCCC894C24084883EC38837C2440007413C74424202A0000008B4C2420E800000000EB11C74424240D0000008B4C2424E80000000033C04883C438C3
291 Relocations:
292 - VirtualAddress: 44
293 SymbolName: f
294 Type: IMAGE_REL_AMD64_REL32
295 - VirtualAddress: 63
296 SymbolName: f
297 Type: IMAGE_REL_AMD64_REL32
298 - Name: .xdata
299 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
300 Alignment: 4
301 SectionData: '0108010008620000'
302 - Name: .pdata
303 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
304 Alignment: 4
305 SectionData: 000000003A00000000000000
306 Relocations:
307 - VirtualAddress: 0
308 SymbolName: '$LN5'
309 Type: IMAGE_REL_AMD64_ADDR32NB
310 - VirtualAddress: 4
311 SymbolName: '$LN5'
312 Type: IMAGE_REL_AMD64_ADDR32NB
313 - VirtualAddress: 8
314 SymbolName: '$unwind$main'
315 Type: IMAGE_REL_AMD64_ADDR32NB
316symbols:
317 - Name: .drectve
318 Value: 0
319 SectionNumber: 1
320 SimpleType: IMAGE_SYM_TYPE_NULL
321 ComplexType: IMAGE_SYM_DTYPE_NULL
322 StorageClass: IMAGE_SYM_CLASS_STATIC
323 SectionDefinition:
324 Length: 47
325 NumberOfRelocations: 0
326 NumberOfLinenumbers: 0
327 CheckSum: 0
328 Number: 0
329 - Name: '.debug$S'
330 Value: 0
331 SectionNumber: 2
332 SimpleType: IMAGE_SYM_TYPE_NULL
333 ComplexType: IMAGE_SYM_DTYPE_NULL
334 StorageClass: IMAGE_SYM_CLASS_STATIC
335 SectionDefinition:
336 Length: 628
337 NumberOfRelocations: 12
338 NumberOfLinenumbers: 0
339 CheckSum: 0
340 Number: 0
341 - Name: '.debug$T'
342 Value: 0
343 SectionNumber: 3
344 SimpleType: IMAGE_SYM_TYPE_NULL
345 ComplexType: IMAGE_SYM_DTYPE_NULL
346 StorageClass: IMAGE_SYM_CLASS_STATIC
347 SectionDefinition:
348 Length: 624
349 NumberOfRelocations: 0
350 NumberOfLinenumbers: 0
351 CheckSum: 0
352 Number: 0
353 - Name: '.text$mn'
354 Value: 0
355 SectionNumber: 4
356 SimpleType: IMAGE_SYM_TYPE_NULL
357 ComplexType: IMAGE_SYM_DTYPE_NULL
358 StorageClass: IMAGE_SYM_CLASS_STATIC
359 SectionDefinition:
360 Length: 74
361 NumberOfRelocations: 2
362 NumberOfLinenumbers: 0
363 CheckSum: 2120072435
364 Number: 0
365 - Name: g
366 Value: 0
367 SectionNumber: 4
368 SimpleType: IMAGE_SYM_TYPE_NULL
369 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
370 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
371 - Name: f
372 Value: 0
373 SectionNumber: 0
374 SimpleType: IMAGE_SYM_TYPE_NULL
375 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
376 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
377 - Name: main
378 Value: 16
379 SectionNumber: 4
380 SimpleType: IMAGE_SYM_TYPE_NULL
381 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
382 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
383 - Name: '$LN5'
384 Value: 16
385 SectionNumber: 4
386 SimpleType: IMAGE_SYM_TYPE_NULL
387 ComplexType: IMAGE_SYM_DTYPE_NULL
388 StorageClass: IMAGE_SYM_CLASS_LABEL
389 - Name: .xdata
390 Value: 0
391 SectionNumber: 5
392 SimpleType: IMAGE_SYM_TYPE_NULL
393 ComplexType: IMAGE_SYM_DTYPE_NULL
394 StorageClass: IMAGE_SYM_CLASS_STATIC
395 SectionDefinition:
396 Length: 8
397 NumberOfRelocations: 0
398 NumberOfLinenumbers: 0
399 CheckSum: 3137252093
400 Number: 0
401 - Name: '$unwind$main'
402 Value: 0
403 SectionNumber: 5
404 SimpleType: IMAGE_SYM_TYPE_NULL
405 ComplexType: IMAGE_SYM_DTYPE_NULL
406 StorageClass: IMAGE_SYM_CLASS_STATIC
407 - Name: .pdata
408 Value: 0
409 SectionNumber: 6
410 SimpleType: IMAGE_SYM_TYPE_NULL
411 ComplexType: IMAGE_SYM_DTYPE_NULL
412 StorageClass: IMAGE_SYM_CLASS_STATIC
413 SectionDefinition:
414 Length: 12
415 NumberOfRelocations: 3
416 NumberOfLinenumbers: 0
417 CheckSum: 336416693
418 Number: 0
419 - Name: '$pdata$main'
420 Value: 0
421 SectionNumber: 6
422 SimpleType: IMAGE_SYM_TYPE_NULL
423 ComplexType: IMAGE_SYM_DTYPE_NULL
424 StorageClass: IMAGE_SYM_CLASS_STATIC
425...
deps/lld/test/COFF/Inputs/pdb-scopes-b.yaml created+365
......@@ -0,0 +1,365 @@
1--- !COFF
2header:
3 Machine: IMAGE_FILE_MACHINE_AMD64
4 Characteristics: [ ]
5sections:
6 - Name: .drectve
7 Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
8 Alignment: 1
9 SectionData: 2020202F44454641554C544C49423A224C4942434D5422202F44454641554C544C49423A224F4C444E414D45532220
10 - Name: '.debug$S'
11 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
12 Alignment: 1
13 Subsections:
14 - !Symbols
15 Records:
16 - Kind: S_OBJNAME
17 ObjNameSym:
18 Signature: 0
19 ObjectName: 'C:\src\llvm-project\build\b.obj'
20 - Kind: S_COMPILE3
21 Compile3Sym:
22 Flags: [ SecurityChecks, HotPatch ]
23 Machine: X64
24 FrontendMajor: 19
25 FrontendMinor: 0
26 FrontendBuild: 24215
27 FrontendQFE: 1
28 BackendMajor: 19
29 BackendMinor: 0
30 BackendBuild: 24215
31 BackendQFE: 1
32 Version: 'Microsoft (R) Optimizing Compiler'
33 - !Symbols
34 Records:
35 - Kind: S_GPROC32_ID
36 ProcSym:
37 CodeSize: 62
38 DbgStart: 8
39 DbgEnd: 57
40 FunctionType: 4101
41 Flags: [ ]
42 DisplayName: f
43 - Kind: S_FRAMEPROC
44 FrameProcSym:
45 TotalFrameBytes: 56
46 PaddingFrameBytes: 0
47 OffsetToPadding: 0
48 BytesOfCalleeSavedRegisters: 0
49 OffsetOfExceptionHandler: 0
50 SectionIdOfExceptionHandler: 0
51 Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ]
52 - Kind: S_REGREL32
53 RegRelativeSym:
54 Offset: 64
55 Type: 116
56 Register: RSP
57 VarName: x
58 - Kind: S_BLOCK32
59 BlockSym:
60 CodeSize: 20
61 Offset: 15
62 BlockName: ''
63 - Kind: S_REGREL32
64 RegRelativeSym:
65 Offset: 32
66 Type: 116
67 Register: RSP
68 VarName: y
69 - Kind: S_END
70 ScopeEndSym:
71 - Kind: S_BLOCK32
72 BlockSym:
73 CodeSize: 20
74 Offset: 37
75 BlockName: ''
76 - Kind: S_REGREL32
77 RegRelativeSym:
78 Offset: 36
79 Type: 116
80 Register: RSP
81 VarName: w
82 - Kind: S_END
83 ScopeEndSym:
84 - Kind: S_PROC_ID_END
85 ScopeEndSym:
86 - !Lines
87 CodeSize: 62
88 Flags: [ ]
89 RelocOffset: 0
90 RelocSegment: 0
91 Blocks:
92 - FileName: 'c:\src\llvm-project\build\b.c'
93 Lines:
94 - Offset: 0
95 LineStart: 2
96 IsStatement: true
97 EndDelta: 0
98 - Offset: 8
99 LineStart: 3
100 IsStatement: true
101 EndDelta: 0
102 - Offset: 15
103 LineStart: 4
104 IsStatement: true
105 EndDelta: 0
106 - Offset: 26
107 LineStart: 5
108 IsStatement: true
109 EndDelta: 0
110 - Offset: 35
111 LineStart: 6
112 IsStatement: true
113 EndDelta: 0
114 - Offset: 37
115 LineStart: 7
116 IsStatement: true
117 EndDelta: 0
118 - Offset: 48
119 LineStart: 8
120 IsStatement: true
121 EndDelta: 0
122 - Offset: 57
123 LineStart: 10
124 IsStatement: true
125 EndDelta: 0
126 Columns:
127 - !FileChecksums
128 Checksums:
129 - FileName: 'c:\src\llvm-project\build\b.c'
130 Kind: MD5
131 Checksum: 8E8C92DB46478902EBEAEBFCFF15A6E0
132 - !StringTable
133 Strings:
134 - 'c:\src\llvm-project\build\b.c'
135 - !Symbols
136 Records:
137 - Kind: S_BUILDINFO
138 BuildInfoSym:
139 BuildId: 4110
140 Relocations:
141 - VirtualAddress: 152
142 SymbolName: f
143 Type: IMAGE_REL_AMD64_SECREL
144 - VirtualAddress: 156
145 SymbolName: f
146 Type: IMAGE_REL_AMD64_SECTION
147 - VirtualAddress: 223
148 SymbolName: f
149 Type: IMAGE_REL_AMD64_SECREL
150 - VirtualAddress: 227
151 SymbolName: f
152 Type: IMAGE_REL_AMD64_SECTION
153 - VirtualAddress: 266
154 SymbolName: f
155 Type: IMAGE_REL_AMD64_SECREL
156 - VirtualAddress: 270
157 SymbolName: f
158 Type: IMAGE_REL_AMD64_SECTION
159 - VirtualAddress: 308
160 SymbolName: f
161 Type: IMAGE_REL_AMD64_SECREL
162 - VirtualAddress: 312
163 SymbolName: f
164 Type: IMAGE_REL_AMD64_SECTION
165 - Name: '.debug$T'
166 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
167 Alignment: 1
168 Types:
169 - Kind: LF_ARGLIST
170 ArgList:
171 ArgIndices: [ 0 ]
172 - Kind: LF_PROCEDURE
173 Procedure:
174 ReturnType: 3
175 CallConv: NearC
176 Options: [ None ]
177 ParameterCount: 0
178 ArgumentList: 4096
179 - Kind: LF_POINTER
180 Pointer:
181 ReferentType: 4097
182 Attrs: 65548
183 - Kind: LF_ARGLIST
184 ArgList:
185 ArgIndices: [ 116 ]
186 - Kind: LF_PROCEDURE
187 Procedure:
188 ReturnType: 3
189 CallConv: NearC
190 Options: [ None ]
191 ParameterCount: 1
192 ArgumentList: 4099
193 - Kind: LF_FUNC_ID
194 FuncId:
195 ParentScope: 0
196 FunctionType: 4100
197 Name: f
198 - Kind: LF_FUNC_ID
199 FuncId:
200 ParentScope: 0
201 FunctionType: 4097
202 Name: g
203 - Kind: LF_STRING_ID
204 StringId:
205 Id: 0
206 String: 'C:\src\llvm-project\build'
207 - Kind: LF_STRING_ID
208 StringId:
209 Id: 0
210 String: 'C:\PROGRA~2\MICROS~1.0\VC\Bin\amd64\cl.exe'
211 - Kind: LF_STRING_ID
212 StringId:
213 Id: 0
214 String: '-c -Z7 -MT -IC:\PROGRA~2\MICROS~1.0\VC\include -IC:\PROGRA~2\MICROS~1.0\VC\atlmfc\include -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\ucrt -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\shared -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\um'
215 - Kind: LF_SUBSTR_LIST
216 StringList:
217 StringIndices: [ 4105 ]
218 - Kind: LF_STRING_ID
219 StringId:
220 Id: 4106
221 String: ' -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\winrt -TC -X'
222 - Kind: LF_STRING_ID
223 StringId:
224 Id: 0
225 String: b.c
226 - Kind: LF_STRING_ID
227 StringId:
228 Id: 0
229 String: 'C:\src\llvm-project\build\vc140.pdb'
230 - Kind: LF_BUILDINFO
231 BuildInfo:
232 ArgIndices: [ 4103, 4104, 4108, 4109, 4107 ]
233 - Name: '.text$mn'
234 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
235 Alignment: 16
236 SectionData: 894C24084883EC38837C24400074168B44244083C003894424208B4C2420E800000000EB148B44244083C004894424248B4C2424E8000000004883C438C3
237 Relocations:
238 - VirtualAddress: 31
239 SymbolName: g
240 Type: IMAGE_REL_AMD64_REL32
241 - VirtualAddress: 53
242 SymbolName: g
243 Type: IMAGE_REL_AMD64_REL32
244 - Name: .xdata
245 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
246 Alignment: 4
247 SectionData: '0108010008620000'
248 - Name: .pdata
249 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
250 Alignment: 4
251 SectionData: '000000003E00000000000000'
252 Relocations:
253 - VirtualAddress: 0
254 SymbolName: '$LN5'
255 Type: IMAGE_REL_AMD64_ADDR32NB
256 - VirtualAddress: 4
257 SymbolName: '$LN5'
258 Type: IMAGE_REL_AMD64_ADDR32NB
259 - VirtualAddress: 8
260 SymbolName: '$unwind$f'
261 Type: IMAGE_REL_AMD64_ADDR32NB
262symbols:
263 - Name: .drectve
264 Value: 0
265 SectionNumber: 1
266 SimpleType: IMAGE_SYM_TYPE_NULL
267 ComplexType: IMAGE_SYM_DTYPE_NULL
268 StorageClass: IMAGE_SYM_CLASS_STATIC
269 SectionDefinition:
270 Length: 47
271 NumberOfRelocations: 0
272 NumberOfLinenumbers: 0
273 CheckSum: 0
274 Number: 0
275 - Name: '.debug$S'
276 Value: 0
277 SectionNumber: 2
278 SimpleType: IMAGE_SYM_TYPE_NULL
279 ComplexType: IMAGE_SYM_DTYPE_NULL
280 StorageClass: IMAGE_SYM_CLASS_STATIC
281 SectionDefinition:
282 Length: 484
283 NumberOfRelocations: 8
284 NumberOfLinenumbers: 0
285 CheckSum: 0
286 Number: 0
287 - Name: '.debug$T'
288 Value: 0
289 SectionNumber: 3
290 SimpleType: IMAGE_SYM_TYPE_NULL
291 ComplexType: IMAGE_SYM_DTYPE_NULL
292 StorageClass: IMAGE_SYM_CLASS_STATIC
293 SectionDefinition:
294 Length: 616
295 NumberOfRelocations: 0
296 NumberOfLinenumbers: 0
297 CheckSum: 0
298 Number: 0
299 - Name: '.text$mn'
300 Value: 0
301 SectionNumber: 4
302 SimpleType: IMAGE_SYM_TYPE_NULL
303 ComplexType: IMAGE_SYM_DTYPE_NULL
304 StorageClass: IMAGE_SYM_CLASS_STATIC
305 SectionDefinition:
306 Length: 62
307 NumberOfRelocations: 2
308 NumberOfLinenumbers: 0
309 CheckSum: 3841032836
310 Number: 0
311 - Name: g
312 Value: 0
313 SectionNumber: 0
314 SimpleType: IMAGE_SYM_TYPE_NULL
315 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
316 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
317 - Name: f
318 Value: 0
319 SectionNumber: 4
320 SimpleType: IMAGE_SYM_TYPE_NULL
321 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
322 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
323 - Name: '$LN5'
324 Value: 0
325 SectionNumber: 4
326 SimpleType: IMAGE_SYM_TYPE_NULL
327 ComplexType: IMAGE_SYM_DTYPE_NULL
328 StorageClass: IMAGE_SYM_CLASS_LABEL
329 - Name: .xdata
330 Value: 0
331 SectionNumber: 5
332 SimpleType: IMAGE_SYM_TYPE_NULL
333 ComplexType: IMAGE_SYM_DTYPE_NULL
334 StorageClass: IMAGE_SYM_CLASS_STATIC
335 SectionDefinition:
336 Length: 8
337 NumberOfRelocations: 0
338 NumberOfLinenumbers: 0
339 CheckSum: 3137252093
340 Number: 0
341 - Name: '$unwind$f'
342 Value: 0
343 SectionNumber: 5
344 SimpleType: IMAGE_SYM_TYPE_NULL
345 ComplexType: IMAGE_SYM_DTYPE_NULL
346 StorageClass: IMAGE_SYM_CLASS_STATIC
347 - Name: .pdata
348 Value: 0
349 SectionNumber: 6
350 SimpleType: IMAGE_SYM_TYPE_NULL
351 ComplexType: IMAGE_SYM_DTYPE_NULL
352 StorageClass: IMAGE_SYM_CLASS_STATIC
353 SectionDefinition:
354 Length: 12
355 NumberOfRelocations: 3
356 NumberOfLinenumbers: 0
357 CheckSum: 2420588879
358 Number: 0
359 - Name: '$pdata$f'
360 Value: 0
361 SectionNumber: 6
362 SimpleType: IMAGE_SYM_TYPE_NULL
363 ComplexType: IMAGE_SYM_DTYPE_NULL
364 StorageClass: IMAGE_SYM_CLASS_STATIC
365...
deps/lld/test/COFF/Inputs/pdb-type-server-simple-a.yaml created+255
......@@ -0,0 +1,255 @@
1--- !COFF
2header:
3 Machine: IMAGE_FILE_MACHINE_AMD64
4 Characteristics: [ ]
5sections:
6 - Name: .drectve
7 Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
8 Alignment: 1
9 SectionData: 2020202F44454641554C544C49423A224C4942434D5422202F44454641554C544C49423A224F4C444E414D45532220
10 - Name: '.debug$S'
11 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
12 Alignment: 1
13 Subsections:
14 - !Symbols
15 Records:
16 - Kind: S_OBJNAME
17 ObjNameSym:
18 Signature: 0
19 ObjectName: 'C:\src\llvm-project\build\a.obj'
20 - Kind: S_COMPILE3
21 Compile3Sym:
22 Flags: [ SecurityChecks, HotPatch ]
23 Machine: X64
24 FrontendMajor: 19
25 FrontendMinor: 0
26 FrontendBuild: 24215
27 FrontendQFE: 1
28 BackendMajor: 19
29 BackendMinor: 0
30 BackendBuild: 24215
31 BackendQFE: 1
32 Version: 'Microsoft (R) Optimizing Compiler'
33 - !Symbols
34 Records:
35 - Kind: S_GPROC32_ID
36 ProcSym:
37 CodeSize: 27
38 DbgStart: 4
39 DbgEnd: 22
40 FunctionType: 4098
41 Flags: [ ]
42 DisplayName: main
43 - Kind: S_FRAMEPROC
44 FrameProcSym:
45 TotalFrameBytes: 56
46 PaddingFrameBytes: 0
47 OffsetToPadding: 0
48 BytesOfCalleeSavedRegisters: 0
49 OffsetOfExceptionHandler: 0
50 SectionIdOfExceptionHandler: 0
51 Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ]
52 - Kind: S_REGREL32
53 RegRelativeSym:
54 Offset: 32
55 Type: 4102
56 Register: RSP
57 VarName: f
58 - Kind: S_PROC_ID_END
59 ScopeEndSym:
60 - !Lines
61 CodeSize: 27
62 Flags: [ ]
63 RelocOffset: 0
64 RelocSegment: 0
65 Blocks:
66 - FileName: 'c:\src\llvm-project\build\a.c'
67 Lines:
68 - Offset: 0
69 LineStart: 3
70 IsStatement: true
71 EndDelta: 0
72 - Offset: 4
73 LineStart: 4
74 IsStatement: true
75 EndDelta: 0
76 - Offset: 12
77 LineStart: 5
78 IsStatement: true
79 EndDelta: 0
80 - Offset: 22
81 LineStart: 6
82 IsStatement: true
83 EndDelta: 0
84 Columns:
85 - !Symbols
86 Records:
87 - Kind: S_UDT
88 UDTSym:
89 Type: 4102
90 UDTName: Foo
91 - !FileChecksums
92 Checksums:
93 - FileName: 'c:\src\llvm-project\build\a.c'
94 Kind: MD5
95 Checksum: BF69E7E933074E1B7ED1FE8FB395965B
96 - !StringTable
97 Strings:
98 - 'c:\src\llvm-project\build\a.c'
99 - !Symbols
100 Records:
101 - Kind: S_BUILDINFO
102 BuildInfoSym:
103 BuildId: 4107
104 Relocations:
105 - VirtualAddress: 152
106 SymbolName: main
107 Type: IMAGE_REL_AMD64_SECREL
108 - VirtualAddress: 156
109 SymbolName: main
110 Type: IMAGE_REL_AMD64_SECTION
111 - VirtualAddress: 224
112 SymbolName: main
113 Type: IMAGE_REL_AMD64_SECREL
114 - VirtualAddress: 228
115 SymbolName: main
116 Type: IMAGE_REL_AMD64_SECTION
117 - Name: '.debug$T'
118 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
119 Alignment: 1
120 Types:
121 - Kind: LF_TYPESERVER2
122 TypeServer2:
123 Guid: '{41414141-4141-4141-4141-414141414141}'
124 Age: 1
125 Name: 'C:\src\llvm-project\build\ts.pdb'
126 - Name: '.text$mn'
127 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
128 Alignment: 16
129 SectionData: 4883EC38C74424202A000000488D4C2420E8000000004883C438C3
130 Relocations:
131 - VirtualAddress: 18
132 SymbolName: g
133 Type: IMAGE_REL_AMD64_REL32
134 - Name: .xdata
135 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
136 Alignment: 4
137 SectionData: '0104010004620000'
138 - Name: .pdata
139 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
140 Alignment: 4
141 SectionData: 000000001B00000000000000
142 Relocations:
143 - VirtualAddress: 0
144 SymbolName: '$LN3'
145 Type: IMAGE_REL_AMD64_ADDR32NB
146 - VirtualAddress: 4
147 SymbolName: '$LN3'
148 Type: IMAGE_REL_AMD64_ADDR32NB
149 - VirtualAddress: 8
150 SymbolName: '$unwind$main'
151 Type: IMAGE_REL_AMD64_ADDR32NB
152symbols:
153 - Name: .drectve
154 Value: 0
155 SectionNumber: 1
156 SimpleType: IMAGE_SYM_TYPE_NULL
157 ComplexType: IMAGE_SYM_DTYPE_NULL
158 StorageClass: IMAGE_SYM_CLASS_STATIC
159 SectionDefinition:
160 Length: 47
161 NumberOfRelocations: 0
162 NumberOfLinenumbers: 0
163 CheckSum: 0
164 Number: 0
165 - Name: '.debug$S'
166 Value: 0
167 SectionNumber: 2
168 SimpleType: IMAGE_SYM_TYPE_NULL
169 ComplexType: IMAGE_SYM_DTYPE_NULL
170 StorageClass: IMAGE_SYM_CLASS_STATIC
171 SectionDefinition:
172 Length: 388
173 NumberOfRelocations: 4
174 NumberOfLinenumbers: 0
175 CheckSum: 0
176 Number: 0
177 - Name: '.debug$T'
178 Value: 0
179 SectionNumber: 3
180 SimpleType: IMAGE_SYM_TYPE_NULL
181 ComplexType: IMAGE_SYM_DTYPE_NULL
182 StorageClass: IMAGE_SYM_CLASS_STATIC
183 SectionDefinition:
184 Length: 64
185 NumberOfRelocations: 0
186 NumberOfLinenumbers: 0
187 CheckSum: 0
188 Number: 0
189 - Name: '.text$mn'
190 Value: 0
191 SectionNumber: 4
192 SimpleType: IMAGE_SYM_TYPE_NULL
193 ComplexType: IMAGE_SYM_DTYPE_NULL
194 StorageClass: IMAGE_SYM_CLASS_STATIC
195 SectionDefinition:
196 Length: 27
197 NumberOfRelocations: 1
198 NumberOfLinenumbers: 0
199 CheckSum: 1939996292
200 Number: 0
201 - Name: g
202 Value: 0
203 SectionNumber: 0
204 SimpleType: IMAGE_SYM_TYPE_NULL
205 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
206 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
207 - Name: main
208 Value: 0
209 SectionNumber: 4
210 SimpleType: IMAGE_SYM_TYPE_NULL
211 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
212 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
213 - Name: '$LN3'
214 Value: 0
215 SectionNumber: 4
216 SimpleType: IMAGE_SYM_TYPE_NULL
217 ComplexType: IMAGE_SYM_DTYPE_NULL
218 StorageClass: IMAGE_SYM_CLASS_LABEL
219 - Name: .xdata
220 Value: 0
221 SectionNumber: 5
222 SimpleType: IMAGE_SYM_TYPE_NULL
223 ComplexType: IMAGE_SYM_DTYPE_NULL
224 StorageClass: IMAGE_SYM_CLASS_STATIC
225 SectionDefinition:
226 Length: 8
227 NumberOfRelocations: 0
228 NumberOfLinenumbers: 0
229 CheckSum: 931692337
230 Number: 0
231 - Name: '$unwind$main'
232 Value: 0
233 SectionNumber: 5
234 SimpleType: IMAGE_SYM_TYPE_NULL
235 ComplexType: IMAGE_SYM_DTYPE_NULL
236 StorageClass: IMAGE_SYM_CLASS_STATIC
237 - Name: .pdata
238 Value: 0
239 SectionNumber: 6
240 SimpleType: IMAGE_SYM_TYPE_NULL
241 ComplexType: IMAGE_SYM_DTYPE_NULL
242 StorageClass: IMAGE_SYM_CLASS_STATIC
243 SectionDefinition:
244 Length: 12
245 NumberOfRelocations: 3
246 NumberOfLinenumbers: 0
247 CheckSum: 567356797
248 Number: 0
249 - Name: '$pdata$main'
250 Value: 0
251 SectionNumber: 6
252 SimpleType: IMAGE_SYM_TYPE_NULL
253 ComplexType: IMAGE_SYM_DTYPE_NULL
254 StorageClass: IMAGE_SYM_CLASS_STATIC
255...
deps/lld/test/COFF/Inputs/pdb-type-server-simple-b.yaml created+173
......@@ -0,0 +1,173 @@
1--- !COFF
2header:
3 Machine: IMAGE_FILE_MACHINE_AMD64
4 Characteristics: [ ]
5sections:
6 - Name: .drectve
7 Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
8 Alignment: 1
9 SectionData: 2020202F44454641554C544C49423A224C4942434D5422202F44454641554C544C49423A224F4C444E414D45532220
10 - Name: '.debug$S'
11 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
12 Alignment: 1
13 Subsections:
14 - !Symbols
15 Records:
16 - Kind: S_OBJNAME
17 ObjNameSym:
18 Signature: 0
19 ObjectName: 'C:\src\llvm-project\build\b.obj'
20 - Kind: S_COMPILE3
21 Compile3Sym:
22 Flags: [ SecurityChecks, HotPatch ]
23 Machine: X64
24 FrontendMajor: 19
25 FrontendMinor: 0
26 FrontendBuild: 24215
27 FrontendQFE: 1
28 BackendMajor: 19
29 BackendMinor: 0
30 BackendBuild: 24215
31 BackendQFE: 1
32 Version: 'Microsoft (R) Optimizing Compiler'
33 - !Symbols
34 Records:
35 - Kind: S_GPROC32_ID
36 ProcSym:
37 CodeSize: 13
38 DbgStart: 5
39 DbgEnd: 12
40 FunctionType: 4099
41 Flags: [ ]
42 DisplayName: g
43 - Kind: S_FRAMEPROC
44 FrameProcSym:
45 TotalFrameBytes: 0
46 PaddingFrameBytes: 0
47 OffsetToPadding: 0
48 BytesOfCalleeSavedRegisters: 0
49 OffsetOfExceptionHandler: 0
50 SectionIdOfExceptionHandler: 0
51 Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ]
52 - Kind: S_REGREL32
53 RegRelativeSym:
54 Offset: 8
55 Type: 4097
56 Register: RSP
57 VarName: p
58 - Kind: S_PROC_ID_END
59 ScopeEndSym:
60 - !Lines
61 CodeSize: 13
62 Flags: [ ]
63 RelocOffset: 0
64 RelocSegment: 0
65 Blocks:
66 - FileName: 'c:\src\llvm-project\build\b.c'
67 Lines:
68 - Offset: 0
69 LineStart: 2
70 IsStatement: true
71 EndDelta: 0
72 Columns:
73 - !Symbols
74 Records:
75 - Kind: S_UDT
76 UDTSym:
77 Type: 4102
78 UDTName: Foo
79 - !FileChecksums
80 Checksums:
81 - FileName: 'c:\src\llvm-project\build\b.c'
82 Kind: MD5
83 Checksum: DDF8FD35CD67990C5D4147516BE10D0C
84 - !StringTable
85 Strings:
86 - 'c:\src\llvm-project\build\b.c'
87 - !Symbols
88 Records:
89 - Kind: S_BUILDINFO
90 BuildInfoSym:
91 BuildId: 4111
92 Relocations:
93 - VirtualAddress: 152
94 SymbolName: g
95 Type: IMAGE_REL_AMD64_SECREL
96 - VirtualAddress: 156
97 SymbolName: g
98 Type: IMAGE_REL_AMD64_SECTION
99 - VirtualAddress: 220
100 SymbolName: g
101 Type: IMAGE_REL_AMD64_SECREL
102 - VirtualAddress: 224
103 SymbolName: g
104 Type: IMAGE_REL_AMD64_SECTION
105 - Name: '.debug$T'
106 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
107 Alignment: 1
108 Types:
109 - Kind: LF_TYPESERVER2
110 TypeServer2:
111 Guid: '{41414141-4141-4141-4141-414141414141}'
112 Age: 1
113 Name: 'C:\src\llvm-project\build\ts.pdb'
114 - Name: '.text$mn'
115 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
116 Alignment: 16
117 SectionData: 48894C2408488B4424088B00C3
118symbols:
119 - Name: .drectve
120 Value: 0
121 SectionNumber: 1
122 SimpleType: IMAGE_SYM_TYPE_NULL
123 ComplexType: IMAGE_SYM_DTYPE_NULL
124 StorageClass: IMAGE_SYM_CLASS_STATIC
125 SectionDefinition:
126 Length: 47
127 NumberOfRelocations: 0
128 NumberOfLinenumbers: 0
129 CheckSum: 0
130 Number: 0
131 - Name: '.debug$S'
132 Value: 0
133 SectionNumber: 2
134 SimpleType: IMAGE_SYM_TYPE_NULL
135 ComplexType: IMAGE_SYM_DTYPE_NULL
136 StorageClass: IMAGE_SYM_CLASS_STATIC
137 SectionDefinition:
138 Length: 360
139 NumberOfRelocations: 4
140 NumberOfLinenumbers: 0
141 CheckSum: 0
142 Number: 0
143 - Name: '.debug$T'
144 Value: 0
145 SectionNumber: 3
146 SimpleType: IMAGE_SYM_TYPE_NULL
147 ComplexType: IMAGE_SYM_DTYPE_NULL
148 StorageClass: IMAGE_SYM_CLASS_STATIC
149 SectionDefinition:
150 Length: 64
151 NumberOfRelocations: 0
152 NumberOfLinenumbers: 0
153 CheckSum: 0
154 Number: 0
155 - Name: '.text$mn'
156 Value: 0
157 SectionNumber: 4
158 SimpleType: IMAGE_SYM_TYPE_NULL
159 ComplexType: IMAGE_SYM_DTYPE_NULL
160 StorageClass: IMAGE_SYM_CLASS_STATIC
161 SectionDefinition:
162 Length: 13
163 NumberOfRelocations: 0
164 NumberOfLinenumbers: 0
165 CheckSum: 3246683207
166 Number: 0
167 - Name: g
168 Value: 0
169 SectionNumber: 4
170 SimpleType: IMAGE_SYM_TYPE_NULL
171 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
172 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
173...
deps/lld/test/COFF/Inputs/pdb-type-server-simple-ts.yaml created+147
......@@ -0,0 +1,147 @@
1---
2MSF:
3 SuperBlock:
4 BlockSize: 4096
5 FreeBlockMap: 1
6 NumBlocks: 19
7 NumDirectoryBytes: 64
8 Unknown1: 0
9 BlockMapAddr: 17
10 NumDirectoryBlocks: 1
11 DirectoryBlocks: [ 16 ]
12 NumStreams: 0
13 FileSize: 77824
14PdbStream:
15 Age: 1
16 Guid: '{41414141-4141-4141-4141-414141414141}'
17 Signature: 1500053944
18 Features: [ VC140 ]
19 Version: VC70
20TpiStream:
21 Version: VC80
22 Records:
23 - Kind: LF_STRUCTURE
24 Class:
25 MemberCount: 0
26 Options: [ None, ForwardReference, HasUniqueName ]
27 FieldList: 0
28 Name: Foo
29 UniqueName: '.?AUFoo@@'
30 DerivationList: 0
31 VTableShape: 0
32 Size: 0
33 - Kind: LF_POINTER
34 Pointer:
35 ReferentType: 4096
36 Attrs: 65548
37 - Kind: LF_ARGLIST
38 ArgList:
39 ArgIndices: [ 4097 ]
40 - Kind: LF_PROCEDURE
41 Procedure:
42 ReturnType: 116
43 CallConv: NearC
44 Options: [ None ]
45 ParameterCount: 1
46 ArgumentList: 4098
47 - Kind: LF_POINTER
48 Pointer:
49 ReferentType: 4099
50 Attrs: 65548
51 - Kind: LF_FIELDLIST
52 FieldList:
53 - Kind: LF_MEMBER
54 DataMember:
55 Attrs: 3
56 Type: 116
57 FieldOffset: 0
58 Name: x
59 - Kind: LF_STRUCTURE
60 Class:
61 MemberCount: 1
62 Options: [ None, HasUniqueName ]
63 FieldList: 4101
64 Name: Foo
65 UniqueName: '.?AUFoo@@'
66 DerivationList: 0
67 VTableShape: 0
68 Size: 4
69 - Kind: LF_ARGLIST
70 ArgList:
71 ArgIndices: [ 0 ]
72 - Kind: LF_PROCEDURE
73 Procedure:
74 ReturnType: 116
75 CallConv: NearC
76 Options: [ None ]
77 ParameterCount: 0
78 ArgumentList: 4103
79IpiStream:
80 Version: VC80
81 Records:
82 - Kind: LF_STRING_ID
83 StringId:
84 Id: 0
85 String: 'c:\src\llvm-project\build\a.c'
86 - Kind: LF_UDT_SRC_LINE
87 UdtSourceLine:
88 UDT: 4102
89 SourceFile: 4096
90 LineNumber: 1
91 - Kind: LF_FUNC_ID
92 FuncId:
93 ParentScope: 0
94 FunctionType: 4104
95 Name: main
96 - Kind: LF_FUNC_ID
97 FuncId:
98 ParentScope: 0
99 FunctionType: 4099
100 Name: g
101 - Kind: LF_STRING_ID
102 StringId:
103 Id: 0
104 String: 'C:\src\llvm-project\build'
105 - Kind: LF_STRING_ID
106 StringId:
107 Id: 0
108 String: 'C:\PROGRA~2\MICROS~1.0\VC\Bin\amd64\cl.exe'
109 - Kind: LF_STRING_ID
110 StringId:
111 Id: 0
112 String: '-c -Zi -MT -IC:\PROGRA~2\MICROS~1.0\VC\include -IC:\PROGRA~2\MICROS~1.0\VC\atlmfc\include -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\ucrt -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\shared -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\um'
113 - Kind: LF_SUBSTR_LIST
114 StringList:
115 StringIndices: [ 4102 ]
116 - Kind: LF_STRING_ID
117 StringId:
118 Id: 4103
119 String: ' -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\winrt -TC -X'
120 - Kind: LF_STRING_ID
121 StringId:
122 Id: 0
123 String: a.c
124 - Kind: LF_STRING_ID
125 StringId:
126 Id: 0
127 String: 'C:\src\llvm-project\build\ts.pdb'
128 - Kind: LF_BUILDINFO
129 BuildInfo:
130 ArgIndices: [ 4100, 4101, 4105, 4106, 4104 ]
131 - Kind: LF_STRING_ID
132 StringId:
133 Id: 0
134 String: 'c:\src\llvm-project\build\b.c'
135 - Kind: LF_UDT_SRC_LINE
136 UdtSourceLine:
137 UDT: 4102
138 SourceFile: 4108
139 LineNumber: 1
140 - Kind: LF_STRING_ID
141 StringId:
142 Id: 0
143 String: b.c
144 - Kind: LF_BUILDINFO
145 BuildInfo:
146 ArgIndices: [ 4100, 4101, 4110, 4106, 4104 ]
147...
deps/lld/test/COFF/Inputs/pdb1.yaml created+302
......@@ -0,0 +1,302 @@
1--- !COFF
2header:
3 Machine: IMAGE_FILE_MACHINE_AMD64
4 Characteristics: [ ]
5sections:
6 - Name: .drectve
7 Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
8 Alignment: 1
9 SectionData: 2020202F44454641554C544C49423A224C4942434D5422202F44454641554C544C49423A224F4C444E414D45532220
10 - Name: '.debug$S'
11 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
12 Alignment: 1
13 Subsections:
14 - !Symbols
15 Records:
16 - Kind: S_OBJNAME
17 ObjNameSym:
18 Signature: 0
19 ObjectName: 'D:\b\ret42-main.obj'
20 - Kind: S_COMPILE3
21 Compile3Sym:
22 Flags: [ SecurityChecks, HotPatch ]
23 Machine: X64
24 FrontendMajor: 19
25 FrontendMinor: 0
26 FrontendBuild: 23026
27 FrontendQFE: 0
28 BackendMajor: 19
29 BackendMinor: 0
30 BackendBuild: 23026
31 BackendQFE: 0
32 Version: 'Microsoft (R) Optimizing Compiler'
33 - !Symbols
34 Records:
35 - Kind: S_GPROC32_ID
36 ProcSym:
37 CodeSize: 14
38 DbgStart: 4
39 DbgEnd: 9
40 FunctionType: 4101
41 Flags: [ ]
42 DisplayName: main
43 - Kind: S_FRAMEPROC
44 FrameProcSym:
45 TotalFrameBytes: 40
46 PaddingFrameBytes: 0
47 OffsetToPadding: 0
48 BytesOfCalleeSavedRegisters: 0
49 OffsetOfExceptionHandler: 0
50 SectionIdOfExceptionHandler: 0
51 Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ]
52 - Kind: S_PROC_ID_END
53 ScopeEndSym:
54 - !Lines
55 CodeSize: 14
56 Flags: [ ]
57 RelocOffset: 0
58 RelocSegment: 0
59 Blocks:
60 - FileName: 'd:\b\ret42-main.c'
61 Lines:
62 - Offset: 0
63 LineStart: 2
64 IsStatement: true
65 EndDelta: 0
66 Columns:
67 - !FileChecksums
68 Checksums:
69 - FileName: 'd:\b\ret42-main.c'
70 Kind: MD5
71 Checksum: C538722F63570DF6705DDE06FE96E5D1
72 - !StringTable
73 Strings:
74 - 'd:\b\ret42-main.c'
75 - !Symbols
76 Records:
77 - Kind: S_BUILDINFO
78 BuildInfoSym:
79 BuildId: 4110
80 Relocations:
81 - VirtualAddress: 140
82 SymbolName: main
83 Type: IMAGE_REL_AMD64_SECREL
84 - VirtualAddress: 144
85 SymbolName: main
86 Type: IMAGE_REL_AMD64_SECTION
87 - VirtualAddress: 196
88 SymbolName: main
89 Type: IMAGE_REL_AMD64_SECREL
90 - VirtualAddress: 200
91 SymbolName: main
92 Type: IMAGE_REL_AMD64_SECTION
93 - Name: '.debug$T'
94 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
95 Alignment: 1
96 Types:
97 - Kind: LF_ARGLIST
98 ArgList:
99 ArgIndices: [ ]
100 - Kind: LF_PROCEDURE
101 Procedure:
102 ReturnType: 116
103 CallConv: NearC
104 Options: [ None ]
105 ParameterCount: 0
106 ArgumentList: 4096
107 - Kind: LF_POINTER
108 Pointer:
109 ReferentType: 4097
110 Attrs: 65548
111 - Kind: LF_ARGLIST
112 ArgList:
113 ArgIndices: [ 0 ]
114 - Kind: LF_PROCEDURE
115 Procedure:
116 ReturnType: 116
117 CallConv: NearC
118 Options: [ None ]
119 ParameterCount: 0
120 ArgumentList: 4099
121 - Kind: LF_FUNC_ID
122 FuncId:
123 ParentScope: 0
124 FunctionType: 4100
125 Name: main
126 - Kind: LF_FUNC_ID
127 FuncId:
128 ParentScope: 0
129 FunctionType: 4097
130 Name: foo
131 - Kind: LF_STRING_ID
132 StringId:
133 Id: 0
134 String: 'D:\b'
135 - Kind: LF_STRING_ID
136 StringId:
137 Id: 0
138 String: 'C:\vs14\VC\BIN\amd64\cl.exe'
139 - Kind: LF_STRING_ID
140 StringId:
141 Id: 0
142 String: '-Z7 -c -MT -IC:\vs14\VC\INCLUDE -IC:\vs14\VC\ATLMFC\INCLUDE -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.10150.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\shared"'
143 - Kind: LF_SUBSTR_LIST
144 StringList:
145 StringIndices: [ 4105 ]
146 - Kind: LF_STRING_ID
147 StringId:
148 Id: 4106
149 String: ' -I"C:\Program Files (x86)\Windows Kits\8.1\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\winrt" -TC -X'
150 - Kind: LF_STRING_ID
151 StringId:
152 Id: 0
153 String: ret42-main.c
154 - Kind: LF_STRING_ID
155 StringId:
156 Id: 0
157 String: 'D:\b\vc140.pdb'
158 - Kind: LF_BUILDINFO
159 BuildInfo:
160 ArgIndices: [ 4103, 4104, 4108, 4109, 4107 ]
161 - Name: '.text$mn'
162 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
163 Alignment: 16
164 SectionData: 4883EC28E8000000004883C428C3
165 Relocations:
166 - VirtualAddress: 5
167 SymbolName: foo
168 Type: IMAGE_REL_AMD64_REL32
169 - Name: .xdata
170 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
171 Alignment: 4
172 SectionData: '0104010004420000'
173 - Name: .pdata
174 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
175 Alignment: 4
176 SectionData: '000000000E00000000000000'
177 Relocations:
178 - VirtualAddress: 0
179 SymbolName: '$LN3'
180 Type: IMAGE_REL_AMD64_ADDR32NB
181 - VirtualAddress: 4
182 SymbolName: '$LN3'
183 Type: IMAGE_REL_AMD64_ADDR32NB
184 - VirtualAddress: 8
185 SymbolName: '$unwind$main'
186 Type: IMAGE_REL_AMD64_ADDR32NB
187symbols:
188 - Name: '@comp.id'
189 Value: 17062386
190 SectionNumber: -1
191 SimpleType: IMAGE_SYM_TYPE_NULL
192 ComplexType: IMAGE_SYM_DTYPE_NULL
193 StorageClass: IMAGE_SYM_CLASS_STATIC
194 - Name: '@feat.00'
195 Value: 2147484048
196 SectionNumber: -1
197 SimpleType: IMAGE_SYM_TYPE_NULL
198 ComplexType: IMAGE_SYM_DTYPE_NULL
199 StorageClass: IMAGE_SYM_CLASS_STATIC
200 - Name: .drectve
201 Value: 0
202 SectionNumber: 1
203 SimpleType: IMAGE_SYM_TYPE_NULL
204 ComplexType: IMAGE_SYM_DTYPE_NULL
205 StorageClass: IMAGE_SYM_CLASS_STATIC
206 SectionDefinition:
207 Length: 47
208 NumberOfRelocations: 0
209 NumberOfLinenumbers: 0
210 CheckSum: 0
211 Number: 0
212 - Name: '.debug$S'
213 Value: 0
214 SectionNumber: 2
215 SimpleType: IMAGE_SYM_TYPE_NULL
216 ComplexType: IMAGE_SYM_DTYPE_NULL
217 StorageClass: IMAGE_SYM_CLASS_STATIC
218 SectionDefinition:
219 Length: 304
220 NumberOfRelocations: 4
221 NumberOfLinenumbers: 0
222 CheckSum: 0
223 Number: 0
224 - Name: '.debug$T'
225 Value: 0
226 SectionNumber: 3
227 SimpleType: IMAGE_SYM_TYPE_NULL
228 ComplexType: IMAGE_SYM_DTYPE_NULL
229 StorageClass: IMAGE_SYM_CLASS_STATIC
230 SectionDefinition:
231 Length: 636
232 NumberOfRelocations: 0
233 NumberOfLinenumbers: 0
234 CheckSum: 0
235 Number: 0
236 - Name: '.text$mn'
237 Value: 0
238 SectionNumber: 4
239 SimpleType: IMAGE_SYM_TYPE_NULL
240 ComplexType: IMAGE_SYM_DTYPE_NULL
241 StorageClass: IMAGE_SYM_CLASS_STATIC
242 SectionDefinition:
243 Length: 14
244 NumberOfRelocations: 1
245 NumberOfLinenumbers: 0
246 CheckSum: 1682752513
247 Number: 0
248 - Name: foo
249 Value: 0
250 SectionNumber: 0
251 SimpleType: IMAGE_SYM_TYPE_NULL
252 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
253 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
254 - Name: main
255 Value: 0
256 SectionNumber: 4
257 SimpleType: IMAGE_SYM_TYPE_NULL
258 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
259 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
260 - Name: '$LN3'
261 Value: 0
262 SectionNumber: 4
263 SimpleType: IMAGE_SYM_TYPE_NULL
264 ComplexType: IMAGE_SYM_DTYPE_NULL
265 StorageClass: IMAGE_SYM_CLASS_LABEL
266 - Name: .xdata
267 Value: 0
268 SectionNumber: 5
269 SimpleType: IMAGE_SYM_TYPE_NULL
270 ComplexType: IMAGE_SYM_DTYPE_NULL
271 StorageClass: IMAGE_SYM_CLASS_STATIC
272 SectionDefinition:
273 Length: 8
274 NumberOfRelocations: 0
275 NumberOfLinenumbers: 0
276 CheckSum: 264583633
277 Number: 0
278 - Name: '$unwind$main'
279 Value: 0
280 SectionNumber: 5
281 SimpleType: IMAGE_SYM_TYPE_NULL
282 ComplexType: IMAGE_SYM_DTYPE_NULL
283 StorageClass: IMAGE_SYM_CLASS_STATIC
284 - Name: .pdata
285 Value: 0
286 SectionNumber: 6
287 SimpleType: IMAGE_SYM_TYPE_NULL
288 ComplexType: IMAGE_SYM_DTYPE_NULL
289 StorageClass: IMAGE_SYM_CLASS_STATIC
290 SectionDefinition:
291 Length: 12
292 NumberOfRelocations: 3
293 NumberOfLinenumbers: 0
294 CheckSum: 361370162
295 Number: 0
296 - Name: '$pdata$main'
297 Value: 0
298 SectionNumber: 6
299 SimpleType: IMAGE_SYM_TYPE_NULL
300 ComplexType: IMAGE_SYM_DTYPE_NULL
301 StorageClass: IMAGE_SYM_CLASS_STATIC
302...
deps/lld/test/COFF/Inputs/pdb2.yaml created+217
......@@ -0,0 +1,217 @@
1--- !COFF
2header:
3 Machine: IMAGE_FILE_MACHINE_AMD64
4 Characteristics: [ ]
5sections:
6 - Name: .drectve
7 Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
8 Alignment: 1
9 SectionData: 2020202F44454641554C544C49423A224C4942434D5422202F44454641554C544C49423A224F4C444E414D45532220
10 - Name: '.debug$S'
11 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
12 Alignment: 1
13 Subsections:
14 - !Symbols
15 Records:
16 - Kind: S_OBJNAME
17 ObjNameSym:
18 Signature: 0
19 ObjectName: 'D:\b\ret42-sub.obj'
20 - Kind: S_COMPILE3
21 Compile3Sym:
22 Flags: [ SecurityChecks, HotPatch ]
23 Machine: X64
24 FrontendMajor: 19
25 FrontendMinor: 0
26 FrontendBuild: 23026
27 FrontendQFE: 0
28 BackendMajor: 19
29 BackendMinor: 0
30 BackendBuild: 23026
31 BackendQFE: 0
32 Version: 'Microsoft (R) Optimizing Compiler'
33 - !Symbols
34 Records:
35 - Kind: S_GPROC32_ID
36 ProcSym:
37 PtrParent: 0
38 PtrEnd: 0
39 PtrNext: 0
40 CodeSize: 6
41 DbgStart: 0
42 DbgEnd: 5
43 FunctionType: 4098
44 Segment: 0
45 Flags: [ ]
46 DisplayName: foo
47 - Kind: S_FRAMEPROC
48 FrameProcSym:
49 TotalFrameBytes: 0
50 PaddingFrameBytes: 0
51 OffsetToPadding: 0
52 BytesOfCalleeSavedRegisters: 0
53 OffsetOfExceptionHandler: 0
54 SectionIdOfExceptionHandler: 0
55 Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ]
56 - Kind: S_PROC_ID_END
57 ScopeEndSym:
58 - !Lines
59 CodeSize: 6
60 Flags: [ ]
61 RelocOffset: 0
62 RelocSegment: 0
63 Blocks:
64 - FileName: 'd:\b\ret42-sub.c'
65 Lines:
66 - Offset: 0
67 LineStart: 1
68 IsStatement: true
69 EndDelta: 0
70 Columns:
71 - !FileChecksums
72 Checksums:
73 - FileName: 'd:\b\ret42-sub.c'
74 Kind: MD5
75 Checksum: EC2D89EFF5A1FEB6B74EE4D79074072F
76 - !StringTable
77 Strings:
78 - 'd:\b\ret42-sub.c'
79 - !Symbols
80 Records:
81 - Kind: S_BUILDINFO
82 BuildInfoSym:
83 BuildId: 4106
84 Relocations:
85 - VirtualAddress: 140
86 SymbolName: foo
87 Type: IMAGE_REL_AMD64_SECREL
88 - VirtualAddress: 144
89 SymbolName: foo
90 Type: IMAGE_REL_AMD64_SECTION
91 - VirtualAddress: 196
92 SymbolName: foo
93 Type: IMAGE_REL_AMD64_SECREL
94 - VirtualAddress: 200
95 SymbolName: foo
96 Type: IMAGE_REL_AMD64_SECTION
97 - Name: '.debug$T'
98 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
99 Alignment: 1
100 Types:
101 - Kind: LF_ARGLIST
102 ArgList:
103 ArgIndices: [ ]
104 - Kind: LF_PROCEDURE
105 Procedure:
106 ReturnType: 116
107 CallConv: NearC
108 Options: [ None ]
109 ParameterCount: 0
110 ArgumentList: 4096
111 - Kind: LF_FUNC_ID
112 FuncId:
113 ParentScope: 0
114 FunctionType: 4097
115 Name: foo
116 - Kind: LF_STRING_ID
117 StringId:
118 Id: 0
119 String: 'D:\b'
120 - Kind: LF_STRING_ID
121 StringId:
122 Id: 0
123 String: 'C:\vs14\VC\BIN\amd64\cl.exe'
124 - Kind: LF_STRING_ID
125 StringId:
126 Id: 0
127 String: '-Z7 -c -MT -IC:\vs14\VC\INCLUDE -IC:\vs14\VC\ATLMFC\INCLUDE -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.10150.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\shared"'
128 - Kind: LF_SUBSTR_LIST
129 StringList:
130 StringIndices: [ 4101 ]
131 - Kind: LF_STRING_ID
132 StringId:
133 Id: 4102
134 String: ' -I"C:\Program Files (x86)\Windows Kits\8.1\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\winrt" -TC -X'
135 - Kind: LF_STRING_ID
136 StringId:
137 Id: 0
138 String: ret42-sub.c
139 - Kind: LF_STRING_ID
140 StringId:
141 Id: 0
142 String: 'D:\b\vc140.pdb'
143 - Kind: LF_BUILDINFO
144 BuildInfo:
145 ArgIndices: [ 4099, 4100, 4104, 4105, 4103 ]
146 - Name: '.text$mn'
147 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
148 Alignment: 16
149 SectionData: B82A000000C3
150symbols:
151 - Name: '@comp.id'
152 Value: 17062386
153 SectionNumber: -1
154 SimpleType: IMAGE_SYM_TYPE_NULL
155 ComplexType: IMAGE_SYM_DTYPE_NULL
156 StorageClass: IMAGE_SYM_CLASS_STATIC
157 - Name: '@feat.00'
158 Value: 2147484048
159 SectionNumber: -1
160 SimpleType: IMAGE_SYM_TYPE_NULL
161 ComplexType: IMAGE_SYM_DTYPE_NULL
162 StorageClass: IMAGE_SYM_CLASS_STATIC
163 - Name: .drectve
164 Value: 0
165 SectionNumber: 1
166 SimpleType: IMAGE_SYM_TYPE_NULL
167 ComplexType: IMAGE_SYM_DTYPE_NULL
168 StorageClass: IMAGE_SYM_CLASS_STATIC
169 SectionDefinition:
170 Length: 47
171 NumberOfRelocations: 0
172 NumberOfLinenumbers: 0
173 CheckSum: 0
174 Number: 0
175 - Name: '.debug$S'
176 Value: 0
177 SectionNumber: 2
178 SimpleType: IMAGE_SYM_TYPE_NULL
179 ComplexType: IMAGE_SYM_DTYPE_NULL
180 StorageClass: IMAGE_SYM_CLASS_STATIC
181 SectionDefinition:
182 Length: 304
183 NumberOfRelocations: 4
184 NumberOfLinenumbers: 0
185 CheckSum: 0
186 Number: 0
187 - Name: '.debug$T'
188 Value: 0
189 SectionNumber: 3
190 SimpleType: IMAGE_SYM_TYPE_NULL
191 ComplexType: IMAGE_SYM_DTYPE_NULL
192 StorageClass: IMAGE_SYM_CLASS_STATIC
193 SectionDefinition:
194 Length: 572
195 NumberOfRelocations: 0
196 NumberOfLinenumbers: 0
197 CheckSum: 0
198 Number: 0
199 - Name: '.text$mn'
200 Value: 0
201 SectionNumber: 4
202 SimpleType: IMAGE_SYM_TYPE_NULL
203 ComplexType: IMAGE_SYM_DTYPE_NULL
204 StorageClass: IMAGE_SYM_CLASS_STATIC
205 SectionDefinition:
206 Length: 6
207 NumberOfRelocations: 0
208 NumberOfLinenumbers: 0
209 CheckSum: 2139436471
210 Number: 0
211 - Name: foo
212 Value: 0
213 SectionNumber: 4
214 SimpleType: IMAGE_SYM_TYPE_NULL
215 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
216 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
217...
deps/lld/test/COFF/Inputs/pdb_comdat_bar.yaml created+440
......@@ -0,0 +1,440 @@
1--- !COFF
2header:
3 Machine: IMAGE_FILE_MACHINE_AMD64
4 Characteristics: [ ]
5sections:
6 - Name: .drectve
7 Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
8 Alignment: 1
9 SectionData: 2020202F44454641554C544C49423A224C4942434D5422202F44454641554C544C49423A224F4C444E414D45532220
10 - Name: '.debug$S'
11 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
12 Alignment: 1
13 Subsections:
14 - !Symbols
15 Records:
16 - Kind: S_OBJNAME
17 ObjNameSym:
18 Signature: 0
19 ObjectName: 'C:\src\llvm-project\build\pdb_comdat_bar.obj'
20 - Kind: S_COMPILE3
21 Compile3Sym:
22 Flags: [ SecurityChecks, HotPatch ]
23 Machine: X64
24 FrontendMajor: 19
25 FrontendMinor: 0
26 FrontendBuild: 24215
27 FrontendQFE: 1
28 BackendMajor: 19
29 BackendMinor: 0
30 BackendBuild: 24215
31 BackendQFE: 1
32 Version: 'Microsoft (R) Optimizing Compiler'
33 - !Symbols
34 Records:
35 - Kind: S_GPROC32_ID
36 ProcSym:
37 PtrParent: 0
38 PtrEnd: 0
39 PtrNext: 0
40 CodeSize: 14
41 DbgStart: 4
42 DbgEnd: 9
43 FunctionType: 4102
44 Segment: 0
45 Flags: [ ]
46 DisplayName: bar
47 - Kind: S_FRAMEPROC
48 FrameProcSym:
49 TotalFrameBytes: 40
50 PaddingFrameBytes: 0
51 OffsetToPadding: 0
52 BytesOfCalleeSavedRegisters: 0
53 OffsetOfExceptionHandler: 0
54 SectionIdOfExceptionHandler: 0
55 Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ]
56 - Kind: S_PROC_ID_END
57 ScopeEndSym:
58 - !Lines
59 CodeSize: 14
60 Flags: [ ]
61 RelocOffset: 0
62 RelocSegment: 0
63 Blocks:
64 - FileName: 'c:\src\llvm-project\build\pdb_comdat_bar.c'
65 Lines:
66 - Offset: 0
67 LineStart: 3
68 IsStatement: true
69 EndDelta: 0
70 - Offset: 4
71 LineStart: 4
72 IsStatement: true
73 EndDelta: 0
74 - Offset: 9
75 LineStart: 5
76 IsStatement: true
77 EndDelta: 0
78 Columns:
79 - !Symbols
80 Records:
81 - Kind: S_GDATA32
82 DataSym:
83 Type: 116
84 DisplayName: global
85 - !FileChecksums
86 Checksums:
87 - FileName: 'c:\src\llvm-project\build\pdb_comdat_bar.c'
88 Kind: MD5
89 Checksum: 365279DB4FCBEDD721BBFC3B14A953C2
90 - FileName: 'c:\src\llvm-project\build\foo.h'
91 Kind: MD5
92 Checksum: D74D834EFAC3AE2B45E606A8320B1D5C
93 - !StringTable
94 Strings:
95 - 'c:\src\llvm-project\build\pdb_comdat_bar.c'
96 - 'c:\src\llvm-project\build\foo.h'
97 - !Symbols
98 Records:
99 - Kind: S_BUILDINFO
100 BuildInfoSym:
101 BuildId: 4110
102 Relocations:
103 - VirtualAddress: 168
104 SymbolName: bar
105 Type: IMAGE_REL_AMD64_SECREL
106 - VirtualAddress: 172
107 SymbolName: bar
108 Type: IMAGE_REL_AMD64_SECTION
109 - VirtualAddress: 224
110 SymbolName: bar
111 Type: IMAGE_REL_AMD64_SECREL
112 - VirtualAddress: 228
113 SymbolName: bar
114 Type: IMAGE_REL_AMD64_SECTION
115 - VirtualAddress: 288
116 SymbolName: global
117 Type: IMAGE_REL_AMD64_SECREL
118 - VirtualAddress: 292
119 SymbolName: global
120 Type: IMAGE_REL_AMD64_SECTION
121 - Name: '.debug$T'
122 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
123 Alignment: 1
124 Types:
125 - Kind: LF_ARGLIST
126 ArgList:
127 ArgIndices: [ 0 ]
128 - Kind: LF_PROCEDURE
129 Procedure:
130 ReturnType: 3
131 CallConv: NearC
132 Options: [ None ]
133 ParameterCount: 0
134 ArgumentList: 4096
135 - Kind: LF_POINTER
136 Pointer:
137 ReferentType: 4097
138 Attrs: 65548
139 - Kind: LF_FUNC_ID
140 FuncId:
141 ParentScope: 0
142 FunctionType: 4097
143 Name: foo
144 - Kind: LF_ARGLIST
145 ArgList:
146 ArgIndices: [ ]
147 - Kind: LF_PROCEDURE
148 Procedure:
149 ReturnType: 3
150 CallConv: NearC
151 Options: [ None ]
152 ParameterCount: 0
153 ArgumentList: 4100
154 - Kind: LF_FUNC_ID
155 FuncId:
156 ParentScope: 0
157 FunctionType: 4101
158 Name: bar
159 - Kind: LF_STRING_ID
160 StringId:
161 Id: 0
162 String: 'C:\src\llvm-project\build'
163 - Kind: LF_STRING_ID
164 StringId:
165 Id: 0
166 String: 'C:\PROGRA~2\MICROS~1.0\VC\Bin\amd64\cl.exe'
167 - Kind: LF_STRING_ID
168 StringId:
169 Id: 0
170 String: '-c -Z7 -MT -IC:\PROGRA~2\MICROS~1.0\VC\include -IC:\PROGRA~2\MICROS~1.0\VC\atlmfc\include -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\ucrt -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\shared -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\um'
171 - Kind: LF_SUBSTR_LIST
172 StringList:
173 StringIndices: [ 4105 ]
174 - Kind: LF_STRING_ID
175 StringId:
176 Id: 4106
177 String: ' -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\winrt -TC -X'
178 - Kind: LF_STRING_ID
179 StringId:
180 Id: 0
181 String: pdb_comdat_bar.c
182 - Kind: LF_STRING_ID
183 StringId:
184 Id: 0
185 String: 'C:\src\llvm-project\build\vc140.pdb'
186 - Kind: LF_BUILDINFO
187 BuildInfo:
188 ArgIndices: [ 4103, 4104, 4108, 4109, 4107 ]
189 - Name: .bss
190 Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
191 Alignment: 4
192 SectionData: ''
193 - Name: '.text$mn'
194 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
195 Alignment: 16
196 SectionData: 4883EC28E8000000004883C428C3
197 Relocations:
198 - VirtualAddress: 5
199 SymbolName: foo
200 Type: IMAGE_REL_AMD64_REL32
201 - Name: '.text$mn'
202 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
203 Alignment: 16
204 SectionData: 8B0500000000FFC0890500000000C3
205 Relocations:
206 - VirtualAddress: 2
207 SymbolName: global
208 Type: IMAGE_REL_AMD64_REL32
209 - VirtualAddress: 10
210 SymbolName: global
211 Type: IMAGE_REL_AMD64_REL32
212 - Name: '.debug$S'
213 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
214 Alignment: 1
215 Subsections:
216 - !Symbols
217 Records:
218 - Kind: S_GPROC32_ID
219 ProcSym:
220 PtrParent: 0
221 PtrEnd: 0
222 PtrNext: 0
223 CodeSize: 15
224 DbgStart: 0
225 DbgEnd: 14
226 FunctionType: 4099
227 Segment: 0
228 Flags: [ ]
229 DisplayName: foo
230 - Kind: S_FRAMEPROC
231 FrameProcSym:
232 TotalFrameBytes: 0
233 PaddingFrameBytes: 0
234 OffsetToPadding: 0
235 BytesOfCalleeSavedRegisters: 0
236 OffsetOfExceptionHandler: 0
237 SectionIdOfExceptionHandler: 0
238 Flags: [ MarkedInline, AsynchronousExceptionHandling, OptimizedForSpeed ]
239 - Kind: S_PROC_ID_END
240 ScopeEndSym:
241 - !Lines
242 CodeSize: 15
243 Flags: [ ]
244 RelocOffset: 0
245 RelocSegment: 0
246 Blocks:
247 - FileName: 'c:\src\llvm-project\build\foo.h'
248 Lines:
249 - Offset: 0
250 LineStart: 2
251 IsStatement: true
252 EndDelta: 0
253 - Offset: 0
254 LineStart: 3
255 IsStatement: true
256 EndDelta: 0
257 - Offset: 14
258 LineStart: 4
259 IsStatement: true
260 EndDelta: 0
261 Columns:
262 Relocations:
263 - VirtualAddress: 44
264 SymbolName: foo
265 Type: IMAGE_REL_AMD64_SECREL
266 - VirtualAddress: 48
267 SymbolName: foo
268 Type: IMAGE_REL_AMD64_SECTION
269 - VirtualAddress: 100
270 SymbolName: foo
271 Type: IMAGE_REL_AMD64_SECREL
272 - VirtualAddress: 104
273 SymbolName: foo
274 Type: IMAGE_REL_AMD64_SECTION
275 - Name: .xdata
276 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
277 Alignment: 4
278 SectionData: '0104010004420000'
279 - Name: .pdata
280 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
281 Alignment: 4
282 SectionData: '000000000E00000000000000'
283 Relocations:
284 - VirtualAddress: 0
285 SymbolName: '$LN3'
286 Type: IMAGE_REL_AMD64_ADDR32NB
287 - VirtualAddress: 4
288 SymbolName: '$LN3'
289 Type: IMAGE_REL_AMD64_ADDR32NB
290 - VirtualAddress: 8
291 SymbolName: '$unwind$bar'
292 Type: IMAGE_REL_AMD64_ADDR32NB
293symbols:
294 - Name: .drectve
295 Value: 0
296 SectionNumber: 1
297 SimpleType: IMAGE_SYM_TYPE_NULL
298 ComplexType: IMAGE_SYM_DTYPE_NULL
299 StorageClass: IMAGE_SYM_CLASS_STATIC
300 SectionDefinition:
301 Length: 47
302 NumberOfRelocations: 0
303 NumberOfLinenumbers: 0
304 CheckSum: 0
305 Number: 0
306 - Name: '.debug$S'
307 Value: 0
308 SectionNumber: 2
309 SimpleType: IMAGE_SYM_TYPE_NULL
310 ComplexType: IMAGE_SYM_DTYPE_NULL
311 StorageClass: IMAGE_SYM_CLASS_STATIC
312 SectionDefinition:
313 Length: 460
314 NumberOfRelocations: 6
315 NumberOfLinenumbers: 0
316 CheckSum: 0
317 Number: 0
318 - Name: '.debug$T'
319 Value: 0
320 SectionNumber: 3
321 SimpleType: IMAGE_SYM_TYPE_NULL
322 ComplexType: IMAGE_SYM_DTYPE_NULL
323 StorageClass: IMAGE_SYM_CLASS_STATIC
324 SectionDefinition:
325 Length: 628
326 NumberOfRelocations: 0
327 NumberOfLinenumbers: 0
328 CheckSum: 0
329 Number: 0
330 - Name: .bss
331 Value: 0
332 SectionNumber: 4
333 SimpleType: IMAGE_SYM_TYPE_NULL
334 ComplexType: IMAGE_SYM_DTYPE_NULL
335 StorageClass: IMAGE_SYM_CLASS_STATIC
336 SectionDefinition:
337 Length: 4
338 NumberOfRelocations: 0
339 NumberOfLinenumbers: 0
340 CheckSum: 0
341 Number: 0
342 - Name: global
343 Value: 0
344 SectionNumber: 4
345 SimpleType: IMAGE_SYM_TYPE_NULL
346 ComplexType: IMAGE_SYM_DTYPE_NULL
347 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
348 - Name: '.text$mn'
349 Value: 0
350 SectionNumber: 5
351 SimpleType: IMAGE_SYM_TYPE_NULL
352 ComplexType: IMAGE_SYM_DTYPE_NULL
353 StorageClass: IMAGE_SYM_CLASS_STATIC
354 SectionDefinition:
355 Length: 14
356 NumberOfRelocations: 1
357 NumberOfLinenumbers: 0
358 CheckSum: 1682752513
359 Number: 0
360 - Name: '.text$mn'
361 Value: 0
362 SectionNumber: 6
363 SimpleType: IMAGE_SYM_TYPE_NULL
364 ComplexType: IMAGE_SYM_DTYPE_NULL
365 StorageClass: IMAGE_SYM_CLASS_STATIC
366 SectionDefinition:
367 Length: 15
368 NumberOfRelocations: 2
369 NumberOfLinenumbers: 0
370 CheckSum: 1746394828
371 Number: 0
372 Selection: IMAGE_COMDAT_SELECT_ANY
373 - Name: '.debug$S'
374 Value: 0
375 SectionNumber: 7
376 SimpleType: IMAGE_SYM_TYPE_NULL
377 ComplexType: IMAGE_SYM_DTYPE_NULL
378 StorageClass: IMAGE_SYM_CLASS_STATIC
379 SectionDefinition:
380 Length: 148
381 NumberOfRelocations: 4
382 NumberOfLinenumbers: 0
383 CheckSum: 0
384 Number: 6
385 Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
386 - Name: foo
387 Value: 0
388 SectionNumber: 6
389 SimpleType: IMAGE_SYM_TYPE_NULL
390 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
391 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
392 - Name: bar
393 Value: 0
394 SectionNumber: 5
395 SimpleType: IMAGE_SYM_TYPE_NULL
396 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
397 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
398 - Name: '$LN3'
399 Value: 0
400 SectionNumber: 5
401 SimpleType: IMAGE_SYM_TYPE_NULL
402 ComplexType: IMAGE_SYM_DTYPE_NULL
403 StorageClass: IMAGE_SYM_CLASS_LABEL
404 - Name: .xdata
405 Value: 0
406 SectionNumber: 8
407 SimpleType: IMAGE_SYM_TYPE_NULL
408 ComplexType: IMAGE_SYM_DTYPE_NULL
409 StorageClass: IMAGE_SYM_CLASS_STATIC
410 SectionDefinition:
411 Length: 8
412 NumberOfRelocations: 0
413 NumberOfLinenumbers: 0
414 CheckSum: 264583633
415 Number: 0
416 - Name: '$unwind$bar'
417 Value: 0
418 SectionNumber: 8
419 SimpleType: IMAGE_SYM_TYPE_NULL
420 ComplexType: IMAGE_SYM_DTYPE_NULL
421 StorageClass: IMAGE_SYM_CLASS_STATIC
422 - Name: .pdata
423 Value: 0
424 SectionNumber: 9
425 SimpleType: IMAGE_SYM_TYPE_NULL
426 ComplexType: IMAGE_SYM_DTYPE_NULL
427 StorageClass: IMAGE_SYM_CLASS_STATIC
428 SectionDefinition:
429 Length: 12
430 NumberOfRelocations: 3
431 NumberOfLinenumbers: 0
432 CheckSum: 361370162
433 Number: 0
434 - Name: '$pdata$bar'
435 Value: 0
436 SectionNumber: 9
437 SimpleType: IMAGE_SYM_TYPE_NULL
438 ComplexType: IMAGE_SYM_DTYPE_NULL
439 StorageClass: IMAGE_SYM_CLASS_STATIC
440...
deps/lld/test/COFF/Inputs/pdb_comdat_main.yaml created+446
......@@ -0,0 +1,446 @@
1--- !COFF
2header:
3 Machine: IMAGE_FILE_MACHINE_AMD64
4 Characteristics: [ ]
5sections:
6 - Name: .drectve
7 Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
8 Alignment: 1
9 SectionData: 2020202F44454641554C544C49423A224C4942434D5422202F44454641554C544C49423A224F4C444E414D45532220
10 - Name: '.debug$S'
11 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
12 Alignment: 1
13 Subsections:
14 - !Symbols
15 Records:
16 - Kind: S_OBJNAME
17 ObjNameSym:
18 Signature: 0
19 ObjectName: 'C:\src\llvm-project\build\pdb_comdat_main.obj'
20 - Kind: S_COMPILE3
21 Compile3Sym:
22 Flags: [ SecurityChecks, HotPatch ]
23 Machine: X64
24 FrontendMajor: 19
25 FrontendMinor: 0
26 FrontendBuild: 24215
27 FrontendQFE: 1
28 BackendMajor: 19
29 BackendMinor: 0
30 BackendBuild: 24215
31 BackendQFE: 1
32 Version: 'Microsoft (R) Optimizing Compiler'
33 - !Symbols
34 Records:
35 - Kind: S_GPROC32_ID
36 ProcSym:
37 PtrParent: 0
38 PtrEnd: 0
39 PtrNext: 0
40 CodeSize: 24
41 DbgStart: 4
42 DbgEnd: 19
43 FunctionType: 4102
44 Segment: 0
45 Flags: [ ]
46 DisplayName: main
47 - Kind: S_FRAMEPROC
48 FrameProcSym:
49 TotalFrameBytes: 40
50 PaddingFrameBytes: 0
51 OffsetToPadding: 0
52 BytesOfCalleeSavedRegisters: 0
53 OffsetOfExceptionHandler: 0
54 SectionIdOfExceptionHandler: 0
55 Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ]
56 - Kind: S_PROC_ID_END
57 ScopeEndSym:
58 - !Lines
59 CodeSize: 24
60 Flags: [ ]
61 RelocOffset: 0
62 RelocSegment: 0
63 Blocks:
64 - FileName: 'c:\src\llvm-project\build\pdb_comdat_main.c'
65 Lines:
66 - Offset: 0
67 LineStart: 2
68 IsStatement: true
69 EndDelta: 0
70 - Offset: 4
71 LineStart: 3
72 IsStatement: true
73 EndDelta: 0
74 - Offset: 9
75 LineStart: 4
76 IsStatement: true
77 EndDelta: 0
78 - Offset: 14
79 LineStart: 5
80 IsStatement: true
81 EndDelta: 0
82 - Offset: 19
83 LineStart: 6
84 IsStatement: true
85 EndDelta: 0
86 Columns:
87 - !Symbols
88 Records:
89 - Kind: S_GDATA32
90 DataSym:
91 Type: 116
92 DisplayName: global
93 - !FileChecksums
94 Checksums:
95 - FileName: 'c:\src\llvm-project\build\pdb_comdat_main.c'
96 Kind: MD5
97 Checksum: F969E51BBE373436D81492EB61387F36
98 - FileName: 'c:\src\llvm-project\build\foo.h'
99 Kind: MD5
100 Checksum: D74D834EFAC3AE2B45E606A8320B1D5C
101 - !StringTable
102 Strings:
103 - 'c:\src\llvm-project\build\pdb_comdat_main.c'
104 - 'c:\src\llvm-project\build\foo.h'
105 - !Symbols
106 Records:
107 - Kind: S_BUILDINFO
108 BuildInfoSym:
109 BuildId: 4111
110 Relocations:
111 - VirtualAddress: 168
112 SymbolName: main
113 Type: IMAGE_REL_AMD64_SECREL
114 - VirtualAddress: 172
115 SymbolName: main
116 Type: IMAGE_REL_AMD64_SECTION
117 - VirtualAddress: 224
118 SymbolName: main
119 Type: IMAGE_REL_AMD64_SECREL
120 - VirtualAddress: 228
121 SymbolName: main
122 Type: IMAGE_REL_AMD64_SECTION
123 - VirtualAddress: 304
124 SymbolName: global
125 Type: IMAGE_REL_AMD64_SECREL
126 - VirtualAddress: 308
127 SymbolName: global
128 Type: IMAGE_REL_AMD64_SECTION
129 - Name: '.debug$T'
130 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
131 Alignment: 1
132 Types:
133 - Kind: LF_ARGLIST
134 ArgList:
135 ArgIndices: [ 0 ]
136 - Kind: LF_PROCEDURE
137 Procedure:
138 ReturnType: 3
139 CallConv: NearC
140 Options: [ None ]
141 ParameterCount: 0
142 ArgumentList: 4096
143 - Kind: LF_POINTER
144 Pointer:
145 ReferentType: 4097
146 Attrs: 65548
147 - Kind: LF_FUNC_ID
148 FuncId:
149 ParentScope: 0
150 FunctionType: 4097
151 Name: foo
152 - Kind: LF_ARGLIST
153 ArgList:
154 ArgIndices: [ ]
155 - Kind: LF_PROCEDURE
156 Procedure:
157 ReturnType: 116
158 CallConv: NearC
159 Options: [ None ]
160 ParameterCount: 0
161 ArgumentList: 4100
162 - Kind: LF_FUNC_ID
163 FuncId:
164 ParentScope: 0
165 FunctionType: 4101
166 Name: main
167 - Kind: LF_FUNC_ID
168 FuncId:
169 ParentScope: 0
170 FunctionType: 4097
171 Name: bar
172 - Kind: LF_STRING_ID
173 StringId:
174 Id: 0
175 String: 'C:\src\llvm-project\build'
176 - Kind: LF_STRING_ID
177 StringId:
178 Id: 0
179 String: 'C:\PROGRA~2\MICROS~1.0\VC\Bin\amd64\cl.exe'
180 - Kind: LF_STRING_ID
181 StringId:
182 Id: 0
183 String: '-c -Z7 -MT -IC:\PROGRA~2\MICROS~1.0\VC\include -IC:\PROGRA~2\MICROS~1.0\VC\atlmfc\include -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\ucrt -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\shared -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\um'
184 - Kind: LF_SUBSTR_LIST
185 StringList:
186 StringIndices: [ 4106 ]
187 - Kind: LF_STRING_ID
188 StringId:
189 Id: 4107
190 String: ' -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\winrt -TC -X'
191 - Kind: LF_STRING_ID
192 StringId:
193 Id: 0
194 String: pdb_comdat_main.c
195 - Kind: LF_STRING_ID
196 StringId:
197 Id: 0
198 String: 'C:\src\llvm-project\build\vc140.pdb'
199 - Kind: LF_BUILDINFO
200 BuildInfo:
201 ArgIndices: [ 4104, 4105, 4109, 4110, 4108 ]
202 - Name: '.text$mn'
203 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
204 Alignment: 16
205 SectionData: 4883EC28E800000000E800000000B82A0000004883C428C3
206 Relocations:
207 - VirtualAddress: 5
208 SymbolName: foo
209 Type: IMAGE_REL_AMD64_REL32
210 - VirtualAddress: 10
211 SymbolName: bar
212 Type: IMAGE_REL_AMD64_REL32
213 - Name: '.text$mn'
214 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
215 Alignment: 16
216 SectionData: 8B0500000000FFC0890500000000C3
217 Relocations:
218 - VirtualAddress: 2
219 SymbolName: global
220 Type: IMAGE_REL_AMD64_REL32
221 - VirtualAddress: 10
222 SymbolName: global
223 Type: IMAGE_REL_AMD64_REL32
224 - Name: '.debug$S'
225 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
226 Alignment: 1
227 Subsections:
228 - !Symbols
229 Records:
230 - Kind: S_GPROC32_ID
231 ProcSym:
232 PtrParent: 0
233 PtrEnd: 0
234 PtrNext: 0
235 CodeSize: 15
236 DbgStart: 0
237 DbgEnd: 14
238 FunctionType: 4099
239 Segment: 0
240 Flags: [ ]
241 DisplayName: foo
242 - Kind: S_FRAMEPROC
243 FrameProcSym:
244 TotalFrameBytes: 0
245 PaddingFrameBytes: 0
246 OffsetToPadding: 0
247 BytesOfCalleeSavedRegisters: 0
248 OffsetOfExceptionHandler: 0
249 SectionIdOfExceptionHandler: 0
250 Flags: [ MarkedInline, AsynchronousExceptionHandling, OptimizedForSpeed ]
251 - Kind: S_PROC_ID_END
252 ScopeEndSym:
253 - !Lines
254 CodeSize: 15
255 Flags: [ ]
256 RelocOffset: 0
257 RelocSegment: 0
258 Blocks:
259 - FileName: 'c:\src\llvm-project\build\foo.h'
260 Lines:
261 - Offset: 0
262 LineStart: 2
263 IsStatement: true
264 EndDelta: 0
265 - Offset: 0
266 LineStart: 3
267 IsStatement: true
268 EndDelta: 0
269 - Offset: 14
270 LineStart: 4
271 IsStatement: true
272 EndDelta: 0
273 Columns:
274 Relocations:
275 - VirtualAddress: 44
276 SymbolName: foo
277 Type: IMAGE_REL_AMD64_SECREL
278 - VirtualAddress: 48
279 SymbolName: foo
280 Type: IMAGE_REL_AMD64_SECTION
281 - VirtualAddress: 100
282 SymbolName: foo
283 Type: IMAGE_REL_AMD64_SECREL
284 - VirtualAddress: 104
285 SymbolName: foo
286 Type: IMAGE_REL_AMD64_SECTION
287 - Name: .xdata
288 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
289 Alignment: 4
290 SectionData: '0104010004420000'
291 - Name: .pdata
292 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
293 Alignment: 4
294 SectionData: '000000001800000000000000'
295 Relocations:
296 - VirtualAddress: 0
297 SymbolName: '$LN3'
298 Type: IMAGE_REL_AMD64_ADDR32NB
299 - VirtualAddress: 4
300 SymbolName: '$LN3'
301 Type: IMAGE_REL_AMD64_ADDR32NB
302 - VirtualAddress: 8
303 SymbolName: '$unwind$main'
304 Type: IMAGE_REL_AMD64_ADDR32NB
305symbols:
306 - Name: .drectve
307 Value: 0
308 SectionNumber: 1
309 SimpleType: IMAGE_SYM_TYPE_NULL
310 ComplexType: IMAGE_SYM_DTYPE_NULL
311 StorageClass: IMAGE_SYM_CLASS_STATIC
312 SectionDefinition:
313 Length: 47
314 NumberOfRelocations: 0
315 NumberOfLinenumbers: 0
316 CheckSum: 0
317 Number: 0
318 - Name: '.debug$S'
319 Value: 0
320 SectionNumber: 2
321 SimpleType: IMAGE_SYM_TYPE_NULL
322 ComplexType: IMAGE_SYM_DTYPE_NULL
323 StorageClass: IMAGE_SYM_CLASS_STATIC
324 SectionDefinition:
325 Length: 480
326 NumberOfRelocations: 6
327 NumberOfLinenumbers: 0
328 CheckSum: 0
329 Number: 0
330 - Name: '.debug$T'
331 Value: 0
332 SectionNumber: 3
333 SimpleType: IMAGE_SYM_TYPE_NULL
334 ComplexType: IMAGE_SYM_DTYPE_NULL
335 StorageClass: IMAGE_SYM_CLASS_STATIC
336 SectionDefinition:
337 Length: 648
338 NumberOfRelocations: 0
339 NumberOfLinenumbers: 0
340 CheckSum: 0
341 Number: 0
342 - Name: '.text$mn'
343 Value: 0
344 SectionNumber: 4
345 SimpleType: IMAGE_SYM_TYPE_NULL
346 ComplexType: IMAGE_SYM_DTYPE_NULL
347 StorageClass: IMAGE_SYM_CLASS_STATIC
348 SectionDefinition:
349 Length: 24
350 NumberOfRelocations: 2
351 NumberOfLinenumbers: 0
352 CheckSum: 492663294
353 Number: 0
354 - Name: '.text$mn'
355 Value: 0
356 SectionNumber: 5
357 SimpleType: IMAGE_SYM_TYPE_NULL
358 ComplexType: IMAGE_SYM_DTYPE_NULL
359 StorageClass: IMAGE_SYM_CLASS_STATIC
360 SectionDefinition:
361 Length: 15
362 NumberOfRelocations: 2
363 NumberOfLinenumbers: 0
364 CheckSum: 1746394828
365 Number: 0
366 Selection: IMAGE_COMDAT_SELECT_ANY
367 - Name: '.debug$S'
368 Value: 0
369 SectionNumber: 6
370 SimpleType: IMAGE_SYM_TYPE_NULL
371 ComplexType: IMAGE_SYM_DTYPE_NULL
372 StorageClass: IMAGE_SYM_CLASS_STATIC
373 SectionDefinition:
374 Length: 148
375 NumberOfRelocations: 4
376 NumberOfLinenumbers: 0
377 CheckSum: 0
378 Number: 5
379 Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
380 - Name: foo
381 Value: 0
382 SectionNumber: 5
383 SimpleType: IMAGE_SYM_TYPE_NULL
384 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
385 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
386 - Name: bar
387 Value: 0
388 SectionNumber: 0
389 SimpleType: IMAGE_SYM_TYPE_NULL
390 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
391 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
392 - Name: main
393 Value: 0
394 SectionNumber: 4
395 SimpleType: IMAGE_SYM_TYPE_NULL
396 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
397 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
398 - Name: '$LN3'
399 Value: 0
400 SectionNumber: 4
401 SimpleType: IMAGE_SYM_TYPE_NULL
402 ComplexType: IMAGE_SYM_DTYPE_NULL
403 StorageClass: IMAGE_SYM_CLASS_LABEL
404 - Name: .xdata
405 Value: 0
406 SectionNumber: 7
407 SimpleType: IMAGE_SYM_TYPE_NULL
408 ComplexType: IMAGE_SYM_DTYPE_NULL
409 StorageClass: IMAGE_SYM_CLASS_STATIC
410 SectionDefinition:
411 Length: 8
412 NumberOfRelocations: 0
413 NumberOfLinenumbers: 0
414 CheckSum: 264583633
415 Number: 0
416 - Name: '$unwind$main'
417 Value: 0
418 SectionNumber: 7
419 SimpleType: IMAGE_SYM_TYPE_NULL
420 ComplexType: IMAGE_SYM_DTYPE_NULL
421 StorageClass: IMAGE_SYM_CLASS_STATIC
422 - Name: .pdata
423 Value: 0
424 SectionNumber: 8
425 SimpleType: IMAGE_SYM_TYPE_NULL
426 ComplexType: IMAGE_SYM_DTYPE_NULL
427 StorageClass: IMAGE_SYM_CLASS_STATIC
428 SectionDefinition:
429 Length: 12
430 NumberOfRelocations: 3
431 NumberOfLinenumbers: 0
432 CheckSum: 2942184094
433 Number: 0
434 - Name: '$pdata$main'
435 Value: 0
436 SectionNumber: 8
437 SimpleType: IMAGE_SYM_TYPE_NULL
438 ComplexType: IMAGE_SYM_DTYPE_NULL
439 StorageClass: IMAGE_SYM_CLASS_STATIC
440 - Name: global
441 Value: 0
442 SectionNumber: 0
443 SimpleType: IMAGE_SYM_TYPE_NULL
444 ComplexType: IMAGE_SYM_DTYPE_NULL
445 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
446...
deps/lld/test/COFF/Inputs/pdb_lines_1.yaml created+480
......@@ -0,0 +1,480 @@
1--- !COFF
2header:
3 Machine: IMAGE_FILE_MACHINE_AMD64
4 Characteristics: [ ]
5sections:
6 - Name: .drectve
7 Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
8 Alignment: 1
9 SectionData: 2020202F44454641554C544C49423A224C4942434D5422202F44454641554C544C49423A224F4C444E414D45532220
10 - Name: '.debug$S'
11 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
12 Alignment: 1
13 Subsections:
14 - !Symbols
15 Records:
16 - Kind: S_OBJNAME
17 ObjNameSym:
18 Signature: 0
19 ObjectName: 'C:\src\llvm-project\build\pdb_lines_1.obj'
20 - Kind: S_COMPILE3
21 Compile3Sym:
22 Flags: [ SecurityChecks, HotPatch ]
23 Machine: X64
24 FrontendMajor: 19
25 FrontendMinor: 0
26 FrontendBuild: 24215
27 FrontendQFE: 1
28 BackendMajor: 19
29 BackendMinor: 0
30 BackendBuild: 24215
31 BackendQFE: 1
32 Version: 'Microsoft (R) Optimizing Compiler'
33 - !Symbols
34 Records:
35 - Kind: S_GPROC32_ID
36 ProcSym:
37 PtrParent: 0
38 PtrEnd: 0
39 PtrNext: 0
40 CodeSize: 19
41 DbgStart: 4
42 DbgEnd: 14
43 FunctionType: 4102
44 Segment: 0
45 Flags: [ ]
46 DisplayName: main
47 - Kind: S_FRAMEPROC
48 FrameProcSym:
49 TotalFrameBytes: 40
50 PaddingFrameBytes: 0
51 OffsetToPadding: 0
52 BytesOfCalleeSavedRegisters: 0
53 OffsetOfExceptionHandler: 0
54 SectionIdOfExceptionHandler: 0
55 Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ]
56 - Kind: S_PROC_ID_END
57 ScopeEndSym:
58 - !Lines
59 CodeSize: 19
60 Flags: [ ]
61 RelocOffset: 0
62 RelocSegment: 0
63 Blocks:
64 - FileName: 'c:\src\llvm-project\build\pdb_lines_1.c'
65 Lines:
66 - Offset: 0
67 LineStart: 2
68 IsStatement: true
69 EndDelta: 0
70 - Offset: 4
71 LineStart: 3
72 IsStatement: true
73 EndDelta: 0
74 - Offset: 9
75 LineStart: 4
76 IsStatement: true
77 EndDelta: 0
78 - Offset: 14
79 LineStart: 5
80 IsStatement: true
81 EndDelta: 0
82 Columns:
83 - !FileChecksums
84 Checksums:
85 - FileName: 'c:\src\llvm-project\build\pdb_lines_1.c'
86 Kind: MD5
87 Checksum: 4EB19DCD86C3BA2238A255C718572E7B
88 - FileName: 'c:\src\llvm-project\build\foo.h'
89 Kind: MD5
90 Checksum: 061EB73ABB642532857A4F1D9CBAC323
91 - !StringTable
92 Strings:
93 - 'c:\src\llvm-project\build\pdb_lines_1.c'
94 - 'c:\src\llvm-project\build\foo.h'
95 - !Symbols
96 Records:
97 - Kind: S_BUILDINFO
98 BuildInfoSym:
99 BuildId: 4111
100 Relocations:
101 - VirtualAddress: 164
102 SymbolName: main
103 Type: IMAGE_REL_AMD64_SECREL
104 - VirtualAddress: 168
105 SymbolName: main
106 Type: IMAGE_REL_AMD64_SECTION
107 - VirtualAddress: 220
108 SymbolName: main
109 Type: IMAGE_REL_AMD64_SECREL
110 - VirtualAddress: 224
111 SymbolName: main
112 Type: IMAGE_REL_AMD64_SECTION
113 - Name: '.debug$T'
114 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
115 Alignment: 1
116 Types:
117 - Kind: LF_ARGLIST
118 ArgList:
119 ArgIndices: [ ]
120 - Kind: LF_PROCEDURE
121 Procedure:
122 ReturnType: 3
123 CallConv: NearC
124 Options: [ None ]
125 ParameterCount: 0
126 ArgumentList: 4096
127 - Kind: LF_POINTER
128 Pointer:
129 ReferentType: 4097
130 Attrs: 65548
131 - Kind: LF_FUNC_ID
132 FuncId:
133 ParentScope: 0
134 FunctionType: 4097
135 Name: foo
136 - Kind: LF_ARGLIST
137 ArgList:
138 ArgIndices: [ 0 ]
139 - Kind: LF_PROCEDURE
140 Procedure:
141 ReturnType: 116
142 CallConv: NearC
143 Options: [ None ]
144 ParameterCount: 0
145 ArgumentList: 4100
146 - Kind: LF_FUNC_ID
147 FuncId:
148 ParentScope: 0
149 FunctionType: 4101
150 Name: main
151 - Kind: LF_FUNC_ID
152 FuncId:
153 ParentScope: 0
154 FunctionType: 4097
155 Name: bar
156 - Kind: LF_STRING_ID
157 StringId:
158 Id: 0
159 String: 'C:\src\llvm-project\build'
160 - Kind: LF_STRING_ID
161 StringId:
162 Id: 0
163 String: 'C:\PROGRA~2\MICROS~1.0\VC\Bin\amd64\cl.exe'
164 - Kind: LF_STRING_ID
165 StringId:
166 Id: 0
167 String: '-c -Z7 -MT -IC:\PROGRA~2\MICROS~1.0\VC\include -IC:\PROGRA~2\MICROS~1.0\VC\atlmfc\include -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\ucrt -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\shared -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\um'
168 - Kind: LF_SUBSTR_LIST
169 StringList:
170 StringIndices: [ 4106 ]
171 - Kind: LF_STRING_ID
172 StringId:
173 Id: 4107
174 String: ' -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\winrt -TC -X'
175 - Kind: LF_STRING_ID
176 StringId:
177 Id: 0
178 String: pdb_lines_1.c
179 - Kind: LF_STRING_ID
180 StringId:
181 Id: 0
182 String: 'C:\src\llvm-project\build\vc140.pdb'
183 - Kind: LF_BUILDINFO
184 BuildInfo:
185 ArgIndices: [ 4104, 4105, 4109, 4110, 4108 ]
186 - Name: '.text$mn'
187 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
188 Alignment: 16
189 SectionData: 4883EC28E800000000B82A0000004883C428C3
190 Relocations:
191 - VirtualAddress: 5
192 SymbolName: foo
193 Type: IMAGE_REL_AMD64_REL32
194 - Name: '.text$mn'
195 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
196 Alignment: 16
197 SectionData: 4883EC28E8000000004883C428C3
198 Relocations:
199 - VirtualAddress: 5
200 SymbolName: bar
201 Type: IMAGE_REL_AMD64_REL32
202 - Name: '.debug$S'
203 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
204 Alignment: 1
205 Subsections:
206 - !Symbols
207 Records:
208 - Kind: S_GPROC32_ID
209 ProcSym:
210 PtrParent: 0
211 PtrEnd: 0
212 PtrNext: 0
213 CodeSize: 14
214 DbgStart: 4
215 DbgEnd: 9
216 FunctionType: 4099
217 Segment: 0
218 Flags: [ ]
219 DisplayName: foo
220 - Kind: S_FRAMEPROC
221 FrameProcSym:
222 TotalFrameBytes: 40
223 PaddingFrameBytes: 0
224 OffsetToPadding: 0
225 BytesOfCalleeSavedRegisters: 0
226 OffsetOfExceptionHandler: 0
227 SectionIdOfExceptionHandler: 0
228 Flags: [ MarkedInline, AsynchronousExceptionHandling, OptimizedForSpeed ]
229 - Kind: S_PROC_ID_END
230 ScopeEndSym:
231 - !Lines
232 CodeSize: 14
233 Flags: [ ]
234 RelocOffset: 0
235 RelocSegment: 0
236 Blocks:
237 - FileName: 'c:\src\llvm-project\build\foo.h'
238 Lines:
239 - Offset: 0
240 LineStart: 2
241 IsStatement: true
242 EndDelta: 0
243 - Offset: 4
244 LineStart: 3
245 IsStatement: true
246 EndDelta: 0
247 - Offset: 9
248 LineStart: 4
249 IsStatement: true
250 EndDelta: 0
251 Columns:
252 Relocations:
253 - VirtualAddress: 44
254 SymbolName: foo
255 Type: IMAGE_REL_AMD64_SECREL
256 - VirtualAddress: 48
257 SymbolName: foo
258 Type: IMAGE_REL_AMD64_SECTION
259 - VirtualAddress: 100
260 SymbolName: foo
261 Type: IMAGE_REL_AMD64_SECREL
262 - VirtualAddress: 104
263 SymbolName: foo
264 Type: IMAGE_REL_AMD64_SECTION
265 - Name: .xdata
266 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ ]
267 Alignment: 4
268 SectionData: '0104010004420000'
269 - Name: .pdata
270 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ ]
271 Alignment: 4
272 SectionData: '000000000E00000000000000'
273 Relocations:
274 - VirtualAddress: 0
275 SymbolName: '$LN3'
276 Type: IMAGE_REL_AMD64_ADDR32NB
277 - VirtualAddress: 4
278 SymbolName: '$LN3'
279 Type: IMAGE_REL_AMD64_ADDR32NB
280 - VirtualAddress: 8
281 SymbolName: '$unwind$foo'
282 Type: IMAGE_REL_AMD64_ADDR32NB
283 - Name: .xdata
284 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
285 Alignment: 4
286 SectionData: '0104010004420000'
287 - Name: .pdata
288 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
289 Alignment: 4
290 SectionData: '000000001300000000000000'
291 Relocations:
292 - VirtualAddress: 0
293 SymbolName: '$LN3'
294 Type: IMAGE_REL_AMD64_ADDR32NB
295 - VirtualAddress: 4
296 SymbolName: '$LN3'
297 Type: IMAGE_REL_AMD64_ADDR32NB
298 - VirtualAddress: 8
299 SymbolName: '$unwind$main'
300 Type: IMAGE_REL_AMD64_ADDR32NB
301symbols:
302 - Name: .drectve
303 Value: 0
304 SectionNumber: 1
305 SimpleType: IMAGE_SYM_TYPE_NULL
306 ComplexType: IMAGE_SYM_DTYPE_NULL
307 StorageClass: IMAGE_SYM_CLASS_STATIC
308 SectionDefinition:
309 Length: 47
310 NumberOfRelocations: 0
311 NumberOfLinenumbers: 0
312 CheckSum: 0
313 Number: 0
314 - Name: '.debug$S'
315 Value: 0
316 SectionNumber: 2
317 SimpleType: IMAGE_SYM_TYPE_NULL
318 ComplexType: IMAGE_SYM_DTYPE_NULL
319 StorageClass: IMAGE_SYM_CLASS_STATIC
320 SectionDefinition:
321 Length: 432
322 NumberOfRelocations: 4
323 NumberOfLinenumbers: 0
324 CheckSum: 0
325 Number: 0
326 - Name: '.debug$T'
327 Value: 0
328 SectionNumber: 3
329 SimpleType: IMAGE_SYM_TYPE_NULL
330 ComplexType: IMAGE_SYM_DTYPE_NULL
331 StorageClass: IMAGE_SYM_CLASS_STATIC
332 SectionDefinition:
333 Length: 644
334 NumberOfRelocations: 0
335 NumberOfLinenumbers: 0
336 CheckSum: 0
337 Number: 0
338 - Name: '.text$mn'
339 Value: 0
340 SectionNumber: 4
341 SimpleType: IMAGE_SYM_TYPE_NULL
342 ComplexType: IMAGE_SYM_DTYPE_NULL
343 StorageClass: IMAGE_SYM_CLASS_STATIC
344 SectionDefinition:
345 Length: 19
346 NumberOfRelocations: 1
347 NumberOfLinenumbers: 0
348 CheckSum: 791570821
349 Number: 0
350 - Name: '.text$mn'
351 Value: 0
352 SectionNumber: 5
353 SimpleType: IMAGE_SYM_TYPE_NULL
354 ComplexType: IMAGE_SYM_DTYPE_NULL
355 StorageClass: IMAGE_SYM_CLASS_STATIC
356 SectionDefinition:
357 Length: 14
358 NumberOfRelocations: 1
359 NumberOfLinenumbers: 0
360 CheckSum: 1682752513
361 Number: 0
362 Selection: IMAGE_COMDAT_SELECT_ANY
363 - Name: '.debug$S'
364 Value: 0
365 SectionNumber: 6
366 SimpleType: IMAGE_SYM_TYPE_NULL
367 ComplexType: IMAGE_SYM_DTYPE_NULL
368 StorageClass: IMAGE_SYM_CLASS_STATIC
369 SectionDefinition:
370 Length: 148
371 NumberOfRelocations: 4
372 NumberOfLinenumbers: 0
373 CheckSum: 0
374 Number: 5
375 Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
376 - Name: bar
377 Value: 0
378 SectionNumber: 0
379 SimpleType: IMAGE_SYM_TYPE_NULL
380 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
381 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
382 - Name: foo
383 Value: 0
384 SectionNumber: 5
385 SimpleType: IMAGE_SYM_TYPE_NULL
386 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
387 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
388 - Name: main
389 Value: 0
390 SectionNumber: 4
391 SimpleType: IMAGE_SYM_TYPE_NULL
392 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
393 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
394 - Name: '$LN3'
395 Value: 0
396 SectionNumber: 5
397 SimpleType: IMAGE_SYM_TYPE_NULL
398 ComplexType: IMAGE_SYM_DTYPE_NULL
399 StorageClass: IMAGE_SYM_CLASS_LABEL
400 - Name: '$LN3'
401 Value: 0
402 SectionNumber: 4
403 SimpleType: IMAGE_SYM_TYPE_NULL
404 ComplexType: IMAGE_SYM_DTYPE_NULL
405 StorageClass: IMAGE_SYM_CLASS_LABEL
406 - Name: .xdata
407 Value: 0
408 SectionNumber: 7
409 SimpleType: IMAGE_SYM_TYPE_NULL
410 ComplexType: IMAGE_SYM_DTYPE_NULL
411 StorageClass: IMAGE_SYM_CLASS_STATIC
412 SectionDefinition:
413 Length: 8
414 NumberOfRelocations: 0
415 NumberOfLinenumbers: 0
416 CheckSum: 264583633
417 Number: 5
418 Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
419 - Name: '$unwind$foo'
420 Value: 0
421 SectionNumber: 7
422 SimpleType: IMAGE_SYM_TYPE_NULL
423 ComplexType: IMAGE_SYM_DTYPE_NULL
424 StorageClass: IMAGE_SYM_CLASS_STATIC
425 - Name: .pdata
426 Value: 0
427 SectionNumber: 8
428 SimpleType: IMAGE_SYM_TYPE_NULL
429 ComplexType: IMAGE_SYM_DTYPE_NULL
430 StorageClass: IMAGE_SYM_CLASS_STATIC
431 SectionDefinition:
432 Length: 12
433 NumberOfRelocations: 3
434 NumberOfLinenumbers: 0
435 CheckSum: 361370162
436 Number: 5
437 Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
438 - Name: '$pdata$foo'
439 Value: 0
440 SectionNumber: 8
441 SimpleType: IMAGE_SYM_TYPE_NULL
442 ComplexType: IMAGE_SYM_DTYPE_NULL
443 StorageClass: IMAGE_SYM_CLASS_STATIC
444 - Name: .xdata
445 Value: 0
446 SectionNumber: 9
447 SimpleType: IMAGE_SYM_TYPE_NULL
448 ComplexType: IMAGE_SYM_DTYPE_NULL
449 StorageClass: IMAGE_SYM_CLASS_STATIC
450 SectionDefinition:
451 Length: 8
452 NumberOfRelocations: 0
453 NumberOfLinenumbers: 0
454 CheckSum: 264583633
455 Number: 0
456 - Name: '$unwind$main'
457 Value: 0
458 SectionNumber: 9
459 SimpleType: IMAGE_SYM_TYPE_NULL
460 ComplexType: IMAGE_SYM_DTYPE_NULL
461 StorageClass: IMAGE_SYM_CLASS_STATIC
462 - Name: .pdata
463 Value: 0
464 SectionNumber: 10
465 SimpleType: IMAGE_SYM_TYPE_NULL
466 ComplexType: IMAGE_SYM_DTYPE_NULL
467 StorageClass: IMAGE_SYM_CLASS_STATIC
468 SectionDefinition:
469 Length: 12
470 NumberOfRelocations: 3
471 NumberOfLinenumbers: 0
472 CheckSum: 4063508168
473 Number: 0
474 - Name: '$pdata$main'
475 Value: 0
476 SectionNumber: 10
477 SimpleType: IMAGE_SYM_TYPE_NULL
478 ComplexType: IMAGE_SYM_DTYPE_NULL
479 StorageClass: IMAGE_SYM_CLASS_STATIC
480...
deps/lld/test/COFF/Inputs/pdb_lines_2.yaml created+209
......@@ -0,0 +1,209 @@
1--- !COFF
2header:
3 Machine: IMAGE_FILE_MACHINE_AMD64
4 Characteristics: [ ]
5sections:
6 - Name: .drectve
7 Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
8 Alignment: 1
9 SectionData: 2020202F44454641554C544C49423A224C4942434D5422202F44454641554C544C49423A224F4C444E414D45532220
10 - Name: '.debug$S'
11 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
12 Alignment: 1
13 Subsections:
14 - !Symbols
15 Records:
16 - Kind: S_OBJNAME
17 ObjNameSym:
18 Signature: 0
19 ObjectName: 'C:\src\llvm-project\build\pdb_lines_2.obj'
20 - Kind: S_COMPILE3
21 Compile3Sym:
22 Flags: [ SecurityChecks, HotPatch ]
23 Machine: X64
24 FrontendMajor: 19
25 FrontendMinor: 0
26 FrontendBuild: 24215
27 FrontendQFE: 1
28 BackendMajor: 19
29 BackendMinor: 0
30 BackendBuild: 24215
31 BackendQFE: 1
32 Version: 'Microsoft (R) Optimizing Compiler'
33 - !Symbols
34 Records:
35 - Kind: S_GPROC32_ID
36 ProcSym:
37 PtrParent: 0
38 PtrEnd: 0
39 PtrNext: 0
40 CodeSize: 1
41 DbgStart: 0
42 DbgEnd: 0
43 FunctionType: 4098
44 Segment: 0
45 Flags: [ ]
46 DisplayName: bar
47 - Kind: S_FRAMEPROC
48 FrameProcSym:
49 TotalFrameBytes: 0
50 PaddingFrameBytes: 0
51 OffsetToPadding: 0
52 BytesOfCalleeSavedRegisters: 0
53 OffsetOfExceptionHandler: 0
54 SectionIdOfExceptionHandler: 0
55 Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ]
56 - Kind: S_PROC_ID_END
57 ScopeEndSym:
58 - !Lines
59 CodeSize: 1
60 Flags: [ ]
61 RelocOffset: 0
62 RelocSegment: 0
63 Blocks:
64 - FileName: 'c:\src\llvm-project\build\pdb_lines_2.c'
65 Lines:
66 - Offset: 0
67 LineStart: 1
68 IsStatement: true
69 EndDelta: 0
70 - Offset: 0
71 LineStart: 2
72 IsStatement: true
73 EndDelta: 0
74 Columns:
75 - !FileChecksums
76 Checksums:
77 - FileName: 'c:\src\llvm-project\build\pdb_lines_2.c'
78 Kind: MD5
79 Checksum: DF91CB3A2B8D917486574BB50CAC4CC7
80 - !StringTable
81 Strings:
82 - 'c:\src\llvm-project\build\pdb_lines_2.c'
83 - !Symbols
84 Records:
85 - Kind: S_BUILDINFO
86 BuildInfoSym:
87 BuildId: 4106
88 Relocations:
89 - VirtualAddress: 164
90 SymbolName: bar
91 Type: IMAGE_REL_AMD64_SECREL
92 - VirtualAddress: 168
93 SymbolName: bar
94 Type: IMAGE_REL_AMD64_SECTION
95 - VirtualAddress: 220
96 SymbolName: bar
97 Type: IMAGE_REL_AMD64_SECREL
98 - VirtualAddress: 224
99 SymbolName: bar
100 Type: IMAGE_REL_AMD64_SECTION
101 - Name: '.debug$T'
102 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
103 Alignment: 1
104 Types:
105 - Kind: LF_ARGLIST
106 ArgList:
107 ArgIndices: [ ]
108 - Kind: LF_PROCEDURE
109 Procedure:
110 ReturnType: 3
111 CallConv: NearC
112 Options: [ None ]
113 ParameterCount: 0
114 ArgumentList: 4096
115 - Kind: LF_FUNC_ID
116 FuncId:
117 ParentScope: 0
118 FunctionType: 4097
119 Name: bar
120 - Kind: LF_STRING_ID
121 StringId:
122 Id: 0
123 String: 'C:\src\llvm-project\build'
124 - Kind: LF_STRING_ID
125 StringId:
126 Id: 0
127 String: 'C:\PROGRA~2\MICROS~1.0\VC\Bin\amd64\cl.exe'
128 - Kind: LF_STRING_ID
129 StringId:
130 Id: 0
131 String: '-c -Z7 -MT -IC:\PROGRA~2\MICROS~1.0\VC\include -IC:\PROGRA~2\MICROS~1.0\VC\atlmfc\include -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\ucrt -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\shared -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\um'
132 - Kind: LF_SUBSTR_LIST
133 StringList:
134 StringIndices: [ 4101 ]
135 - Kind: LF_STRING_ID
136 StringId:
137 Id: 4102
138 String: ' -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\winrt -TC -X'
139 - Kind: LF_STRING_ID
140 StringId:
141 Id: 0
142 String: pdb_lines_2.c
143 - Kind: LF_STRING_ID
144 StringId:
145 Id: 0
146 String: 'C:\src\llvm-project\build\vc140.pdb'
147 - Kind: LF_BUILDINFO
148 BuildInfo:
149 ArgIndices: [ 4099, 4100, 4104, 4105, 4103 ]
150 - Name: '.text$mn'
151 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
152 Alignment: 16
153 SectionData: C3
154symbols:
155 - Name: .drectve
156 Value: 0
157 SectionNumber: 1
158 SimpleType: IMAGE_SYM_TYPE_NULL
159 ComplexType: IMAGE_SYM_DTYPE_NULL
160 StorageClass: IMAGE_SYM_CLASS_STATIC
161 SectionDefinition:
162 Length: 47
163 NumberOfRelocations: 0
164 NumberOfLinenumbers: 0
165 CheckSum: 0
166 Number: 0
167 - Name: '.debug$S'
168 Value: 0
169 SectionNumber: 2
170 SimpleType: IMAGE_SYM_TYPE_NULL
171 ComplexType: IMAGE_SYM_DTYPE_NULL
172 StorageClass: IMAGE_SYM_CLASS_STATIC
173 SectionDefinition:
174 Length: 360
175 NumberOfRelocations: 4
176 NumberOfLinenumbers: 0
177 CheckSum: 0
178 Number: 0
179 - Name: '.debug$T'
180 Value: 0
181 SectionNumber: 3
182 SimpleType: IMAGE_SYM_TYPE_NULL
183 ComplexType: IMAGE_SYM_DTYPE_NULL
184 StorageClass: IMAGE_SYM_CLASS_STATIC
185 SectionDefinition:
186 Length: 568
187 NumberOfRelocations: 0
188 NumberOfLinenumbers: 0
189 CheckSum: 0
190 Number: 0
191 - Name: '.text$mn'
192 Value: 0
193 SectionNumber: 4
194 SimpleType: IMAGE_SYM_TYPE_NULL
195 ComplexType: IMAGE_SYM_DTYPE_NULL
196 StorageClass: IMAGE_SYM_CLASS_STATIC
197 SectionDefinition:
198 Length: 1
199 NumberOfRelocations: 0
200 NumberOfLinenumbers: 0
201 CheckSum: 40735498
202 Number: 0
203 - Name: bar
204 Value: 0
205 SectionNumber: 4
206 SimpleType: IMAGE_SYM_TYPE_NULL
207 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
208 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
209...
deps/lld/test/COFF/Inputs/resource.res created
Binary files /dev/null and b/deps/lld/test/COFF/Inputs/resource.res differ
deps/lld/test/COFF/Inputs/ret42.lib created
Binary files /dev/null and b/deps/lld/test/COFF/Inputs/ret42.lib differ
deps/lld/test/COFF/Inputs/ret42.obj created
Binary files /dev/null and b/deps/lld/test/COFF/Inputs/ret42.obj differ
deps/lld/test/COFF/Inputs/ret42.yaml created+45
......@@ -0,0 +1,45 @@
1--- !COFF
2header:
3 Machine: IMAGE_FILE_MACHINE_AMD64
4 Characteristics: []
5sections:
6 - Name: '.text$mn'
7 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
8 Alignment: 16
9 SectionData: B82A000000C3
10 - Name: .data
11 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
12 Alignment: 16
13 SectionData: ''
14symbols:
15 - Name: '.text$mn'
16 Value: 0
17 SectionNumber: 1
18 SimpleType: IMAGE_SYM_TYPE_NULL
19 ComplexType: IMAGE_SYM_DTYPE_NULL
20 StorageClass: IMAGE_SYM_CLASS_STATIC
21 SectionDefinition:
22 Length: 6
23 NumberOfRelocations: 0
24 NumberOfLinenumbers: 0
25 CheckSum: 0
26 Number: 0
27 - Name: .data
28 Value: 0
29 SectionNumber: 2
30 SimpleType: IMAGE_SYM_TYPE_NULL
31 ComplexType: IMAGE_SYM_DTYPE_NULL
32 StorageClass: IMAGE_SYM_CLASS_STATIC
33 SectionDefinition:
34 Length: 0
35 NumberOfRelocations: 0
36 NumberOfLinenumbers: 0
37 CheckSum: 0
38 Number: 0
39 - Name: main
40 Value: 0
41 SectionNumber: 1
42 SimpleType: IMAGE_SYM_TYPE_NULL
43 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
44 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
45...
deps/lld/test/COFF/Inputs/std32.lib created
Binary files /dev/null and b/deps/lld/test/COFF/Inputs/std32.lib differ
deps/lld/test/COFF/Inputs/std64.lib created
Binary files /dev/null and b/deps/lld/test/COFF/Inputs/std64.lib differ
deps/lld/test/COFF/Inputs/thinlto-mangled-qux.ll created+28
......@@ -0,0 +1,28 @@
1target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-pc-windows-msvc19.0.24215"
3
4%class.baz = type { %class.bar }
5%class.bar = type { i32 (...)** }
6
7$"\01?x@bar@@UEBA_NXZ" = comdat any
8
9$"\01??_7baz@@6B@" = comdat any
10
11$"\01??_Gbaz@@UEAAPEAXI@Z" = comdat any
12
13@"\01??_7baz@@6B@" = linkonce_odr unnamed_addr constant { [2 x i8*] } { [2 x i8*] [i8* bitcast (i8* (%class.baz*, i32)* @"\01??_Gbaz@@UEAAPEAXI@Z" to i8*), i8* bitcast (i1 (%class.bar*)* @"\01?x@bar@@UEBA_NXZ" to i8*)] }, comdat, !type !0, !type !1
14
15define void @"\01?qux@@YAXXZ"() local_unnamed_addr {
16 ret void
17}
18
19define linkonce_odr i8* @"\01??_Gbaz@@UEAAPEAXI@Z"(%class.baz* %this, i32 %should_call_delete) unnamed_addr comdat {
20 ret i8* null
21}
22
23define linkonce_odr zeroext i1 @"\01?x@bar@@UEBA_NXZ"(%class.bar* %this) unnamed_addr comdat {
24 ret i1 false
25}
26
27!0 = !{i64 0, !"?AVbar@@"}
28!1 = !{i64 0, !"?AVbaz@@"}
deps/lld/test/COFF/Inputs/weak-external.ll created+6
......@@ -0,0 +1,6 @@
1target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-pc-windows-msvc"
3
4define void @g() {
5 ret void
6}
deps/lld/test/COFF/Inputs/weak-external2.ll created+6
......@@ -0,0 +1,6 @@
1target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-pc-windows-msvc"
3
4define void @f() {
5 ret void
6}
deps/lld/test/COFF/Inputs/weak-external3.ll created+8
......@@ -0,0 +1,8 @@
1target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-pc-windows-msvc"
3
4@f = weak alias void(), void()* @g
5
6define void @g() {
7 ret void
8}
deps/lld/test/COFF/alternatename.test created+61
......@@ -0,0 +1,61 @@
1# RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj
2# RUN: lld-link /entry:foo /subsystem:console \
3# RUN: /alternatename:foo=main /out:%t.exe %t.obj
4# RUN: lld-link /entry:foo /subsystem:console \
5# RUN: /alternatename:foo=main \
6# RUN: /alternatename:foo=main \
7# RUN: /alternatename:nosuchsym1=nosuchsym2 \
8# RUN: /out:%t.exe %t.obj
9
10# RUN: yaml2obj < %s > %t.obj
11# RUN: lld-link /entry:foo /subsystem:console /out:%t.exe %t.obj
12
13--- !COFF
14header:
15 Machine: IMAGE_FILE_MACHINE_AMD64
16 Characteristics: []
17sections:
18 - Name: '.text$mn'
19 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
20 Alignment: 16
21 SectionData: B82A000000C3
22 - Name: .data
23 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
24 Alignment: 16
25 SectionData: ''
26 - Name: .drectve
27 Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
28 Alignment: 1
29 SectionData: 2f616c7465726e6174656e616d653a666f6f3d6d61696e00 # /alternatename:foo=main
30symbols:
31 - Name: '.text$mn'
32 Value: 0
33 SectionNumber: 1
34 SimpleType: IMAGE_SYM_TYPE_NULL
35 ComplexType: IMAGE_SYM_DTYPE_NULL
36 StorageClass: IMAGE_SYM_CLASS_STATIC
37 SectionDefinition:
38 Length: 6
39 NumberOfRelocations: 0
40 NumberOfLinenumbers: 0
41 CheckSum: 0
42 Number: 0
43 - Name: .data
44 Value: 0
45 SectionNumber: 2
46 SimpleType: IMAGE_SYM_TYPE_NULL
47 ComplexType: IMAGE_SYM_DTYPE_NULL
48 StorageClass: IMAGE_SYM_CLASS_STATIC
49 SectionDefinition:
50 Length: 0
51 NumberOfRelocations: 0
52 NumberOfLinenumbers: 0
53 CheckSum: 0
54 Number: 0
55 - Name: main
56 Value: 0
57 SectionNumber: 1
58 SimpleType: IMAGE_SYM_TYPE_NULL
59 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
60 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
61...
deps/lld/test/COFF/ar-comdat.test created+38
......@@ -0,0 +1,38 @@
1# RUN: yaml2obj %s > %t1.obj
2# RUN: yaml2obj %s > %t2.obj
3# RUN: llvm-lib /out:%t.lib %t1.obj %t2.obj
4# RUN: lld-link /out:%t.exe /lldmap:%t.map /entry:main /subsystem:console %p/Inputs/ret42.obj %t.lib
5# RUN: FileCheck %s < %t.map
6
7# CHECK-NOT: .lib
8
9--- !COFF
10header:
11 Machine: IMAGE_FILE_MACHINE_AMD64
12 Characteristics: [ ]
13sections:
14 - Name: .bss
15 Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
16 Alignment: 4
17 SectionData: ''
18symbols:
19 - Name: .bss
20 Value: 0
21 SectionNumber: 1
22 SimpleType: IMAGE_SYM_TYPE_NULL
23 ComplexType: IMAGE_SYM_DTYPE_NULL
24 StorageClass: IMAGE_SYM_CLASS_STATIC
25 SectionDefinition:
26 Length: 4
27 NumberOfRelocations: 0
28 NumberOfLinenumbers: 0
29 CheckSum: 0
30 Number: 1
31 Selection: IMAGE_COMDAT_SELECT_ANY
32 - Name: x
33 Value: 0
34 SectionNumber: 1
35 SimpleType: IMAGE_SYM_TYPE_NULL
36 ComplexType: IMAGE_SYM_DTYPE_NULL
37 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
38...
deps/lld/test/COFF/arm-thumb-branch-error.s created+10
......@@ -0,0 +1,10 @@
1// RUN: llvm-mc -filetype=obj -triple=thumbv7a-windows-gnu %s -o %t
2// RUN: llvm-mc -filetype=obj -triple=thumbv7a-windows-gnu %S/Inputs/far-arm-thumb-abs.s -o %tfar
3// RUN: not lld-link -entry:_start -subsystem:console %t %tfar -out:%t2 2>&1 | FileCheck %s
4// REQUIRES: arm
5 .syntax unified
6 .globl _start
7_start:
8 bl too_far1
9
10// CHECK: relocation out of range
deps/lld/test/COFF/arm64-magic.yaml created+46
......@@ -0,0 +1,46 @@
1# RUN: yaml2obj < %s > %t.obj
2# RUN: lld-link /out:%t.exe /entry:mainCRTStartup /subsystem:console %t.obj
3# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
4
5# CHECK: Format: COFF-ARM64
6# CHECK: Arch: aarch64
7# CHECK: AddressSize: 64bit
8# CHECK: ImageFileHeader {
9# CHECK: Machine: IMAGE_FILE_MACHINE_ARM64 (0xAA64)
10# CHECK: Characteristics [ (0x22)
11# CHECK: IMAGE_FILE_EXECUTABLE_IMAGE (0x2)
12# CHECK: IMAGE_FILE_LARGE_ADDRESS_AWARE (0x20)
13# CHECK: ]
14# CHECK: }
15# CHECK: ImageOptionalHeader {
16# CHECK: Magic: 0x20B
17
18--- !COFF
19header:
20 Machine: IMAGE_FILE_MACHINE_ARM64
21 Characteristics: []
22sections:
23 - Name: .text
24 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_PURGEABLE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
25 Alignment: 4
26 SectionData: 'e0031f2ac0035fd6'
27symbols:
28 - Name: .text
29 Value: 0
30 SectionNumber: 1
31 SimpleType: IMAGE_SYM_TYPE_NULL
32 ComplexType: IMAGE_SYM_DTYPE_NULL
33 StorageClass: IMAGE_SYM_CLASS_STATIC
34 SectionDefinition:
35 Length: 8
36 NumberOfRelocations: 0
37 NumberOfLinenumbers: 0
38 CheckSum: 0
39 Number: 1
40 - Name: mainCRTStartup
41 Value: 0
42 SectionNumber: 1
43 SimpleType: IMAGE_SYM_TYPE_NULL
44 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
45 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
46...
deps/lld/test/COFF/arm64-relocs-imports.test created+136
......@@ -0,0 +1,136 @@
1# REQUIRES: aarch64
2
3# RUN: yaml2obj < %s > %t.obj
4# RUN: llvm-objdump -d %t.obj | FileCheck %s -check-prefix BEFORE
5# RUN: lld-link /entry:main /subsystem:console /out:%t.exe %t.obj %p/Inputs/library-arm64.lib
6# RUN: llvm-objdump -d %t.exe | FileCheck %s -check-prefix AFTER
7
8# BEFORE: Disassembly of section .text:
9# BEFORE: 0: fe 0f 1f f8 str x30, [sp, #-16]!
10# BEFORE: 4: 00 00 00 90 adrp x0, #0
11# BEFORE: 8: 00 08 00 91 add x0, x0, #2
12# BEFORE: c: 00 00 00 94 bl #0
13# BEFORE: 10: 00 01 40 39 ldrb w0, [x8]
14# BEFORE: 14: 00 01 40 79 ldrh w0, [x8]
15# BEFORE: 18: 00 01 40 b9 ldr w0, [x8]
16# BEFORE: 1c: 00 01 40 f9 ldr x0, [x8]
17# BEFORE: 20: e0 03 1f 2a mov w0, wzr
18# BEFORE: 24: fe 07 41 f8 ldr x30, [sp], #16
19# BEFORE: 28: c0 03 5f d6 ret
20# BEFORE: 2c: 08 00 00 00 <unknown>
21# BEFORE: 30: 00 00 00 00 <unknown>
22
23# AFTER: Disassembly of section .text:
24# AFTER: 140002000: fe 0f 1f f8 str x30, [sp, #-16]!
25# AFTER: 140002004: e0 ff ff f0 adrp x0, #-4096
26# AFTER: 140002008: 00 18 00 91 add x0, x0, #6
27# AFTER: 14000200c: 0a 00 00 94 bl #40
28# AFTER: 140002010: 00 21 40 39 ldrb w0, [x8, #8]
29# AFTER: 140002014: 00 11 40 79 ldrh w0, [x8, #8]
30# AFTER: 140002018: 00 09 40 b9 ldr w0, [x8, #8]
31# AFTER: 14000201c: 00 05 40 f9 ldr x0, [x8, #8]
32# AFTER: 140002020: e0 03 1f 2a mov w0, wzr
33# AFTER: 140002024: fe 07 41 f8 ldr x30, [sp], #16
34# AFTER: 140002028: c0 03 5f d6 ret
35# AFTER: 14000202c: 10 10 00 40 <unknown>
36# AFTER: 140002030: 01 00 00 00 <unknown>
37# AFTER: 140002034: 10 00 00 b0 adrp x16, #4096
38# AFTER: 140002038: 10 1e 40 f9 ldr x16, [x16, #56]
39# AFTER: 14000203c: 00 02 1f d6 br x16
40
41--- !COFF
42header:
43 Machine: IMAGE_FILE_MACHINE_ARM64
44 Characteristics: [ ]
45sections:
46 - Name: .text
47 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
48 Alignment: 4
49 SectionData: FE0F1FF80000009000080091000000940001403900014079000140B9000140F9E0031F2AFE0741F8C0035FD60800000000000000
50 Relocations:
51 - VirtualAddress: 4
52 SymbolName: .Lstr
53 Type: 4
54 - VirtualAddress: 8
55 SymbolName: .Lstr
56 Type: 6
57 - VirtualAddress: 12
58 SymbolName: function
59 Type: 3
60 - VirtualAddress: 16
61 SymbolName: .Lglobal
62 Type: 7
63 - VirtualAddress: 20
64 SymbolName: .Lglobal
65 Type: 7
66 - VirtualAddress: 24
67 SymbolName: .Lglobal
68 Type: 7
69 - VirtualAddress: 28
70 SymbolName: .Lglobal
71 Type: 7
72 - VirtualAddress: 44
73 SymbolName: .Lglobal
74 Type: 14
75 - Name: .data
76 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
77 Alignment: 4
78 SectionData: ''
79 - Name: .bss
80 Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
81 Alignment: 4
82 SectionData: ''
83 - Name: .rdata
84 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
85 Alignment: 1
86 SectionData: 00000000202068656C6C6F20776F726C6400
87symbols:
88 - Name: .text
89 Value: 0
90 SectionNumber: 1
91 SimpleType: IMAGE_SYM_TYPE_NULL
92 ComplexType: IMAGE_SYM_DTYPE_NULL
93 StorageClass: IMAGE_SYM_CLASS_STATIC
94 SectionDefinition:
95 Length: 28
96 NumberOfRelocations: 3
97 NumberOfLinenumbers: 0
98 CheckSum: 1438860354
99 Number: 1
100 - Name: .rdata
101 Value: 0
102 SectionNumber: 4
103 SimpleType: IMAGE_SYM_TYPE_NULL
104 ComplexType: IMAGE_SYM_DTYPE_NULL
105 StorageClass: IMAGE_SYM_CLASS_STATIC
106 SectionDefinition:
107 Length: 12
108 NumberOfRelocations: 0
109 NumberOfLinenumbers: 0
110 CheckSum: 872944732
111 Number: 4
112 - Name: main
113 Value: 0
114 SectionNumber: 1
115 SimpleType: IMAGE_SYM_TYPE_NULL
116 ComplexType: IMAGE_SYM_DTYPE_NULL
117 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
118 - Name: .Lstr
119 Value: 4
120 SectionNumber: 4
121 SimpleType: IMAGE_SYM_TYPE_NULL
122 ComplexType: IMAGE_SYM_DTYPE_NULL
123 StorageClass: IMAGE_SYM_CLASS_STATIC
124 - Name: .Lglobal
125 Value: 8
126 SectionNumber: 4
127 SimpleType: IMAGE_SYM_TYPE_NULL
128 ComplexType: IMAGE_SYM_DTYPE_NULL
129 StorageClass: IMAGE_SYM_CLASS_STATIC
130 - Name: function
131 Value: 0
132 SectionNumber: 0
133 SimpleType: IMAGE_SYM_TYPE_NULL
134 ComplexType: IMAGE_SYM_DTYPE_NULL
135 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
136...
deps/lld/test/COFF/armnt-blx23t.test created+66
......@@ -0,0 +1,66 @@
1# REQUIRES: arm
2
3# RUN: yaml2obj < %s > %t.obj
4# RUN: llvm-objdump -d %t.obj | FileCheck %s -check-prefix BEFORE
5# RUN: lld-link /entry:function /subsystem:console /out:%t.exe %t.obj
6# RUN: llvm-objdump -d %t.exe | FileCheck %s -check-prefix AFTER
7
8# BEFORE: Disassembly of section .text:
9# BEFORE: 0: 70 47 bx lr
10# BEFORE: 2: 00 bf nop
11# BEFORE: 4: 2d e9 00 48 push.w {r11, lr}
12# BEFORE: 8: eb 46 mov r11, sp
13# BEFORE: a: 20 20 movs r0, #32
14# BEFORE: c: 00 f0 00 f8 bl #0
15# BEFORE: 10: 01 30 adds r0, #1
16# BEFORE: 12: bd e8 00 88 pop.w {r11, pc}
17
18# AFTER: Disassembly of section .text:
19# AFTER: 1000: 70 47 bx lr
20# AFTER: 1002: 00 bf nop
21# AFTER: 1004: 2d e9 00 48 push.w {r11, lr}
22# AFTER: 1008: eb 46 mov r11, sp
23# AFTER: 100a: 20 20 movs r0, #32
24# AFTER: 100c: ff f7 f8 ff bl #-16
25# AFTER: 1010: 01 30 adds r0, #1
26# AFTER: 1012: bd e8 00 88 pop.w {r11, pc}
27
28--- !COFF
29header:
30 Machine: IMAGE_FILE_MACHINE_ARMNT
31 Characteristics: [ ]
32sections:
33 - Name: .text
34 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_PURGEABLE, IMAGE_SCN_MEM_16BIT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
35 Alignment: 4
36 SectionData: 704700BF2DE90048EB46202000F000F80130BDE80088
37 Relocations:
38 - VirtualAddress: 12
39 SymbolName: identity
40 Type: 21
41symbols:
42 - Name: .text
43 Value: 0
44 SectionNumber: 1
45 SimpleType: IMAGE_SYM_TYPE_NULL
46 ComplexType: IMAGE_SYM_DTYPE_NULL
47 StorageClass: IMAGE_SYM_CLASS_STATIC
48 SectionDefinition:
49 Length: 22
50 NumberOfRelocations: 1
51 NumberOfLinenumbers: 0
52 CheckSum: 0
53 Number: 1
54 - Name: identity
55 Value: 0
56 SectionNumber: 1
57 SimpleType: IMAGE_SYM_TYPE_NULL
58 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
59 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
60 - Name: function
61 Value: 4
62 SectionNumber: 1
63 SimpleType: IMAGE_SYM_TYPE_NULL
64 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
65 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
66...
deps/lld/test/COFF/armnt-branch24t.test created+59
......@@ -0,0 +1,59 @@
1# REQUIRES: arm
2
3# RUN: yaml2obj < %s > %t.obj
4# RUN: llvm-objdump -d %t.obj | FileCheck %s -check-prefix BEFORE
5# RUN: lld-link /entry:function /subsystem:console /out:%t.exe %t.obj
6# RUN: llvm-objdump -d %t.exe | FileCheck %s -check-prefix AFTER
7
8# BEFORE: Disassembly of section .text:
9# BEFORE: 0: 70 47 bx lr
10# BEFORE: 2: 00 bf nop
11# BEFORE: 4: 20 20 movs r0, #32
12# BEFORE: 6: 00 f0 00 b8 b.w #0
13
14# AFTER: Disassembly of section .text:
15# AFTER: .text:
16# AFTER: 1000: 70 47 bx lr
17# AFTER: 1002: 00 bf nop
18# AFTER: 1004: 20 20 movs r0, #32
19# AFTER: 1006: ff f7 fb bf b.w #-10
20
21--- !COFF
22header:
23 Machine: IMAGE_FILE_MACHINE_ARMNT
24 Characteristics: []
25sections:
26 - Name: .text
27 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_PURGEABLE, IMAGE_SCN_MEM_16BIT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
28 Alignment: 4
29 SectionData: 704700BF202000F000B8
30 Relocations:
31 - VirtualAddress: 6
32 SymbolName: identity
33 Type: 20
34symbols:
35 - Name: .text
36 Value: 0
37 SectionNumber: 1
38 SimpleType: IMAGE_SYM_TYPE_NULL
39 ComplexType: IMAGE_SYM_DTYPE_NULL
40 StorageClass: IMAGE_SYM_CLASS_STATIC
41 SectionDefinition:
42 Length: 10
43 NumberOfRelocations: 1
44 NumberOfLinenumbers: 0
45 CheckSum: 0
46 Number: 1
47 - Name: identity
48 Value: 0
49 SectionNumber: 1
50 SimpleType: IMAGE_SYM_TYPE_NULL
51 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
52 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
53 - Name: function
54 Value: 4
55 SectionNumber: 1
56 SimpleType: IMAGE_SYM_TYPE_NULL
57 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
58 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
59...
deps/lld/test/COFF/armnt-entry-point.test created+5
......@@ -0,0 +1,5 @@
1# RUN: yaml2obj < %p/Inputs/armnt-executable.obj.yaml > %t.obj
2# RUN: lld-link /out:%t.exe /entry:mainCRTStartup /subsystem:console %t.obj
3# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
4
5CHECK: AddressOfEntryPoint: 0x1001
deps/lld/test/COFF/armnt-imports.test created+51
......@@ -0,0 +1,51 @@
1# RUN: yaml2obj < %s > %t.obj
2# RUN: lld-link /out:%t.exe /subsystem:console %t.obj \
3# RUN: /entry:mainCRTStartup %p/Inputs/library.lib
4# RUN: llvm-readobj -coff-imports %t.exe | FileCheck %s
5
6# CHECK: Import {
7# CHECK: Name: library.dll
8# CHECK: ImportLookupTableRVA: 0x2028
9# CHECK: ImportAddressTableRVA: 0x2030
10# CHECK: Symbol: function (0)
11# CHECK: }
12
13--- !COFF
14header:
15 Machine: IMAGE_FILE_MACHINE_ARMNT
16 Characteristics: [ ]
17sections:
18 - Name: .text
19 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_PURGEABLE, IMAGE_SCN_MEM_16BIT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
20 Alignment: 4
21 SectionData: 40F20000C0F2000000680047
22 Relocations:
23 - VirtualAddress: 0
24 SymbolName: __imp_function
25 Type: 17
26symbols:
27 - Name: .text
28 Value: 0
29 SectionNumber: 1
30 SimpleType: IMAGE_SYM_TYPE_NULL
31 ComplexType: IMAGE_SYM_DTYPE_NULL
32 StorageClass: IMAGE_SYM_CLASS_STATIC
33 SectionDefinition:
34 Length: 12
35 NumberOfRelocations: 1
36 NumberOfLinenumbers: 0
37 CheckSum: 0
38 Number: 1
39 - Name: mainCRTStartup
40 Value: 0
41 SectionNumber: 1
42 SimpleType: IMAGE_SYM_TYPE_NULL
43 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
44 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
45 - Name: __imp_function
46 Value: 0
47 SectionNumber: 0
48 SimpleType: IMAGE_SYM_TYPE_NULL
49 ComplexType: IMAGE_SYM_DTYPE_NULL
50 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
51...
deps/lld/test/COFF/armnt-mov32t-exec.test created+60
......@@ -0,0 +1,60 @@
1# REQUIRES: arm
2
3# RUN: yaml2obj < %s > %t.obj
4# RUN: llvm-objdump -d %t.obj | FileCheck %s -check-prefix BEFORE
5# RUN: lld-link /out:%t.exe /subsystem:console /entry:get_function %t.obj
6# RUN: llvm-objdump -d %t.exe | FileCheck %s -check-prefix AFTER
7
8# BEFORE: Disassembly of section .text:
9# BEFORE: 0: 70 47 bx lr
10# BEFORE: 2: 00 bf nop
11# BEFORE: 4: 40 f2 00 00 movw r0, #0
12# BEFORE: 8: c0 f2 00 00 movt r0, #0
13# BEFORE: c: 70 47 bx lr
14
15# AFTER: Disassembly of section .text:
16# AFTER: 1000: 70 47 bx lr
17# AFTER: 1002: 00 bf nop
18# AFTER: 1004: 41 f2 01 00 movw r0, #4097
19# AFTER: 1008: c0 f2 40 00 movt r0, #64
20# AFTER: 100c: 70 47 bx lr
21
22--- !COFF
23header:
24 Machine: IMAGE_FILE_MACHINE_ARMNT
25 Characteristics: [ ]
26sections:
27 - Name: .text
28 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_PURGEABLE, IMAGE_SCN_MEM_16BIT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
29 Alignment: 4
30 SectionData: 704700BF40F20000C0F200007047
31 Relocations:
32 - VirtualAddress: 4
33 SymbolName: function
34 Type: 17
35symbols:
36 - Name: .text
37 Value: 0
38 SectionNumber: 1
39 SimpleType: IMAGE_SYM_TYPE_NULL
40 ComplexType: IMAGE_SYM_DTYPE_NULL
41 StorageClass: IMAGE_SYM_CLASS_STATIC
42 SectionDefinition:
43 Length: 14
44 NumberOfRelocations: 1
45 NumberOfLinenumbers: 0
46 CheckSum: 0
47 Number: 1
48 - Name: function
49 Value: 0
50 SectionNumber: 1
51 SimpleType: IMAGE_SYM_TYPE_NULL
52 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
53 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
54 - Name: get_function
55 Value: 4
56 SectionNumber: 1
57 SimpleType: IMAGE_SYM_TYPE_NULL
58 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
59 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
60...
deps/lld/test/COFF/armnt-movt32t.test created+72
......@@ -0,0 +1,72 @@
1# REQUIRES: arm
2
3# RUN: yaml2obj < %s > %t.obj
4# RUN: llvm-objdump -d %t.obj | FileCheck %s -check-prefix BEFORE
5# RUN: lld-link /entry:get_buffer /subsystem:console /out:%t.exe %t.obj
6# RUN: llvm-objdump -d %t.exe | FileCheck %s -check-prefix AFTER
7
8# BEFORE: Disassembly of section .text:
9# BEFORE: 0: 40 f2 00 00 movw r0, #0
10# BEFORE: 4: c0 f2 00 00 movt r0, #0
11# BEFORE: 8: 70 47 bx lr
12
13# AFTER: Disassembly of section .text:
14# AFTER: 0: 41 f2 00 00 movw r0, #4096
15# AFTER: 4: c0 f2 40 00 movt r0, #64
16# AFTER: 8: 70 47 bx lr
17
18--- !COFF
19header:
20 Machine: IMAGE_FILE_MACHINE_ARMNT
21 Characteristics: [ ]
22sections:
23 - Name: .text
24 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_PURGEABLE, IMAGE_SCN_MEM_16BIT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
25 Alignment: 4
26 SectionData: 40F20000C0F200007047
27 Relocations:
28 - VirtualAddress: 0
29 SymbolName: buffer
30 Type: 17
31 - Name: .rdata
32 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
33 Alignment: 1
34 SectionData: '62756666657200'
35symbols:
36 - Name: .text
37 Value: 0
38 SectionNumber: 1
39 SimpleType: IMAGE_SYM_TYPE_NULL
40 ComplexType: IMAGE_SYM_DTYPE_NULL
41 StorageClass: IMAGE_SYM_CLASS_STATIC
42 SectionDefinition:
43 Length: 10
44 NumberOfRelocations: 1
45 NumberOfLinenumbers: 0
46 CheckSum: 0
47 Number: 1
48 - Name: .rdata
49 Value: 0
50 SectionNumber: 2
51 SimpleType: IMAGE_SYM_TYPE_NULL
52 ComplexType: IMAGE_SYM_DTYPE_NULL
53 StorageClass: IMAGE_SYM_CLASS_STATIC
54 SectionDefinition:
55 Length: 7
56 NumberOfRelocations: 0
57 NumberOfLinenumbers: 0
58 CheckSum: 0
59 Number: 2
60 - Name: get_buffer
61 Value: 0
62 SectionNumber: 1
63 SimpleType: IMAGE_SYM_TYPE_NULL
64 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
65 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
66 - Name: buffer
67 Value: 0
68 SectionNumber: 2
69 SimpleType: IMAGE_SYM_TYPE_NULL
70 ComplexType: IMAGE_SYM_DTYPE_NULL
71 StorageClass: IMAGE_SYM_CLASS_STATIC
72...
deps/lld/test/COFF/associative-comdat.s created+46
......@@ -0,0 +1,46 @@
1# RUN: llvm-mc -triple=x86_64-windows-msvc %s -filetype=obj -o %t1.obj
2# RUN: llvm-mc -triple=x86_64-windows-msvc %S/Inputs/associative-comdat-2.s -filetype=obj -o %t2.obj
3
4# RUN: lld-link -entry:main %t1.obj %t2.obj -out:%t.gc.exe
5# RUN: llvm-readobj -sections %t.gc.exe | FileCheck %s
6
7# RUN: lld-link -entry:main %t1.obj %t2.obj -opt:noref -out:%t.nogc.exe
8# RUN: llvm-readobj -sections %t.nogc.exe | FileCheck %s
9
10# CHECK: Sections [
11# CHECK: Section {
12# CHECK: Number: 1
13# CHECK-LABEL: Name: .data (2E 64 61 74 61 00 00 00)
14# CHECK-NEXT: VirtualSize: 0x4
15# CHECK: Section {
16# CHECK-LABEL: Name: .rdata (2E 72 64 61 74 61 00 00)
17# This is the critical check to show that only *one* definition of
18# foo_assoc was retained. This *must* be 8, not 16.
19# CHECK-NEXT: VirtualSize: 0x8
20
21 .text
22 .def main;
23 .scl 2;
24 .type 32;
25 .endef
26 .globl main # -- Begin function main
27 .p2align 4, 0x90
28main: # @main
29# BB#0:
30 movl foo(%rip), %eax
31 retq
32 # -- End function
33
34# Defines foo and foo_assoc globals. foo is comdat, and foo_assoc is comdat
35# associative with it. foo_assoc should be discarded iff foo is discarded,
36# either by linker GC or normal comdat merging.
37
38 .section .rdata,"dr",associative,foo
39 .p2align 3
40 .quad foo
41
42 .section .data,"dw",discard,foo
43 .globl foo # @foo
44 .p2align 2
45foo:
46 .long 42
deps/lld/test/COFF/base.test created+57
......@@ -0,0 +1,57 @@
1# RUN: yaml2obj < %s > %t.obj
2
3# RUN: lld-link /out:%t.exe /entry:main %t.obj
4# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=DEFAULT-HEADER %s
5# RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=DEFAULT-TEXT %s
6
7# DEFAULT-HEADER: ImageBase: 0x140000000
8# DEFAULT-TEXT: Contents of section .text:
9# DEFAULT-TEXT-NEXT: 1000 00000040 01000000
10
11# RUN: lld-link /out:%t.exe /entry:main %t.obj /base:0x280000000
12# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=BASE-HEADER %s
13# RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=BASE-TEXT %s
14
15# BASE-HEADER: ImageBase: 0x280000000
16# BASE-TEXT: Contents of section .text:
17# BASE-TEXT-NEXT: 1000 00000080 02000000
18
19--- !COFF
20header:
21 Machine: IMAGE_FILE_MACHINE_AMD64
22 Characteristics: []
23sections:
24 - Name: .text
25 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
26 Alignment: 4096
27 SectionData: 0000000000000000
28 Relocations:
29 - VirtualAddress: 0
30 SymbolName: __ImageBase
31 Type: IMAGE_REL_AMD64_ADDR64
32symbols:
33 - Name: .text
34 Value: 0
35 SectionNumber: 1
36 SimpleType: IMAGE_SYM_TYPE_NULL
37 ComplexType: IMAGE_SYM_DTYPE_NULL
38 StorageClass: IMAGE_SYM_CLASS_STATIC
39 SectionDefinition:
40 Length: 8
41 NumberOfRelocations: 1
42 NumberOfLinenumbers: 0
43 CheckSum: 0
44 Number: 0
45 - Name: main
46 Value: 0
47 SectionNumber: 1
48 SimpleType: IMAGE_SYM_TYPE_NULL
49 ComplexType: IMAGE_SYM_DTYPE_NULL
50 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
51 - Name: __ImageBase
52 Value: 0
53 SectionNumber: 0
54 SimpleType: IMAGE_SYM_TYPE_NULL
55 ComplexType: IMAGE_SYM_DTYPE_NULL
56 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
57...
deps/lld/test/COFF/baserel.test created+215
......@@ -0,0 +1,215 @@
1# RUN: yaml2obj < %s > %t.obj
2#
3# RUN: lld-link /out:%t.exe /entry:main %t.obj %p/Inputs/std64.lib
4# RUN: llvm-readobj -coff-basereloc %t.exe | FileCheck %s -check-prefix=BASEREL
5#
6# RUN: lld-link /out:%t.exe /entry:main /fixed %t.obj %p/Inputs/std64.lib
7# RUN: llvm-readobj -coff-basereloc %t.exe | FileCheck %s -check-prefix=NOBASEREL
8#
9# BASEREL: BaseReloc [
10# BASEREL-NEXT: Entry {
11# BASEREL-NEXT: Type: DIR64
12# BASEREL-NEXT: Address: 0x2007
13# BASEREL-NEXT: }
14# BASEREL-NEXT: Entry {
15# BASEREL-NEXT: Type: DIR64
16# BASEREL-NEXT: Address: 0x200C
17# BASEREL-NEXT: }
18# BASEREL-NEXT: Entry {
19# BASEREL-NEXT: Type: DIR64
20# BASEREL-NEXT: Address: 0x201E
21# BASEREL-NEXT: }
22# BASEREL-NEXT: Entry {
23# BASEREL-NEXT: Type: ABSOLUTE
24# BASEREL-NEXT: Address: 0x2000
25# BASEREL-NEXT: }
26# BASEREL-NEXT: Entry {
27# BASEREL-NEXT: Type: DIR64
28# BASEREL-NEXT: Address: 0x3007
29# BASEREL-NEXT: }
30# BASEREL-NEXT: Entry {
31# BASEREL-NEXT: Type: DIR64
32# BASEREL-NEXT: Address: 0x300C
33# BASEREL-NEXT: }
34# BASEREL-NEXT: Entry {
35# BASEREL-NEXT: Type: DIR64
36# BASEREL-NEXT: Address: 0x301E
37# BASEREL-NEXT: }
38# BASEREL-NEXT: Entry {
39# BASEREL-NEXT: Type: ABSOLUTE
40# BASEREL-NEXT: Address: 0x3000
41# BASEREL-NEXT: }
42#
43# NOBASEREL: BaseReloc [
44# NOBASEREL-NEXT: ]
45#
46# RUN: lld-link /out:%t.exe /entry:main %t.obj %p/Inputs/std64.lib
47# RUN: llvm-readobj -file-headers -sections %t.exe | FileCheck %s \
48# RUN: --check-prefix=BASEREL-HEADER
49#
50# RN: lld-link /out:%t.exe /entry:main /fixed %t.obj %p/Inputs/std64.lib
51# RN: llvm-readobj -file-headers %t.exe | FileCheck %s \
52# RN: --check-prefix=NOBASEREL-HEADER
53#
54# BASEREL-HEADER-NOT: IMAGE_FILE_RELOCS_STRIPPED
55#
56# NOBASEREL-HEADER: IMAGE_FILE_RELOCS_STRIPPED
57#
58# BASEREL-HEADER: BaseRelocationTableRVA: 0x5000
59# BASEREL-HEADER: BaseRelocationTableSize: 0x20
60# BASEREL-HEADER: Name: .reloc (2E 72 65 6C 6F 63 00 00)
61# BASEREL-HEADER-NEXT: VirtualSize: 0x20
62# BASEREL-HEADER-NEXT: VirtualAddress: 0x5000
63# BASEREL-HEADER-NEXT: RawDataSize: 512
64# BASEREL-HEADER-NEXT: PointerToRawData: 0xC00
65# BASEREL-HEADER-NEXT: PointerToRelocations: 0x0
66# BASEREL-HEADER-NEXT: PointerToLineNumbers: 0x0
67# BASEREL-HEADER-NEXT: RelocationCount: 0
68# BASEREL-HEADER-NEXT: LineNumberCount: 0
69# BASEREL-HEADER-NEXT: Characteristics [ (0x42000040)
70# BASEREL-HEADER-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)
71# BASEREL-HEADER-NEXT: IMAGE_SCN_MEM_DISCARDABLE (0x2000000)
72# BASEREL-HEADER-NEXT: IMAGE_SCN_MEM_READ (0x40000000)
73# BASEREL-HEADER-NEXT: ]
74
75--- !COFF
76header:
77 Machine: IMAGE_FILE_MACHINE_AMD64
78 Characteristics: []
79sections:
80 - Name: .text
81 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
82 Alignment: 4096
83 SectionData: B800000000000000005068000000000000000068000000000000000050E8000000000000000050E8000000000000000050E80000000000000000
84 Relocations:
85 - VirtualAddress: 0
86 SymbolName: abs_symbol
87 Type: IMAGE_REL_AMD64_ADDR64
88 - VirtualAddress: 7
89 SymbolName: caption
90 Type: IMAGE_REL_AMD64_ADDR64
91 - VirtualAddress: 12
92 SymbolName: message
93 Type: IMAGE_REL_AMD64_ADDR64
94 - VirtualAddress: 18
95 SymbolName: MessageBoxA
96 Type: IMAGE_REL_AMD64_REL32
97 - VirtualAddress: 24
98 SymbolName: ExitProcess
99 Type: IMAGE_REL_AMD64_REL32
100 - VirtualAddress: 30
101 SymbolName: __ImageBase
102 Type: IMAGE_REL_AMD64_ADDR64
103 - Name: .text2
104 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
105 Alignment: 4096
106 SectionData: B800000000000000005068000000000000000068000000000000000050E8000000000000000050E8000000000000000050E80000000000000000
107 Relocations:
108 - VirtualAddress: 0
109 SymbolName: abs_symbol
110 Type: IMAGE_REL_AMD64_ADDR64
111 - VirtualAddress: 7
112 SymbolName: caption
113 Type: IMAGE_REL_AMD64_ADDR64
114 - VirtualAddress: 12
115 SymbolName: message
116 Type: IMAGE_REL_AMD64_ADDR64
117 - VirtualAddress: 18
118 SymbolName: MessageBoxA
119 Type: IMAGE_REL_AMD64_REL32
120 - VirtualAddress: 24
121 SymbolName: ExitProcess
122 Type: IMAGE_REL_AMD64_REL32
123 - VirtualAddress: 30
124 SymbolName: __ImageBase
125 Type: IMAGE_REL_AMD64_ADDR64
126 - Name: .data
127 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
128 Alignment: 4
129 SectionData: 48656C6C6F0048656C6C6F20576F726C6400
130symbols:
131 - Name: "@comp.id"
132 Value: 10394907
133 SectionNumber: 65535
134 SimpleType: IMAGE_SYM_TYPE_NULL
135 ComplexType: IMAGE_SYM_DTYPE_NULL
136 StorageClass: IMAGE_SYM_CLASS_STATIC
137 - Name: .text
138 Value: 0
139 SectionNumber: 1
140 SimpleType: IMAGE_SYM_TYPE_NULL
141 ComplexType: IMAGE_SYM_DTYPE_NULL
142 StorageClass: IMAGE_SYM_CLASS_STATIC
143 SectionDefinition:
144 Length: 28
145 NumberOfRelocations: 6
146 NumberOfLinenumbers: 0
147 CheckSum: 0
148 Number: 0
149 - Name: .text2
150 Value: 0
151 SectionNumber: 1
152 SimpleType: IMAGE_SYM_TYPE_NULL
153 ComplexType: IMAGE_SYM_DTYPE_NULL
154 StorageClass: IMAGE_SYM_CLASS_STATIC
155 SectionDefinition:
156 Length: 28
157 NumberOfRelocations: 6
158 NumberOfLinenumbers: 0
159 CheckSum: 0
160 Number: 0
161 - Name: .data
162 Value: 0
163 SectionNumber: 3
164 SimpleType: IMAGE_SYM_TYPE_NULL
165 ComplexType: IMAGE_SYM_DTYPE_NULL
166 StorageClass: IMAGE_SYM_CLASS_STATIC
167 SectionDefinition:
168 Length: 18
169 NumberOfRelocations: 0
170 NumberOfLinenumbers: 0
171 CheckSum: 0
172 Number: 0
173 - Name: MessageBoxA
174 Value: 0
175 SectionNumber: 0
176 SimpleType: IMAGE_SYM_TYPE_NULL
177 ComplexType: IMAGE_SYM_DTYPE_NULL
178 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
179 - Name: ExitProcess
180 Value: 0
181 SectionNumber: 0
182 SimpleType: IMAGE_SYM_TYPE_NULL
183 ComplexType: IMAGE_SYM_DTYPE_NULL
184 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
185 - Name: message
186 Value: 6
187 SectionNumber: 2
188 SimpleType: IMAGE_SYM_TYPE_NULL
189 ComplexType: IMAGE_SYM_DTYPE_NULL
190 StorageClass: IMAGE_SYM_CLASS_STATIC
191 - Name: main
192 Value: 0
193 SectionNumber: 1
194 SimpleType: IMAGE_SYM_TYPE_NULL
195 ComplexType: IMAGE_SYM_DTYPE_NULL
196 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
197 - Name: caption
198 Value: 0
199 SectionNumber: 2
200 SimpleType: IMAGE_SYM_TYPE_NULL
201 ComplexType: IMAGE_SYM_DTYPE_NULL
202 StorageClass: IMAGE_SYM_CLASS_STATIC
203 - Name: abs_symbol
204 Value: 0xDEADBEEF
205 SectionNumber: -1
206 SimpleType: IMAGE_SYM_TYPE_NULL
207 ComplexType: IMAGE_SYM_DTYPE_NULL
208 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
209 - Name: __ImageBase
210 Value: 0
211 SectionNumber: 0
212 SimpleType: IMAGE_SYM_TYPE_NULL
213 ComplexType: IMAGE_SYM_DTYPE_NULL
214 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
215...
deps/lld/test/COFF/cl-gl.test created+4
......@@ -0,0 +1,4 @@
1# RUN: not lld-link /out:%t.exe /entry:main %S/Inputs/cl-gl.obj >& %t.log
2# RUN: FileCheck %s < %t.log
3
4# CHECK: is not a native COFF file. Recompile without /GL
deps/lld/test/COFF/combined-resources.test created+213
......@@ -0,0 +1,213 @@
1// Check that lld properly handles merging multiple .res files.
2// The inputs were generated with the following commands, using the original
3// Windows rc.exe
4// > rc /fo combined-resources.res /nologo combined-resources.rc
5// > rc /fo combined-resources-2.res /nologo combined-resources-2.rc
6
7# RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj
8# RUN: lld-link /out:%t.exe /entry:main %t.obj %p/Inputs/resource.res \
9# RUN: %p/Inputs/combined-resources.res %p/Inputs/combined-resources-2.res
10
11# RUN: llvm-readobj -coff-resources -file-headers -section-data %t.exe | \
12# RUN: FileCheck %s
13
14CHECK: ResourceTableRVA: 0x1000
15CHECK-NEXT: ResourceTableSize: 0xC1C
16CHECK-DAG: Resources [
17CHECK-NEXT: Total Number of Resources: 13
18CHECK-DAG: .rsrc Data (
19CHECK-NEXT: 0000: 00000000 00000000 00000000 01000600 |................|
20CHECK-NEXT: 0010: 38030080 48000080 02000000 60000080 |8...H.......`...|
21CHECK-NEXT: 0020: 04000000 80000080 05000000 A0000080 |................|
22CHECK-NEXT: 0030: 06000000 B8000080 09000000 D0000080 |................|
23CHECK-NEXT: 0040: 0A000000 F0000080 00000000 00000000 |................|
24CHECK-NEXT: 0050: 00000000 01000000 50030080 08010080 |........P.......|
25CHECK-NEXT: 0060: 00000000 00000000 00000000 02000000 |................|
26CHECK-NEXT: 0070: FE020080 20010080 0C030080 38010080 |.... .......8...|
27CHECK-NEXT: 0080: 00000000 00000000 00000000 01000100 |................|
28CHECK-NEXT: 0090: 2C030080 50010080 60380000 68010080 |,...P...`8..h...|
29CHECK-NEXT: 00A0: 00000000 00000000 00000000 01000000 |................|
30CHECK-NEXT: 00B0: 16030080 80010080 00000000 00000000 |................|
31CHECK-NEXT: 00C0: 00000000 00000100 01000000 98010080 |................|
32CHECK-NEXT: 00D0: 00000000 00000000 00000000 01000100 |................|
33CHECK-NEXT: 00E0: E0020080 B0010080 0C000000 D0010080 |................|
34CHECK-NEXT: 00F0: 00000000 00000000 00000000 01000000 |................|
35CHECK-NEXT: 0100: 66030080 E8010080 00000000 00000000 |f...............|
36CHECK-NEXT: 0110: 00000000 00000100 09040000 10020000 |................|
37CHECK-NEXT: 0120: 00000000 00000000 00000000 00000100 |................|
38CHECK-NEXT: 0130: 09040000 20020000 00000000 00000000 |.... ...........|
39CHECK-NEXT: 0140: 00000000 00000100 09040000 30020000 |............0...|
40CHECK-NEXT: 0150: 00000000 00000000 00000000 00000100 |................|
41CHECK-NEXT: 0160: 090C0000 40020000 00000000 00000000 |....@...........|
42CHECK-NEXT: 0170: 00000000 00000100 04080000 50020000 |............P...|
43CHECK-NEXT: 0180: 00000000 00000000 00000000 00000100 |................|
44CHECK-NEXT: 0190: 09040000 60020000 00000000 00000000 |....`...........|
45CHECK-NEXT: 01A0: 00000000 00000100 09040000 70020000 |............p...|
46CHECK-NEXT: 01B0: 00000000 00000000 00000000 00000200 |................|
47CHECK-NEXT: 01C0: 09040000 80020000 04080000 90020000 |................|
48CHECK-NEXT: 01D0: 00000000 00000000 00000000 00000100 |................|
49CHECK-NEXT: 01E0: 09040000 A0020000 00000000 00000000 |................|
50CHECK-NEXT: 01F0: 00000000 00000300 09040000 B0020000 |................|
51CHECK-NEXT: 0200: 04080000 C0020000 07100000 D0020000 |................|
52CHECK-NEXT: 0210: FC1A0000 39000000 00000000 00000000 |....9...........|
53CHECK-NEXT: 0220: C4130000 28030000 00000000 00000000 |....(...........|
54CHECK-NEXT: 0230: EC160000 28030000 00000000 00000000 |....(...........|
55CHECK-NEXT: 0240: CC1A0000 30000000 00000000 00000000 |....0...........|
56CHECK-NEXT: 0250: 141A0000 2E000000 00000000 00000000 |................|
57CHECK-NEXT: 0260: 441A0000 6C000000 00000000 00000000 |D...l...........|
58CHECK-NEXT: 0270: 7C130000 2A000000 00000000 00000000 ||...*...........|
59CHECK-NEXT: 0280: AC130000 18000000 00000000 00000000 |................|
60CHECK-NEXT: 0290: 041C0000 18000000 00000000 00000000 |................|
61CHECK-NEXT: 02A0: B41A0000 18000000 00000000 00000000 |................|
62CHECK-NEXT: 02B0: 3C1B0000 36000000 00000000 00000000 |<...6...........|
63CHECK-NEXT: 02C0: 741B0000 43000000 00000000 00000000 |t...C...........|
64CHECK-NEXT: 02D0: BC1B0000 42000000 00000000 00000000 |....B...........|
65CHECK-NEXT: 02E0: 0E004D00 59004100 43004300 45004C00 |..M.Y.A.C.C.E.L.|
66CHECK-NEXT: 02F0: 45005200 41005400 4F005200 53000600 |E.R.A.T.O.R.S...|
67CHECK-NEXT: 0300: 43005500 52005300 4F005200 04004F00 |C.U.R.S.O.R...O.|
68CHECK-NEXT: 0310: 4B004100 59000A00 54004500 53005400 |K.A.Y...T.E.S.T.|
69CHECK-NEXT: 0320: 44004900 41004C00 4F004700 05002200 |D.I.A.L.O.G...".|
70CHECK-NEXT: 0330: 45004100 54002200 0B005300 54005200 |E.A.T."...S.T.R.|
71CHECK-NEXT: 0340: 49004E00 47004100 52005200 41005900 |I.N.G.A.R.R.A.Y.|
72CHECK-NEXT: 0350: 0A004D00 59005200 45005300 4F005500 |..M.Y.R.E.S.O.U.|
73CHECK-NEXT: 0360: 52004300 45000900 52004100 4E004400 |R.C.E...R.A.N.D.|
74CHECK-NEXT: 0370: 4F004D00 44004100 54000000 00000500 |O.M.D.A.T.......|
75CHECK-NEXT: 0380: 48006500 6C006C00 6F000000 00000000 |H.e.l.l.o.......|
76CHECK-NEXT: 0390: 00000000 00000000 00000000 00000000 |................|
77CHECK-NEXT: 03A0: 00000000 00000000 00000000 11000300 |................|
78CHECK-NEXT: 03B0: E7030000 0D004400 4C040000 82001200 |......D.L.......|
79CHECK-NEXT: 03C0: BC010000 28000000 10000000 10000000 |....(...........|
80CHECK-NEXT: 03D0: 01001800 00000000 00030000 C40E0000 |................|
81CHECK-NEXT: 03E0: C40E0000 00000000 00000000 FFFFFFFF |................|
82CHECK-NEXT: 03F0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
83CHECK-NEXT: 0400: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
84CHECK-NEXT: 0410: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
85CHECK-NEXT: 0420: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
86CHECK-NEXT: 0430: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
87CHECK-NEXT: 0440: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
88CHECK-NEXT: 0450: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
89CHECK-NEXT: 0460: FF7F7F7F 7C7C7C78 78787575 75FFFFFF |....|||xxxuuu...|
90CHECK-NEXT: 0470: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
91CHECK-NEXT: 0480: FFFFFFFF FFFFFFFF 979797FF FFFFFFFF |................|
92CHECK-NEXT: 0490: FF838383 AAAAAADB DBDB7979 79757575 |..........yyyuuu|
93CHECK-NEXT: 04A0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
94CHECK-NEXT: 04B0: FFFFFFFF FFFFFFFF 9C9C9C98 9898FFFF |................|
95CHECK-NEXT: 04C0: FF888888 DBDBDBB7 B7B77D7D 7DFFFFFF |..........}}}...|
96CHECK-NEXT: 04D0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
97CHECK-NEXT: 04E0: FFFFFFFF FFFFFFFF A0A0A09C 9C9C9393 |................|
98CHECK-NEXT: 04F0: 93ADADAD F2F2F284 84848181 81FFFFFF |................|
99CHECK-NEXT: 0500: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
100CHECK-NEXT: 0510: FFFFFFFF FFFFFFFF A4A4A4D7 D7D79D9D |................|
101CHECK-NEXT: 0520: 9DD0D0D0 EEEEEE91 91918D8D 8DFFFFFF |................|
102CHECK-NEXT: 0530: FFFFFF81 81817E7E 7EFFFFFF FFFFFFFF |......~~~.......|
103CHECK-NEXT: 0540: FFFFFFFF FFFFFFFF A9A9A9F2 F2F2E5E5 |................|
104CHECK-NEXT: 0550: E5E2E2E2 95959591 91918D8D 8D898989 |................|
105CHECK-NEXT: 0560: 868686FF FFFFFFFF FFFFFFFF FFFFFFFF |................|
106CHECK-NEXT: 0570: FFFFFFFF FFFFFFFF ADADADF2 F2F2E1E1 |................|
107CHECK-NEXT: 0580: E1DFDFDF E7E7E7E4 E4E4BBBB BB8E8E8E |................|
108CHECK-NEXT: 0590: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
109CHECK-NEXT: 05A0: FFFFFFFF FFFFFFFF B5B5B5F2 F2F2E8E8 |................|
110CHECK-NEXT: 05B0: E8E7E7E7 EAEAEAC6 C6C69E9E 9EFFFFFF |................|
111CHECK-NEXT: 05C0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
112CHECK-NEXT: 05D0: FFFFFFFF FFFFFFFF B9B9B9F4 F4F4ECEC |................|
113CHECK-NEXT: 05E0: ECEDEDED CBCBCBA7 A7A7FFFF FFFFFFFF |................|
114CHECK-NEXT: 05F0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
115CHECK-NEXT: 0600: FFFFFFFF FFFFFFFF BDBDBDF7 F7F7EFEF |................|
116CHECK-NEXT: 0610: EFD0D0D0 AFAFAFFF FFFFFFFF FFFFFFFF |................|
117CHECK-NEXT: 0620: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
118CHECK-NEXT: 0630: FFFFFFFF FFFFFFFF C1C1C1F7 F7F7D5D5 |................|
119CHECK-NEXT: 0640: D5B6B6B6 FFFFFFFF FFFFFFFF FFFFFFFF |................|
120CHECK-NEXT: 0650: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
121CHECK-NEXT: 0660: FFFFFFFF FFFFFFFF C4C4C4D9 D9D9BEBE |................|
122CHECK-NEXT: 0670: BEFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
123CHECK-NEXT: 0680: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
124CHECK-NEXT: 0690: FFFFFFFF FFFFFFFF C8C8C8C5 C5C5FFFF |................|
125CHECK-NEXT: 06A0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
126CHECK-NEXT: 06B0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
127CHECK-NEXT: 06C0: FFFFFFFF FFFFFFFF CBCBCBFF FFFFFFFF |................|
128CHECK-NEXT: 06D0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
129CHECK-NEXT: 06E0: FFFFFFFF FFFFFFFF FFFFFFFF 28000000 |............(...|
130CHECK-NEXT: 06F0: 10000000 10000000 01001800 00000000 |................|
131CHECK-NEXT: 0700: 00030000 C40E0000 C40E0000 00000000 |................|
132CHECK-NEXT: 0710: 00000000 FFFFFFFF FFFFFFFF FFFFFFFF |................|
133CHECK-NEXT: 0720: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
134CHECK-NEXT: 0730: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
135CHECK-NEXT: 0740: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
136CHECK-NEXT: 0750: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
137CHECK-NEXT: 0760: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
138CHECK-NEXT: 0770: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
139CHECK-NEXT: 0780: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
140CHECK-NEXT: 0790: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
141CHECK-NEXT: 07A0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
142CHECK-NEXT: 07B0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
143CHECK-NEXT: 07C0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
144CHECK-NEXT: 07D0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
145CHECK-NEXT: 07E0: A0E3A901 B31801B3 1801B318 01B31801 |................|
146CHECK-NEXT: 07F0: B31801B3 1861D06F FFFFFFFF FFFFFFFF |.....a.o........|
147CHECK-NEXT: 0800: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
148CHECK-NEXT: 0810: 01B31800 D7331CDB 49DBF9E2 9BEFAF00 |.....3..I.......|
149CHECK-NEXT: 0820: D73300D7 3301B318 FFFFFFFF FFFFFFFF |.3..3...........|
150CHECK-NEXT: 0830: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
151CHECK-NEXT: 0840: 01B31800 DE55F6FE F9DBFAE7 FEFFFE86 |.....U..........|
152CHECK-NEXT: 0850: EFAE00DE 5501B318 FFFFFFFF FFFFFFFF |....U...........|
153CHECK-NEXT: 0860: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
154CHECK-NEXT: 0870: 01B31800 E676DBFB EC00E676 57EFA5FB |.....v.....vW...|
155CHECK-NEXT: 0880: FFFD55EE A401B318 FFFFFFFF FFFFFFFF |..U.............|
156CHECK-NEXT: 0890: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
157CHECK-NEXT: 08A0: 01B31800 ED9800ED 9800ED98 00ED9887 |................|
158CHECK-NEXT: 08B0: F7CFFEFF FF01B318 FFFFFFFF FFFFFFFF |................|
159CHECK-NEXT: 08C0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
160CHECK-NEXT: 08D0: 01B31800 F4BA00F4 BA00F4BA 00F4BA00 |................|
161CHECK-NEXT: 08E0: F4BA9CFB E401B318 FFFFFFFF FFFFFFFF |................|
162CHECK-NEXT: 08F0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
163CHECK-NEXT: 0900: 01B31800 FBDB00FB DB00FBDB 00FBDB00 |................|
164CHECK-NEXT: 0910: FBDB00FB DB01B318 FFFFFFFF FFFFFFFF |................|
165CHECK-NEXT: 0920: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
166CHECK-NEXT: 0930: 9FE2A801 B31801B3 1801B318 01B31801 |................|
167CHECK-NEXT: 0940: B31801B3 1861D06F FFFFFFFF FFFFFFFF |.....a.o........|
168CHECK-NEXT: 0950: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
169CHECK-NEXT: 0960: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
170CHECK-NEXT: 0970: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
171CHECK-NEXT: 0980: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
172CHECK-NEXT: 0990: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
173CHECK-NEXT: 09A0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
174CHECK-NEXT: 09B0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
175CHECK-NEXT: 09C0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
176CHECK-NEXT: 09D0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
177CHECK-NEXT: 09E0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
178CHECK-NEXT: 09F0: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
179CHECK-NEXT: 0A00: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF |................|
180CHECK-NEXT: 0A10: FFFFFFFF 00000000 00006400 79007500 |..........d.y.u.|
181CHECK-NEXT: 0A20: 00000000 65007300 68006100 6C006100 |....e.s.h.a.l.a.|
182CHECK-NEXT: 0A30: 00008000 66006B00 61006F00 79006100 |....f.k.a.o.y.a.|
183CHECK-NEXT: 0A40: 00000000 0000C080 00000000 02000A00 |................|
184CHECK-NEXT: 0A50: 0A00C800 2C010000 00005400 65007300 |....,.....T.e.s.|
185CHECK-NEXT: 0A60: 74000000 01000250 00000000 0A000A00 |t......P........|
186CHECK-NEXT: 0A70: E6000E00 0100FFFF 82004300 6F006E00 |..........C.o.n.|
187CHECK-NEXT: 0A80: 74006900 6E007500 65003A00 00000000 |t.i.n.u.e.:.....|
188CHECK-NEXT: 0A90: 00000150 00000000 42008600 A1000D00 |...P....B.......|
189CHECK-NEXT: 0AA0: 0200FFFF 80002600 4F004B00 00000000 |......&.O.K.....|
190CHECK-NEXT: 0AB0: 00000000 11005800 A4000000 0D004800 |......X.......H.|
191CHECK-NEXT: 0AC0: 2E160000 82001200 BC010000 00000000 |................|
192CHECK-NEXT: 0AD0: 00006400 66006900 73006800 00000000 |..d.f.i.s.h.....|
193CHECK-NEXT: 0AE0: 65007300 61006C00 61006400 00008000 |e.s.a.l.a.d.....|
194CHECK-NEXT: 0AF0: 66006400 75006300 6B000000 74686973 |f.d.u.c.k...this|
195CHECK-NEXT: 0B00: 20697320 61207573 65722064 6566696E | is a user defin|
196CHECK-NEXT: 0B10: 65642072 65736F75 72636500 69742063 |ed resource.it c|
197CHECK-NEXT: 0B20: 6F6E7461 696E7320 6D616E79 20737472 |ontains many str|
198CHECK-NEXT: 0B30: 696E6773 00000000 00000000 74686973 |ings........this|
199CHECK-NEXT: 0B40: 20697320 61207261 6E646F6D 20626974 | is a random bit|
200CHECK-NEXT: 0B50: 206F6620 64617461 20746861 74206D65 | of data that me|
201CHECK-NEXT: 0B60: 616E7320 6E6F7468 696E6700 A9230E14 |ans nothing..#..|
202CHECK-NEXT: 0B70: F4F60000 7A686534 20736869 34207969 |....zhe4 shi4 yi|
203CHECK-NEXT: 0B80: 31676534 20737569 326A6931 20646520 |1ge4 sui2ji1 de |
204CHECK-NEXT: 0B90: 73687534 6A75342C 207A6865 34207969 |shu4ju4, zhe4 yi|
205CHECK-NEXT: 0BA0: 34776569 347A6865 20736865 6E326D65 |4wei4zhe shen2me|
206CHECK-NEXT: 0BB0: 00A9230E 14F4F600 00000000 44696573 |..#.........Dies|
207CHECK-NEXT: 0BC0: 20697374 2065696E 207A7566 C3A46C6C | ist ein zuf..ll|
208CHECK-NEXT: 0BD0: 69676573 20426974 20766F6E 20446174 |iges Bit von Dat|
209CHECK-NEXT: 0BE0: 656E2C20 64696520 6E696368 74732062 |en, die nichts b|
210CHECK-NEXT: 0BF0: 65646575 74657400 A9230E14 F4F60000 |edeutet..#......|
211CHECK-NEXT: 0C00: 00000000 11000300 E7030000 0D004400 |..............D.|
212CHECK-NEXT: 0C10: 4C040000 82001200 BC010000 |L...........|
213CHECK-NEXT: )
deps/lld/test/COFF/common.test created+103
......@@ -0,0 +1,103 @@
1# REQUIRES: x86
2# RUN: yaml2obj %s > %t.obj
3# RUN: lld-link /out:%t.exe /entry:main %t.obj %t.obj
4# RUN: llvm-objdump -d %t.exe | FileCheck %s
5
6# Operands of B8 (MOV EAX) are common symbols
7# CHECK: 3000: b8 00 10 00 40
8# CHECK: 3005: b8 04 10 00 40
9# CHECK: 300a: b8 20 10 00 40
10# CHECK: 300f: b8 60 10 00 40
11# CHECK: 3014: b8 70 10 00 40
12
13--- !COFF
14header:
15 Machine: IMAGE_FILE_MACHINE_AMD64
16 Characteristics: []
17sections:
18 - Name: .text
19 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
20 Alignment: 4
21 SectionData: b800000000b800000000b800000000b800000000b800000000
22 Relocations:
23 - VirtualAddress: 1
24 SymbolName: bssdata4
25 Type: IMAGE_REL_AMD64_ADDR32
26 - VirtualAddress: 6
27 SymbolName: bsspad1
28 Type: IMAGE_REL_AMD64_ADDR32
29 - VirtualAddress: 11
30 SymbolName: bssdata64
31 Type: IMAGE_REL_AMD64_ADDR32
32 - VirtualAddress: 16
33 SymbolName: bsspad2
34 Type: IMAGE_REL_AMD64_ADDR32
35 - VirtualAddress: 21
36 SymbolName: bssdata16
37 Type: IMAGE_REL_AMD64_ADDR32
38 - Name: .data
39 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
40 Alignment: 4
41 SectionData: 03000000
42symbols:
43 - Name: .text
44 Value: 0
45 SectionNumber: 1
46 SimpleType: IMAGE_SYM_TYPE_NULL
47 ComplexType: IMAGE_SYM_DTYPE_NULL
48 StorageClass: IMAGE_SYM_CLASS_STATIC
49 SectionDefinition:
50 Length: 0
51 NumberOfRelocations: 5
52 NumberOfLinenumbers: 0
53 CheckSum: 0
54 Number: 0
55 - Name: .data
56 Value: 0
57 SectionNumber: 2
58 SimpleType: IMAGE_SYM_TYPE_NULL
59 ComplexType: IMAGE_SYM_DTYPE_NULL
60 StorageClass: IMAGE_SYM_CLASS_STATIC
61 SectionDefinition:
62 Length: 4
63 NumberOfRelocations: 0
64 NumberOfLinenumbers: 0
65 CheckSum: 0
66 Number: 0
67 - Name: main
68 Value: 0
69 SectionNumber: 1
70 SimpleType: IMAGE_SYM_TYPE_NULL
71 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
72 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
73 - Name: bssdata4
74 Value: 4
75 SectionNumber: 0
76 SimpleType: IMAGE_SYM_TYPE_NULL
77 ComplexType: IMAGE_SYM_DTYPE_NULL
78 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
79 - Name: bsspad1
80 Value: 1
81 SectionNumber: 0
82 SimpleType: IMAGE_SYM_TYPE_NULL
83 ComplexType: IMAGE_SYM_DTYPE_NULL
84 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
85 - Name: bssdata64
86 Value: 64
87 SectionNumber: 0
88 SimpleType: IMAGE_SYM_TYPE_NULL
89 ComplexType: IMAGE_SYM_DTYPE_NULL
90 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
91 - Name: bsspad2
92 Value: 1
93 SectionNumber: 0
94 SimpleType: IMAGE_SYM_TYPE_NULL
95 ComplexType: IMAGE_SYM_DTYPE_NULL
96 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
97 - Name: bssdata16
98 Value: 16
99 SectionNumber: 0
100 SimpleType: IMAGE_SYM_TYPE_NULL
101 ComplexType: IMAGE_SYM_DTYPE_NULL
102 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
103...
deps/lld/test/COFF/conflict-mangled.test created+37
......@@ -0,0 +1,37 @@
1# REQUIRES: system-windows
2# RUN: yaml2obj < %s > %t1.obj
3# RUN: yaml2obj < %s > %t2.obj
4# RUN: not lld-link /out:%t.exe %t1.obj %t2.obj >& %t.log
5# RUN: FileCheck %s < %t.log
6
7# CHECK: duplicate symbol: "int __cdecl mangled(void)" (?mangled@@YAHXZ) in {{.+}}1.obj and in {{.+}}2.obj
8
9--- !COFF
10header:
11 Machine: IMAGE_FILE_MACHINE_AMD64
12 Characteristics: []
13sections:
14 - Name: .text
15 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
16 Alignment: 16
17 SectionData: 000000000000
18symbols:
19 - Name: .text
20 Value: 0
21 SectionNumber: 1
22 SimpleType: IMAGE_SYM_TYPE_NULL
23 ComplexType: IMAGE_SYM_DTYPE_NULL
24 StorageClass: IMAGE_SYM_CLASS_STATIC
25 SectionDefinition:
26 Length: 6
27 NumberOfRelocations: 0
28 NumberOfLinenumbers: 0
29 CheckSum: 0
30 Number: 0
31 - Name: '?mangled@@YAHXZ'
32 Value: 0
33 SectionNumber: 1
34 SimpleType: IMAGE_SYM_TYPE_NULL
35 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
36 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
37...
deps/lld/test/COFF/conflict.test created+42
......@@ -0,0 +1,42 @@
1# REQUIRES: x86
2# RUN: yaml2obj < %s > %t1.obj
3# RUN: yaml2obj < %s > %t2.obj
4# RUN: not lld-link /out:%t.exe %t1.obj %t2.obj >& %t.log
5# RUN: FileCheck %s < %t.log
6
7# RUN: llvm-as -o %t.lto1.obj %S/Inputs/conflict.ll
8# RUN: llvm-as -o %t.lto2.obj %S/Inputs/conflict.ll
9# RUN: not lld-link /out:%t.exe %t.lto1.obj %t.lto2.obj >& %t.log
10# RUN: FileCheck %s < %t.log
11
12# CHECK: duplicate symbol: foo in {{.+}}1.obj and in {{.+}}2.obj
13
14--- !COFF
15header:
16 Machine: IMAGE_FILE_MACHINE_AMD64
17 Characteristics: []
18sections:
19 - Name: .text
20 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
21 Alignment: 16
22 SectionData: 000000000000
23symbols:
24 - Name: .text
25 Value: 0
26 SectionNumber: 1
27 SimpleType: IMAGE_SYM_TYPE_NULL
28 ComplexType: IMAGE_SYM_DTYPE_NULL
29 StorageClass: IMAGE_SYM_CLASS_STATIC
30 SectionDefinition:
31 Length: 6
32 NumberOfRelocations: 0
33 NumberOfLinenumbers: 0
34 CheckSum: 0
35 Number: 0
36 - Name: foo
37 Value: 0
38 SectionNumber: 1
39 SimpleType: IMAGE_SYM_TYPE_NULL
40 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
41 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
42...
deps/lld/test/COFF/constant-export.test created+92
......@@ -0,0 +1,92 @@
1# RUN: mkdir -p %t
2# RUN: yaml2obj -o %t/constant-export.obj %s
3# RUN: lld-link /machine:x86 /dll /entry:__CFConstantStringClassReference -out:%t/constant-export.dll %t/constant-export.obj
4# RUN: llvm-readobj -coff-exports %t/constant-export.lib | FileCheck %s
5
6# CHECK: Type: const
7# CHECK: Name type: noprefix
8# CHECK: Symbol: __imp____CFConstantStringClassReference
9
10--- !COFF
11header:
12 Machine: IMAGE_FILE_MACHINE_I386
13 Characteristics: [ ]
14sections:
15 - Name: .text
16 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
17 Alignment: 4
18 SectionData: ''
19 - Name: .data
20 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
21 Alignment: 4
22 SectionData: ''
23 - Name: .bss
24 Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
25 Alignment: 4
26 SectionData: ''
27 - Name: .drectve
28 Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
29 Alignment: 1
30 SectionData: 20202D6578706F72743A5F5F5F4346436F6E7374616E74537472696E67436C6173735265666572656E63652C434F4E5354414E54
31symbols:
32 - Name: .text
33 Value: 0
34 SectionNumber: 1
35 SimpleType: IMAGE_SYM_TYPE_NULL
36 ComplexType: IMAGE_SYM_DTYPE_NULL
37 StorageClass: IMAGE_SYM_CLASS_STATIC
38 SectionDefinition:
39 Length: 0
40 NumberOfRelocations: 0
41 NumberOfLinenumbers: 0
42 CheckSum: 0
43 Number: 1
44 - Name: .data
45 Value: 0
46 SectionNumber: 2
47 SimpleType: IMAGE_SYM_TYPE_NULL
48 ComplexType: IMAGE_SYM_DTYPE_NULL
49 StorageClass: IMAGE_SYM_CLASS_STATIC
50 SectionDefinition:
51 Length: 0
52 NumberOfRelocations: 0
53 NumberOfLinenumbers: 0
54 CheckSum: 0
55 Number: 2
56 - Name: .bss
57 Value: 0
58 SectionNumber: 3
59 SimpleType: IMAGE_SYM_TYPE_NULL
60 ComplexType: IMAGE_SYM_DTYPE_NULL
61 StorageClass: IMAGE_SYM_CLASS_STATIC
62 SectionDefinition:
63 Length: 0
64 NumberOfRelocations: 0
65 NumberOfLinenumbers: 0
66 CheckSum: 0
67 Number: 3
68 - Name: .drectve
69 Value: 0
70 SectionNumber: 4
71 SimpleType: IMAGE_SYM_TYPE_NULL
72 ComplexType: IMAGE_SYM_DTYPE_NULL
73 StorageClass: IMAGE_SYM_CLASS_STATIC
74 SectionDefinition:
75 Length: 52
76 NumberOfRelocations: 0
77 NumberOfLinenumbers: 0
78 CheckSum: 1983959296
79 Number: 4
80 - Name: '@feat.00'
81 Value: 1
82 SectionNumber: -1
83 SimpleType: IMAGE_SYM_TYPE_NULL
84 ComplexType: IMAGE_SYM_DTYPE_NULL
85 StorageClass: IMAGE_SYM_CLASS_STATIC
86 - Name: ___CFConstantStringClassReference
87 Value: 128
88 SectionNumber: 0
89 SimpleType: IMAGE_SYM_TYPE_NULL
90 ComplexType: IMAGE_SYM_DTYPE_NULL
91 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
92...
deps/lld/test/COFF/constant.test created+6
......@@ -0,0 +1,6 @@
1REQUIRES: x86
2RUN: mkdir -p %t
3RUN: llvm-mc -triple i686-unknown-windows-msvc -filetype obj -o %t/import.o %S/Inputs/constant-import.s
4RUN: llc -mtriple i686-unknown-windows-msvc -filetype obj -o %t/export.o %S/Inputs/constant-export.ll
5RUN: lld-link -machine:x86 -dll -out:%t/export.dll %t/export.o -entry:__CFConstantStringClassReference
6RUN: lld-link -machine:x86 -dll -out:%t/import.dll %t/import.o %t/export.lib
deps/lld/test/COFF/debug.test created+38
......@@ -0,0 +1,38 @@
1# RUN: yaml2obj %s > %t.obj
2# RUN: lld-link /out:%t.exe /entry:main /subsystem:console %t.obj
3
4--- !COFF
5header:
6 Machine: IMAGE_FILE_MACHINE_AMD64
7 Characteristics: []
8sections:
9 - Name: .text
10 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
11 Alignment: 4
12 SectionData: B82A000000C3
13symbols:
14 - Name: .text
15 Value: 0
16 SectionNumber: 1
17 SimpleType: IMAGE_SYM_TYPE_NULL
18 ComplexType: IMAGE_SYM_DTYPE_NULL
19 StorageClass: IMAGE_SYM_CLASS_STATIC
20 SectionDefinition:
21 Length: 6
22 NumberOfRelocations: 0
23 NumberOfLinenumbers: 0
24 CheckSum: 0
25 Number: 0
26 - Name: main
27 Value: 0
28 SectionNumber: 1
29 SimpleType: IMAGE_SYM_TYPE_NULL
30 ComplexType: IMAGE_SYM_DTYPE_NULL
31 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
32 - Name: debug
33 Value: 0
34 SectionNumber: -2
35 SimpleType: IMAGE_SYM_TYPE_NULL
36 ComplexType: IMAGE_SYM_DTYPE_NULL
37 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
38...
deps/lld/test/COFF/def-export-stdcall.s created+27
......@@ -0,0 +1,27 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=i686-windows-msvc %s -o %t.obj
3# RUN: echo -e "LIBRARY foo\nEXPORTS\n stdcall" > %t.def
4# RUN: lld-link -entry:dllmain -dll -def:%t.def %t.obj -out:%t.dll -implib:%t.lib
5# RUN: llvm-readobj %t.lib | FileCheck %s
6# CHECK: Name type: undecorate
7# CHECK: __imp__stdcall@8
8# CHECK: _stdcall@8
9
10 .def _stdcall@8;
11 .scl 2;
12 .type 32;
13 .endef
14 .globl _stdcall@8
15_stdcall@8:
16 movl 8(%esp), %eax
17 addl 4(%esp), %eax
18 retl $8
19
20 .def _dllmain;
21 .scl 2;
22 .type 32;
23 .endef
24 .globl _dllmain
25_dllmain:
26 retl
27
deps/lld/test/COFF/def-name.test created+26
......@@ -0,0 +1,26 @@
1# RUN: rm -rf %t
2# RUN: mkdir -p %t
3# RUN: cd %t
4# RUN: yaml2obj < %p/Inputs/ret42.yaml > in.obj
5
6# RUN: lld-link /entry:main in.obj
7# RUN: lld-link /entry:main /dll in.obj
8
9# RUN: echo -e "NAME foo\n" > fooexe.def
10# RUN: echo -e "LIBRARY foo\n" > foodll.def
11# RUN: lld-link /entry:main /def:fooexe.def in.obj
12# RUN: lld-link /entry:main /def:foodll.def /dll in.obj
13
14# RUN: lld-link /entry:main /out:bar.exe /def:fooexe.def in.obj
15# RUN: lld-link /entry:main /out:bar.dll /def:foodll.def /dll in.obj
16
17# RUN: llvm-readobj in.exe | FileCheck %s
18# RUN: llvm-readobj in.dll | FileCheck %s
19
20# RUN: llvm-readobj foo.exe | FileCheck %s
21# RUN: llvm-readobj foo.dll | FileCheck %s
22
23# RUN: llvm-readobj bar.exe | FileCheck %s
24# RUN: llvm-readobj bar.dll | FileCheck %s
25
26CHECK: File:
deps/lld/test/COFF/defparser.test created+13
......@@ -0,0 +1,13 @@
1# RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj
2
3# RUN: echo -e "LIBRARY foo\nEXPORTS ? @" > %t.def
4# RUN: not lld-link /def:%t.def %t.obj
5
6# RUN: echo -e "LIBRARY foo\nHEAP abc" > %t.def
7# RUN: not lld-link /def:%t.def %t.obj
8
9# RUN: echo -e "LIBRARY foo\nSTACK abc" > %t.def
10# RUN: not lld-link /def:%t.def %t.obj
11
12# RUN: echo -e "foo" > %t.def
13# RUN: not lld-link /def:%t.def %t.obj
deps/lld/test/COFF/delayimports-error.test created+46
......@@ -0,0 +1,46 @@
1# RUN: mkdir -p %t.dir
2# RUN: yaml2obj < %p/Inputs/delayimports-error.yaml > %t1.obj
3# RUN: lld-link /out:%t.dir/foo.dll /dll %t1.obj /export:datasym,DATA /noentry
4
5# RUN: yaml2obj < %s > %t2.obj
6# RUN: not lld-link /out:%t.exe /entry:main %t2.obj %t.dir/foo.lib /delayload:foo.dll \
7# RUN: /alternatename:__delayLoadHelper2=main /opt:noref >& %t.log
8# RUN: FileCheck %s < %t.log
9
10# CHECK: cannot delay-load foo.dll due to import of data: __imp_datasym
11
12--- !COFF
13header:
14 Machine: IMAGE_FILE_MACHINE_AMD64
15 Characteristics: []
16sections:
17 - Name: .text
18 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
19 Alignment: 16
20 SectionData: 0000000000000000
21symbols:
22 - Name: .text
23 Value: 0
24 SectionNumber: 1
25 SimpleType: IMAGE_SYM_TYPE_NULL
26 ComplexType: IMAGE_SYM_DTYPE_NULL
27 StorageClass: IMAGE_SYM_CLASS_STATIC
28 SectionDefinition:
29 Length: 8
30 NumberOfRelocations: 0
31 NumberOfLinenumbers: 0
32 CheckSum: 0
33 Number: 0
34 - Name: main
35 Value: 0
36 SectionNumber: 1
37 SimpleType: IMAGE_SYM_TYPE_NULL
38 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
39 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
40 - Name: __imp_datasym
41 Value: 0
42 SectionNumber: 0
43 SimpleType: IMAGE_SYM_TYPE_NULL
44 ComplexType: IMAGE_SYM_DTYPE_NULL
45 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
46...
deps/lld/test/COFF/delayimports.test created+41
......@@ -0,0 +1,41 @@
1# RUN: lld-link /out:%t.exe /entry:main /subsystem:console \
2# RUN: %p/Inputs/hello64.obj %p/Inputs/std64.lib /delayload:STD64.DLL \
3# RUN: /alternatename:__delayLoadHelper2=main
4# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORT %s
5# RUN: llvm-readobj -coff-basereloc %t.exe | FileCheck -check-prefix=BASEREL %s
6
7IMPORT: DelayImport {
8IMPORT-NEXT: Name: std64.dll
9IMPORT-NEXT: Attributes: 0x1
10IMPORT-NEXT: ModuleHandle: 0x1018
11IMPORT-NEXT: ImportAddressTable: 0x1020
12IMPORT-NEXT: ImportNameTable: 0x3040
13IMPORT-NEXT: BoundDelayImportTable: 0x0
14IMPORT-NEXT: UnloadDelayImportTable: 0x0
15IMPORT-NEXT: Import {
16IMPORT-NEXT: Symbol: ExitProcess (0)
17IMPORT-NEXT: Address: 0x140002066
18IMPORT-NEXT: }
19IMPORT-NEXT: Import {
20IMPORT-NEXT: Symbol: (50)
21IMPORT-NEXT: Address: 0x1400020BD
22IMPORT-NEXT: }
23IMPORT-NEXT: Import {
24IMPORT-NEXT: Symbol: MessageBoxA (0)
25IMPORT-NEXT: Address: 0x140002114
26IMPORT-NEXT: }
27IMPORT-NEXT: }
28
29BASEREL: BaseReloc [
30BASEREL-NEXT: Entry {
31BASEREL-NEXT: Type: DIR64
32BASEREL-NEXT: Address: 0x1020
33BASEREL-NEXT: }
34BASEREL-NEXT: Entry {
35BASEREL-NEXT: Type: DIR64
36BASEREL-NEXT: Address: 0x1028
37BASEREL-NEXT: }
38BASEREL-NEXT: Entry {
39BASEREL-NEXT: Type: DIR64
40BASEREL-NEXT: Address: 0x1030
41BASEREL-NEXT: }
deps/lld/test/COFF/delayimports32.test created+87
......@@ -0,0 +1,87 @@
1# REQUIRES: x86
2# RUN: yaml2obj < %p/Inputs/hello32.yaml > %t.obj
3# RUN: lld-link %t.obj %p/Inputs/std32.lib /subsystem:console \
4# RUN: /entry:main@0 /alternatename:___delayLoadHelper2@8=_main@0 \
5# RUN: /debug /delayload:std32.dll /out:%t.exe
6# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORT %s
7# RUN: llvm-readobj -coff-basereloc %t.exe | FileCheck -check-prefix=BASEREL %s
8# RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=DISASM %s
9
10IMPORT: Format: COFF-i386
11IMPORT-NEXT: Arch: i386
12IMPORT-NEXT: AddressSize: 32bit
13IMPORT-NEXT: DelayImport {
14IMPORT-NEXT: Name: std32.dll
15IMPORT-NEXT: Attributes: 0x1
16IMPORT-NEXT: ModuleHandle: 0x1018
17IMPORT-NEXT: ImportAddressTable: 0x1020
18IMPORT-NEXT: ImportNameTable: 0x4040
19IMPORT-NEXT: BoundDelayImportTable: 0x0
20IMPORT-NEXT: UnloadDelayImportTable: 0x0
21IMPORT-NEXT: Import {
22IMPORT-NEXT: Symbol: ExitProcess (0)
23IMPORT-NEXT: Address: 0x402029
24IMPORT-NEXT: }
25IMPORT-NEXT: Import {
26IMPORT-NEXT: Symbol: MessageBoxA (0)
27IMPORT-NEXT: Address: 0x40203E
28IMPORT-NEXT: }
29IMPORT-NEXT: }
30
31BASEREL: BaseReloc [
32BASEREL-NEXT: Entry {
33BASEREL-NEXT: Type: HIGHLOW
34BASEREL-NEXT: Address: 0x1020
35BASEREL-NEXT: }
36BASEREL-NEXT: Entry {
37BASEREL-NEXT: Type: HIGHLOW
38BASEREL-NEXT: Address: 0x1024
39BASEREL-NEXT: }
40BASEREL-NEXT: Entry {
41BASEREL-NEXT: Type: HIGHLOW
42BASEREL-NEXT: Address: 0x2005
43BASEREL-NEXT: }
44BASEREL-NEXT: Entry {
45BASEREL-NEXT: Type: HIGHLOW
46BASEREL-NEXT: Address: 0x200C
47BASEREL-NEXT: }
48BASEREL-NEXT: Entry {
49BASEREL-NEXT: Type: HIGHLOW
50BASEREL-NEXT: Address: 0x201F
51BASEREL-NEXT: }
52BASEREL-NEXT: Entry {
53BASEREL-NEXT: Type: HIGHLOW
54BASEREL-NEXT: Address: 0x2025
55BASEREL-NEXT: }
56BASEREL-NEXT: Entry {
57BASEREL-NEXT: Type: HIGHLOW
58BASEREL-NEXT: Address: 0x202C
59BASEREL-NEXT: }
60BASEREL-NEXT: Entry {
61BASEREL-NEXT: Type: HIGHLOW
62BASEREL-NEXT: Address: 0x2031
63BASEREL-NEXT: }
64BASEREL-NEXT: Entry {
65BASEREL-NEXT: Type: HIGHLOW
66BASEREL-NEXT: Address: 0x2041
67BASEREL-NEXT: }
68BASEREL-NEXT: Entry {
69BASEREL-NEXT: Type: HIGHLOW
70BASEREL-NEXT: Address: 0x2046
71BASEREL-NEXT: }
72BASEREL-NEXT: ]
73
74DISASM: 202b: 68 20 10 40 00 pushl $4198432
75DISASM-NEXT: 2030: 68 00 40 40 00 pushl $4210688
76DISASM-NEXT: 2035: e8 c6 ff ff ff calll -58 <_main@0>
77DISASM-NEXT: 203a: 5a popl %edx
78DISASM-NEXT: 203b: 59 popl %ecx
79DISASM-NEXT: 203c: ff e0 jmpl *%eax
80DISASM-NEXT: 203e: 51 pushl %ecx
81DISASM-NEXT: 203f: 52 pushl %edx
82DISASM-NEXT: 2040: 68 24 10 40 00 pushl $4198436
83DISASM-NEXT: 2045: 68 00 40 40 00 pushl $4210688
84DISASM-NEXT: 204a: e8 b1 ff ff ff calll -79 <_main@0>
85DISASM-NEXT: 204f: 5a popl %edx
86DISASM-NEXT: 2050: 59 popl %ecx
87DISASM-NEXT: 2051: ff e0 jmpl *%eax
deps/lld/test/COFF/dll.test created+50
......@@ -0,0 +1,50 @@
1# RUN: yaml2obj < %p/Inputs/export.yaml > %t.obj
2# RUN: lld-link /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2 \
3# RUN: /export:mangled
4# RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=EXPORT %s
5
6EXPORT: Export Table:
7EXPORT: DLL name: dll.test.tmp.dll
8EXPORT: Ordinal RVA Name
9EXPORT-NEXT: 0 0
10EXPORT-NEXT: 1 0x1008 exportfn1
11EXPORT-NEXT: 2 0x1010 exportfn2
12EXPORT-NEXT: 3 0x1010 exportfn3
13EXPORT-NEXT: 4 0x1010 mangled
14
15# RUN: yaml2obj < %p/Inputs/export2.yaml > %t5.obj
16# RUN: rm -f %t5.lib
17# RUN: llvm-ar cru %t5.lib %t5.obj
18# RUN: lld-link /out:%t5.dll /dll %t.obj %t5.lib /export:mangled2
19# RUN: llvm-objdump -p %t5.dll | FileCheck -check-prefix=EXPORT2 %s
20
21EXPORT2: Export Table:
22EXPORT2: DLL name: dll.test.tmp5.dll
23EXPORT2: Ordinal RVA Name
24EXPORT2-NEXT: 0 0
25EXPORT2-NEXT: 1 0x1010 exportfn3
26EXPORT2-NEXT: 2 0x101c mangled2
27
28# RUN: llvm-as -o %t.lto.obj %p/Inputs/export.ll
29# RUN: lld-link /out:%t.lto.dll /dll %t.lto.obj /export:exportfn1 /export:exportfn2
30# RUN: llvm-objdump -p %t.lto.dll | FileCheck -check-prefix=EXPORT-LTO %s
31
32EXPORT-LTO: Export Table:
33EXPORT-LTO: DLL name: dll.test.tmp.lto.dll
34EXPORT-LTO: Ordinal RVA Name
35EXPORT-LTO-NEXT: 0 0
36EXPORT-LTO-NEXT: 1 0x1010 exportfn1
37EXPORT-LTO-NEXT: 2 0x1020 exportfn2
38EXPORT-LTO-NEXT: 3 0x1030 exportfn3
39
40# RUN: lld-link /out:%t.dll /dll %t.obj /implib:%t2.lib \
41# RUN: /export:exportfn1 /export:exportfn2
42# RUN: yaml2obj < %p/Inputs/import.yaml > %t2.obj
43# RUN: lld-link /out:%t2.exe /entry:main %t2.obj %t2.lib
44# RUN: llvm-readobj -coff-imports %t2.exe | FileCheck -check-prefix=IMPORT %s
45
46# RUN: lld-link /out:%t2.lto.exe /entry:main %t2.obj %t.lto.lib
47# RUN: llvm-readobj -coff-imports %t2.lto.exe | FileCheck -check-prefix=IMPORT %s
48
49IMPORT: Symbol: exportfn1
50IMPORT: Symbol: exportfn2
deps/lld/test/COFF/dllimport-gc.test created+56
......@@ -0,0 +1,56 @@
1# RUN: yaml2obj < %p/Inputs/export.yaml > %t-lib.obj
2# RUN: lld-link /out:%t.dll /dll %t-lib.obj /implib:%t.lib /export:exportfn1
3
4# RUN: yaml2obj < %p/Inputs/oldname.yaml > %t-oldname.obj
5
6# RUN: yaml2obj < %s > %t.obj
7
8# RUN: lld-link /out:%t1.exe /entry:main %t.obj %t-oldname.obj %t.lib
9# RUN: llvm-readobj -coff-imports %t1.exe | FileCheck -check-prefix=REF %s
10# REF-NOT: Symbol: exportfn1
11
12# RUN: lld-link /out:%t2.exe /entry:main %t.obj %t-oldname.obj %t.lib /opt:noref
13# RUN: llvm-readobj -coff-imports %t2.exe | FileCheck -check-prefix=NOREF %s
14# NOREF: Symbol: exportfn1
15
16--- !COFF
17header:
18 Machine: IMAGE_FILE_MACHINE_AMD64
19 Characteristics: []
20sections:
21 - Name: .text
22 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
23 Alignment: 4
24 SectionData: 0000000000000000
25symbols:
26 - Name: .text
27 Value: 0
28 SectionNumber: 1
29 SimpleType: IMAGE_SYM_TYPE_NULL
30 ComplexType: IMAGE_SYM_DTYPE_NULL
31 StorageClass: IMAGE_SYM_CLASS_STATIC
32 SectionDefinition:
33 Length: 8
34 NumberOfRelocations: 0
35 NumberOfLinenumbers: 0
36 CheckSum: 0
37 Number: 0
38 - Name: main
39 Value: 0
40 SectionNumber: 1
41 SimpleType: IMAGE_SYM_TYPE_NULL
42 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
43 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
44 - Name: exportfn1
45 Value: 0
46 SectionNumber: 0
47 SimpleType: IMAGE_SYM_TYPE_NULL
48 ComplexType: IMAGE_SYM_DTYPE_NULL
49 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
50 - Name: exportfn1_alias
51 Value: 0
52 SectionNumber: 0
53 SimpleType: IMAGE_SYM_TYPE_NULL
54 ComplexType: IMAGE_SYM_DTYPE_NULL
55 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
56...
deps/lld/test/COFF/driver-windows.test created+3
......@@ -0,0 +1,3 @@
1# REQUIRES: system-windows
2# RUN: not LLD-LINK 2>&1 | FileCheck %s
3CHECK: no input files
deps/lld/test/COFF/driver.test created+3
......@@ -0,0 +1,3 @@
1# RUN: not lld-link nosuchfile.obj >& %t.log
2# RUN: FileCheck -check-prefix=MISSING %s < %t.log
3MISSING: nosuchfile.obj: {{[Nn]}}o such file or directory
deps/lld/test/COFF/entry-inference.test created+50
......@@ -0,0 +1,50 @@
1# RUN: sed -e s/ENTRYNAME/main/ %s | yaml2obj > %t.obj
2# RUN: not lld-link /out:%t.exe %t.obj > %t.log 2>&1
3# RUN: FileCheck -check-prefix=MAIN %s < %t.log
4
5# RUN: sed s/ENTRYNAME/wmain/ %s | yaml2obj > %t.obj
6# RUN: not lld-link /out:%t.exe %t.obj > %t.log 2>&1
7# RUN: FileCheck -check-prefix=WMAIN %s < %t.log
8
9# RUN: sed s/ENTRYNAME/WinMain/ %s | yaml2obj > %t.obj
10# RUN: not lld-link /out:%t.exe %t.obj > %t.log 2>&1
11# RUN: FileCheck -check-prefix=WINMAIN %s < %t.log
12
13# RUN: sed s/ENTRYNAME/wWinMain/ %s | yaml2obj > %t.obj
14# RUN: not lld-link /out:%t.exe %t.obj > %t.log 2>&1
15# RUN: FileCheck -check-prefix=WWINMAIN %s < %t.log
16
17# MAIN: <root>: undefined symbol: mainCRTStartup
18# WMAIN: <root>: undefined symbol: wmainCRTStartup
19# WINMAIN: <root>: undefined symbol: WinMainCRTStartup
20# WWINMAIN: <root>: undefined symbol: wWinMainCRTStartup
21
22--- !COFF
23header:
24 Machine: IMAGE_FILE_MACHINE_AMD64
25 Characteristics: []
26sections:
27 - Name: .text
28 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
29 Alignment: 4
30 SectionData: B82A000000C3
31symbols:
32 - Name: .text
33 Value: 0
34 SectionNumber: 1
35 SimpleType: IMAGE_SYM_TYPE_NULL
36 ComplexType: IMAGE_SYM_DTYPE_NULL
37 StorageClass: IMAGE_SYM_CLASS_STATIC
38 SectionDefinition:
39 Length: 6
40 NumberOfRelocations: 0
41 NumberOfLinenumbers: 0
42 CheckSum: 0
43 Number: 0
44 - Name: ENTRYNAME
45 Value: 0
46 SectionNumber: 1
47 SimpleType: IMAGE_SYM_TYPE_NULL
48 ComplexType: IMAGE_SYM_DTYPE_NULL
49 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
50...
deps/lld/test/COFF/entry-inference2.test created+39
......@@ -0,0 +1,39 @@
1# RUN: yaml2obj < %s > %t.obj
2# RUN: not lld-link /out:%t.exe %t.obj /verbose > %t.log 2>&1
3# RUN: FileCheck %s < %t.log
4
5# CHECK: Entry name inferred: WinMainCRTStartup
6
7--- !COFF
8header:
9 Machine: IMAGE_FILE_MACHINE_AMD64
10 Characteristics: []
11sections:
12 - Name: .text
13 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
14 Alignment: 4
15 SectionData: B82A000000C3
16 - Name: .drectve
17 Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
18 Alignment: 1
19 SectionData: 2f616c7465726e6174656e616d653a6d61696e3d57696e4d61696e00 # /alternatename:main=WinMain
20symbols:
21 - Name: .text
22 Value: 0
23 SectionNumber: 1
24 SimpleType: IMAGE_SYM_TYPE_NULL
25 ComplexType: IMAGE_SYM_DTYPE_NULL
26 StorageClass: IMAGE_SYM_CLASS_STATIC
27 SectionDefinition:
28 Length: 6
29 NumberOfRelocations: 0
30 NumberOfLinenumbers: 0
31 CheckSum: 0
32 Number: 0
33 - Name: WinMain
34 Value: 0
35 SectionNumber: 1
36 SimpleType: IMAGE_SYM_TYPE_NULL
37 ComplexType: IMAGE_SYM_DTYPE_NULL
38 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
39...
deps/lld/test/COFF/entry-inference32.test created+35
......@@ -0,0 +1,35 @@
1# RUN: yaml2obj < %s > %t.obj
2# RUN: not lld-link /out:%t.exe %t.obj /verbose > %t.log 2>&1
3# RUN: FileCheck %s < %t.log
4
5# CHECK: Entry name inferred: _WinMainCRTStartup
6
7--- !COFF
8header:
9 Machine: IMAGE_FILE_MACHINE_I386
10 Characteristics: []
11sections:
12 - Name: .text
13 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
14 Alignment: 4
15 SectionData: B82A000000C3
16symbols:
17 - Name: .text
18 Value: 0
19 SectionNumber: 1
20 SimpleType: IMAGE_SYM_TYPE_NULL
21 ComplexType: IMAGE_SYM_DTYPE_NULL
22 StorageClass: IMAGE_SYM_CLASS_STATIC
23 SectionDefinition:
24 Length: 6
25 NumberOfRelocations: 0
26 NumberOfLinenumbers: 0
27 CheckSum: 0
28 Number: 0
29 - Name: _WinMain@16
30 Value: 0
31 SectionNumber: 1
32 SimpleType: IMAGE_SYM_TYPE_NULL
33 ComplexType: IMAGE_SYM_DTYPE_NULL
34 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
35...
deps/lld/test/COFF/entry-mangled.test created+36
......@@ -0,0 +1,36 @@
1# REQUIRES: x86
2# RUN: yaml2obj < %s > %t.obj
3# RUN: lld-link /out:%t.exe /entry:main %t.obj
4# RUN: llvm-as -o %t.lto.obj %S/Inputs/entry-mangled.ll
5# RUN: lld-link /out:%t.exe /entry:main %t.lto.obj
6
7--- !COFF
8header:
9 Machine: IMAGE_FILE_MACHINE_AMD64
10 Characteristics: []
11sections:
12 - Name: .text
13 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
14 Alignment: 4
15 SectionData: 000000000000
16symbols:
17 - Name: .text
18 Value: 0
19 SectionNumber: 1
20 SimpleType: IMAGE_SYM_TYPE_NULL
21 ComplexType: IMAGE_SYM_DTYPE_NULL
22 StorageClass: IMAGE_SYM_CLASS_STATIC
23 SectionDefinition:
24 Length: 6
25 NumberOfRelocations: 0
26 NumberOfLinenumbers: 0
27 CheckSum: 0
28 Number: 0
29 Selection: IMAGE_COMDAT_SELECT_ANY
30 - Name: '?main@@YAHXZ'
31 Value: 0
32 SectionNumber: 1
33 SimpleType: IMAGE_SYM_TYPE_NULL
34 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
35 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
36...
deps/lld/test/COFF/entrylib.ll created+12
......@@ -0,0 +1,12 @@
1; REQUIRES: x86
2; RUN: llvm-as -o %t.obj %s
3; RUN: rm -f %t.lib
4; RUN: llvm-ar cru %t.lib %t.obj
5; RUN: lld-link /out:%t.exe /entry:main %t.lib
6
7target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
8target triple = "x86_64-pc-windows-msvc"
9
10define i32 @main() {
11 ret i32 0
12}
deps/lld/test/COFF/error-limit.test created+29
......@@ -0,0 +1,29 @@
1RUN: not lld-link 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 \
2RUN: 21 22 2>&1 | FileCheck -check-prefix=DEFAULT %s
3
4DEFAULT: could not open 01
5DEFAULT: could not open 20
6DEFAULT-NEXT: too many errors emitted, stopping now (use /ERRORLIMIT:0 to see all errors)
7DEFAULT-NOT: could not open 21
8
9RUN: not lld-link /ERRORLIMIT:5 01 02 03 04 05 06 07 08 09 10 2>&1 \
10RUN: | FileCheck -check-prefix=LIMIT5 %s
11
12LIMIT5: could not open 01
13LIMIT5: could not open 05
14LIMIT5-NEXT: too many errors emitted, stopping now (use /ERRORLIMIT:0 to see all errors)
15LIMIT5-NOT: could not open 06
16
17RUN: not lld-link /ERRORLIMIT:0 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 \
18RUN: 16 17 18 19 20 21 22 2>&1 | FileCheck -check-prefix=UNLIMITED %s
19
20UNLIMITED: could not open 01
21UNLIMITED: could not open 20
22UNLIMITED: could not open 21
23UNLIMITED: could not open 22
24UNLIMITED-NOT: too many errors emitted, stopping now (use /ERRORLIMIT:0 to see all errors)
25
26RUN: not lld-link /ERRORLIMIT:XYZ 01 02 03 04 05 06 07 08 09 10 11 12 13 14 \
27RUN: 15 16 17 18 19 20 21 22 2>&1 | FileCheck -check-prefix=WRONG %s
28
29WRONG: /ERRORLIMIT: number expected, but got XYZ
deps/lld/test/COFF/export-exe.test created+10
......@@ -0,0 +1,10 @@
1# RUN: lld-link /entry:main /out:%t.exe /subsystem:windows \
2# RUN: %p/Inputs/ret42.obj /export:main
3# RUN: llvm-objdump -p %t.exe | FileCheck %s
4
5CHECK: Export Table:
6CHECK-NEXT: DLL name: export-exe.test.tmp.exe
7CHECK-NEXT: Ordinal base: 0
8CHECK-NEXT: Ordinal RVA Name
9CHECK-NEXT: 0 0
10CHECK-NEXT: 1 0x1000 main
deps/lld/test/COFF/export.test created+95
......@@ -0,0 +1,95 @@
1# RUN: yaml2obj < %p/Inputs/export.yaml > %t.obj
2#
3# RUN: lld-link /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2
4# RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK1 %s
5
6CHECK1: Export Table:
7CHECK1: DLL name: export.test.tmp.dll
8CHECK1: Ordinal RVA Name
9CHECK1-NEXT: 0 0
10CHECK1-NEXT: 1 0x1008 exportfn1
11CHECK1-NEXT: 2 0x1010 exportfn2
12
13# RUN: lld-link /out:%t.dll /dll %t.obj /export:exportfn1,@5 /export:exportfn2
14# RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK2 %s
15
16CHECK2: Export Table:
17CHECK2: DLL name: export.test.tmp.dll
18CHECK2: Ordinal RVA Name
19CHECK2-NEXT: 0 0
20CHECK2-NEXT: 1 0
21CHECK2-NEXT: 2 0
22CHECK2-NEXT: 3 0
23CHECK2-NEXT: 4 0
24CHECK2-NEXT: 5 0x1008 exportfn1
25CHECK2-NEXT: 6 0x1010 exportfn2
26CHECK2-NEXT: 7 0x1010 exportfn3
27
28# RUN: lld-link /out:%t.dll /dll %t.obj /export:exportfn1,@5,noname /export:exportfn2
29# RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK3 %s
30
31CHECK3: Export Table:
32CHECK3: DLL name: export.test.tmp.dll
33CHECK3: Ordinal RVA Name
34CHECK3-NEXT: 0 0
35CHECK3-NEXT: 1 0
36CHECK3-NEXT: 2 0
37CHECK3-NEXT: 3 0
38CHECK3-NEXT: 4 0
39CHECK3-NEXT: 5 0x1008
40CHECK3-NEXT: 6 0x1010 exportfn2
41
42# RUN: lld-link /out:%t.dll /dll %t.obj /export:f1=exportfn1 /export:f2=exportfn2 /implib:%t.lib
43# RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK4 %s
44# RUN: llvm-nm %t.lib | FileCheck -check-prefix=CHECK4-NM %s
45
46CHECK4: Export Table:
47CHECK4: DLL name: export.test.tmp.dll
48CHECK4: Ordinal RVA Name
49CHECK4-NEXT: 0 0
50CHECK4-NEXT: 1 0x1010 exportfn3
51CHECK4-NEXT: 2 0x1008 f1
52CHECK4-NEXT: 3 0x1010 f2
53CHECK4-NM: 00000000 T f1
54CHECK4-NM: 00000000 T f2
55
56# RUN: echo "EXPORTS exportfn1 @3" > %t.def
57# RUN: echo "fn2=exportfn2 @2" >> %t.def
58# RUN: lld-link /out:%t.dll /dll %t.obj /def:%t.def
59# RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK5 %s
60
61CHECK5: Export Table:
62CHECK5: DLL name: export.test.tmp.dll
63CHECK5: Ordinal RVA Name
64CHECK5-NEXT: 0 0
65CHECK5-NEXT: 1 0
66CHECK5-NEXT: 2 0x1010 fn2
67CHECK5-NEXT: 3 0x1008 exportfn1
68CHECK5-NEXT: 4 0x1010 exportfn3
69
70# RUN: lld-link /out:%t.DLL /dll %t.obj /export:exportfn1 /export:exportfn2 \
71# RUN: /export:exportfn1 /export:exportfn2,@5 >& %t.log
72# RUN: FileCheck -check-prefix=CHECK6 %s < %t.log
73
74CHECK6: duplicate /export option: exportfn2
75CHECK6-NOT: duplicate /export option: exportfn1
76
77# RUN: llvm-nm -M %t.lib | FileCheck --check-prefix=SYMTAB %s
78
79SYMTAB: __imp_exportfn1 in export.test.tmp.DLL
80SYMTAB: exportfn1 in export.test.tmp.DLL
81SYMTAB: __imp_exportfn2 in export.test.tmp.DLL
82SYMTAB: exportfn2 in export.test.tmp.DLL
83SYMTAB: __imp_exportfn3 in export.test.tmp.DLL
84SYMTAB: exportfn3 in export.test.tmp.DLL
85
86# RUN: lld-link /out:%t.dll /dll %t.obj /export:foo=kernel32.foobar
87# RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=FORWARDER %s
88
89FORWARDER: Export Table:
90FORWARDER: DLL name: export.test.tmp.dll
91FORWARDER: Ordinal base: 0
92FORWARDER: Ordinal RVA Name
93FORWARDER: 0 0
94FORWARDER: 1 0x1010 exportfn
95FORWARDER: 2 foo (forwarded to kernel32.foobar)
deps/lld/test/COFF/export32.test created+142
......@@ -0,0 +1,142 @@
1# RUN: yaml2obj < %s > %t.obj
2#
3# RUN: lld-link /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2
4# RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK1 %s
5
6# CHECK1: Export Table:
7# CHECK1: DLL name: export32.test.tmp.dll
8# CHECK1: Ordinal RVA Name
9# CHECK1-NEXT: 0 0
10# CHECK1-NEXT: 1 0x1008 exportfn1
11# CHECK1-NEXT: 2 0x1010 exportfn2
12
13# RUN: lld-link /out:%t.dll /dll %t.obj /export:exportfn1,@5 \
14# RUN: /export:exportfn2 /export:mangled
15# RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK2 %s
16
17# CHECK2: Export Table:
18# CHECK2: DLL name: export32.test.tmp.dll
19# CHECK2: Ordinal RVA Name
20# CHECK2-NEXT: 0 0
21# CHECK2-NEXT: 1 0
22# CHECK2-NEXT: 2 0
23# CHECK2-NEXT: 3 0
24# CHECK2-NEXT: 4 0
25# CHECK2-NEXT: 5 0x1008 exportfn1
26# CHECK2-NEXT: 6 0x1010 exportfn2
27# CHECK2-NEXT: 7 0x1010 exportfn3
28# CHECK2-NEXT: 8 0x1010 mangled
29
30# RUN: lld-link /out:%t.dll /dll %t.obj /export:exportfn1,@5,noname /export:exportfn2
31# RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK3 %s
32
33# CHECK3: Export Table:
34# CHECK3: DLL name: export32.test.tmp.dll
35# CHECK3: Ordinal RVA Name
36# CHECK3-NEXT: 0 0
37# CHECK3-NEXT: 1 0
38# CHECK3-NEXT: 2 0
39# CHECK3-NEXT: 3 0
40# CHECK3-NEXT: 4 0
41# CHECK3-NEXT: 5 0x1008
42# CHECK3-NEXT: 6 0x1010 exportfn2
43
44# RUN: lld-link /out:%t.dll /dll %t.obj /export:f1=exportfn1 /export:f2=exportfn2
45# RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK4 %s
46
47# CHECK4: Export Table:
48# CHECK4: DLL name: export32.test.tmp.dll
49# CHECK4: Ordinal RVA Name
50# CHECK4-NEXT: 0 0
51# CHECK4-NEXT: 1 0x1010 exportfn3
52# CHECK4-NEXT: 2 0x1008 f1
53# CHECK4-NEXT: 3 0x1010 f2
54
55# RUN: echo "EXPORTS exportfn1 @3" > %t.def
56# RUN: echo "fn2=exportfn2 @2" >> %t.def
57# RUN: lld-link /out:%t.dll /dll %t.obj /def:%t.def
58# RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK5 %s
59
60# CHECK5: Export Table:
61# CHECK5: DLL name: export32.test.tmp.dll
62# CHECK5: Ordinal RVA Name
63# CHECK5-NEXT: 0 0
64# CHECK5-NEXT: 1 0
65# CHECK5-NEXT: 2 0x1010 fn2
66# CHECK5-NEXT: 3 0x1008 exportfn1
67# CHECK5-NEXT: 4 0x1010 exportfn3
68
69# RUN: lld-link /out:%t.dll /dll %t.obj /export:exportfn1 /export:exportfn2 \
70# RUN: /export:exportfn1 /export:exportfn2,@5 >& %t.log
71# RUN: FileCheck -check-prefix=CHECK6 %s < %t.log
72
73# CHECK6: duplicate /export option: _exportfn2
74# CHECK6-NOT: duplicate /export option: _exportfn1
75
76# RUN: lld-link /out:%t.dll /dll %t.obj /export:foo=mangled
77# RUN: llvm-objdump -p %t.dll | FileCheck -check-prefix=CHECK7 %s
78
79# CHECK7: Export Table:
80# CHECK7: DLL name: export32.test.tmp.dll
81# CHECK7: Ordinal RVA Name
82# CHECK7-NEXT: 0 0
83# CHECK7-NEXT: 1 0
84# CHECK7-NEXT: 2 0x1010 foo
85
86--- !COFF
87header:
88 Machine: IMAGE_FILE_MACHINE_I386
89 Characteristics: []
90sections:
91 - Name: .text
92 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
93 Alignment: 4
94 SectionData: B800000000506800000000680000000050E80000000050E800000000
95 - Name: .drectve
96 Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
97 Alignment: 1
98 SectionData: 2f6578706f72743a5f6578706f7274666e3300 # /export:_exportfn3
99symbols:
100 - Name: .text
101 Value: 0
102 SectionNumber: 1
103 SimpleType: IMAGE_SYM_TYPE_NULL
104 ComplexType: IMAGE_SYM_DTYPE_NULL
105 StorageClass: IMAGE_SYM_CLASS_STATIC
106 SectionDefinition:
107 Length: 28
108 NumberOfRelocations: 4
109 NumberOfLinenumbers: 0
110 CheckSum: 0
111 Number: 0
112 - Name: __DllMainCRTStartup@12
113 Value: 0
114 SectionNumber: 1
115 SimpleType: IMAGE_SYM_TYPE_NULL
116 ComplexType: IMAGE_SYM_DTYPE_NULL
117 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
118 - Name: _exportfn1
119 Value: 8
120 SectionNumber: 1
121 SimpleType: IMAGE_SYM_TYPE_NULL
122 ComplexType: IMAGE_SYM_DTYPE_NULL
123 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
124 - Name: _exportfn2@4
125 Value: 16
126 SectionNumber: 1
127 SimpleType: IMAGE_SYM_TYPE_NULL
128 ComplexType: IMAGE_SYM_DTYPE_NULL
129 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
130 - Name: _exportfn3
131 Value: 16
132 SectionNumber: 1
133 SimpleType: IMAGE_SYM_TYPE_NULL
134 ComplexType: IMAGE_SYM_DTYPE_NULL
135 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
136 - Name: '?mangled@@YAHXZ'
137 Value: 16
138 SectionNumber: 1
139 SimpleType: IMAGE_SYM_TYPE_NULL
140 ComplexType: IMAGE_SYM_DTYPE_NULL
141 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
142...
deps/lld/test/COFF/failifmismatch.test created+11
......@@ -0,0 +1,11 @@
1# RUN: lld-link /entry:main /subsystem:console /out:%t.exe \
2# RUN: %p/Inputs/ret42.obj
3
4# RUN: lld-link /entry:main /subsystem:console /out:%t.exe \
5# RUN: %p/Inputs/ret42.obj /failifmismatch:k1=v1 /failifmismatch:k2=v1
6
7# RUN: lld-link /entry:main /subsystem:console /out:%t.exe \
8# RUN: %p/Inputs/ret42.obj /failifmismatch:k1=v1 /failifmismatch:k1=v1
9
10# RUN: not lld-link /entry:main /subsystem:console /out:%t.exe \
11# RUN: %p/Inputs/ret42.obj /failifmismatch:k1=v1 /failifmismatch:k1=v2
deps/lld/test/COFF/filetype.test created+4
......@@ -0,0 +1,4 @@
1# Make sure input file type is detected by file magic and not by extension.
2
3# RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.lib
4# RUN: lld-link /out:%t.exe /entry:main %t.lib
deps/lld/test/COFF/force.test created+43
......@@ -0,0 +1,43 @@
1# RUN: yaml2obj < %s > %t.obj
2# RUN: not lld-link /out:%t.exe /entry:main %t.obj >& %t.log
3# RUN: FileCheck %s < %t.log
4# RUN: lld-link /out:%t.exe /entry:main %t.obj /force >& %t.log
5# RUN: FileCheck %s < %t.log
6
7# CHECK: .obj: undefined symbol: foo
8
9--- !COFF
10header:
11 Machine: IMAGE_FILE_MACHINE_AMD64
12 Characteristics: []
13sections:
14 - Name: .text
15 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
16 Alignment: 4
17 SectionData: 000000000000
18symbols:
19 - Name: .text
20 Value: 0
21 SectionNumber: 1
22 SimpleType: IMAGE_SYM_TYPE_NULL
23 ComplexType: IMAGE_SYM_DTYPE_NULL
24 StorageClass: IMAGE_SYM_CLASS_STATIC
25 SectionDefinition:
26 Length: 6
27 NumberOfRelocations: 0
28 NumberOfLinenumbers: 0
29 CheckSum: 0
30 Number: 0
31 - Name: main
32 Value: 0
33 SectionNumber: 1
34 SimpleType: IMAGE_SYM_TYPE_NULL
35 ComplexType: IMAGE_SYM_DTYPE_NULL
36 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
37 - Name: foo
38 Value: 0
39 SectionNumber: 0
40 SimpleType: IMAGE_SYM_TYPE_NULL
41 ComplexType: IMAGE_SYM_DTYPE_NULL
42 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
43...
deps/lld/test/COFF/guardcf.test created+74
......@@ -0,0 +1,74 @@
1# RUN: yaml2obj < %s > %t.obj
2# RUN: lld-link /entry:main /out:%t.exe %t.obj
3
4--- !COFF
5header:
6 Machine: IMAGE_FILE_MACHINE_AMD64
7 Characteristics: []
8sections:
9 - Name: .text
10 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
11 Alignment: 4
12 SectionData: 000000000000
13symbols:
14 - Name: .text
15 Value: 0
16 SectionNumber: 1
17 SimpleType: IMAGE_SYM_TYPE_NULL
18 ComplexType: IMAGE_SYM_DTYPE_NULL
19 StorageClass: IMAGE_SYM_CLASS_STATIC
20 SectionDefinition:
21 Length: 6
22 NumberOfRelocations: 0
23 NumberOfLinenumbers: 0
24 CheckSum: 0
25 Number: 0
26 - Name: main
27 Value: 0
28 SectionNumber: 1
29 SimpleType: IMAGE_SYM_TYPE_NULL
30 ComplexType: IMAGE_SYM_DTYPE_NULL
31 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
32 - Name: __guard_fids_count
33 Value: 0
34 SectionNumber: 0
35 SimpleType: IMAGE_SYM_TYPE_NULL
36 ComplexType: IMAGE_SYM_DTYPE_NULL
37 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
38 - Name: __guard_fids_table
39 Value: 0
40 SectionNumber: 0
41 SimpleType: IMAGE_SYM_TYPE_NULL
42 ComplexType: IMAGE_SYM_DTYPE_NULL
43 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
44 - Name: __guard_flags
45 Value: 0
46 SectionNumber: 0
47 SimpleType: IMAGE_SYM_TYPE_NULL
48 ComplexType: IMAGE_SYM_DTYPE_NULL
49 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
50 - Name: __guard_iat_count
51 Value: 0
52 SectionNumber: 0
53 SimpleType: IMAGE_SYM_TYPE_NULL
54 ComplexType: IMAGE_SYM_DTYPE_NULL
55 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
56 - Name: __guard_iat_table
57 Value: 0
58 SectionNumber: 0
59 SimpleType: IMAGE_SYM_TYPE_NULL
60 ComplexType: IMAGE_SYM_DTYPE_NULL
61 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
62 - Name: __guard_longjmp_count
63 Value: 0
64 SectionNumber: 0
65 SimpleType: IMAGE_SYM_TYPE_NULL
66 ComplexType: IMAGE_SYM_DTYPE_NULL
67 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
68 - Name: __guard_longjmp_table
69 Value: 0
70 SectionNumber: 0
71 SimpleType: IMAGE_SYM_TYPE_NULL
72 ComplexType: IMAGE_SYM_DTYPE_NULL
73 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
74...
deps/lld/test/COFF/heap.test created+25
......@@ -0,0 +1,25 @@
1# RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj
2
3# RUN: lld-link /out:%t.exe /entry:main %t.obj
4# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=DEFAULT %s
5
6DEFAULT: SizeOfHeapReserve: 1048576
7DEFAULT: SizeOfHeapCommit: 4096
8
9# RUN: lld-link /out:%t.exe /entry:main /heap:0x3000 %t.obj
10# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK1 %s
11# RUN: echo "HEAPSIZE 12288" > %t.def
12# RUN: lld-link /out:%t.exe /entry:main /def:%t.def %t.obj
13# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK1 %s
14
15CHECK1: SizeOfHeapReserve: 12288
16CHECK1: SizeOfHeapCommit: 4096
17
18# RUN: lld-link /out:%t.exe /entry:main /heap:0x5000,0x3000 %t.obj
19# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK2 %s
20# RUN: echo "HEAPSIZE 20480,12288" > %t.def
21# RUN: lld-link /out:%t.exe /entry:main /def:%t.def %t.obj
22# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK2 %s
23
24CHECK2: SizeOfHeapReserve: 20480
25CHECK2: SizeOfHeapCommit: 12288
deps/lld/test/COFF/hello32.test created+132
......@@ -0,0 +1,132 @@
1# RUN: yaml2obj < %p/Inputs/hello32.yaml > %t.obj
2# RUN: lld-link %t.obj %p/Inputs/std32.lib /subsystem:console \
3# RUN: /entry:main@0 /out:%t.exe /appcontainer
4# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=HEADER %s
5# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORTS %s
6# RUN: llvm-readobj -coff-basereloc %t.exe | FileCheck -check-prefix=BASEREL %s
7
8HEADER: Format: COFF-i386
9HEADER-NEXT: Arch: i386
10HEADER-NEXT: AddressSize: 32bit
11HEADER-NEXT: ImageFileHeader {
12HEADER-NEXT: Machine: IMAGE_FILE_MACHINE_I386 (0x14C)
13HEADER-NEXT: SectionCount: 4
14HEADER-NEXT: TimeDateStamp: 1970-01-01 00:00:00 (0x0)
15HEADER-NEXT: PointerToSymbolTable: 0x0
16HEADER-NEXT: SymbolCount: 0
17HEADER-NEXT: OptionalHeaderSize: 224
18HEADER-NEXT: Characteristics [ (0x102)
19HEADER-NEXT: IMAGE_FILE_32BIT_MACHINE (0x100)
20HEADER-NEXT: IMAGE_FILE_EXECUTABLE_IMAGE (0x2)
21HEADER-NEXT: ]
22HEADER-NEXT: }
23HEADER-NEXT: ImageOptionalHeader {
24HEADER-NEXT: Magic: 0x10B
25HEADER-NEXT: MajorLinkerVersion: 14
26HEADER-NEXT: MinorLinkerVersion: 0
27HEADER-NEXT: SizeOfCode: 512
28HEADER-NEXT: SizeOfInitializedData: 1536
29HEADER-NEXT: SizeOfUninitializedData: 0
30HEADER-NEXT: AddressOfEntryPoint: 0x2000
31HEADER-NEXT: BaseOfCode: 0x2000
32HEADER-NEXT: BaseOfData: 0x0
33HEADER-NEXT: ImageBase: 0x400000
34HEADER-NEXT: SectionAlignment: 4096
35HEADER-NEXT: FileAlignment: 512
36HEADER-NEXT: MajorOperatingSystemVersion: 6
37HEADER-NEXT: MinorOperatingSystemVersion: 0
38HEADER-NEXT: MajorImageVersion: 0
39HEADER-NEXT: MinorImageVersion: 0
40HEADER-NEXT: MajorSubsystemVersion: 6
41HEADER-NEXT: MinorSubsystemVersion: 0
42HEADER-NEXT: SizeOfImage: 16896
43HEADER-NEXT: SizeOfHeaders: 512
44HEADER-NEXT: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI (0x3)
45HEADER-NEXT: Characteristics [ (0x9940)
46HEADER-NEXT: IMAGE_DLL_CHARACTERISTICS_APPCONTAINER (0x1000)
47HEADER-NEXT: IMAGE_DLL_CHARACTERISTICS_DYNAMIC_BASE (0x40)
48HEADER-NEXT: IMAGE_DLL_CHARACTERISTICS_NO_BIND (0x800)
49HEADER-NEXT: IMAGE_DLL_CHARACTERISTICS_NX_COMPAT (0x100)
50HEADER-NEXT: IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE (0x8000)
51HEADER-NEXT: ]
52HEADER-NEXT: SizeOfStackReserve: 1048576
53HEADER-NEXT: SizeOfStackCommit: 4096
54HEADER-NEXT: SizeOfHeapReserve: 1048576
55HEADER-NEXT: SizeOfHeapCommit: 4096
56HEADER-NEXT: NumberOfRvaAndSize: 16
57HEADER-NEXT: DataDirectory {
58HEADER-NEXT: ExportTableRVA: 0x0
59HEADER-NEXT: ExportTableSize: 0x0
60HEADER-NEXT: ImportTableRVA: 0x3000
61HEADER-NEXT: ImportTableSize: 0x28
62HEADER-NEXT: ResourceTableRVA: 0x0
63HEADER-NEXT: ResourceTableSize: 0x0
64HEADER-NEXT: ExceptionTableRVA: 0x0
65HEADER-NEXT: ExceptionTableSize: 0x0
66HEADER-NEXT: CertificateTableRVA: 0x0
67HEADER-NEXT: CertificateTableSize: 0x0
68HEADER-NEXT: BaseRelocationTableRVA: 0x4000
69HEADER-NEXT: BaseRelocationTableSize: 0x10
70HEADER-NEXT: DebugRVA: 0x0
71HEADER-NEXT: DebugSize: 0x0
72HEADER-NEXT: ArchitectureRVA: 0x0
73HEADER-NEXT: ArchitectureSize: 0x0
74HEADER-NEXT: GlobalPtrRVA: 0x0
75HEADER-NEXT: GlobalPtrSize: 0x0
76HEADER-NEXT: TLSTableRVA: 0x0
77HEADER-NEXT: TLSTableSize: 0x0
78HEADER-NEXT: LoadConfigTableRVA: 0x0
79HEADER-NEXT: LoadConfigTableSize: 0x0
80HEADER-NEXT: BoundImportRVA: 0x0
81HEADER-NEXT: BoundImportSize: 0x0
82HEADER-NEXT: IATRVA: 0x3034
83HEADER-NEXT: IATSize: 0xC
84HEADER-NEXT: DelayImportDescriptorRVA: 0x0
85HEADER-NEXT: DelayImportDescriptorSize: 0x0
86HEADER-NEXT: CLRRuntimeHeaderRVA: 0x0
87HEADER-NEXT: CLRRuntimeHeaderSize: 0x0
88HEADER-NEXT: ReservedRVA: 0x0
89HEADER-NEXT: ReservedSize: 0x0
90HEADER-NEXT: }
91HEADER-NEXT: }
92HEADER-NEXT: DOSHeader {
93HEADER-NEXT: Magic: MZ
94HEADER-NEXT: UsedBytesInTheLastPage: 0
95HEADER-NEXT: FileSizeInPages: 0
96HEADER-NEXT: NumberOfRelocationItems: 0
97HEADER-NEXT: HeaderSizeInParagraphs: 0
98HEADER-NEXT: MinimumExtraParagraphs: 0
99HEADER-NEXT: MaximumExtraParagraphs: 0
100HEADER-NEXT: InitialRelativeSS: 0
101HEADER-NEXT: InitialSP: 0
102HEADER-NEXT: Checksum: 0
103HEADER-NEXT: InitialIP: 0
104HEADER-NEXT: InitialRelativeCS: 0
105HEADER-NEXT: AddressOfRelocationTable: 64
106HEADER-NEXT: OverlayNumber: 0
107HEADER-NEXT: OEMid: 0
108HEADER-NEXT: OEMinfo: 0
109HEADER-NEXT: AddressOfNewExeHeader: 64
110HEADER-NEXT: }
111
112IMPORTS: Format: COFF-i386
113IMPORTS: Arch: i386
114IMPORTS: AddressSize: 32bit
115IMPORTS: Import {
116IMPORTS: Name: std32.dll
117IMPORTS: ImportLookupTableRVA: 0x3028
118IMPORTS: ImportAddressTableRVA: 0x3034
119IMPORTS: Symbol: ExitProcess (0)
120IMPORTS: Symbol: MessageBoxA (1)
121IMPORTS: }
122
123BASEREL: BaseReloc [
124BASEREL: Entry {
125BASEREL: Type: HIGHLOW
126BASEREL: Address: 0x2005
127BASEREL: }
128BASEREL: Entry {
129BASEREL: Type: HIGHLOW
130BASEREL: Address: 0x200C
131BASEREL: }
132BASEREL: ]
deps/lld/test/COFF/help.test created+3
......@@ -0,0 +1,3 @@
1# RUN: lld-link /help | FileCheck %s
2
3CHECK: OVERVIEW: LLVM Linker
deps/lld/test/COFF/icf-associative.test created+104
......@@ -0,0 +1,104 @@
1# RUN: yaml2obj < %s > %t.obj
2# RUN: lld-link /entry:foo /out:%t.exe /subsystem:console /include:bar \
3# RUN: /debug /verbose %t.obj > %t.log 2>&1
4# RUN: FileCheck %s < %t.log
5
6# CHECK: Selected foo
7# CHECK: Removed bar
8
9--- !COFF
10header:
11 Machine: IMAGE_FILE_MACHINE_AMD64
12 Characteristics: []
13sections:
14 - Name: '.text$mn'
15 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
16 Alignment: 16
17 SectionData: 4883EC28E8000000004883C428C3
18
19 - Name: '.debug_blah'
20 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
21 Alignment: 1
22 SectionData: 0000000000000000000000000000
23
24 - Name: '.text$mn'
25 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
26 Alignment: 16
27 SectionData: 4883EC28E8000000004883C428C3
28
29 - Name: '.debug_blah'
30 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
31 Alignment: 1
32 SectionData: FFFFFFFFFFFFFFFFFFFFFFFFFFFF
33
34symbols:
35 - Name: '.text$mn'
36 Value: 0
37 SectionNumber: 1
38 SimpleType: IMAGE_SYM_TYPE_NULL
39 ComplexType: IMAGE_SYM_DTYPE_NULL
40 StorageClass: IMAGE_SYM_CLASS_STATIC
41 SectionDefinition:
42 Length: 14
43 NumberOfRelocations: 0
44 NumberOfLinenumbers: 0
45 CheckSum: 1682752513
46 Number: 0
47 Selection: IMAGE_COMDAT_SELECT_ANY
48
49 - Name: '.debug_blah'
50 Value: 0
51 SectionNumber: 2
52 SimpleType: IMAGE_SYM_TYPE_NULL
53 ComplexType: IMAGE_SYM_DTYPE_NULL
54 StorageClass: IMAGE_SYM_CLASS_STATIC
55 SectionDefinition:
56 Length: 14
57 NumberOfRelocations: 0
58 NumberOfLinenumbers: 0
59 CheckSum: 0
60 Number: 1
61 Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
62
63 - Name: '.text$mn'
64 Value: 0
65 SectionNumber: 3
66 SimpleType: IMAGE_SYM_TYPE_NULL
67 ComplexType: IMAGE_SYM_DTYPE_NULL
68 StorageClass: IMAGE_SYM_CLASS_STATIC
69 SectionDefinition:
70 Length: 14
71 NumberOfRelocations: 0
72 NumberOfLinenumbers: 0
73 CheckSum: 1682752513
74 Number: 0
75 Selection: IMAGE_COMDAT_SELECT_ANY
76
77 - Name: '.debug_blah'
78 Value: 0
79 SectionNumber: 4
80 SimpleType: IMAGE_SYM_TYPE_NULL
81 ComplexType: IMAGE_SYM_DTYPE_NULL
82 StorageClass: IMAGE_SYM_CLASS_STATIC
83 SectionDefinition:
84 Length: 14
85 NumberOfRelocations: 0
86 NumberOfLinenumbers: 0
87 CheckSum: 0
88 Number: 3
89 Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
90
91 - Name: foo
92 Value: 0
93 SectionNumber: 1
94 SimpleType: IMAGE_SYM_TYPE_NULL
95 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
96 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
97
98 - Name: bar
99 Value: 0
100 SectionNumber: 3
101 SimpleType: IMAGE_SYM_TYPE_NULL
102 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
103 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
104...
deps/lld/test/COFF/icf-circular.test created+81
......@@ -0,0 +1,81 @@
1# RUN: yaml2obj < %s > %t.obj
2# RUN: lld-link /entry:foo /out:%t.exe /subsystem:console /include:bar \
3# RUN: /verbose %t.obj > %t.log 2>&1
4# RUN: FileCheck %s < %t.log
5
6# CHECK: Selected foo
7# CHECK: Removed bar
8
9--- !COFF
10header:
11 Machine: IMAGE_FILE_MACHINE_AMD64
12 Characteristics: []
13sections:
14 - Name: '.text$mn'
15 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
16 Alignment: 16
17 SectionData: 4883EC28E8000000004883C428C3
18 Relocations:
19 - VirtualAddress: 5
20 SymbolName: foo
21 Type: IMAGE_REL_AMD64_REL32
22 - VirtualAddress: 10
23 SymbolName: __ImageBase
24 Type: IMAGE_REL_AMD64_REL32
25 - Name: '.text$mn'
26 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
27 Alignment: 16
28 SectionData: 4883EC28E8000000004883C428C3
29 Relocations:
30 - VirtualAddress: 5
31 SymbolName: bar
32 Type: IMAGE_REL_AMD64_REL32
33 - VirtualAddress: 10
34 SymbolName: __ImageBase
35 Type: IMAGE_REL_AMD64_REL32
36symbols:
37 - Name: '.text$mn'
38 Value: 0
39 SectionNumber: 1
40 SimpleType: IMAGE_SYM_TYPE_NULL
41 ComplexType: IMAGE_SYM_DTYPE_NULL
42 StorageClass: IMAGE_SYM_CLASS_STATIC
43 SectionDefinition:
44 Length: 14
45 NumberOfRelocations: 1
46 NumberOfLinenumbers: 0
47 CheckSum: 1682752513
48 Number: 0
49 Selection: IMAGE_COMDAT_SELECT_NODUPLICATES
50 - Name: '.text$mn'
51 Value: 0
52 SectionNumber: 2
53 SimpleType: IMAGE_SYM_TYPE_NULL
54 ComplexType: IMAGE_SYM_DTYPE_NULL
55 StorageClass: IMAGE_SYM_CLASS_STATIC
56 SectionDefinition:
57 Length: 14
58 NumberOfRelocations: 1
59 NumberOfLinenumbers: 0
60 CheckSum: 1682752513
61 Number: 0
62 Selection: IMAGE_COMDAT_SELECT_NODUPLICATES
63 - Name: foo
64 Value: 0
65 SectionNumber: 1
66 SimpleType: IMAGE_SYM_TYPE_NULL
67 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
68 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
69 - Name: bar
70 Value: 0
71 SectionNumber: 2
72 SimpleType: IMAGE_SYM_TYPE_NULL
73 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
74 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
75 - Name: __ImageBase
76 Value: 0
77 SectionNumber: 0
78 SimpleType: IMAGE_SYM_TYPE_NULL
79 ComplexType: IMAGE_SYM_DTYPE_NULL
80 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
81...
deps/lld/test/COFF/icf-circular2.test created+69
......@@ -0,0 +1,69 @@
1# RUN: yaml2obj < %s > %t.obj
2# RUN: lld-link /entry:foo /out:%t.exe /subsystem:console /include:bar \
3# RUN: /verbose %t.obj > %t.log 2>&1
4# RUN: FileCheck %s < %t.log
5
6# CHECK: Selected foo
7# CHECK: Removed bar
8
9--- !COFF
10header:
11 Machine: IMAGE_FILE_MACHINE_AMD64
12 Characteristics: []
13sections:
14 - Name: '.text$mn'
15 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
16 Alignment: 16
17 SectionData: 4883EC28E8000000004883C428C3
18 Relocations:
19 - VirtualAddress: 5
20 SymbolName: foo
21 Type: IMAGE_REL_AMD64_REL32
22 - Name: '.text$mn'
23 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
24 Alignment: 16
25 SectionData: 4883EC28E8000000004883C428C3
26 Relocations:
27 - VirtualAddress: 5
28 SymbolName: foo
29 Type: IMAGE_REL_AMD64_REL32
30symbols:
31 - Name: '.text$mn'
32 Value: 0
33 SectionNumber: 1
34 SimpleType: IMAGE_SYM_TYPE_NULL
35 ComplexType: IMAGE_SYM_DTYPE_NULL
36 StorageClass: IMAGE_SYM_CLASS_STATIC
37 SectionDefinition:
38 Length: 14
39 NumberOfRelocations: 1
40 NumberOfLinenumbers: 0
41 CheckSum: 1682752513
42 Number: 0
43 Selection: IMAGE_COMDAT_SELECT_NODUPLICATES
44 - Name: '.text$mn'
45 Value: 0
46 SectionNumber: 2
47 SimpleType: IMAGE_SYM_TYPE_NULL
48 ComplexType: IMAGE_SYM_DTYPE_NULL
49 StorageClass: IMAGE_SYM_CLASS_STATIC
50 SectionDefinition:
51 Length: 14
52 NumberOfRelocations: 1
53 NumberOfLinenumbers: 0
54 CheckSum: 1682752513
55 Number: 0
56 Selection: IMAGE_COMDAT_SELECT_NODUPLICATES
57 - Name: foo
58 Value: 0
59 SectionNumber: 1
60 SimpleType: IMAGE_SYM_TYPE_NULL
61 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
62 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
63 - Name: bar
64 Value: 0
65 SectionNumber: 2
66 SimpleType: IMAGE_SYM_TYPE_NULL
67 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
68 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
69...
deps/lld/test/COFF/icf-data.test created+61
......@@ -0,0 +1,61 @@
1# RUN: yaml2obj < %s > %t.obj
2# RUN: lld-link /entry:foo /out:%t.exe /subsystem:console /include:bar \
3# RUN: /verbose %t.obj > %t.log 2>&1
4# RUN: FileCheck %s < %t.log
5
6# CHECK-NOT: Removed foo
7# CHECK-NOT: Removed bar
8
9--- !COFF
10header:
11 Machine: IMAGE_FILE_MACHINE_AMD64
12 Characteristics: []
13sections:
14 - Name: '.text$mn'
15 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ ]
16 Alignment: 16
17 SectionData: 4883EC28E8000000004883C428C3
18 - Name: '.text$mn'
19 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ ]
20 Alignment: 16
21 SectionData: 4883EC28E8000000004883C428C3
22symbols:
23 - Name: '.text$mn'
24 Value: 0
25 SectionNumber: 1
26 SimpleType: IMAGE_SYM_TYPE_NULL
27 ComplexType: IMAGE_SYM_DTYPE_NULL
28 StorageClass: IMAGE_SYM_CLASS_STATIC
29 SectionDefinition:
30 Length: 14
31 NumberOfRelocations: 0
32 NumberOfLinenumbers: 0
33 CheckSum: 1682752513
34 Number: 0
35 Selection: IMAGE_COMDAT_SELECT_NODUPLICATES
36 - Name: '.text$mn'
37 Value: 0
38 SectionNumber: 2
39 SimpleType: IMAGE_SYM_TYPE_NULL
40 ComplexType: IMAGE_SYM_DTYPE_NULL
41 StorageClass: IMAGE_SYM_CLASS_STATIC
42 SectionDefinition:
43 Length: 14
44 NumberOfRelocations: 0
45 NumberOfLinenumbers: 0
46 CheckSum: 1682752513
47 Number: 0
48 Selection: IMAGE_COMDAT_SELECT_NODUPLICATES
49 - Name: foo
50 Value: 0
51 SectionNumber: 1
52 SimpleType: IMAGE_SYM_TYPE_NULL
53 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
54 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
55 - Name: bar
56 Value: 0
57 SectionNumber: 2
58 SimpleType: IMAGE_SYM_TYPE_NULL
59 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
60 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
61...
deps/lld/test/COFF/icf-different-align.test created+61
......@@ -0,0 +1,61 @@
1# RUN: yaml2obj < %s > %t.obj
2# RUN: lld-link /entry:foo /out:%t.exe /subsystem:console /include:bar \
3# RUN: /verbose %t.obj > %t.log 2>&1
4# RUN: FileCheck %s < %t.log
5
6# CHECK-NOT: Selected foo
7# CHECK-NOT: Removed bar
8
9--- !COFF
10header:
11 Machine: IMAGE_FILE_MACHINE_AMD64
12 Characteristics: []
13sections:
14 - Name: '.text$mn'
15 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
16 Alignment: 8
17 SectionData: 4883EC28E8000000004883C428C3
18 - Name: '.text$mn'
19 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
20 Alignment: 16
21 SectionData: 4883EC28E8000000004883C428C3
22symbols:
23 - Name: '.text$mn'
24 Value: 0
25 SectionNumber: 1
26 SimpleType: IMAGE_SYM_TYPE_NULL
27 ComplexType: IMAGE_SYM_DTYPE_NULL
28 StorageClass: IMAGE_SYM_CLASS_STATIC
29 SectionDefinition:
30 Length: 14
31 NumberOfRelocations: 0
32 NumberOfLinenumbers: 0
33 CheckSum: 1682752513
34 Number: 0
35 Selection: IMAGE_COMDAT_SELECT_NODUPLICATES
36 - Name: '.text$mn'
37 Value: 0
38 SectionNumber: 2
39 SimpleType: IMAGE_SYM_TYPE_NULL
40 ComplexType: IMAGE_SYM_DTYPE_NULL
41 StorageClass: IMAGE_SYM_CLASS_STATIC
42 SectionDefinition:
43 Length: 14
44 NumberOfRelocations: 0
45 NumberOfLinenumbers: 0
46 CheckSum: 1682752513
47 Number: 0
48 Selection: IMAGE_COMDAT_SELECT_NODUPLICATES
49 - Name: foo
50 Value: 0
51 SectionNumber: 1
52 SimpleType: IMAGE_SYM_TYPE_NULL
53 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
54 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
55 - Name: bar
56 Value: 0
57 SectionNumber: 2
58 SimpleType: IMAGE_SYM_TYPE_NULL
59 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
60 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
61...
deps/lld/test/COFF/icf-local.test created+66
......@@ -0,0 +1,66 @@
1# COMDAT sections with non-external linkage should not be merged by ICF.
2
3# RUN: yaml2obj < %s > %t1.obj
4# RUN: sed s/foo/main/ %s | yaml2obj > %t2.obj
5# RUN: lld-link /out:%t.exe /entry:main /subsystem:console /verbose \
6# RUN: %t1.obj %t2.obj > %t.log 2>&1
7# RUN: FileCheck %s < %t.log
8
9# CHECK-NOT: Removed bar
10
11--- !COFF
12header:
13 Machine: IMAGE_FILE_MACHINE_AMD64
14 Characteristics: []
15sections:
16 - Name: .text
17 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
18 Alignment: 16
19 SectionData: 488D0500000000C3
20 Relocations:
21 - VirtualAddress: 3
22 SymbolName: bar
23 Type: IMAGE_REL_AMD64_REL32
24 - Name: .rdata
25 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_READ ]
26 Alignment: 8
27 SectionData: 2A000000000000002B00000000000000
28symbols:
29 - Name: .text
30 Value: 0
31 SectionNumber: 1
32 SimpleType: IMAGE_SYM_TYPE_NULL
33 ComplexType: IMAGE_SYM_DTYPE_NULL
34 StorageClass: IMAGE_SYM_CLASS_STATIC
35 SectionDefinition:
36 Length: 8
37 NumberOfRelocations: 1
38 NumberOfLinenumbers: 0
39 CheckSum: 1092178131
40 Number: 1
41 - Name: .rdata
42 Value: 0
43 SectionNumber: 2
44 SimpleType: IMAGE_SYM_TYPE_NULL
45 ComplexType: IMAGE_SYM_DTYPE_NULL
46 StorageClass: IMAGE_SYM_CLASS_STATIC
47 SectionDefinition:
48 Length: 16
49 NumberOfRelocations: 0
50 NumberOfLinenumbers: 0
51 CheckSum: 1200668497
52 Number: 5
53 Selection: IMAGE_COMDAT_SELECT_ANY
54 - Name: foo
55 Value: 0
56 SectionNumber: 1
57 SimpleType: IMAGE_SYM_TYPE_NULL
58 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
59 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
60 - Name: bar
61 Value: 0
62 SectionNumber: 2
63 SimpleType: IMAGE_SYM_TYPE_NULL
64 ComplexType: IMAGE_SYM_DTYPE_NULL
65 StorageClass: IMAGE_SYM_CLASS_STATIC
66...
deps/lld/test/COFF/icf-simple.test created+71
......@@ -0,0 +1,71 @@
1# RUN: yaml2obj < %s > %t.obj
2# RUN: lld-link /entry:foo /out:%t.exe /subsystem:console /include:bar \
3# RUN: /verbose %t.obj > %t.log 2>&1
4# RUN: FileCheck -check-prefix=ICF %s < %t.log
5
6# ICF: Selected foo
7# ICF: Removed bar
8
9# RUN: lld-link /entry:foo /out:%t.exe /subsystem:console /include:bar \
10# RUN: /verbose /opt:noicf %t.obj > %t.log 2>&1
11# RUN: FileCheck -check-prefix=NOICF %s < %t.log
12# RUN: lld-link /entry:foo /out:%t.exe /subsystem:console /include:bar \
13# RUN: /verbose /opt:noref,noicf %t.obj > %t.log 2>&1
14# RUN: FileCheck -check-prefix=NOICF %s < %t.log
15
16# NOICF-NOT: Removed foo
17# NOICF-NOT: Removed bar
18
19--- !COFF
20header:
21 Machine: IMAGE_FILE_MACHINE_AMD64
22 Characteristics: []
23sections:
24 - Name: '.text$mn'
25 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
26 Alignment: 16
27 SectionData: 4883EC28E8000000004883C428C3
28 - Name: '.text$mn'
29 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
30 Alignment: 16
31 SectionData: 4883EC28E8000000004883C428C3
32symbols:
33 - Name: '.text$mn'
34 Value: 0
35 SectionNumber: 1
36 SimpleType: IMAGE_SYM_TYPE_NULL
37 ComplexType: IMAGE_SYM_DTYPE_NULL
38 StorageClass: IMAGE_SYM_CLASS_STATIC
39 SectionDefinition:
40 Length: 14
41 NumberOfRelocations: 0
42 NumberOfLinenumbers: 0
43 CheckSum: 1682752513
44 Number: 0
45 Selection: IMAGE_COMDAT_SELECT_NODUPLICATES
46 - Name: '.text$mn'
47 Value: 0
48 SectionNumber: 2
49 SimpleType: IMAGE_SYM_TYPE_NULL
50 ComplexType: IMAGE_SYM_DTYPE_NULL
51 StorageClass: IMAGE_SYM_CLASS_STATIC
52 SectionDefinition:
53 Length: 14
54 NumberOfRelocations: 0
55 NumberOfLinenumbers: 0
56 CheckSum: 1682752513
57 Number: 0
58 Selection: IMAGE_COMDAT_SELECT_NODUPLICATES
59 - Name: foo
60 Value: 0
61 SectionNumber: 1
62 SimpleType: IMAGE_SYM_TYPE_NULL
63 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
64 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
65 - Name: bar
66 Value: 0
67 SectionNumber: 2
68 SimpleType: IMAGE_SYM_TYPE_NULL
69 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
70 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
71...
deps/lld/test/COFF/implib-name.test created+71
......@@ -0,0 +1,71 @@
1# RUN: mkdir -p %T
2# RUN: llvm-mc -triple x86_64-unknown-windows-msvc -filetype obj -o %T/object.obj %S/Inputs/object.s
3
4# RUN: lld-link /dll /machine:x64 /def:%S/Inputs/named.def /out:%T/library.dll %T/object.obj /entry:f /subsystem:CONSOLE
5# RUN: llvm-ar t %T/library.lib | FileCheck %s -check-prefix CHECK-DEFAULT-DLL-EXT
6
7# RUN: lld-link /machine:x64 /def:%S/Inputs/named.def /out:%T/library.lib
8# RUN: llvm-ar t %T/library.lib | FileCheck %s -check-prefix CHECK-DEFAULT-DLL-EXT
9
10CHECK-DEFAULT-DLL-EXT: library.dll
11CHECK-DEFAULT-DLL-EXT: library.dll
12CHECK-DEFAULT-DLL-EXT: library.dll
13CHECK-DEFAULT-DLL-EXT: library.dll
14
15# RUN: lld-link /machine:x64 /def:%S/Inputs/named.def /out:%T/library.exe %T/object.obj /entry:f /subsystem:CONSOLE
16# RUN: llvm-ar t %T/library.lib | FileCheck %s -check-prefix CHECK-DEFAULT-EXE-EXT
17
18CHECK-DEFAULT-EXE-EXT: library.exe
19CHECK-DEFAULT-EXE-EXT: library.exe
20CHECK-DEFAULT-EXE-EXT: library.exe
21CHECK-DEFAULT-EXE-EXT: library.exe
22
23# RUN: lld-link /dll /machine:x64 /def:%S/Inputs/extension.def /out:%T/extension.dll /entry:f /subsystem:CONSOLE
24# RUN: llvm-ar t %T/extension.lib | FileCheck %s -check-prefix CHECK-EXTENSION
25
26# RUN: lld-link /machine:x64 /def:%S/Inputs/extension.def /out:%T/extension.exe /entry:f /subsystem:CONSOLE
27# RUN: llvm-ar t %T/extension.lib | FileCheck %s -check-prefix CHECK-EXTENSION
28
29# RUN: lld-link /machine:x64 /def:%S/Inputs/extension.def /out:%T/extension.lib
30# RUN: llvm-ar t %T/extension.lib | FileCheck %s -check-prefix CHECK-EXTENSION
31
32CHECK-EXTENSION: library.ext
33CHECK-EXTENSION: library.ext
34CHECK-EXTENSION: library.ext
35CHECK-EXTENSION: library.ext
36
37# RUN: lld-link /dll /machine:x64 /def:%S/Inputs/default.def /out:%T/default.dll /entry:f /subsystem:CONSOLE
38# RUN: llvm-ar t %T/default.lib | FileCheck %s -check-prefix CHECK-OUTPUT-NAME-DLL
39
40# RUN: lld-link /machine:x64 /def:%S/Inputs/default.def /out:%T/default.lib
41# RUN: llvm-ar t %T/default.lib | FileCheck %s -check-prefix CHECK-OUTPUT-NAME-DLL
42
43CHECK-OUTPUT-NAME-DLL: default.dll
44CHECK-OUTPUT-NAME-DLL: default.dll
45CHECK-OUTPUT-NAME-DLL: default.dll
46CHECK-OUTPUT-NAME-DLL: default.dll
47
48# RUN: lld-link /machine:x64 /def:%S/Inputs/default.def /out:%T/default.exe %T/object.obj /entry:f /subsystem:CONSOLE
49# RUN: llvm-ar t %T/default.lib | FileCheck %s -check-prefix CHECK-OUTPUT-NAME-EXE
50
51CHECK-OUTPUT-NAME-EXE: default.exe
52CHECK-OUTPUT-NAME-EXE: default.exe
53CHECK-OUTPUT-NAME-EXE: default.exe
54CHECK-OUTPUT-NAME-EXE: default.exe
55
56# RUN: lld-link /machine:x64 /out:%T/default.exe %T/object.obj /entry:f /subsystem:CONSOLE
57# RUN: llvm-ar t %T/default.lib | FileCheck %s -check-prefix CHECK-NODEF-EXE
58
59CHECK-NODEF-EXE: default.exe
60CHECK-NODEF-EXE: default.exe
61CHECK-NODEF-EXE: default.exe
62CHECK-NODEF-EXE: default.exe
63
64# RUN: lld-link /machine:x64 /dll /out:%T/default.dll %T/object.obj /entry:f /subsystem:CONSOLE
65# RUN: llvm-ar t %T/default.lib | FileCheck %s -check-prefix CHECK-NODEF-DLL
66
67CHECK-NODEF-DLL: default.dll
68CHECK-NODEF-DLL: default.dll
69CHECK-NODEF-DLL: default.dll
70CHECK-NODEF-DLL: default.dll
71
deps/lld/test/COFF/imports-mangle.test created+66
......@@ -0,0 +1,66 @@
1# RUN: yaml2obj < %s > %t.obj
2# RUN: lld-link /out:%t.exe /opt:noref /entry:main \
3# RUN: %t.obj %p/Inputs/imports-mangle.lib
4# RUN: llvm-readobj -coff-imports %t.exe | FileCheck %s
5
6# CHECK: Import {
7# CHECK: Symbol: sym4 (0)
8# CHECK: Symbol: _sym3 (1)
9# CHECK: Symbol: sym1 (2)
10# CHECK: Symbol: (2)
11# CHECK: }
12
13--- !COFF
14header:
15 Machine: IMAGE_FILE_MACHINE_AMD64
16 Characteristics: []
17sections:
18 - Name: .text
19 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
20 Alignment: 4
21 SectionData: 000000000000
22symbols:
23 - Name: .text
24 Value: 0
25 SectionNumber: 1
26 SimpleType: IMAGE_SYM_TYPE_NULL
27 ComplexType: IMAGE_SYM_DTYPE_NULL
28 StorageClass: IMAGE_SYM_CLASS_STATIC
29 SectionDefinition:
30 Length: 6
31 NumberOfRelocations: 0
32 NumberOfLinenumbers: 0
33 CheckSum: 0
34 Number: 0
35 Selection: IMAGE_COMDAT_SELECT_ANY
36 - Name: main
37 Value: 0
38 SectionNumber: 1
39 SimpleType: IMAGE_SYM_TYPE_NULL
40 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
41 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
42 - Name: sym1
43 Value: 0
44 SectionNumber: 0
45 SimpleType: IMAGE_SYM_TYPE_NULL
46 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
47 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
48 - Name: sym2
49 Value: 0
50 SectionNumber: 0
51 SimpleType: IMAGE_SYM_TYPE_NULL
52 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
53 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
54 - Name: __sym3
55 Value: 0
56 SectionNumber: 0
57 SimpleType: IMAGE_SYM_TYPE_NULL
58 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
59 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
60 - Name: '?sym4@@YAHH@Z'
61 Value: 0
62 SectionNumber: 0
63 SimpleType: IMAGE_SYM_TYPE_NULL
64 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
65 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
66...
deps/lld/test/COFF/imports.test created+36
......@@ -0,0 +1,36 @@
1# REQUIRES: x86
2# Verify that the lld can handle .lib files and emit .idata sections.
3#
4# RUN: lld-link /out:%t.exe /entry:main /subsystem:console \
5# RUN: %p/Inputs/hello64.obj %p/Inputs/std64.lib
6# RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=TEXT %s
7# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORT %s
8
9# RUN: lld-link /out:%t.exe /entry:main /subsystem:console \
10# RUN: %p/Inputs/hello64.obj %p/Inputs/std64.lib /include:ExitProcess
11# RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=TEXT %s
12# RUN: llvm-readobj -coff-imports %t.exe | FileCheck -check-prefix=IMPORT %s
13
14TEXT: Disassembly of section .text:
15TEXT-NEXT: .text:
16TEXT-NEXT: subq $40, %rsp
17TEXT-NEXT: movq $0, %rcx
18TEXT-NEXT: leaq -4108(%rip), %rdx
19TEXT-NEXT: leaq -4121(%rip), %r8
20TEXT-NEXT: movl $0, %r9d
21TEXT-NEXT: callq 60
22TEXT-NEXT: movl $0, %ecx
23TEXT-NEXT: callq 18
24TEXT-NEXT: callq 29
25TEXT: jmpq *4098(%rip)
26TEXT: jmpq *4090(%rip)
27TEXT: jmpq *4082(%rip)
28
29IMPORT: Import {
30IMPORT-NEXT: Name: std64.dll
31IMPORT-NEXT: ImportLookupTableRVA: 0x3028
32IMPORT-NEXT: ImportAddressTableRVA: 0x3048
33IMPORT-NEXT: Symbol: ExitProcess (0)
34IMPORT-NEXT: Symbol: (50)
35IMPORT-NEXT: Symbol: MessageBoxA (1)
36IMPORT-NEXT: }
deps/lld/test/COFF/include-lto.ll created+22
......@@ -0,0 +1,22 @@
1; REQUIRES: x86
2; RUN: llvm-as -o %t.obj %s
3; RUN: lld-link /dll /out:%t.dll %t.obj
4; RUN: llvm-objdump -d %t.dll | FileCheck %s
5
6; Checks that code for foo is emitted, as required by the /INCLUDE directive.
7; CHECK: xorl %eax, %eax
8; CHECK-NEXT: retq
9
10target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
11target triple = "x86_64-pc-windows-msvc"
12
13define void @_DllMainCRTStartup() {
14 ret void
15}
16
17define i32 @foo() {
18 ret i32 0
19}
20
21!llvm.linker.options = !{!0}
22!0 = !{!"/INCLUDE:foo"}
deps/lld/test/COFF/include.test created+83
......@@ -0,0 +1,83 @@
1# RUN: yaml2obj < %s > %t.obj
2
3# RUN: lld-link /out:%t.exe /entry:main %t.obj /verbose >& %t.log
4### FileCheck doesn't like empty input, so write something.
5# RUN: echo dummy >> %t.log
6# RUN: FileCheck -check-prefix=CHECK1 %s < %t.log
7
8# RUN: lld-link /out:%t.exe /entry:main %t.obj /verbose /include:unused >& %t.log
9# RUN: echo dummy >> %t.log
10# RUN: FileCheck -check-prefix=CHECK2 %s < %t.log
11
12# CHECK1: Discarded unused
13# CHECK1-NOT: Discarded used
14# CHECK2-NOT: Discarded unused
15# CHECK2-NOT: Discarded used
16
17--- !COFF
18header:
19 Machine: IMAGE_FILE_MACHINE_AMD64
20 Characteristics: []
21sections:
22 - Name: '.text$mn'
23 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
24 Alignment: 4
25 SectionData: B82A000000C3
26 - Name: '.text$mn'
27 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
28 Alignment: 4
29 SectionData: B82A000000C3
30 - Name: '.text$mn'
31 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
32 Alignment: 4
33 SectionData: B82A000000C3
34 - Name: .drectve
35 Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
36 Alignment: 1
37 SectionData: 2f696e636c7564653a7573656400 # /include:used
38symbols:
39 - Name: '.text$mn'
40 Value: 0
41 SectionNumber: 1
42 SimpleType: IMAGE_SYM_TYPE_NULL
43 ComplexType: IMAGE_SYM_DTYPE_NULL
44 StorageClass: IMAGE_SYM_CLASS_STATIC
45 SectionDefinition:
46 Length: 6
47 NumberOfRelocations: 0
48 NumberOfLinenumbers: 0
49 CheckSum: 0
50 Number: 0
51 Selection: IMAGE_COMDAT_SELECT_ANY
52 - Name: '.text$mn'
53 Value: 0
54 SectionNumber: 2
55 SimpleType: IMAGE_SYM_TYPE_NULL
56 ComplexType: IMAGE_SYM_DTYPE_NULL
57 StorageClass: IMAGE_SYM_CLASS_STATIC
58 SectionDefinition:
59 Length: 6
60 NumberOfRelocations: 0
61 NumberOfLinenumbers: 0
62 CheckSum: 0
63 Number: 0
64 Selection: IMAGE_COMDAT_SELECT_ANY
65 - Name: main
66 Value: 0
67 SectionNumber: 1
68 SimpleType: IMAGE_SYM_TYPE_NULL
69 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
70 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
71 - Name: used
72 Value: 0
73 SectionNumber: 2
74 SimpleType: IMAGE_SYM_TYPE_NULL
75 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
76 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
77 - Name: unused
78 Value: 0
79 SectionNumber: 3
80 SimpleType: IMAGE_SYM_TYPE_NULL
81 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
82 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
83...
deps/lld/test/COFF/include2.test created+14
......@@ -0,0 +1,14 @@
1# RUN: yaml2obj < %p/Inputs/include1a.yaml > %t1.obj
2# RUN: yaml2obj < %p/Inputs/include1b.yaml > %t2.obj
3# RUN: yaml2obj < %p/Inputs/include1c.yaml > %t3.obj
4# RUN: rm -f %t2.lib %t3.lib
5# RUN: llvm-ar cru %t2.lib %t2.obj
6# RUN: llvm-ar cru %t3.lib %t3.obj
7# RUN: lld-link /out:%t.exe /entry:main %t1.obj %t2.lib %t3.lib /verbose >& %t.log
8# RUN: FileCheck %s < %t.log
9
10CHECK: include2.test.tmp1.obj
11CHECK: include2.test.tmp2.lib
12CHECK: include2.test.tmp2.lib(include2.test.tmp2.obj) for foo
13CHECK: include2.test.tmp3.lib
14CHECK: include2.test.tmp3.lib(include2.test.tmp3.obj) for bar
deps/lld/test/COFF/internal.test created+42
......@@ -0,0 +1,42 @@
1# Test that non-external symbols don't conflict
2
3# RUN: yaml2obj < %s > %t1.obj
4# RUN: yaml2obj < %s > %t2.obj
5# RUN: yaml2obj < %p/Inputs/ret42.yaml > %t3.obj
6# RUN: lld-link /out:%t.exe /entry:main %t1.obj %t2.obj %t3.obj
7
8--- !COFF
9header:
10 Machine: IMAGE_FILE_MACHINE_AMD64
11 Characteristics: []
12sections:
13 - Name: .text
14 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
15 Alignment: 4
16 SectionData: 000000000000
17symbols:
18 - Name: .text
19 Value: 0
20 SectionNumber: 1
21 SimpleType: IMAGE_SYM_TYPE_NULL
22 ComplexType: IMAGE_SYM_DTYPE_NULL
23 StorageClass: IMAGE_SYM_CLASS_STATIC
24 SectionDefinition:
25 Length: 6
26 NumberOfRelocations: 0
27 NumberOfLinenumbers: 0
28 CheckSum: 0
29 Number: 0
30 - Name: defined
31 Value: 0
32 SectionNumber: 1
33 SimpleType: IMAGE_SYM_TYPE_NULL
34 ComplexType: IMAGE_SYM_DTYPE_NULL
35 StorageClass: IMAGE_SYM_CLASS_STATIC
36 - Name: absolute
37 Value: 0xdeadbeef
38 SectionNumber: -1
39 SimpleType: IMAGE_SYM_TYPE_NULL
40 ComplexType: IMAGE_SYM_DTYPE_NULL
41 StorageClass: IMAGE_SYM_CLASS_STATIC
42...
deps/lld/test/COFF/invalid-debug-type.test created+5
......@@ -0,0 +1,5 @@
1# RUN: yaml2obj < %p/Inputs/pdb1.yaml > %t1.obj
2# RUN: yaml2obj < %p/Inputs/pdb2.yaml > %t2.obj
3# RUN: lld-link /debug /debugtype:invalid /pdb:%t.pdb /dll /out:%t.dll /entry:main /nodefaultlib \
4# RUN: %t1.obj %t2.obj
5
deps/lld/test/COFF/invalid-obj.test created+14
......@@ -0,0 +1,14 @@
1# RUN: yaml2obj %s > %t.obj
2# RUN: not lld-link %t.obj 2>&1 | FileCheck %s
3
4# CHECK: getSectionName failed: #1:
5
6--- !COFF
7header:
8 Machine: IMAGE_FILE_MACHINE_AMD64
9 Characteristics: []
10sections:
11 - Name: '/1'
12 Characteristics: []
13 SectionData: 00
14symbols:
deps/lld/test/COFF/largeaddressaware.test created+21
......@@ -0,0 +1,21 @@
1# RUN: yaml2obj < %p/Inputs/hello32.yaml > %t.obj
2# RUN: lld-link %t.obj %p/Inputs/std32.lib /subsystem:console \
3# RUN: /entry:main@0 /out:%t.exe /largeaddressaware
4# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=HEADER %s
5
6HEADER: Format: COFF-i386
7HEADER-NEXT: Arch: i386
8HEADER-NEXT: AddressSize: 32bit
9HEADER-NEXT: ImageFileHeader {
10HEADER-NEXT: Machine: IMAGE_FILE_MACHINE_I386 (0x14C)
11HEADER-NEXT: SectionCount: 4
12HEADER-NEXT: TimeDateStamp: 1970-01-01 00:00:00 (0x0)
13HEADER-NEXT: PointerToSymbolTable: 0x0
14HEADER-NEXT: SymbolCount: 0
15HEADER-NEXT: OptionalHeaderSize: 224
16HEADER-NEXT: Characteristics [ (0x122)
17HEADER-NEXT: IMAGE_FILE_32BIT_MACHINE (0x100)
18HEADER-NEXT: IMAGE_FILE_EXECUTABLE_IMAGE (0x2)
19HEADER-NEXT: IMAGE_FILE_LARGE_ADDRESS_AWARE (0x20)
20HEADER-NEXT: ]
21HEADER-NEXT: }
deps/lld/test/COFF/lib.test created+11
......@@ -0,0 +1,11 @@
1# RUN: lld-link /machine:x64 /def:%S/Inputs/library.def /out:%t.lib
2# RUN: llvm-nm %t.lib | FileCheck %s
3
4CHECK: 00000000 R __imp_constant
5CHECK: 00000000 R constant
6
7CHECK: 00000000 D __imp_data
8
9CHECK: 00000000 T __imp_function
10CHECK: 00000000 T function
11
deps/lld/test/COFF/libpath.test created+18
......@@ -0,0 +1,18 @@
1# RUN: mkdir -p %t/a %t/b %t/c
2# RUN: cp %p/Inputs/std64.lib %t/a/
3# RUN: cp %p/Inputs/std64.lib %t/b/
4# RUN: cp %p/Inputs/std64.lib %t/c/
5
6# RUN: env LIB=%t/a lld-link /out:%t.exe /entry:main /verbose \
7# RUN: std64.lib /subsystem:console %p/Inputs/hello64.obj \
8# RUN: /libpath:%t/b /libpath:%t/c > %t.log
9# RUN: FileCheck -check-prefix=CHECK1 %s < %t.log
10
11CHECK1: b{{[/\\]}}std64.lib
12
13# RUN: lld-link /out:%t.exe /entry:main /verbose \
14# RUN: std64.lib /subsystem:console %p/Inputs/hello64.obj \
15# RUN: /libpath:%t/a /libpath:%t/b /libpath:%t/c > %t.log
16# RUN: FileCheck -check-prefix=CHECK2 %s < %t.log
17
18CHECK2: a{{[/\\]}}std64.lib
deps/lld/test/COFF/linkenv.test created+4
......@@ -0,0 +1,4 @@
1# RUN: env LINK=-help lld-link | FileCheck %s
2# RUN: env _LINK_=-help lld-link | FileCheck %s
3
4CHECK: OVERVIEW: LLVM Linker
deps/lld/test/COFF/linkrepro.test created+37
......@@ -0,0 +1,37 @@
1# REQUIRES: x86, shell
2
3# RUN: rm -rf %t.dir
4# RUN: mkdir -p %t.dir/build1 %t.dir/build2 %t.dir/build3
5# RUN: yaml2obj < %p/Inputs/hello32.yaml > %t.obj
6
7# RUN: cd %t.dir/build1
8# RUN: lld-link %t.obj %p/Inputs/std32.lib /subsystem:console \
9# RUN: /entry:main@0 /linkrepro:. /out:%t.exe
10# RUN: tar xf repro.tar
11# RUN: diff %t.obj repro/%:t.obj
12# RUN: diff %p/Inputs/std32.lib repro/%:p/Inputs/std32.lib
13# RUN: FileCheck %s --check-prefix=RSP < repro/response.txt
14
15# RUN: cd %t.dir/build2
16# RUN: lld-link %t.obj /libpath:%p/Inputs /defaultlib:std32 /subsystem:console \
17# RUN: /entry:main@0 /linkrepro:. /out:%t.exe
18# RUN: tar xf repro.tar
19# RUN: diff %t.obj repro/%:t.obj
20# RUN: diff %p/Inputs/std32.lib repro/%:p/Inputs/std32.lib
21# RUN: FileCheck %s --check-prefix=RSP < repro/response.txt
22
23# RUN: cd %t.dir/build3
24# RUN: env LIB=%p/Inputs lld-link %t.obj /defaultlib:std32 /subsystem:console \
25# RUN: /entry:main@0 /linkrepro:. /out:%t.exe
26# RUN: tar xf repro.tar
27# RUN: diff %t.obj repro/%:t.obj
28# RUN: diff %p/Inputs/std32.lib repro/%:p/Inputs/std32.lib
29# RUN: FileCheck %s --check-prefix=RSP < repro/response.txt
30
31# RSP: /subsystem:console
32# RSP: /entry:main@0
33# RSP-NOT: /linkrepro:
34# RSP: /out:
35# RSP: linkrepro.test.tmp.obj
36# RSP-NOT: defaultlib
37# RSP: std32.lib
deps/lld/test/COFF/lldmap.test created+10
......@@ -0,0 +1,10 @@
1# RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj
2# RUN: lld-link /out:%t.exe /entry:main /lldmap:%T/foo.map %t.obj
3# RUN: FileCheck -strict-whitespace %s < %T/foo.map
4# RUN: lld-link /out:%T/bar.exe /entry:main /lldmap %t.obj
5# RUN: FileCheck -strict-whitespace %s < %T/bar.map
6
7# CHECK: Address Size Align Out In Symbol
8# CHECK-NEXT: 00001000 00000006 4096 .text
9# CHECK-NEXT: 00001000 00000006 16 {{.*}}lldmap.test.tmp.obj:(.text$mn)
10# CHECK-NEXT: 00001000 00000000 0 main
deps/lld/test/COFF/loadcfg.ll created+15
......@@ -0,0 +1,15 @@
1; RUN: llvm-as -o %t.obj %s
2; RUN: lld-link /out:%t.exe %t.obj /entry:main /subsystem:console
3; RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
4
5; CHECK: LoadConfigTableRVA: 0x1000
6; CHECK: LoadConfigTableSize: 0x70
7
8target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
9target triple = "x86_64-pc-windows-msvc"
10
11@_load_config_used = constant [28 x i32] [i32 112, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0, i32 0]
12
13define void @main() {
14 ret void
15}
deps/lld/test/COFF/loadcfg.test created+75
......@@ -0,0 +1,75 @@
1# RUN: yaml2obj < %s > %t.obj
2# RUN: lld-link /out:%t.exe %t.obj /entry:main /subsystem:console
3# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
4
5# CHECK: LoadConfigTableRVA: 0x1000
6# CHECK: LoadConfigTableSize: 0x70
7
8--- !COFF
9header:
10 Machine: IMAGE_FILE_MACHINE_AMD64
11 Characteristics: []
12sections:
13 - Name: .text
14 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
15 Alignment: 4
16 SectionData: B82A000000C3
17 - Name: .text
18 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
19 Alignment: 4
20 SectionData: B82A000000C3
21 - Name: .rdata
22 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
23 Alignment: 16
24 SectionData: '70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
25symbols:
26 - Name: .text
27 Value: 0
28 SectionNumber: 1
29 SimpleType: IMAGE_SYM_TYPE_NULL
30 ComplexType: IMAGE_SYM_DTYPE_NULL
31 StorageClass: IMAGE_SYM_CLASS_STATIC
32 SectionDefinition:
33 Length: 6
34 NumberOfRelocations: 0
35 NumberOfLinenumbers: 0
36 CheckSum: 0
37 Number: 0
38 - Name: .text
39 Value: 0
40 SectionNumber: 2
41 SimpleType: IMAGE_SYM_TYPE_NULL
42 ComplexType: IMAGE_SYM_DTYPE_NULL
43 StorageClass: IMAGE_SYM_CLASS_STATIC
44 SectionDefinition:
45 Length: 6
46 NumberOfRelocations: 0
47 NumberOfLinenumbers: 0
48 CheckSum: 0
49 Number: 0
50 Selection: IMAGE_COMDAT_SELECT_ANY
51 - Name: main
52 Value: 0
53 SectionNumber: 1
54 SimpleType: IMAGE_SYM_TYPE_NULL
55 ComplexType: IMAGE_SYM_DTYPE_NULL
56 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
57 - Name: .rdata
58 Value: 0
59 SectionNumber: 3
60 SimpleType: IMAGE_SYM_TYPE_NULL
61 ComplexType: IMAGE_SYM_DTYPE_NULL
62 StorageClass: IMAGE_SYM_CLASS_STATIC
63 SectionDefinition:
64 Length: 112
65 NumberOfRelocations: 0
66 NumberOfLinenumbers: 0
67 CheckSum: 0
68 Number: 3
69 - Name: _load_config_used
70 Value: 0
71 SectionNumber: 3
72 SimpleType: IMAGE_SYM_TYPE_NULL
73 ComplexType: IMAGE_SYM_DTYPE_NULL
74 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
75...
deps/lld/test/COFF/loadcfg32.test created+58
......@@ -0,0 +1,58 @@
1# RUN: yaml2obj < %s > %t.obj
2# RUN: lld-link /out:%t.exe %t.obj /entry:main /subsystem:console
3# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
4
5# CHECK: LoadConfigTableRVA: 0x1000
6# CHECK: LoadConfigTableSize: 0x40
7
8--- !COFF
9header:
10 Machine: IMAGE_FILE_MACHINE_I386
11 Characteristics: []
12sections:
13 - Name: .text
14 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
15 Alignment: 4
16 SectionData: B82A000000C3
17 - Name: .rdata
18 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
19 Alignment: 4
20 SectionData: '40000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
21symbols:
22 - Name: .text
23 Value: 0
24 SectionNumber: 1
25 SimpleType: IMAGE_SYM_TYPE_NULL
26 ComplexType: IMAGE_SYM_DTYPE_NULL
27 StorageClass: IMAGE_SYM_CLASS_STATIC
28 SectionDefinition:
29 Length: 6
30 NumberOfRelocations: 0
31 NumberOfLinenumbers: 0
32 CheckSum: 0
33 Number: 0
34 - Name: _main
35 Value: 0
36 SectionNumber: 1
37 SimpleType: IMAGE_SYM_TYPE_NULL
38 ComplexType: IMAGE_SYM_DTYPE_NULL
39 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
40 - Name: .rdata
41 Value: 0
42 SectionNumber: 2
43 SimpleType: IMAGE_SYM_TYPE_NULL
44 ComplexType: IMAGE_SYM_DTYPE_NULL
45 StorageClass: IMAGE_SYM_CLASS_STATIC
46 SectionDefinition:
47 Length: 64
48 NumberOfRelocations: 0
49 NumberOfLinenumbers: 0
50 CheckSum: 0
51 Number: 2
52 - Name: __load_config_used
53 Value: 0
54 SectionNumber: 2
55 SimpleType: IMAGE_SYM_TYPE_NULL
56 ComplexType: IMAGE_SYM_DTYPE_NULL
57 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
58...
deps/lld/test/COFF/locally-imported.test created+61
......@@ -0,0 +1,61 @@
1# RUN: yaml2obj < %s > %t.obj
2# RUN: lld-link /out:%t.exe /entry:main %t.obj
3# RUN: llvm-objdump -s %t.exe | FileCheck %s
4# RUN: llvm-readobj -coff-basereloc %t.exe | FileCheck -check-prefix=BASEREL %s
5
6# CHECK: Contents of section .text:
7# CHECK-NEXT: 1000 00200000
8# CHECK: Contents of section .rdata:
9# CHECK-NEXT: 2000 04100040 01000000
10
11# BASEREL: BaseReloc [
12# BASEREL-NEXT: Entry {
13# BASEREL-NEXT: Type: DIR64
14# BASEREL-NEXT: Address: 0x2000
15# BASEREL-NEXT: }
16# BASEREL-NEXT: Entry {
17# BASEREL-NEXT: Type: ABSOLUTE
18# BASEREL-NEXT: Address: 0x2000
19# BASEREL-NEXT: }
20# BASEREL-NEXT: ]
21
22--- !COFF
23header:
24 Machine: IMAGE_FILE_MACHINE_AMD64
25 Characteristics: []
26sections:
27 - Name: .text
28 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
29 Alignment: 4
30 SectionData: 00000000
31 Relocations:
32 - VirtualAddress: 0
33 SymbolName: __imp_main
34 Type: IMAGE_REL_AMD64_ADDR32NB
35symbols:
36 - Name: .text
37 Value: 0
38 SectionNumber: 1
39 SimpleType: IMAGE_SYM_TYPE_NULL
40 ComplexType: IMAGE_SYM_DTYPE_NULL
41 StorageClass: IMAGE_SYM_CLASS_STATIC
42 SectionDefinition:
43 Length: 4
44 NumberOfRelocations: 1
45 NumberOfLinenumbers: 0
46 CheckSum: 0
47 Number: 0
48 Selection: IMAGE_COMDAT_SELECT_ANY
49 - Name: main
50 Value: 4
51 SectionNumber: 1
52 SimpleType: IMAGE_SYM_TYPE_NULL
53 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
54 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
55 - Name: __imp_main
56 Value: 0
57 SectionNumber: 0
58 SimpleType: IMAGE_SYM_TYPE_NULL
59 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
60 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
61...
deps/lld/test/COFF/locally-imported32.test created+50
......@@ -0,0 +1,50 @@
1# RUN: yaml2obj < %s > %t.obj
2# RUN: lld-link /out:%t.exe /entry:main %t.obj
3# RUN: llvm-objdump -s %t.exe | FileCheck %s
4
5# CHECK: Contents of section .text:
6# CHECK-NEXT: 1000 00200000
7
8# CHECK: Contents of section .rdata:
9# CHECK-NEXT: 2000 04104000
10
11--- !COFF
12header:
13 Machine: IMAGE_FILE_MACHINE_I386
14 Characteristics: []
15sections:
16 - Name: .text
17 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
18 Alignment: 4
19 SectionData: 00000000
20 Relocations:
21 - VirtualAddress: 0
22 SymbolName: __imp__main
23 Type: IMAGE_REL_I386_DIR32NB
24symbols:
25 - Name: .text
26 Value: 0
27 SectionNumber: 1
28 SimpleType: IMAGE_SYM_TYPE_NULL
29 ComplexType: IMAGE_SYM_DTYPE_NULL
30 StorageClass: IMAGE_SYM_CLASS_STATIC
31 SectionDefinition:
32 Length: 4
33 NumberOfRelocations: 1
34 NumberOfLinenumbers: 0
35 CheckSum: 0
36 Number: 0
37 Selection: IMAGE_COMDAT_SELECT_ANY
38 - Name: _main
39 Value: 4
40 SectionNumber: 1
41 SimpleType: IMAGE_SYM_TYPE_NULL
42 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
43 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
44 - Name: __imp__main
45 Value: 0
46 SectionNumber: 0
47 SimpleType: IMAGE_SYM_TYPE_NULL
48 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
49 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
50...
deps/lld/test/COFF/long-section-name.test created+58
......@@ -0,0 +1,58 @@
1# RUN: yaml2obj < %s > %t.obj
2# RUN: lld-link /debug /out:%t.exe /entry:main %t.obj
3# RUN: llvm-readobj -sections %t.exe | FileCheck %s
4
5# CHECK: Name: .data_long_section_name
6# CHECK: Name: .text_long_section_name
7
8--- !COFF
9header:
10 Machine: IMAGE_FILE_MACHINE_AMD64
11 Characteristics: [ ]
12sections:
13 - Name: .text_long_section_name
14 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
15 Alignment: 4
16 SectionData: B82A000000C3
17 - Name: .data_long_section_name
18 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
19 Alignment: 4
20 SectionData: "00"
21symbols:
22 - Name: "@comp.id"
23 Value: 10394907
24 SectionNumber: 65535
25 SimpleType: IMAGE_SYM_TYPE_NULL
26 ComplexType: IMAGE_SYM_DTYPE_NULL
27 StorageClass: IMAGE_SYM_CLASS_STATIC
28 - Name: .text_long_section_name
29 Value: 0
30 SectionNumber: 1
31 SimpleType: IMAGE_SYM_TYPE_NULL
32 ComplexType: IMAGE_SYM_DTYPE_NULL
33 StorageClass: IMAGE_SYM_CLASS_STATIC
34 SectionDefinition:
35 Length: 6
36 NumberOfRelocations: 0
37 NumberOfLinenumbers: 0
38 CheckSum: 0
39 Number: 0
40 - Name: .data_long_section_name
41 Value: 0
42 SectionNumber: 2
43 SimpleType: IMAGE_SYM_TYPE_NULL
44 ComplexType: IMAGE_SYM_DTYPE_NULL
45 StorageClass: IMAGE_SYM_CLASS_STATIC
46 SectionDefinition:
47 Length: 0
48 NumberOfRelocations: 0
49 NumberOfLinenumbers: 0
50 CheckSum: 0
51 Number: 0
52 - Name: main
53 Value: 0
54 SectionNumber: 1
55 SimpleType: IMAGE_SYM_TYPE_NULL
56 ComplexType: IMAGE_SYM_DTYPE_NULL
57 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
58...
deps/lld/test/COFF/lto-chkstk.ll created+17
......@@ -0,0 +1,17 @@
1; RUN: llvm-as -o %t.obj %s
2; RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o %T/lto-chkstk-foo.obj %S/Inputs/lto-chkstk-foo.s
3; RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o %T/lto-chkstk-chkstk.obj %S/Inputs/lto-chkstk-chkstk.s
4; RUN: llvm-ar cru %t.lib %T/lto-chkstk-chkstk.obj
5; RUN: lld-link /out:%t.exe /entry:main /subsystem:console %t.obj %T/lto-chkstk-foo.obj %t.lib
6
7target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
8target triple = "x86_64-pc-windows-msvc"
9
10define void @main() {
11entry:
12 %array4096 = alloca [4096 x i8]
13 call void @foo([4096 x i8]* %array4096)
14 ret void
15}
16
17declare void @foo([4096 x i8]*)
deps/lld/test/COFF/lto-comdat.ll created+108
......@@ -0,0 +1,108 @@
1; RUN: llvm-as -o %T/comdat-main.lto.obj %s
2; RUN: llvm-as -o %T/comdat1.lto.obj %S/Inputs/lto-comdat1.ll
3; RUN: llvm-as -o %T/comdat2.lto.obj %S/Inputs/lto-comdat2.ll
4; RUN: rm -f %T/comdat.lto.lib
5; RUN: llvm-ar cru %T/comdat.lto.lib %T/comdat1.lto.obj %T/comdat2.lto.obj
6
7; RUN: llc -filetype=obj -o %T/comdat-main.obj %s
8; RUN: llc -filetype=obj -o %T/comdat1.obj %S/Inputs/lto-comdat1.ll
9; RUN: llc -filetype=obj -o %T/comdat2.obj %S/Inputs/lto-comdat2.ll
10; RUN: rm -f %T/comdat.lib
11; RUN: llvm-ar cru %T/comdat.lib %T/comdat1.obj %T/comdat2.obj
12
13; Check that, when we use an LTO main with LTO objects, we optimize away all
14; of f1, f2, and comdat.
15; RUN: lld-link /out:%T/comdat-main.exe /entry:main /subsystem:console %T/comdat-main.lto.obj %T/comdat1.lto.obj %T/comdat2.lto.obj
16; RUN: llvm-readobj -file-headers %T/comdat-main.exe | FileCheck -check-prefix=HEADERS-11 %s
17; RUN: llvm-objdump -d %T/comdat-main.exe | FileCheck -check-prefix=TEXT-11 %s
18; RUN: lld-link /out:%T/comdat-main.exe /entry:main /subsystem:console %T/comdat-main.lto.obj %T/comdat.lto.lib
19; RUN: llvm-readobj -file-headers %T/comdat-main.exe | FileCheck -check-prefix=HEADERS-11 %s
20; RUN: llvm-objdump -d %T/comdat-main.exe | FileCheck -check-prefix=TEXT-11 %s
21
22; Check that, when we use a non-LTO main with LTO objects, we pick the comdat
23; implementation in LTO, elide calls to it from inside LTO, and retain the
24; call to comdat from main.
25; RUN: lld-link /out:%T/comdat-main.exe /entry:main /subsystem:console %T/comdat-main.obj %T/comdat1.lto.obj %T/comdat2.lto.obj
26; RUN: llvm-readobj -file-headers %T/comdat-main.exe | FileCheck -check-prefix=HEADERS-01 %s
27; RUN: llvm-objdump -d %T/comdat-main.exe | FileCheck -check-prefix=TEXT-01 %s
28; RUN: lld-link /out:%T/comdat-main.exe /entry:main /subsystem:console %T/comdat-main.obj %T/comdat.lto.lib
29; RUN: llvm-readobj -file-headers %T/comdat-main.exe | FileCheck -check-prefix=HEADERS-01 %s
30; RUN: llvm-objdump -d %T/comdat-main.exe | FileCheck -check-prefix=TEXT-01 %s
31
32; Check that, when we use an LTO main with non-LTO objects, we pick the comdat
33; implementation in LTO, elide the call to it from inside LTO, and keep the
34; calls to comdat from the non-LTO objects.
35; RUN: lld-link /out:%T/comdat-main.exe /entry:main /subsystem:console %T/comdat-main.lto.obj %T/comdat1.obj %T/comdat2.obj
36; RUN: llvm-readobj -file-headers %T/comdat-main.exe | FileCheck -check-prefix=HEADERS-10 %s
37; RUN: llvm-objdump -d %T/comdat-main.exe | FileCheck -check-prefix=TEXT-10 %s
38; RUN: lld-link /out:%T/comdat-main.exe /entry:main /subsystem:console %T/comdat-main.lto.obj %T/comdat.lib
39; RUN: llvm-readobj -file-headers %T/comdat-main.exe | FileCheck -check-prefix=HEADERS-10 %s
40; RUN: llvm-objdump -d %T/comdat-main.exe | FileCheck -check-prefix=TEXT-10 %s
41
42; HEADERS-11: AddressOfEntryPoint: 0x1000
43; TEXT-11: Disassembly of section .text:
44; TEXT-11-NEXT: .text:
45; TEXT-11-NEXT: xorl %eax, %eax
46; TEXT-11-NEXT: retq
47
48; HEADERS-01: AddressOfEntryPoint: 0x2000
49; TEXT-01: Disassembly of section .text:
50; TEXT-01-NEXT: .text:
51; TEXT-01-NEXT: subq $40, %rsp
52; TEXT-01-NEXT: callq 39
53; TEXT-01-NEXT: callq 50
54; TEXT-01-NEXT: callq 13
55; TEXT-01-NEXT: xorl %eax, %eax
56; TEXT-01-NEXT: addq $40, %rsp
57; TEXT-01: retq
58; TEXT-01-NOT: callq
59; TEXT-01: retq
60; TEXT-01-NOT: callq
61; TEXT-01: retq
62; TEXT-01-NOT: callq
63; TEXT-01: retq
64; TEXT-01-NOT: {{.}}
65
66; HEADERS-10: AddressOfEntryPoint: 0x2020
67; TEXT-10: Disassembly of section .text:
68; TEXT-10-NEXT: .text:
69; TEXT-10-NEXT: subq $40, %rsp
70; TEXT-10-NEXT: callq 55
71; TEXT-10-NEXT: nop
72; TEXT-10-NEXT: addq $40, %rsp
73; TEXT-10-NEXT: retq
74; TEXT-10-NEXT: int3
75; TEXT-10-NEXT: subq $40, %rsp
76; TEXT-10-NEXT: callq 39
77; TEXT-10-NEXT: nop
78; TEXT-10-NEXT: addq $40, %rsp
79; TEXT-10-NEXT: retq
80; TEXT-10-NEXT: int3
81; TEXT-10-NEXT: subq $40, %rsp
82; TEXT-10-NEXT: callq -41
83; TEXT-10-NEXT: callq -30
84; TEXT-10-NEXT: xorl %eax, %eax
85; TEXT-10-NEXT: addq $40, %rsp
86; TEXT-10-NEXT: retq
87; TEXT-10-NOT: callq
88; TEXT-10: retq
89; TEXT-10-NOT: {{.}}
90
91target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
92target triple = "x86_64-pc-windows-msvc"
93
94$comdat = comdat any
95
96define i32 @main() {
97 call void @f1()
98 call void @f2()
99 call void @comdat()
100 ret i32 0
101}
102
103define linkonce_odr void @comdat() comdat {
104 ret void
105}
106
107declare void @f1()
108declare void @f2()
deps/lld/test/COFF/lto-debug-pass-arguments.ll created+16
......@@ -0,0 +1,16 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.obj
3; RUN: lld-link /dll /out:%t.dll %t.obj /mllvm:-debug-pass=Arguments 2>&1 | FileCheck %s
4
5target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
6target triple = "x86_64-pc-windows-msvc"
7
8define void @dummy() {
9 ret void
10}
11
12define void @_DllMainCRTStartup() {
13 ret void
14}
15
16; CHECK: Pass Arguments:
deps/lld/test/COFF/lto-lazy-reference.ll created+21
......@@ -0,0 +1,21 @@
1; RUN: llc -mtriple=i686-pc-windows-msvc -filetype=obj -o %T/lto-lazy-reference-quadruple.obj %S/Inputs/lto-lazy-reference-quadruple.ll
2; RUN: llvm-as -o %T/lto-lazy-reference-dummy.bc %S/Inputs/lto-lazy-reference-dummy.ll
3; RUN: rm -f %t.lib
4; RUN: llvm-ar cru %t.lib %T/lto-lazy-reference-quadruple.obj %T/lto-lazy-reference-dummy.bc
5; RUN: llvm-as -o %t.obj %s
6; RUN: lld-link /out:%t.exe /entry:main /subsystem:console %t.obj %t.lib
7
8target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
9target triple = "i686-pc-windows-msvc18.0.0"
10
11define double @main(double %x) {
12entry:
13 ; When compiled, this defines the __real@40800000 symbol, which already has a
14 ; lazy definition in the lib file from lto-lazy-reference-quadruple.obj. This
15 ; test makes sure we *don't* try to take the definition from the lazy
16 ; reference, because that can bring in new references to bitcode files after
17 ; LTO, such as lto-lazy-reference-dummy.bc in this case.
18 %mul = fmul double %x, 4.0
19
20 ret double %mul
21}
deps/lld/test/COFF/lto-linker-opts.ll created+8
......@@ -0,0 +1,8 @@
1; RUN: llvm-as -o %T/lto-linker-opts.obj %s
2; RUN: env LIB=%S/Inputs lld-link /out:%T/lto-linker-opts.exe /entry:main /subsystem:console %T/lto-linker-opts.obj
3
4target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
5target triple = "x86_64-pc-windows-msvc"
6
7!llvm.linker.options = !{!0}
8!0 = !{!"/DEFAULTLIB:ret42.lib"}
deps/lld/test/COFF/lto-new-symbol.ll created+16
......@@ -0,0 +1,16 @@
1; RUN: llvm-as -o %t.obj %s
2; RUN: lld-link /out:%t.exe /entry:foo /subsystem:console %t.obj
3
4target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
5target triple = "x86_64-pc-windows-msvc"
6
7define void @foo(<4 x i32>* %p, <4 x float>* %q, i1 %t) nounwind {
8entry:
9 br label %loop
10loop:
11 store <4 x i32><i32 1073741824, i32 1073741824, i32 1073741824, i32 1073741824>, <4 x i32>* %p
12 store <4 x float><float 2.0, float 2.0, float 2.0, float 2.0>, <4 x float>* %q
13 br i1 %t, label %loop, label %ret
14ret:
15 ret void
16}
deps/lld/test/COFF/lto-opt-level.ll created+21
......@@ -0,0 +1,21 @@
1; RUN: llvm-as -o %t.obj %s
2; RUN: lld-link /out:%t0.exe /entry:main /subsystem:console /opt:lldlto=0 /debug %t.obj
3; RUN: llvm-nm %t0.exe | FileCheck --check-prefix=CHECK-O0 %s
4; RUN: lld-link /out:%t2.exe /entry:main /subsystem:console /opt:lldlto=2 /debug %t.obj
5; RUN: llvm-nm %t2.exe | FileCheck --check-prefix=CHECK-O2 %s
6; RUN: lld-link /out:%t2a.exe /entry:main /subsystem:console /debug %t.obj
7; RUN: llvm-nm %t2a.exe | FileCheck --check-prefix=CHECK-O2 %s
8
9target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
10target triple = "x86_64-pc-windows-msvc"
11
12; CHECK-O0: foo
13; CHECK-O2-NOT: foo
14define internal void @foo() {
15 ret void
16}
17
18define void @main() {
19 call void @foo()
20 ret void
21}
deps/lld/test/COFF/lto-parallel.ll created+20
......@@ -0,0 +1,20 @@
1; RUN: llvm-as -o %t.obj %s
2; RUN: lld-link /out:%t.exe /entry:foo /include:bar /opt:lldltopartitions=2 /subsystem:console /lldmap:%t.map %t.obj
3; RUN: FileCheck %s < %t.map
4
5target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
6target triple = "x86_64-pc-windows-msvc"
7
8; CHECK: lto.tmp
9; CHECK-NEXT: foo
10define void @foo() {
11 call void @bar()
12 ret void
13}
14
15; CHECK: lto.tmp
16; CHECK: bar
17define void @bar() {
18 call void @foo()
19 ret void
20}
deps/lld/test/COFF/lto.ll created+130
......@@ -0,0 +1,130 @@
1; RUN: llvm-as -o %T/main.lto.obj %s
2; RUN: llvm-as -o %T/foo.lto.obj %S/Inputs/lto-dep.ll
3; RUN: rm -f %T/foo.lto.lib
4; RUN: llvm-ar cru %T/foo.lto.lib %T/foo.lto.obj
5
6; RUN: llc -filetype=obj -o %T/main.obj %s
7; RUN: llc -filetype=obj -o %T/foo.obj %S/Inputs/lto-dep.ll
8; RUN: rm -f %T/foo.lib
9; RUN: llvm-ar cru %T/foo.lib %T/foo.obj
10
11; RUN: lld-link /out:%T/main.exe /entry:main /include:f2 /subsystem:console %T/main.lto.obj %T/foo.lto.obj
12; RUN: llvm-readobj -file-headers %T/main.exe | FileCheck -check-prefix=HEADERS-11 %s
13; RUN: llvm-objdump -d %T/main.exe | FileCheck -check-prefix=TEXT-11 %s
14; RUN: lld-link /out:%T/main.exe /entry:main /include:f2 /subsystem:console %T/main.lto.obj %T/foo.lto.lib /verbose 2>&1 | FileCheck -check-prefix=VERBOSE %s
15; RUN: llvm-readobj -file-headers %T/main.exe | FileCheck -check-prefix=HEADERS-11 %s
16; RUN: llvm-objdump -d %T/main.exe | FileCheck -check-prefix=TEXT-11 %s
17
18; RUN: lld-link /out:%T/main.exe /entry:main /subsystem:console %T/main.obj %T/foo.lto.obj
19; RUN: llvm-readobj -file-headers %T/main.exe | FileCheck -check-prefix=HEADERS-01 %s
20; RUN: llvm-objdump -d %T/main.exe | FileCheck -check-prefix=TEXT-01 %s
21; RUN: lld-link /out:%T/main.exe /entry:main /subsystem:console %T/main.obj %T/foo.lto.lib
22; RUN: llvm-readobj -file-headers %T/main.exe | FileCheck -check-prefix=HEADERS-01 %s
23; RUN: llvm-objdump -d %T/main.exe | FileCheck -check-prefix=TEXT-01 %s
24
25; RUN: lld-link /out:%T/main.exe /entry:main /subsystem:console %T/main.lto.obj %T/foo.obj
26; RUN: llvm-readobj -file-headers %T/main.exe | FileCheck -check-prefix=HEADERS-10 %s
27; RUN: llvm-objdump -d %T/main.exe | FileCheck -check-prefix=TEXT-10 %s
28; RUN: lld-link /out:%T/main.exe /entry:main /subsystem:console %T/main.lto.obj %T/foo.lib
29; RUN: llvm-readobj -file-headers %T/main.exe | FileCheck -check-prefix=HEADERS-10 %s
30; RUN: llvm-objdump -d %T/main.exe | FileCheck -check-prefix=TEXT-10 %s
31
32; VERBOSE: foo.lto.lib({{.*}}foo.lto.obj)
33
34; HEADERS-11: AddressOfEntryPoint: 0x1000
35; TEXT-11: Disassembly of section .text:
36; TEXT-11-NEXT: .text:
37; TEXT-11-NEXT: xorl %eax, %eax
38; TEXT-11-NEXT: retq
39; TEXT-11-NEXT: int3
40; TEXT-11-NEXT: int3
41; TEXT-11-NEXT: int3
42; TEXT-11-NEXT: int3
43; TEXT-11-NEXT: int3
44; TEXT-11-NEXT: int3
45; TEXT-11-NEXT: int3
46; TEXT-11-NEXT: int3
47; TEXT-11-NEXT: int3
48; TEXT-11-NEXT: int3
49; TEXT-11-NEXT: int3
50; TEXT-11-NEXT: int3
51; TEXT-11-NEXT: int3
52; TEXT-11-NEXT: movl $2, %eax
53; TEXT-11-NEXT: retq
54
55; HEADERS-01: AddressOfEntryPoint: 0x2000
56; TEXT-01: Disassembly of section .text:
57; TEXT-01-NEXT: .text:
58; TEXT-01-NEXT: subq $40, %rsp
59; TEXT-01-NEXT: callq 23
60; TEXT-01-NEXT: xorl %eax, %eax
61; TEXT-01-NEXT: addq $40, %rsp
62; TEXT-01-NEXT: retq
63; TEXT-01-NEXT: retq
64; TEXT-01-NEXT: int3
65; TEXT-01-NEXT: int3
66; TEXT-01-NEXT: int3
67; TEXT-01-NEXT: int3
68; TEXT-01-NEXT: int3
69; TEXT-01-NEXT: int3
70; TEXT-01-NEXT: int3
71; TEXT-01-NEXT: int3
72; TEXT-01-NEXT: int3
73; TEXT-01-NEXT: int3
74; TEXT-01-NEXT: int3
75; TEXT-01-NEXT: int3
76; TEXT-01-NEXT: int3
77; TEXT-01-NEXT: int3
78; TEXT-01-NEXT: int3
79; TEXT-01-NEXT: retq
80
81; HEADERS-10: AddressOfEntryPoint: 0x2020
82; TEXT-10: Disassembly of section .text:
83; TEXT-10-NEXT: .text:
84; TEXT-10-NEXT: retq
85; TEXT-10-NEXT: nopw %cs:(%rax,%rax)
86; TEXT-10-NEXT: retq
87; TEXT-10-NEXT: int3
88; TEXT-10-NEXT: int3
89; TEXT-10-NEXT: int3
90; TEXT-10-NEXT: int3
91; TEXT-10-NEXT: int3
92; TEXT-10-NEXT: int3
93; TEXT-10-NEXT: int3
94; TEXT-10-NEXT: int3
95; TEXT-10-NEXT: int3
96; TEXT-10-NEXT: int3
97; TEXT-10-NEXT: int3
98; TEXT-10-NEXT: int3
99; TEXT-10-NEXT: int3
100; TEXT-10-NEXT: int3
101; TEXT-10-NEXT: int3
102; TEXT-10-NEXT: subq $40, %rsp
103; TEXT-10-NEXT: callq -41
104; TEXT-10-NEXT: xorl %eax, %eax
105; TEXT-10-NEXT: addq $40, %rsp
106; TEXT-10-NEXT: retq
107
108target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
109target triple = "x86_64-pc-windows-msvc"
110
111define i32 @main() {
112 call void @foo()
113 ret i32 0
114}
115
116declare void @foo()
117
118$f1 = comdat any
119define i32 @f1() comdat($f1) {
120 ret i32 1
121}
122
123$f2 = comdat any
124define i32 @f2() comdat($f2) {
125 ret i32 2
126}
127
128define internal void @internal() {
129 ret void
130}
deps/lld/test/COFF/machine.test created+30
......@@ -0,0 +1,30 @@
1# RUN: yaml2obj %p/Inputs/machine-x64.yaml > %t.obj
2# RUN: lld-link /entry:main /subsystem:console /out:%t.exe %t.obj
3# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=AMD64 %s
4# RUN: lld-link /entry:main /subsystem:console /machine:x64 \
5# RUN: /out:%t.exe %t.obj
6# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=AMD64 %s
7
8AMD64: Machine: IMAGE_FILE_MACHINE_AMD64
9
10# RUN: yaml2obj %p/Inputs/machine-x86.yaml > %t.obj
11# RUN: lld-link /entry:main /subsystem:console /out:%t.exe %t.obj
12# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=I386 %s
13# RUN: lld-link /entry:main /subsystem:console /machine:x86 \
14# RUN: /out:%t.exe %t.obj /fixed
15# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=I386 %s
16
17I386: Machine: IMAGE_FILE_MACHINE_I386
18
19# RUN: yaml2obj %p/Inputs/machine-x64.yaml > %t.obj
20# RUN: not lld-link /entry:main /subsystem:console /machine:x86 \
21# RUN: /out:%t.exe %t.obj /fixed >& %t.log
22# RUN: FileCheck -check-prefix=INCOMPAT %s < %t.log
23
24# RUN: yaml2obj %p/Inputs/machine-x86.yaml > %t1.obj
25# RUN: sed -e s/main/foo/ %p/Inputs/machine-x64.yaml | yaml2obj > %t2.obj
26# RUN: not lld-link /entry:main /subsystem:console /out:%t.exe \
27# RUN: %t1.obj %t2.obj >& %t.log
28# RUN: FileCheck -check-prefix=INCOMPAT %s < %t.log
29
30INCOMPAT: .obj: machine type x64 conflicts with x86
deps/lld/test/COFF/manifest.test created+66
......@@ -0,0 +1,66 @@
1# RUN: yaml2obj %p/Inputs/ret42.yaml > %t.obj
2
3# RUN: rm -f %t.exe.manifest
4# RUN: lld-link /out:%t.exe /entry:main %t.obj
5# RUN: test ! -e %t.exe.manifest
6
7# RUN: lld-link /manifest /out:%t.exe /entry:main %t.obj
8# RUN: FileCheck -check-prefix=MANIFEST %s < %t.exe.manifest
9
10MANIFEST: <?xml version="1.0" standalone="yes"?>
11MANIFEST: <assembly xmlns="urn:schemas-microsoft-com:asm.v1"
12MANIFEST: manifestVersion="1.0">
13MANIFEST: <trustInfo>
14MANIFEST: <security>
15MANIFEST: <requestedPrivileges>
16MANIFEST: <requestedExecutionLevel level='asInvoker' uiAccess='false'/>
17MANIFEST: </requestedPrivileges>
18MANIFEST: </security>
19MANIFEST: </trustInfo>
20MANIFEST: </assembly>
21
22# RUN: lld-link /out:%t.exe /entry:main /manifest \
23# RUN: /manifestuac:"level='requireAdministrator' uiAccess='true'" %t.obj
24# RUN: FileCheck -check-prefix=UAC %s < %t.exe.manifest
25
26UAC: <?xml version="1.0" standalone="yes"?>
27UAC: <assembly xmlns="urn:schemas-microsoft-com:asm.v1"
28UAC: manifestVersion="1.0">
29UAC: <trustInfo>
30UAC: <security>
31UAC: <requestedPrivileges>
32UAC: <requestedExecutionLevel level='requireAdministrator' uiAccess='true'/>
33UAC: </requestedPrivileges>
34UAC: </security>
35UAC: </trustInfo>
36UAC: </assembly>
37
38# /manifestdependency implies /manifest. (/manifestuac doesn't.)
39# RUN: lld-link /out:%t.exe /entry:main \
40# RUN: /manifestdependency:"foo='bar'" %t.obj
41# RUN: FileCheck -check-prefix=DEPENDENCY %s < %t.exe.manifest
42
43DEPENDENCY: <?xml version="1.0" standalone="yes"?>
44DEPENDENCY: <assembly xmlns="urn:schemas-microsoft-com:asm.v1"
45DEPENDENCY: manifestVersion="1.0">
46DEPENDENCY: <trustInfo>
47DEPENDENCY: <security>
48DEPENDENCY: <requestedPrivileges>
49DEPENDENCY: <requestedExecutionLevel level='asInvoker' uiAccess='false'/>
50DEPENDENCY: </requestedPrivileges>
51DEPENDENCY: </security>
52DEPENDENCY: </trustInfo>
53DEPENDENCY: <dependency>
54DEPENDENCY: <dependentAssembly>
55DEPENDENCY: <assemblyIdentity foo='bar' />
56DEPENDENCY: </dependentAssembly>
57DEPENDENCY: </dependency>
58DEPENDENCY: </assembly>
59
60# RUN: lld-link /manifest /out:%t.exe /entry:main /manifestuac:no %t.obj
61# RUN: FileCheck -check-prefix=NOUAC %s < %t.exe.manifest
62
63NOUAC: <?xml version="1.0" standalone="yes"?>
64NOUAC: <assembly xmlns="urn:schemas-microsoft-com:asm.v1"
65NOUAC: manifestVersion="1.0">
66NOUAC: </assembly>
deps/lld/test/COFF/manifestinput.test created+26
......@@ -0,0 +1,26 @@
1# REQUIRES: win_mt
2
3# RUN: yaml2obj %p/Inputs/ret42.yaml > %t.obj
4# RUN: lld-link /out:%t.exe /entry:main \
5# RUN: /manifest:embed \
6# RUN: /manifestuac:"level='requireAdministrator'" \
7# RUN: /manifestinput:%p/Inputs/manifestinput.test %t.obj
8# RUN: llvm-readobj -coff-resources -file-headers %t.exe | FileCheck %s \
9# RUN: -check-prefix TEST_EMBED
10
11TEST_EMBED: ResourceTableRVA: 0x1000
12TEST_EMBED-NEXT: ResourceTableSize: 0x298
13TEST_EMBED-DAG: Resources [
14TEST_EMBED-NEXT: Total Number of Resources: 1
15TEST_EMBED-DAG: Number of String Entries: 0
16TEST_EMBED-NEXT: Number of ID Entries: 1
17TEST_EMBED-NEXT: Type: kRT_MANIFEST (ID 24) [
18TEST_EMBED-NEXT: Table Offset: 0x18
19TEST_EMBED-NEXT: Number of String Entries: 0
20TEST_EMBED-NEXT: Number of ID Entries: 1
21TEST_EMBED-NEXT: Name: (ID 1) [
22TEST_EMBED-NEXT: Table Offset: 0x30
23TEST_EMBED-NEXT: Number of String Entries: 0
24TEST_EMBED-NEXT: Number of ID Entries: 1
25TEST_EMBED-NEXT: Language: (ID 1033) [
26TEST_EMBED-NEXT: Entry Offset: 0x48
deps/lld/test/COFF/merge.test created+53
......@@ -0,0 +1,53 @@
1# RUN: yaml2obj < %s > %t.obj
2# RUN: lld-link /out:%t.exe /entry:main /subsystem:console /force \
3# RUN: /merge:.foo=.abc /merge:.bar=.def %t.obj /debug
4# RUN: llvm-readobj -sections %t.exe | FileCheck %s
5
6# CHECK: Name: .def
7# CHECK: Name: .abc
8
9--- !COFF
10header:
11 Machine: IMAGE_FILE_MACHINE_AMD64
12 Characteristics: []
13sections:
14 - Name: .foo
15 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
16 Alignment: 4
17 SectionData: 000000000000
18 - Name: .bar
19 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
20 Alignment: 4
21 SectionData: 000000000000
22symbols:
23 - Name: .foo
24 Value: 0
25 SectionNumber: 1
26 SimpleType: IMAGE_SYM_TYPE_NULL
27 ComplexType: IMAGE_SYM_DTYPE_NULL
28 StorageClass: IMAGE_SYM_CLASS_STATIC
29 SectionDefinition:
30 Length: 6
31 NumberOfRelocations: 0
32 NumberOfLinenumbers: 0
33 CheckSum: 0
34 Number: 0
35 - Name: .bar
36 Value: 0
37 SectionNumber: 2
38 SimpleType: IMAGE_SYM_TYPE_NULL
39 ComplexType: IMAGE_SYM_DTYPE_NULL
40 StorageClass: IMAGE_SYM_CLASS_STATIC
41 SectionDefinition:
42 Length: 6
43 NumberOfRelocations: 0
44 NumberOfLinenumbers: 0
45 CheckSum: 0
46 Number: 0
47 - Name: main
48 Value: 0
49 SectionNumber: 1
50 SimpleType: IMAGE_SYM_TYPE_NULL
51 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
52 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
53...
deps/lld/test/COFF/msvclto-archive.ll created+40
......@@ -0,0 +1,40 @@
1; REQUIRES: x86
2;; Make sure we re-create archive files to strip bitcode files.
3
4;; Do not create empty archives because the MSVC linker
5;; doesn't support them.
6; RUN: llvm-as -o %t.obj %s
7; RUN: rm -f %t-main1.a
8; RUN: llvm-ar cru %t-main1.a %t.obj
9; RUN: mkdir -p %t.dir
10; RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o %t.dir/bitcode.obj %p/Inputs/msvclto.s
11; RUN: lld-link %t-main1.a %t.dir/bitcode.obj /msvclto /out:%t.exe /opt:lldlto=1 /opt:icf \
12; RUN: /entry:main /verbose > %t.log || true
13; RUN: FileCheck -check-prefix=BC %s < %t.log
14; BC-NOT: Creating a temporary archive for
15
16; RUN: rm -f %t-main2.a
17; RUN: llvm-ar cru %t-main2.a %t.dir/bitcode.obj
18; RUN: lld-link %t.obj %t-main2.a /msvclto /out:%t.exe /opt:lldlto=1 /opt:icf \
19; RUN: /entry:main /verbose > %t.log || true
20; RUN: FileCheck -check-prefix=OBJ %s < %t.log
21; OBJ-NOT: Creating a temporary archive
22
23;; Make sure that we always rebuild thin archives because
24;; the MSVC linker doesn't support thin archives.
25; RUN: rm -f %t-main3.a
26; RUN: llvm-ar cruT %t-main3.a %t.dir/bitcode.obj
27; RUN: lld-link %t.obj %t-main3.a /msvclto /out:%t.exe /opt:lldlto=1 /opt:icf \
28; RUN: /entry:main /verbose > %t.log || true
29; RUN: FileCheck -check-prefix=THIN %s < %t.log
30; THIN: Creating a temporary archive
31
32target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
33target triple = "x86_64-pc-windows-msvc"
34
35declare void @foo()
36
37define i32 @main() {
38 call void @foo()
39 ret i32 0
40}
deps/lld/test/COFF/msvclto-order.ll created+25
......@@ -0,0 +1,25 @@
1; REQUIRES: x86
2; RUN: opt -thinlto-bc %s -o %t.obj
3; RUN: llc -filetype=obj %S/Inputs/msvclto-order-a.ll -o %T/msvclto-order-a.obj
4; RUN: llvm-ar crs %T/msvclto-order-a.lib %T/msvclto-order-a.obj
5; RUN: llc -filetype=obj %S/Inputs/msvclto-order-b.ll -o %T/msvclto-order-b.obj
6; RUN: llvm-ar crs %T/msvclto-order-b.lib %T/msvclto-order-b.obj
7; RUN: lld-link /verbose /msvclto /out:%t.exe /entry:main %t.obj \
8; RUN: %T/msvclto-order-a.lib %T/msvclto-order-b.lib > %t.log || true
9; RUN: FileCheck %s < %t.log
10
11; CHECK: : link.exe
12; CHECK-NOT: .lib{{$}}
13; CHECK: lld-msvclto-order-a{{.*}}.obj
14; CHECK-NOT: lld-msvclto-order-b{{.*}}.obj
15; CHECK: .lib{{$}}
16
17target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
18target triple = "x86_64-pc-windows-msvc"
19
20declare void @foo()
21
22define i32 @main() {
23 call void @foo()
24 ret i32 0
25}
deps/lld/test/COFF/msvclto.ll created+20
......@@ -0,0 +1,20 @@
1; REQUIRES: x86
2; RUN: llvm-as -o %t.obj %s
3; RUN: mkdir -p %t.dir
4; RUN: llvm-mc -triple=x86_64-pc-windows-msvc -filetype=obj -o %t.dir/bitcode.obj %p/Inputs/msvclto.s
5; RUN: lld-link %t.obj %t.dir/bitcode.obj /msvclto /out:%t.exe /opt:lldlto=1 /opt:icf \
6; RUN: /entry:main /verbose > %t.log || true
7; RUN: FileCheck %s < %t.log
8
9; CHECK: /opt:icf /entry:main
10; CHECK: /verbose
11
12target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
13target triple = "x86_64-pc-windows-msvc"
14
15declare void @foo()
16
17define i32 @main() {
18 call void @foo()
19 ret i32 0
20}
deps/lld/test/COFF/nodefaultlib.test created+30
......@@ -0,0 +1,30 @@
1# RUN: cp %p/Inputs/hello64.obj %T
2# RUN: cp %p/Inputs/std64.lib %T
3
4# RUN: not lld-link /out:%t.exe /entry:main /subsystem:console \
5# RUN: hello64.obj /defaultlib:std64.lib >& %t.log
6# RUN: FileCheck -check-prefix=CHECK1 %s < %t.log
7
8# RUN: not lld-link /out:%t.exe /entry:main /subsystem:console \
9# RUN: hello64 /defaultlib:std64.lib >& %t.log
10# RUN: FileCheck -check-prefix=CHECK2 %s < %t.log
11
12# RUN: lld-link /libpath:%T /out:%t.exe /entry:main \
13# RUN: /subsystem:console hello64.obj /defaultlib:std64.lib \
14# RUN: /nodefaultlib:std64.lib >& %t.log || true
15# RUN: FileCheck -check-prefix=CHECK3 %s < %t.log
16
17# RUN: lld-link /libpath:%T /out:%t.exe /entry:main \
18# RUN: /subsystem:console hello64.obj /defaultlib:std64 \
19# RUN: /nodefaultlib:std64.lib >& %t.log || true
20# RUN: FileCheck -check-prefix=CHECK3 %s < %t.log
21
22CHECK1: hello64.obj: {{[Nn]}}o such file or directory
23CHECK2: hello64: {{[Nn]}}o such file or directory
24CHECK3: hello64.obj: undefined symbol: MessageBoxA
25
26# RUN: lld-link /libpath:%T /out:%t.exe /entry:main \
27# RUN: /subsystem:console hello64.obj /defaultlib:std64.lib
28
29# RUN: env LIB=%T lld-link /out:%t.exe /entry:main \
30# RUN: /subsystem:console hello64.obj /defaultlib:std64.lib
deps/lld/test/COFF/noentry.test created+8
......@@ -0,0 +1,8 @@
1# RUN: yaml2obj < %p/Inputs/export.yaml > %t.obj
2# RUN: lld-link /out:%t.dll /dll %t.obj
3# RUN: llvm-readobj -file-headers %t.dll | FileCheck -check-prefix=ENTRY %s
4# RUN: lld-link /out:%t.dll /dll /noentry %t.obj
5# RUN: llvm-readobj -file-headers %t.dll | FileCheck -check-prefix=NOENTRY %s
6
7ENTRY: AddressOfEntryPoint: 0x1000
8NOENTRY: AddressOfEntryPoint: 0x0
deps/lld/test/COFF/nopdb.test created+14
......@@ -0,0 +1,14 @@
1# Check that /debug creates %t.pdb.
2# RUN: rm -f %t.pdb
3# RUN: lld-link /debug /entry:main /out:%t.exe %p/Inputs/ret42.obj
4# RUN: ls %t.pdb
5
6# Check that /debug /nopdb does not create %t.pdb.
7# RUN: rm -f %t.pdb
8# RUN: lld-link /debug /nopdb /entry:main /out:%t.exe %p/Inputs/ret42.obj
9# RUN: not ls %t.pdb
10
11# Check that /debug /nopdb /pdb:%t.pdb does not create %t.pdb.
12# RUN: rm -f %t.pdb
13# RUN: lld-link /debug /nopdb /pdb:%t.pdb /entry:main /out:%t.exe %p/Inputs/ret42.obj
14# RUN: not ls %t.pdb
deps/lld/test/COFF/opt.test created+69
......@@ -0,0 +1,69 @@
1# RUN: yaml2obj < %s > %t.obj
2
3# RUN: lld-link /out:%t.exe /entry:main %t.obj \
4# RUN: /verbose >& %t.log
5### FileCheck doesn't like empty input, so write something.
6# RUN: echo dummy >> %t.log
7# RUN: FileCheck -check-prefix=CHECK1 %s < %t.log
8
9# RUN: lld-link /out:%t.exe /entry:main %t.obj \
10# RUN: /verbose /opt:noref >& %t.log
11# RUN: echo dummy >> %t.log
12# RUN: FileCheck -check-prefix=CHECK2 %s < %t.log
13
14# CHECK1: Discarded unused
15# CHECK2-NOT: Discarded unused
16
17--- !COFF
18header:
19 Machine: IMAGE_FILE_MACHINE_AMD64
20 Characteristics: []
21sections:
22 - Name: '.text$mn'
23 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
24 Alignment: 4
25 SectionData: B82A000000C3
26 - Name: '.text$mn'
27 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
28 Alignment: 4
29 SectionData: B82A000000C3
30symbols:
31 - Name: '.text$mn'
32 Value: 0
33 SectionNumber: 1
34 SimpleType: IMAGE_SYM_TYPE_NULL
35 ComplexType: IMAGE_SYM_DTYPE_NULL
36 StorageClass: IMAGE_SYM_CLASS_STATIC
37 SectionDefinition:
38 Length: 6
39 NumberOfRelocations: 0
40 NumberOfLinenumbers: 0
41 CheckSum: 0
42 Number: 0
43 Selection: IMAGE_COMDAT_SELECT_ANY
44 - Name: '.text$mn'
45 Value: 0
46 SectionNumber: 2
47 SimpleType: IMAGE_SYM_TYPE_NULL
48 ComplexType: IMAGE_SYM_DTYPE_NULL
49 StorageClass: IMAGE_SYM_CLASS_STATIC
50 SectionDefinition:
51 Length: 6
52 NumberOfRelocations: 0
53 NumberOfLinenumbers: 0
54 CheckSum: 0
55 Number: 0
56 Selection: IMAGE_COMDAT_SELECT_ANY
57 - Name: main
58 Value: 0
59 SectionNumber: 1
60 SimpleType: IMAGE_SYM_TYPE_NULL
61 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
62 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
63 - Name: unused
64 Value: 0
65 SectionNumber: 2
66 SimpleType: IMAGE_SYM_TYPE_NULL
67 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
68 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
69...
deps/lld/test/COFF/options.test created+45
......@@ -0,0 +1,45 @@
1# RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj
2
3# RUN: lld-link /out:%t.exe /entry:main %t.obj
4# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=BIND %s
5BIND: IMAGE_DLL_CHARACTERISTICS_NO_BIND
6
7# RUN: lld-link /out:%t.exe /entry:main %t.obj
8# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=ISO %s
9# RUN: lld-link /allowisolation /out:%t.exe /entry:main %t.obj
10# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=ISO %s
11ISO-NOT: IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION
12
13# RUN: lld-link /allowisolation:no /out:%t.exe /entry:main %t.obj
14# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NOISO %s
15NOISO: IMAGE_DLL_CHARACTERISTICS_NO_ISOLATION
16
17# RUN: lld-link /out:%t.exe /entry:main %t.obj
18# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=ENT %s
19# RUN: lld-link /out:%t.exe /entry:main /highentropyva %t.obj
20# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=ENT %s
21ENT: IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA
22
23# RUN: lld-link /out:%t.exe /highentropyva:no /out:%t.exe /entry:main %t.obj
24# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NOENT %s
25NOENT-NOT: IMAGE_DLL_CHARACTERISTICS_HIGH_ENTROPY_VA
26
27# RUN: lld-link /out:%t.exe /entry:main %t.obj
28# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NXCOMPAT %s
29# RUN: lld-link /out:%t.exe /entry:main /nxcompat %t.obj
30# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NXCOMPAT %s
31NXCOMPAT: IMAGE_DLL_CHARACTERISTICS_NX_COMPAT
32
33# RUN: lld-link /out:%t.exe /nxcompat:no /out:%t.exe /entry:main %t.obj
34# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NONXCOMPAT %s
35NONXCOMPAT-NOT: IMAGE_DLL_CHARACTERISTICS_NX_COMPAT
36
37# RUN: lld-link /out:%t.exe /entry:main %t.obj
38# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=TSAWARE %s
39# RUN: lld-link /out:%t.exe /entry:main /tsaware %t.obj
40# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=TSAWARE %s
41TSAWARE: IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE
42
43# RUN: lld-link /tsaware:no /out:%t.exe /entry:main %t.obj
44# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=NOTSAWARE %s
45NOTSAWARE-NOT: IMAGE_DLL_CHARACTERISTICS_TERMINAL_SERVER_AWARE
deps/lld/test/COFF/order.test created+15
......@@ -0,0 +1,15 @@
1# RUN: yaml2obj < %p/Inputs/include1a.yaml > %t1.obj
2# RUN: yaml2obj < %p/Inputs/include1b.yaml > %t2.obj
3# RUN: yaml2obj < %p/Inputs/include1c.yaml > %t3.obj
4# RUN: rm -f %t2.lib %t3.lib
5# RUN: llvm-ar cru %t2.lib %t2.obj
6# RUN: llvm-ar cru %t3.lib %t3.obj
7# RUN: lld-link /out:%t.exe /entry:main \
8# RUN: %t1.obj %t2.lib %t3.obj %t3.lib /verbose >& %t.log
9# RUN: FileCheck %s < %t.log
10
11CHECK: order.test.tmp1.obj
12CHECK: order.test.tmp2.lib
13CHECK: order.test.tmp3.obj
14CHECK: order.test.tmp3.lib
15CHECK: order.test.tmp2.lib(order.test.tmp2.obj) for foo
deps/lld/test/COFF/out.test created+17
......@@ -0,0 +1,17 @@
1# RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj
2
3# RUN: mkdir -p %T/out/tmp
4# RUN: cp %t.obj %T/out/out1.obj
5# RUN: cp %t.obj %T/out/tmp/out2
6# RUN: cp %t.obj %T/out/tmp/out3.xyz
7
8# RUN: rm -f out1.exe out2.exe out3.exe out3.dll
9# RUN: lld-link /entry:main %T/out/out1.obj
10# RUN: lld-link /entry:main %T/out/tmp/out2
11# RUN: lld-link /dll /entry:main %T/out/tmp/out3.xyz
12
13# RUN: llvm-readobj out1.exe | FileCheck %s
14# RUN: llvm-readobj out2.exe | FileCheck %s
15# RUN: llvm-readobj out3.dll | FileCheck %s
16
17CHECK: File:
deps/lld/test/COFF/pdb-comdat.test created+99
......@@ -0,0 +1,99 @@
1Consider this example program with an inline function "foo":
2
3==> foo.h <==
4extern int global;
5__inline void foo() {
6 ++global;
7}
8void bar();
9==> pdb_comdat_main.c <==
10#include "foo.h"
11int main(void) {
12 foo();
13 bar();
14 return 42;
15}
16==> pdb_comdat_bar.c <==
17#include "foo.h"
18void bar(void) {
19 foo();
20}
21
22Both object files will contain debug info for foo, but only the debug info from
23pdb_comdat_main.obj should be included in the PDB.
24
25RUN: rm -rf %t && mkdir -p %t && cd %t
26RUN: yaml2obj %S/Inputs/pdb_comdat_main.yaml -o pdb_comdat_main.obj
27RUN: yaml2obj %S/Inputs/pdb_comdat_bar.yaml -o pdb_comdat_bar.obj
28RUN: lld-link pdb_comdat_main.obj pdb_comdat_bar.obj -out:t.exe -debug -pdb:t.pdb -nodefaultlib -entry:main
29RUN: llvm-pdbutil dump -l -symbols t.pdb | FileCheck %s
30
31CHECK: Lines
32CHECK: ============================================================
33CHECK-LABEL: Mod 0000 | `{{.*}}pdb_comdat_main.obj`:
34CHECK: c:\src\llvm-project\build\pdb_comdat_main.c (MD5: F969E51BBE373436D81492EB61387F36)
35CHECK: c:\src\llvm-project\build\foo.h (MD5: D74D834EFAC3AE2B45E606A8320B1D5C)
36CHECK-LABEL: Mod 0001 | `{{.*}}pdb_comdat_bar.obj`:
37CHECK: c:\src\llvm-project\build\pdb_comdat_bar.c (MD5: 365279DB4FCBEDD721BBFC3B14A953C2)
38CHECK-NOT: c:\src\llvm-project\build\foo.h
39CHECK-LABEL: Mod 0002 | `* Linker *`:
40
41CHECK: Symbols
42CHECK: ============================================================
43CHECK-LABEL: Mod 0000 | `{{.*}}pdb_comdat_main.obj`:
44CHECK: 4 | S_OBJNAME [size = 56] sig=0, `C:\src\llvm-project\build\pdb_comdat_main.obj`
45CHECK: 60 | S_COMPILE3 [size = 60]
46CHECK: machine = intel x86-x64, Ver = Microsoft (R) Optimizing Compiler, language = c
47CHECK: frontend = 19.0.24215.1, backend = 19.0.24215.1
48CHECK: flags = security checks | hot patchable
49CHECK: 120 | S_GPROC32_ID [size = 44] `main`
50CHECK: parent = 0, end = 196, addr = 0002:0000, code size = 24
51CHECK: debug start = 4, debug end = 19, flags = none
52CHECK: 164 | S_FRAMEPROC [size = 32]
53CHECK: size = 40, padding size = 0, offset to padding = 0
54CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000
55CHECK: flags = has async eh | opt speed
56CHECK: 196 | S_END [size = 4]
57CHECK: 200 | S_GDATA32 [size = 24] `global`
58CHECK: type = 0x0074 (int), addr = 0000:0000
59CHECK: 224 | S_BUILDINFO [size = 8] BuildId = `0x100A`
60CHECK: 232 | S_GPROC32_ID [size = 44] `foo`
61CHECK: parent = 0, end = 308, addr = 0002:0032, code size = 15
62CHECK: debug start = 0, debug end = 14, flags = none
63CHECK: 276 | S_FRAMEPROC [size = 32]
64CHECK: size = 0, padding size = 0, offset to padding = 0
65CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000
66CHECK: flags = marked inline | has async eh | opt speed
67CHECK: 308 | S_END [size = 4]
68CHECK-LABEL: Mod 0001 | `{{.*}}pdb_comdat_bar.obj`:
69CHECK: 4 | S_OBJNAME [size = 56] sig=0, `C:\src\llvm-project\build\pdb_comdat_bar.obj`
70CHECK: 60 | S_COMPILE3 [size = 60]
71CHECK: machine = intel x86-x64, Ver = Microsoft (R) Optimizing Compiler, language = c
72CHECK: frontend = 19.0.24215.1, backend = 19.0.24215.1
73CHECK: flags = security checks | hot patchable
74CHECK: 120 | S_GPROC32_ID [size = 44] `bar`
75CHECK: parent = 0, end = 196, addr = 0002:0048, code size = 14
76CHECK: debug start = 4, debug end = 9, flags = none
77CHECK: 164 | S_FRAMEPROC [size = 32]
78CHECK: size = 40, padding size = 0, offset to padding = 0
79CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000
80CHECK: flags = has async eh | opt speed
81CHECK: 196 | S_END [size = 4]
82CHECK: 200 | S_GDATA32 [size = 24] `global`
83CHECK: type = 0x0074 (int), addr = 0000:0000
84CHECK: 224 | S_BUILDINFO [size = 8] BuildId = `0x100D`
85CHECK-NOT: S_GPROC32_ID {{.*}} `foo`
86CHECK-LABEL: Mod 0002 | `* Linker *`:
87
88Reorder the object files and verify that the other table is selected.
89
90RUN: lld-link pdb_comdat_bar.obj pdb_comdat_main.obj -out:t.exe -debug -pdb:t.pdb -nodefaultlib -entry:main
91RUN: llvm-pdbutil dump -l t.pdb | FileCheck %s --check-prefix=REORDER
92
93REORDER-LABEL: Mod 0000 | `{{.*}}pdb_comdat_bar.obj`:
94REORDER: c:\src\llvm-project\build\pdb_comdat_bar.c (MD5: 365279DB4FCBEDD721BBFC3B14A953C2)
95REORDER: c:\src\llvm-project\build\foo.h (MD5: D74D834EFAC3AE2B45E606A8320B1D5C)
96REORDER-LABEL: Mod 0001 | `{{.*}}pdb_comdat_main.obj`:
97REORDER: c:\src\llvm-project\build\pdb_comdat_main.c
98REORDER-NOT: c:\src\llvm-project\build\foo.h
99REORDER-LABEL: Mod 0002 | `* Linker *`:
deps/lld/test/COFF/pdb-diff.test created+212
......@@ -0,0 +1,212 @@
1This test verifies that we produce PDBs compatible with MSVC in various ways.
2We check in a cl-generated object file, PDB, and original source which serve
3as the "baseline" for us to measure against. Then we link the same object
4file with LLD and compare the two PDBs. Since the baseline object file and
5PDB are already checked in, we just run LLD on the object file.
6
7RUN: lld-link /debug /pdb:%T/pdb-diff-lld.pdb /nodefaultlib /entry:main %S/Inputs/pdb-diff.obj
8RUN: llvm-pdbutil diff -result -values=false -left-bin-root=%S -right-bin-root=D:/src/llvm-mono/lld/test/COFF/ %T/pdb-diff-lld.pdb %S/Inputs/pdb-diff-cl.pdb | FileCheck %s
9
10CHECK: ----------------------
11CHECK-NEXT: | MSF Super Block |
12CHECK-NEXT: |----------------+---|
13CHECK-NEXT: | File | |
14CHECK-NEXT: |----------------+---|
15CHECK-NEXT: | Block Size | I |
16CHECK-NEXT: |----------------+---|
17CHECK-NEXT: | Block Count |
18CHECK-NEXT: |----------------+---|
19CHECK-NEXT: | Unknown 1 | I |
20CHECK-NEXT: |----------------+---|
21CHECK-NEXT: | Directory Size |
22CHECK-NEXT: |----------------+---|
23CHECK-NEXT: ------------------------------------
24CHECK-NEXT: | Stream Directory |
25CHECK-NEXT: |------------------------------+---|
26CHECK-NEXT: | File | |
27CHECK-NEXT: |------------------------------+---|
28CHECK-NEXT: | Stream Count | D |
29CHECK-NEXT: |------------------------------+---|
30CHECK-NEXT: | Old MSF Directory | I |
31CHECK-NEXT: |------------------------------+---|
32CHECK-NEXT: | PDB Stream | I |
33CHECK-NEXT: |------------------------------+---|
34CHECK-NEXT: | TPI Stream | I |
35CHECK-NEXT: |------------------------------+---|
36CHECK-NEXT: | DBI Stream | I |
37CHECK-NEXT: |------------------------------+---|
38CHECK-NEXT: | IPI Stream | I |
39CHECK-NEXT: |------------------------------+---|
40CHECK-NEXT: | New FPO Data | {{[EI]}} |
41CHECK-NEXT: |------------------------------+---|
42CHECK-NEXT: | Section Header Data | {{[EI]}} |
43CHECK-NEXT: |------------------------------+---|
44CHECK-NEXT: | Named Stream "/names" | {{[EI]}} |
45CHECK-NEXT: |------------------------------+---|
46CHECK-NEXT: | Named Stream "/LinkInfo" | {{[EI]}} |
47CHECK-NEXT: |------------------------------+---|
48CHECK-NEXT: | Module "Inputs\pdb-diff.obj" | {{[EI]}} |
49CHECK-NEXT: |------------------------------+---|
50CHECK-NEXT: | Module "* Linker *" | {{[EI]}} |
51CHECK-NEXT: |------------------------------+---|
52CHECK-NEXT: | TPI Hash | {{[EI]}} |
53CHECK-NEXT: |------------------------------+---|
54CHECK-NEXT: | IPI Hash | {{[EI]}} |
55CHECK-NEXT: |------------------------------+---|
56CHECK-NEXT: | Public Symbol Hash | {{[EI]}} |
57CHECK-NEXT: |------------------------------+---|
58CHECK-NEXT: | Public Symbol Records | {{[EI]}} |
59CHECK-NEXT: |------------------------------+---|
60CHECK-NEXT: | Global Symbol Hash | D |
61CHECK-NEXT: |------------------------------+---|
62CHECK-NEXT: ------------------------------------
63CHECK-NEXT: | String Table |
64CHECK-NEXT: |------------------------------+---|
65CHECK-NEXT: | File | |
66CHECK-NEXT: |------------------------------+---|
67CHECK-NEXT: | Number of Strings | D |
68CHECK-NEXT: |------------------------------+---|
69CHECK-NEXT: | Hash Version | I |
70CHECK-NEXT: |------------------------------+---|
71CHECK-NEXT: | Byte Size |
72CHECK-NEXT: |------------------------------+---|
73CHECK-NEXT: | Signature | I |
74CHECK-NEXT: |------------------------------+---|
75CHECK-NEXT: | Empty Strings |
76CHECK-NEXT: |------------------------------+---|
77CHECK-NEXT: | {{.*}}pdb-diff.cpp | {{[EI]}} |
78CHECK-NEXT: |------------------------------+---|
79CHECK-NEXT: | $T0 $ebp = $...p $T0 8 + = | D |
80CHECK-NEXT: |------------------------------+---|
81CHECK-NEXT: | d:\src\llvm-...er internal) | D |
82CHECK-NEXT: |------------------------------+---|
83CHECK-NEXT: ----------------------------
84CHECK-NEXT: | PDB Stream |
85CHECK-NEXT: |----------------------+---|
86CHECK-NEXT: | File | |
87CHECK-NEXT: |----------------------+---|
88CHECK-NEXT: | Stream Size |
89CHECK-NEXT: |----------------------+---|
90CHECK-NEXT: | Age | I |
91CHECK-NEXT: |----------------------+---|
92CHECK-NEXT: | Guid | D |
93CHECK-NEXT: |----------------------+---|
94CHECK-NEXT: | Signature | D |
95CHECK-NEXT: |----------------------+---|
96CHECK-NEXT: | Version | I |
97CHECK-NEXT: |----------------------+---|
98CHECK-NEXT: | Features (set) | I |
99CHECK-NEXT: |----------------------+---|
100CHECK-NEXT: | Feature | I |
101CHECK-NEXT: |----------------------+---|
102CHECK-NEXT: | Named Stream Size |
103CHECK-NEXT: |----------------------+---|
104CHECK-NEXT: | Named Streams (map) | {{[EI]}} |
105CHECK-NEXT: |----------------------+---|
106CHECK-NEXT: | /names | {{[EI]}} |
107CHECK-NEXT: |----------------------+---|
108CHECK-NEXT: | /LinkInfo | {{[EI]}} |
109CHECK-NEXT: |----------------------+---|
110CHECK-NEXT: ----------------------------------------------
111CHECK-NEXT: | DBI Stream |
112CHECK-NEXT: |----------------------------------------+---|
113CHECK-NEXT: | File | |
114CHECK-NEXT: |----------------------------------------+---|
115CHECK-NEXT: | Dbi Version | I |
116CHECK-NEXT: |----------------------------------------+---|
117CHECK-NEXT: | Age | I |
118CHECK-NEXT: |----------------------------------------+---|
119CHECK-NEXT: | Machine | I |
120CHECK-NEXT: |----------------------------------------+---|
121CHECK-NEXT: | Flags | D |
122CHECK-NEXT: |----------------------------------------+---|
123CHECK-NEXT: | Build Major | D |
124CHECK-NEXT: |----------------------------------------+---|
125CHECK-NEXT: | Build Minor | D |
126CHECK-NEXT: |----------------------------------------+---|
127CHECK-NEXT: | Build Number | D |
128CHECK-NEXT: |----------------------------------------+---|
129CHECK-NEXT: | PDB DLL Version | D |
130CHECK-NEXT: |----------------------------------------+---|
131CHECK-NEXT: | PDB DLL RBLD | I |
132CHECK-NEXT: |----------------------------------------+---|
133CHECK-NEXT: | DBG (FPO) | I |
134CHECK-NEXT: |----------------------------------------+---|
135CHECK-NEXT: | DBG (Exception) | I |
136CHECK-NEXT: |----------------------------------------+---|
137CHECK-NEXT: | DBG (Fixup) | I |
138CHECK-NEXT: |----------------------------------------+---|
139CHECK-NEXT: | DBG (OmapToSrc) | I |
140CHECK-NEXT: |----------------------------------------+---|
141CHECK-NEXT: | DBG (OmapFromSrc) | I |
142CHECK-NEXT: |----------------------------------------+---|
143CHECK-NEXT: | DBG (SectionHdr) | {{[EI]}} |
144CHECK-NEXT: |----------------------------------------+---|
145CHECK-NEXT: | DBG (TokenRidMap) | I |
146CHECK-NEXT: |----------------------------------------+---|
147CHECK-NEXT: | DBG (Xdata) | I |
148CHECK-NEXT: |----------------------------------------+---|
149CHECK-NEXT: | DBG (Pdata) | I |
150CHECK-NEXT: |----------------------------------------+---|
151CHECK-NEXT: | DBG (NewFPO) | {{[EI]}} |
152CHECK-NEXT: |----------------------------------------+---|
153CHECK-NEXT: | DBG (SectionHdrOrig) | I |
154CHECK-NEXT: |----------------------------------------+---|
155CHECK-NEXT: | Globals Stream | D |
156CHECK-NEXT: |----------------------------------------+---|
157CHECK-NEXT: | Publics Stream | {{[EI]}} |
158CHECK-NEXT: |----------------------------------------+---|
159CHECK-NEXT: | Symbol Records | {{[EI]}} |
160CHECK-NEXT: |----------------------------------------+---|
161CHECK-NEXT: | Has CTypes | I |
162CHECK-NEXT: |----------------------------------------+---|
163CHECK-NEXT: | Is Incrementally Linked | D |
164CHECK-NEXT: |----------------------------------------+---|
165CHECK-NEXT: | Is Stripped | I |
166CHECK-NEXT: |----------------------------------------+---|
167CHECK-NEXT: | Module Count | I |
168CHECK-NEXT: |----------------------------------------+---|
169CHECK-NEXT: | Source File Count | I |
170CHECK-NEXT: |----------------------------------------+---|
171CHECK-NEXT: | Module "Inputs\pdb-diff.obj" |
172CHECK-NEXT: |----------------------------------------+---|
173CHECK-NEXT: | - Modi | I |
174CHECK-NEXT: |----------------------------------------+---|
175CHECK-NEXT: | - Obj File Name | {{[EI]}} |
176CHECK-NEXT: |----------------------------------------+---|
177CHECK-NEXT: | - Debug Stream | {{[EI]}} |
178CHECK-NEXT: |----------------------------------------+---|
179CHECK-NEXT: | - C11 Byte Size | I |
180CHECK-NEXT: |----------------------------------------+---|
181CHECK-NEXT: | - C13 Byte Size | I |
182CHECK-NEXT: |----------------------------------------+---|
183CHECK-NEXT: | - # of files | I |
184CHECK-NEXT: |----------------------------------------+---|
185CHECK-NEXT: | - Pdb File Path Index | I |
186CHECK-NEXT: |----------------------------------------+---|
187CHECK-NEXT: | - Source File Name Index | I |
188CHECK-NEXT: |----------------------------------------+---|
189CHECK-NEXT: | - Symbol Byte Size | D |
190CHECK-NEXT: |----------------------------------------+---|
191CHECK-NEXT: | Module "* Linker *" |
192CHECK-NEXT: |----------------------------------------+---|
193CHECK-NEXT: | - Modi | I |
194CHECK-NEXT: |----------------------------------------+---|
195CHECK-NEXT: | - Obj File Name | I |
196CHECK-NEXT: |----------------------------------------+---|
197CHECK-NEXT: | - Debug Stream | {{[EI]}} |
198CHECK-NEXT: |----------------------------------------+---|
199CHECK-NEXT: | - C11 Byte Size | I |
200CHECK-NEXT: |----------------------------------------+---|
201CHECK-NEXT: | - C13 Byte Size | I |
202CHECK-NEXT: |----------------------------------------+---|
203CHECK-NEXT: | - # of files | I |
204CHECK-NEXT: |----------------------------------------+---|
205CHECK-NEXT: | - Pdb File Path Index | {{[EI]}} |
206CHECK-NEXT: |----------------------------------------+---|
207CHECK-NEXT: | - Source File Name Index | {{[EI]}} |
208CHECK-NEXT: |----------------------------------------+---|
209CHECK-NEXT: | - Symbol Byte Size |
210CHECK-NEXT: |----------------------------------------+---|
211
212
deps/lld/test/COFF/pdb-global-gc.yaml created+116
......@@ -0,0 +1,116 @@
1# RUN: yaml2obj %s -o %t.obj
2# RUN: llvm-mc %S/Inputs/pdb-global-gc.s -triple x86_64-windows-msvc -filetype=obj -o %t2.obj
3# RUN: lld-link %t.obj %t2.obj -debug -entry:main \
4# RUN: -nodefaultlib -debug -out:%t.exe -pdb:%t.pdb -verbose
5# RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s
6
7# This tests the case where an __imp_ chunk is discarded by linker GC. The debug
8# info may refer to the __imp_ symbol still.
9
10# Compile this code with MSVC to regenerate the test case:
11# extern char __declspec(dllimport) __wc_mb_cur;
12# int discarded() { return __wc_mb_cur; }
13# int main() { return g2; }
14
15# CHECK: Symbols
16# CHECK: ============================================================
17# CHECK: Mod 0000 | `{{.*}}pdb-global-gc.yaml.tmp.obj`:
18# CHECK: 4 | S_GDATA32 [size = 28] `__wc_mb_cur`
19# CHECK-NEXT: type = 0x0070 (char), addr = 0000:0000
20# CHECK: Mod 0001 | `{{.*}}pdb-global-gc.yaml.tmp2.obj`:
21# CHECK: Mod 0002 | `* Linker *`:
22
23--- !COFF
24header:
25 Machine: IMAGE_FILE_MACHINE_AMD64
26 Characteristics: [ ]
27sections:
28 - Name: '.debug$S'
29 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
30 Alignment: 1
31 Subsections:
32 - !Symbols
33 Records:
34 - Kind: S_GDATA32
35 DataSym:
36 Type: 112
37 DisplayName: __wc_mb_cur
38 - !StringTable
39 Strings:
40 Relocations:
41 - VirtualAddress: 20
42 SymbolName: __wc_mb_cur
43 Type: IMAGE_REL_AMD64_SECREL
44 - VirtualAddress: 24
45 SymbolName: __wc_mb_cur
46 Type: IMAGE_REL_AMD64_SECTION
47 - Name: '.text$mn'
48 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
49 Alignment: 16
50 SectionData: 0FBE0500000000C3
51 Relocations:
52 - VirtualAddress: 3
53 SymbolName: __wc_mb_cur
54 Type: IMAGE_REL_AMD64_REL32
55 - Name: '.text$mn'
56 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
57 Alignment: 16
58 SectionData: B82A000000C3
59symbols:
60 - Name: '.debug$S'
61 Value: 0
62 SectionNumber: 1
63 SimpleType: IMAGE_SYM_TYPE_NULL
64 ComplexType: IMAGE_SYM_DTYPE_NULL
65 StorageClass: IMAGE_SYM_CLASS_STATIC
66 SectionDefinition:
67 Length: 240
68 NumberOfRelocations: 2
69 NumberOfLinenumbers: 0
70 CheckSum: 0
71 Number: 0
72 - Name: '.text$mn'
73 Value: 0
74 SectionNumber: 2
75 SimpleType: IMAGE_SYM_TYPE_NULL
76 ComplexType: IMAGE_SYM_DTYPE_NULL
77 StorageClass: IMAGE_SYM_CLASS_STATIC
78 SectionDefinition:
79 Length: 11
80 NumberOfRelocations: 1
81 NumberOfLinenumbers: 0
82 CheckSum: 2906070869
83 Number: 0
84 Selection: IMAGE_COMDAT_SELECT_NODUPLICATES
85 - Name: '.text$mn'
86 Value: 0
87 SectionNumber: 3
88 SimpleType: IMAGE_SYM_TYPE_NULL
89 ComplexType: IMAGE_SYM_DTYPE_NULL
90 StorageClass: IMAGE_SYM_CLASS_STATIC
91 SectionDefinition:
92 Length: 6
93 NumberOfRelocations: 0
94 NumberOfLinenumbers: 0
95 CheckSum: 2139436471
96 Number: 0
97 Selection: IMAGE_COMDAT_SELECT_NODUPLICATES
98 - Name: discarded
99 Value: 0
100 SectionNumber: 2
101 SimpleType: IMAGE_SYM_TYPE_NULL
102 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
103 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
104 - Name: main
105 Value: 0
106 SectionNumber: 3
107 SimpleType: IMAGE_SYM_TYPE_NULL
108 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
109 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
110 - Name: __wc_mb_cur
111 Value: 0
112 SectionNumber: 0
113 SimpleType: IMAGE_SYM_TYPE_NULL
114 ComplexType: IMAGE_SYM_DTYPE_NULL
115 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
116...
deps/lld/test/COFF/pdb-import-gc.yaml created+114
......@@ -0,0 +1,114 @@
1# RUN: yaml2obj %s -o %t.obj
2# RUN: lld-link %t.obj %S/Inputs/pdb-import-gc.lib -debug -entry:main \
3# RUN: -nodefaultlib -debug -out:%t.exe -pdb:%t.pdb
4# RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s
5
6# This tests the case where an __imp_ chunk is discarded by linker GC. The debug
7# info may refer to the __imp_ symbol still.
8
9# Compile this code with MSVC to regenerate the test case:
10# extern char __declspec(dllimport) __wc_mb_cur;
11# int discarded() { return __wc_mb_cur; }
12# int main() { return g2; }
13
14# CHECK: Symbols
15# CHECK: ============================================================
16# CHECK: Mod 0000 | `{{.*}}pdb-import-gc.yaml.tmp.obj`:
17# CHECK: 4 | S_GDATA32 [size = 32] `__imp___wc_mb_cur`
18# CHECK-NEXT: type = 0x0070 (char), addr = 0000:0000
19# CHECK: Mod 0001 | `* Linker *`:
20
21--- !COFF
22header:
23 Machine: IMAGE_FILE_MACHINE_AMD64
24 Characteristics: [ ]
25sections:
26 - Name: '.debug$S'
27 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
28 Alignment: 1
29 Subsections:
30 - !Symbols
31 Records:
32 - Kind: S_GDATA32
33 DataSym:
34 Type: 112
35 DisplayName: __imp___wc_mb_cur
36 - !StringTable
37 Strings:
38 Relocations:
39 - VirtualAddress: 20
40 SymbolName: __imp___wc_mb_cur
41 Type: IMAGE_REL_AMD64_SECREL
42 - VirtualAddress: 24
43 SymbolName: __imp___wc_mb_cur
44 Type: IMAGE_REL_AMD64_SECTION
45 - Name: '.text$mn'
46 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
47 Alignment: 16
48 SectionData: 488B05000000000FBE00C3
49 Relocations:
50 - VirtualAddress: 3
51 SymbolName: __imp___wc_mb_cur
52 Type: IMAGE_REL_AMD64_REL32
53 - Name: '.text$mn'
54 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_LNK_COMDAT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
55 Alignment: 16
56 SectionData: B82A000000C3
57symbols:
58 - Name: '.debug$S'
59 Value: 0
60 SectionNumber: 1
61 SimpleType: IMAGE_SYM_TYPE_NULL
62 ComplexType: IMAGE_SYM_DTYPE_NULL
63 StorageClass: IMAGE_SYM_CLASS_STATIC
64 SectionDefinition:
65 Length: 240
66 NumberOfRelocations: 2
67 NumberOfLinenumbers: 0
68 CheckSum: 0
69 Number: 0
70 - Name: '.text$mn'
71 Value: 0
72 SectionNumber: 2
73 SimpleType: IMAGE_SYM_TYPE_NULL
74 ComplexType: IMAGE_SYM_DTYPE_NULL
75 StorageClass: IMAGE_SYM_CLASS_STATIC
76 SectionDefinition:
77 Length: 11
78 NumberOfRelocations: 1
79 NumberOfLinenumbers: 0
80 CheckSum: 2906070869
81 Number: 0
82 Selection: IMAGE_COMDAT_SELECT_NODUPLICATES
83 - Name: '.text$mn'
84 Value: 0
85 SectionNumber: 3
86 SimpleType: IMAGE_SYM_TYPE_NULL
87 ComplexType: IMAGE_SYM_DTYPE_NULL
88 StorageClass: IMAGE_SYM_CLASS_STATIC
89 SectionDefinition:
90 Length: 6
91 NumberOfRelocations: 0
92 NumberOfLinenumbers: 0
93 CheckSum: 2139436471
94 Number: 0
95 Selection: IMAGE_COMDAT_SELECT_NODUPLICATES
96 - Name: discarded
97 Value: 0
98 SectionNumber: 2
99 SimpleType: IMAGE_SYM_TYPE_NULL
100 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
101 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
102 - Name: main
103 Value: 0
104 SectionNumber: 3
105 SimpleType: IMAGE_SYM_TYPE_NULL
106 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
107 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
108 - Name: __imp___wc_mb_cur
109 Value: 0
110 SectionNumber: 0
111 SimpleType: IMAGE_SYM_TYPE_NULL
112 ComplexType: IMAGE_SYM_DTYPE_NULL
113 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
114...
deps/lld/test/COFF/pdb-invalid-func-type.yaml created+146
......@@ -0,0 +1,146 @@
1# This test has an S_GPROC32_ID symbol with an invalid type index. Make sure we
2# keep the record, or we'll have unbalanced scopes, which is bad. This situation
3# can arise when we can't find the type server PDB.
4
5# RUN: yaml2obj %s -o %t.obj
6# RUN: lld-link %t.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main
7# RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s
8
9# CHECK: Mod 0000 | `{{.*}}pdb-invalid-func-type.yaml.tmp.obj`:
10# CHECK: 4 | S_GPROC32_ID [size = 44] `main`
11# CHECK: parent = 0, end = 80, addr = 0001:0000, code size = 3
12# CHECK: 48 | S_FRAMEPROC [size = 32]
13# CHECK: 80 | S_END [size = 4]
14
15--- !COFF
16header:
17 Machine: IMAGE_FILE_MACHINE_AMD64
18 Characteristics: [ ]
19sections:
20 - Name: '.debug$S'
21 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
22 Alignment: 1
23 Subsections:
24 - !Symbols
25 Records:
26 - Kind: S_GPROC32_ID
27 ProcSym:
28 CodeSize: 3
29 DbgStart: 0
30 DbgEnd: 2
31 # Corrupt function type!
32 FunctionType: 4101
33 Flags: [ ]
34 DisplayName: main
35 - Kind: S_FRAMEPROC
36 FrameProcSym:
37 TotalFrameBytes: 0
38 PaddingFrameBytes: 0
39 OffsetToPadding: 0
40 BytesOfCalleeSavedRegisters: 0
41 OffsetOfExceptionHandler: 0
42 SectionIdOfExceptionHandler: 0
43 Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ]
44 - Kind: S_PROC_ID_END
45 ScopeEndSym:
46 - !Lines
47 CodeSize: 3
48 Flags: [ ]
49 RelocOffset: 0
50 RelocSegment: 0
51 Blocks:
52 - FileName: 'c:\src\llvm-project\build\t.c'
53 Lines:
54 - Offset: 0
55 LineStart: 1
56 IsStatement: true
57 EndDelta: 0
58 Columns:
59 - !FileChecksums
60 Checksums:
61 - FileName: 'c:\src\llvm-project\build\t.c'
62 Kind: MD5
63 Checksum: 270A878DCC1B845655B162F56C4F5020
64 - !StringTable
65 Strings:
66 - 'c:\src\llvm-project\build\t.c'
67 Relocations:
68 - VirtualAddress: 44
69 SymbolName: main
70 Type: IMAGE_REL_AMD64_SECREL
71 - VirtualAddress: 48
72 SymbolName: main
73 Type: IMAGE_REL_AMD64_SECTION
74 - VirtualAddress: 100
75 SymbolName: main
76 Type: IMAGE_REL_AMD64_SECREL
77 - VirtualAddress: 104
78 SymbolName: main
79 Type: IMAGE_REL_AMD64_SECTION
80 - Name: '.debug$T'
81 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
82 Alignment: 1
83 Types:
84 - Kind: LF_ARGLIST
85 ArgList:
86 ArgIndices: [ 0 ]
87 - Kind: LF_PROCEDURE
88 Procedure:
89 ReturnType: 116
90 CallConv: NearC
91 Options: [ None ]
92 ParameterCount: 0
93 ArgumentList: 4096
94 - Kind: LF_FUNC_ID
95 FuncId:
96 ParentScope: 0
97 FunctionType: 4097
98 Name: main
99 - Name: '.text$mn'
100 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
101 Alignment: 16
102 SectionData: 33C0C3
103symbols:
104 - Name: '.debug$S'
105 Value: 0
106 SectionNumber: 1
107 SimpleType: IMAGE_SYM_TYPE_NULL
108 ComplexType: IMAGE_SYM_DTYPE_NULL
109 StorageClass: IMAGE_SYM_CLASS_STATIC
110 SectionDefinition:
111 Length: 328
112 NumberOfRelocations: 4
113 NumberOfLinenumbers: 0
114 CheckSum: 0
115 Number: 0
116 - Name: '.debug$T'
117 Value: 0
118 SectionNumber: 2
119 SimpleType: IMAGE_SYM_TYPE_NULL
120 ComplexType: IMAGE_SYM_DTYPE_NULL
121 StorageClass: IMAGE_SYM_CLASS_STATIC
122 SectionDefinition:
123 Length: 564
124 NumberOfRelocations: 0
125 NumberOfLinenumbers: 0
126 CheckSum: 0
127 Number: 0
128 - Name: '.text$mn'
129 Value: 0
130 SectionNumber: 3
131 SimpleType: IMAGE_SYM_TYPE_NULL
132 ComplexType: IMAGE_SYM_DTYPE_NULL
133 StorageClass: IMAGE_SYM_CLASS_STATIC
134 SectionDefinition:
135 Length: 3
136 NumberOfRelocations: 0
137 NumberOfLinenumbers: 0
138 CheckSum: 4021952397
139 Number: 0
140 - Name: main
141 Value: 0
142 SectionNumber: 3
143 SimpleType: IMAGE_SYM_TYPE_NULL
144 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
145 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
146...
deps/lld/test/COFF/pdb-lib.s created+36
......@@ -0,0 +1,36 @@
1# REQUIRES: x86
2# RUN: rm -rf %t && mkdir -p %t && cd %t
3# RUN: llvm-mc -filetype=obj -triple=i686-windows-msvc %s -o foo.obj
4# RUN: llc %S/Inputs/bar.ll -filetype=obj -mtriple=i686-windows-msvc -o bar.obj
5# RUN: llvm-lib bar.obj -out:bar.lib
6# RUN: lld-link -debug -pdb:foo.pdb foo.obj bar.lib -out:foo.exe -entry:main
7# RUN: llvm-pdbutil dump -modules %t/foo.pdb | FileCheck %s
8
9# Make sure that the PDB has module descriptors. foo.obj and bar.lib should be
10# absolute paths, and bar.obj should be the relative path passed to llvm-lib.
11
12# CHECK: Modules
13# CHECK-NEXT: ============================================================
14# CHECK-NEXT: Mod 0000 | Name: `{{.*pdb-lib.s.tmp[/\\]foo.obj}}`:
15# CHECK-NEXT: Obj: `{{.*pdb-lib.s.tmp[/\\]foo.obj}}`:
16# CHECK-NEXT: debug stream: 9, # files: 0, has ec info: false
17# CHECK-NEXT: pdb file ni: 0 ``, src file ni: 0 ``
18# CHECK-NEXT: Mod 0001 | Name: `bar.obj`:
19# CHECK-NEXT: Obj: `{{.*pdb-lib.s.tmp[/\\]bar.lib}}`:
20# CHECK-NEXT: debug stream: 10, # files: 0, has ec info: false
21# CHECK-NEXT: pdb file ni: 0 ``, src file ni: 0 ``
22# CHECK-NEXT: Mod 0002 | Name: `* Linker *`:
23# CHECK-NEXT: Obj: ``:
24# CHECK-NEXT: debug stream: 11, # files: 0, has ec info: false
25# CHECK-NEXT: pdb file ni: 1 `{{.*foo.pdb}}`, src file ni: 0 ``
26
27 .def _main;
28 .scl 2;
29 .type 32;
30 .endef
31 .globl _main
32_main:
33 calll _bar
34 xor %eax, %eax
35 retl
36
deps/lld/test/COFF/pdb-linker-module.test created+18
......@@ -0,0 +1,18 @@
1RUN: lld-link /debug /pdb:%t.pdb /nodefaultlib /entry:main %S/Inputs/pdb-diff.obj
2RUN: llvm-pdbutil dump -modules -symbols %t.pdb | FileCheck %s
3
4CHECK: Mod 0001 | `* Linker *`:
5CHECK-NEXT: 4 | S_OBJNAME [size = 20] sig=0, `* Linker *`
6CHECK-NEXT: 24 | S_COMPILE3 [size = 40]
7CHECK-NEXT: machine = intel 80386, Ver = LLVM Linker, language = link
8CHECK-NEXT: frontend = 0.0.0.0, backend = 0.0.0.0
9CHECK-NEXT: flags = none
10CHECK-NEXT: 64 | S_ENVBLOCK
11CHECK-NEXT: - cwd
12CHECK-NEXT: -
13CHECK-NEXT: - exe
14CHECK-NEXT: - {{.*}}lld-link
15CHECK-NEXT: - pdb
16CHECK-NEXT: - {{.*}}pdb-linker-module{{.*}}pdb
17CHECK-NEXT: - cmd
18CHECK-NEXT: - /debug /pdb:{{.*}}pdb-linker-module{{.*}}pdb /nodefaultlib /entry:main {{.*}}pdb-diff.obj
deps/lld/test/COFF/pdb-none.test created+14
......@@ -0,0 +1,14 @@
1# RUN: yaml2obj < %p/Inputs/pdb1.yaml > %t1.obj
2# RUN: yaml2obj < %p/Inputs/pdb2.yaml > %t2.obj
3# RUN: lld-link /debug /debugtype:pdata /pdb:%t.pdb /dll /out:%t.dll /entry:main /nodefaultlib \
4# RUN: %t1.obj %t2.obj
5
6# RUN: llvm-pdbutil pdb2yaml -pdb-stream %t.pdb | FileCheck %s
7
8# CHECK: PdbStream:
9# CHECK-NEXT: Age: 0
10# CHECK-NEXT: Guid:
11# CHECK-NEXT: Signature:
12# CHECK-NEXT: Features: [ VC140 ]
13# CHECK-NEXT: Version: VC70
14
deps/lld/test/COFF/pdb-options.test created+21
......@@ -0,0 +1,21 @@
1# RUN: yaml2obj < %p/Inputs/pdb1.yaml > %t1.obj
2# RUN: yaml2obj < %p/Inputs/pdb2.yaml > %t2.obj
3
4; If /DEBUG is not specified, /pdb is ignored.
5# RUN: rm -f %t.pdb
6# RUN: lld-link /pdb:%t.pdb /entry:main /nodefaultlib %t1.obj %t2.obj
7# RUN: not ls %t.pdb
8
9; If /DEBUG and /pdb are specified, it uses the specified name.
10# RUN: lld-link /DEBUG /pdb:%t.pdb /entry:main /nodefaultlib %t1.obj %t2.obj
11# RUN: ls %t.pdb
12# RUN: rm %t.pdb
13
14; If /DEBUG is specified but not /pdb, it uses a default name in the current
15; directory. This is a bit hacky since but we need to be IN our test specific
16; temporary directory when we run this command or we can't test this
17# RUN: cd %T
18# RUN: lld-link /DEBUG /entry:main /nodefaultlib %t1.obj %t2.obj
19# RUN: ls %t1.pdb
20# RUN: rm %t*
21# RUN: cd %T/..
deps/lld/test/COFF/pdb-safeseh.yaml created+85
......@@ -0,0 +1,85 @@
1# RUN: yaml2obj %s -o %t.obj
2# RUN: lld-link -debug -entry:main -out:%t.exe -pdb:%t.pdb %t.obj
3# RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s
4
5# There is an S_GDATA32 symbol record with .secrel32 and .secidx relocations in
6# it in this debug info. This is similar to the relocations in the loadcfg.obj
7# file in the MSVC CRT. We need to make sure that our relocation logic matches
8# MSVC's for these absolute, linker-provided symbols.
9
10# CHECK: Mod 0000 |
11# CHECK-NEXT: 4 | S_GDATA32 [size = 40] `___safe_se_handler_table`
12# CHECK-NEXT: type = 0x0022 (unsigned long), addr = 0003:0000
13# CHECK-NEXT: Mod 0001 | `* Linker *`:
14
15--- !COFF
16header:
17 Machine: IMAGE_FILE_MACHINE_I386
18 Characteristics: [ ]
19sections:
20 - Name: '.debug$S'
21 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
22 Alignment: 1
23 Subsections:
24 - !Symbols
25 Records:
26 - Kind: S_GDATA32
27 DataSym:
28 Type: 34
29 DisplayName: ___safe_se_handler_table
30 - !StringTable
31 Strings:
32 Relocations:
33 - VirtualAddress: 20
34 SymbolName: ___safe_se_handler_table
35 Type: IMAGE_REL_I386_SECREL
36 - VirtualAddress: 24
37 SymbolName: ___safe_se_handler_table
38 Type: IMAGE_REL_I386_SECTION
39 - Name: '.text$mn'
40 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
41 Alignment: 16
42 SectionData: 488D0500000000C3
43 Relocations:
44 - VirtualAddress: 3
45 SymbolName: ___safe_se_handler_table
46 Type: IMAGE_REL_I386_REL32
47symbols:
48 - Name: '.debug$S'
49 Value: 0
50 SectionNumber: 1
51 SimpleType: IMAGE_SYM_TYPE_NULL
52 ComplexType: IMAGE_SYM_DTYPE_NULL
53 StorageClass: IMAGE_SYM_CLASS_STATIC
54 SectionDefinition:
55 Length: 372
56 NumberOfRelocations: 6
57 NumberOfLinenumbers: 0
58 CheckSum: 0
59 Number: 0
60 - Name: '.text$mn'
61 Value: 0
62 SectionNumber: 2
63 SimpleType: IMAGE_SYM_TYPE_NULL
64 ComplexType: IMAGE_SYM_DTYPE_NULL
65 StorageClass: IMAGE_SYM_CLASS_STATIC
66 SectionDefinition:
67 Length: 8
68 NumberOfRelocations: 1
69 NumberOfLinenumbers: 0
70 CheckSum: 1092178131
71 Number: 0
72 - Name: _main
73 Value: 0
74 SectionNumber: 2
75 SimpleType: IMAGE_SYM_TYPE_NULL
76 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
77 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
78 - Name: ___safe_se_handler_table
79 Value: 0
80 SectionNumber: 0
81 SimpleType: IMAGE_SYM_TYPE_NULL
82 ComplexType: IMAGE_SYM_DTYPE_NULL
83 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
84...
85
deps/lld/test/COFF/pdb-scopes.test created+75
......@@ -0,0 +1,75 @@
1Consider this program:
2
3$ cat a.c
4void g(int x) {}
5void f(int x);
6int main(int argc) {
7 if (argc) {
8 int x = 42;
9 f(x);
10 } else {
11 int y = 13;
12 f(y);
13 }
14}
15
16$ cat b.c
17extern void g();
18void f(int x) {
19 if (x) {
20 int y = x + 3;
21 g(y);
22 } else {
23 int w = x + 4;
24 g(w);
25 }
26}
27
28This program is interesting because there are two TUs, and each TU has nested
29scopes. Make sure we get the right parent and end offsets.
30
31RUN: yaml2obj %S/Inputs/pdb-scopes-a.yaml -o %t-a.obj
32RUN: yaml2obj %S/Inputs/pdb-scopes-b.yaml -o %t-b.obj
33RUN: lld-link %t-a.obj %t-b.obj -debug -entry:main -nodefaultlib -out:%t.exe -pdb:%t.pdb
34RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s
35
36CHECK-LABEL: Mod 0000 | `{{.*}}pdb-scopes.test.tmp-a.obj`:
37CHECK: 104 | S_GPROC32_ID [size = 44] `g`
38CHECK: parent = 0, end = 196, addr = 0002:0000, code size = 5
39CHECK: debug start = 4, debug end = 4, flags = none
40CHECK: 180 | S_REGREL32 [size = 16] `x`
41CHECK: 196 | S_END [size = 4]
42CHECK: 200 | S_GPROC32_ID [size = 44] `main`
43CHECK: parent = 0, end = 384, addr = 0002:0016, code size = 58
44CHECK: debug start = 8, debug end = 53, flags = none
45CHECK: 276 | S_REGREL32 [size = 20] `argc`
46CHECK: 296 | S_BLOCK32 [size = 24] ``
47CHECK: parent = 200, end = 336
48CHECK: code size = 17, addr = 0002:0031
49CHECK: 320 | S_REGREL32 [size = 16] `x`
50CHECK: 336 | S_END [size = 4]
51CHECK: 340 | S_BLOCK32 [size = 24] ``
52CHECK: parent = 200, end = 380
53CHECK: code size = 17, addr = 0002:0050
54CHECK: 364 | S_REGREL32 [size = 16] `y`
55CHECK: 380 | S_END [size = 4]
56CHECK: 384 | S_END [size = 4]
57
58CHECK-LABEL: Mod 0001 | `{{.*}}pdb-scopes.test.tmp-b.obj`:
59CHECK: 104 | S_GPROC32_ID [size = 44] `f`
60CHECK: parent = 0, end = 284, addr = 0002:0080, code size = 62
61CHECK: debug start = 8, debug end = 57, flags = none
62CHECK: 180 | S_REGREL32 [size = 16] `x`
63CHECK: 196 | S_BLOCK32 [size = 24] ``
64CHECK: parent = 104, end = 236
65CHECK: code size = 20, addr = 0002:0095
66CHECK: 220 | S_REGREL32 [size = 16] `y`
67CHECK: 236 | S_END [size = 4]
68CHECK: 240 | S_BLOCK32 [size = 24] ``
69CHECK: parent = 104, end = 280
70CHECK: code size = 20, addr = 0002:0117
71CHECK: 264 | S_REGREL32 [size = 16] `w`
72CHECK: 280 | S_END [size = 4]
73CHECK: 284 | S_END [size = 4]
74
75CHECK-LABEL: Mod 0002 | `* Linker *`:
deps/lld/test/COFF/pdb-secrel-absolute.yaml created+84
......@@ -0,0 +1,84 @@
1# RUN: yaml2obj %s -o %t.obj
2# RUN: lld-link -debug -entry:main -out:%t.exe -pdb:%t.pdb %t.obj
3# RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s
4
5# There is an S_GDATA32 symbol record with .secrel32 and .secidx relocations in
6# it in this debug info. This is similar to the relocations in the loadcfg.obj
7# file in the MSVC CRT. We need to make sure that our relocation logic matches
8# MSVC's for these absolute, linker-provided symbols.
9
10# CHECK: Mod 0000 |
11# CHECK-NEXT: 4 | S_GDATA32 [size = 36] `__guard_fids_table`
12# CHECK-NEXT: type = 0x0022 (unsigned long), addr = 0003:0000
13# CHECK-NEXT: Mod 0001 | `* Linker *`:
14
15--- !COFF
16header:
17 Machine: IMAGE_FILE_MACHINE_AMD64
18 Characteristics: [ ]
19sections:
20 - Name: '.debug$S'
21 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
22 Alignment: 1
23 Subsections:
24 - !Symbols
25 Records:
26 - Kind: S_GDATA32
27 DataSym:
28 Type: 34
29 DisplayName: __guard_fids_table
30 - !StringTable
31 Strings:
32 Relocations:
33 - VirtualAddress: 20
34 SymbolName: __guard_fids_table
35 Type: IMAGE_REL_AMD64_SECREL
36 - VirtualAddress: 24
37 SymbolName: __guard_fids_table
38 Type: IMAGE_REL_AMD64_SECTION
39 - Name: '.text$mn'
40 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
41 Alignment: 16
42 SectionData: 488D0500000000C3
43 Relocations:
44 - VirtualAddress: 3
45 SymbolName: __guard_fids_table
46 Type: IMAGE_REL_AMD64_REL32
47symbols:
48 - Name: '.debug$S'
49 Value: 0
50 SectionNumber: 1
51 SimpleType: IMAGE_SYM_TYPE_NULL
52 ComplexType: IMAGE_SYM_DTYPE_NULL
53 StorageClass: IMAGE_SYM_CLASS_STATIC
54 SectionDefinition:
55 Length: 372
56 NumberOfRelocations: 6
57 NumberOfLinenumbers: 0
58 CheckSum: 0
59 Number: 0
60 - Name: '.text$mn'
61 Value: 0
62 SectionNumber: 2
63 SimpleType: IMAGE_SYM_TYPE_NULL
64 ComplexType: IMAGE_SYM_DTYPE_NULL
65 StorageClass: IMAGE_SYM_CLASS_STATIC
66 SectionDefinition:
67 Length: 8
68 NumberOfRelocations: 1
69 NumberOfLinenumbers: 0
70 CheckSum: 1092178131
71 Number: 0
72 - Name: main
73 Value: 0
74 SectionNumber: 2
75 SimpleType: IMAGE_SYM_TYPE_NULL
76 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
77 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
78 - Name: __guard_fids_table
79 Value: 0
80 SectionNumber: 0
81 SimpleType: IMAGE_SYM_TYPE_NULL
82 ComplexType: IMAGE_SYM_DTYPE_NULL
83 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
84...
deps/lld/test/COFF/pdb-source-lines.test created+124
......@@ -0,0 +1,124 @@
1Test the linker line tables on roughly the following example:
2
3==> foo.h <==
4void bar(void);
5inline void foo(void) {
6 bar();
7}
8==> pdb_lines_1.c <==
9#include "foo.h"
10int main(void) {
11 foo();
12 return 42;
13}
14==> pdb_lines_2.c <==
15void bar(void) {
16}
17
18$ cl -c -Z7 pdb_lines*.c
19
20RUN: yaml2obj %S/Inputs/pdb_lines_1.yaml -o %t.pdb_lines_1.obj
21RUN: yaml2obj %S/Inputs/pdb_lines_2.yaml -o %t.pdb_lines_2.obj
22RUN: lld-link -debug -entry:main -nodefaultlib -out:%t.exe -pdb:%t.pdb %t.pdb_lines_1.obj %t.pdb_lines_2.obj
23RUN: llvm-pdbutil pdb2yaml -modules -module-files -subsections=lines,fc %t.pdb | FileCheck %s
24
25CHECK-LABEL: DbiStream:
26CHECK-NEXT: VerHeader: V70
27CHECK-NEXT: Age: 1
28CHECK-NEXT: BuildNumber: 0
29CHECK-NEXT: PdbDllVersion: 0
30CHECK-NEXT: PdbDllRbld: 0
31CHECK-NEXT: Flags: 0
32CHECK-NEXT: MachineType: x86
33CHECK-NEXT: Modules:
34
35CHECK-LABEL: - Module: {{.*}}pdb_lines_1.obj
36CHECK-NEXT: ObjFile: {{.*}}pdb_lines_1.obj
37CHECK-NEXT: SourceFiles:
38CHECK-NEXT: - '{{.*}}pdb_lines_1.c'
39CHECK-NEXT: - '{{.*}}foo.h'
40CHECK-NEXT: Subsections:
41CHECK-NEXT: - !Lines
42CHECK-NEXT: CodeSize: 19
43CHECK-NEXT: Flags: [ ]
44CHECK-NEXT: RelocOffset: 0
45CHECK-NEXT: RelocSegment: 2
46CHECK-NEXT: Blocks:
47CHECK-NEXT: - FileName: '{{.*}}pdb_lines_1.c'
48CHECK-NEXT: Lines:
49CHECK-NEXT: - Offset: 0
50CHECK-NEXT: LineStart: 2
51CHECK-NEXT: IsStatement: true
52CHECK-NEXT: EndDelta: 0
53CHECK-NEXT: - Offset: 4
54CHECK-NEXT: LineStart: 3
55CHECK-NEXT: IsStatement: true
56CHECK-NEXT: EndDelta: 0
57CHECK-NEXT: - Offset: 9
58CHECK-NEXT: LineStart: 4
59CHECK-NEXT: IsStatement: true
60CHECK-NEXT: EndDelta: 0
61CHECK-NEXT: - Offset: 14
62CHECK-NEXT: LineStart: 5
63CHECK-NEXT: IsStatement: true
64CHECK-NEXT: EndDelta: 0
65CHECK-NEXT: Columns:
66CHECK-NEXT: - !FileChecksums
67CHECK-NEXT: Checksums:
68CHECK-NEXT: - FileName: '{{.*}}pdb_lines_1.c'
69CHECK-NEXT: Kind: MD5
70CHECK-NEXT: Checksum: 4EB19DCD86C3BA2238A255C718572E7B
71CHECK-NEXT: - FileName: '{{.*}}foo.h'
72CHECK-NEXT: Kind: MD5
73CHECK-NEXT: Checksum: 061EB73ABB642532857A4F1D9CBAC323
74CHECK-NEXT: - !Lines
75CHECK-NEXT: CodeSize: 14
76CHECK-NEXT: Flags: [ ]
77CHECK-NEXT: RelocOffset: 32
78CHECK-NEXT: RelocSegment: 2
79CHECK-NEXT: Blocks:
80CHECK-NEXT: - FileName: '{{.*}}foo.h'
81CHECK-NEXT: Lines:
82CHECK-NEXT: - Offset: 0
83CHECK-NEXT: LineStart: 2
84CHECK-NEXT: IsStatement: true
85CHECK-NEXT: EndDelta: 0
86CHECK-NEXT: - Offset: 4
87CHECK-NEXT: LineStart: 3
88CHECK-NEXT: IsStatement: true
89CHECK-NEXT: EndDelta: 0
90CHECK-NEXT: - Offset: 9
91CHECK-NEXT: LineStart: 4
92CHECK-NEXT: IsStatement: true
93CHECK-NEXT: EndDelta: 0
94CHECK-NEXT: Columns:
95
96CHECK-LABEL: - Module: {{.*}}pdb_lines_2.obj
97CHECK-NEXT: ObjFile: {{.*}}pdb_lines_2.obj
98CHECK-NEXT: SourceFiles:
99CHECK-NEXT: - '{{.*}}pdb_lines_2.c'
100CHECK-NEXT: Subsections:
101CHECK-NEXT: - !Lines
102CHECK-NEXT: CodeSize: 1
103CHECK-NEXT: Flags: [ ]
104CHECK-NEXT: RelocOffset: 48
105CHECK-NEXT: RelocSegment: 2
106CHECK-NEXT: Blocks:
107CHECK-NEXT: - FileName: '{{.*}}pdb_lines_2.c'
108CHECK-NEXT: Lines:
109CHECK-NEXT: - Offset: 0
110CHECK-NEXT: LineStart: 1
111CHECK-NEXT: IsStatement: true
112CHECK-NEXT: EndDelta: 0
113CHECK-NEXT: - Offset: 0
114CHECK-NEXT: LineStart: 2
115CHECK-NEXT: IsStatement: true
116CHECK-NEXT: EndDelta: 0
117CHECK-NEXT: Columns:
118CHECK-NEXT: - !FileChecksums
119CHECK-NEXT: Checksums:
120CHECK-NEXT: - FileName: '{{.*}}pdb_lines_2.c'
121CHECK-NEXT: Kind: MD5
122CHECK-NEXT: Checksum: DF91CB3A2B8D917486574BB50CAC4CC7
123CHECK-NEXT: - Module: '* Linker *'
124CHECK-NEXT: ObjFile: ''
deps/lld/test/COFF/pdb-symbol-types.yaml created+344
......@@ -0,0 +1,344 @@
1# RUN: yaml2obj %s -o %t.obj
2# RUN: lld-link %t.obj -nodefaultlib -entry:main -debug -out:%t.exe -pdb:%t.pdb
3# RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck %s
4
5# To regenerate the object file:
6# $ cat symbol-types.c
7# struct Foo { int x; };
8# typedef struct Foo UDT_Foo;
9# UDT_Foo global_foo = {42};
10# int main() { return global_foo.x; }
11# $ cl -c -Z7 symbol-types.c
12
13# Note that the type of 'global' goes from 0x1005 in the object file to 0x1004
14# in the PDB because the LF_FUNC_ID is moved to the id stream.
15
16# CHECK: Symbols
17# CHECK: ============================================================
18# CHECK-LABEL: Mod 0000 | `{{.*}}pdb-symbol-types.yaml.tmp.obj`:
19# CHECK: 4 | S_OBJNAME [size = 52] sig=0, `C:\src\llvm-project\build\symbol-types.obj`
20# CHECK: 56 | S_COMPILE3 [size = 60]
21# CHECK: machine = intel x86-x64, Ver = Microsoft (R) Optimizing Compiler, language = c
22# CHECK: frontend = 19.0.24215.1, backend = 19.0.24215.1
23# CHECK: flags = security checks | hot patchable
24# CHECK: 116 | S_GPROC32_ID [size = 44] `main`
25# CHECK: parent = 0, end = 192, addr = 0002:0000, code size = 7
26# CHECK: debug start = 0, debug end = 6, flags = none
27# CHECK: 160 | S_FRAMEPROC [size = 32]
28# CHECK: size = 0, padding size = 0, offset to padding = 0
29# CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000
30# CHECK: flags = has async eh | opt speed
31# CHECK: 192 | S_END [size = 4]
32# CHECK: 196 | S_GDATA32 [size = 28] `global_foo`
33# CHECK: type = 0x1004 (Foo), addr = 0001:0000
34# CHECK: 224 | S_UDT [size = 16] `UDT_Foo`
35# CHECK: original type = 0x1004
36# CHECK: 240 | S_UDT [size = 12] `Foo`
37# CHECK: original type = 0x1004
38# CHECK: 252 | S_BUILDINFO [size = 8] BuildId = `0x100A`
39# CHECK-LABEL: Mod 0001 | `* Linker *`:
40
41--- !COFF
42header:
43 Machine: IMAGE_FILE_MACHINE_AMD64
44 Characteristics: [ ]
45sections:
46 - Name: .drectve
47 Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
48 Alignment: 1
49 SectionData: 2020202F44454641554C544C49423A224C4942434D5422202F44454641554C544C49423A224F4C444E414D45532220
50 - Name: '.debug$S'
51 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
52 Alignment: 1
53 Subsections:
54 - !Symbols
55 Records:
56 - Kind: S_OBJNAME
57 ObjNameSym:
58 Signature: 0
59 ObjectName: 'C:\src\llvm-project\build\symbol-types.obj'
60 - Kind: S_COMPILE3
61 Compile3Sym:
62 Flags: [ SecurityChecks, HotPatch ]
63 Machine: X64
64 FrontendMajor: 19
65 FrontendMinor: 0
66 FrontendBuild: 24215
67 FrontendQFE: 1
68 BackendMajor: 19
69 BackendMinor: 0
70 BackendBuild: 24215
71 BackendQFE: 1
72 Version: 'Microsoft (R) Optimizing Compiler'
73 - !Symbols
74 Records:
75 - Kind: S_GPROC32_ID
76 ProcSym:
77 CodeSize: 7
78 DbgStart: 0
79 DbgEnd: 6
80 FunctionType: 4098
81 Flags: [ ]
82 DisplayName: main
83 - Kind: S_FRAMEPROC
84 FrameProcSym:
85 TotalFrameBytes: 0
86 PaddingFrameBytes: 0
87 OffsetToPadding: 0
88 BytesOfCalleeSavedRegisters: 0
89 OffsetOfExceptionHandler: 0
90 SectionIdOfExceptionHandler: 0
91 Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ]
92 - Kind: S_PROC_ID_END
93 ScopeEndSym:
94 - !Lines
95 CodeSize: 7
96 Flags: [ ]
97 RelocOffset: 0
98 RelocSegment: 0
99 Blocks:
100 - FileName: 'c:\src\llvm-project\build\symbol-types.c'
101 Lines:
102 - Offset: 0
103 LineStart: 4
104 IsStatement: true
105 EndDelta: 0
106 - Offset: 0
107 LineStart: 5
108 IsStatement: true
109 EndDelta: 0
110 - Offset: 6
111 LineStart: 6
112 IsStatement: true
113 EndDelta: 0
114 Columns:
115 - !Symbols
116 Records:
117 - Kind: S_GDATA32
118 DataSym:
119 Type: 4101
120 DisplayName: global_foo
121 - Kind: S_UDT
122 UDTSym:
123 Type: 4101
124 UDTName: UDT_Foo
125 - Kind: S_UDT
126 UDTSym:
127 Type: 4101
128 UDTName: Foo
129 - !FileChecksums
130 Checksums:
131 - FileName: 'c:\src\llvm-project\build\symbol-types.c'
132 Kind: MD5
133 Checksum: F833E1A4909FF6FEC5689A664F3BE725
134 - !StringTable
135 Strings:
136 - 'c:\src\llvm-project\build\symbol-types.c'
137 - !Symbols
138 Records:
139 - Kind: S_BUILDINFO
140 BuildInfoSym:
141 BuildId: 4111
142 Relocations:
143 - VirtualAddress: 164
144 SymbolName: main
145 Type: IMAGE_REL_AMD64_SECREL
146 - VirtualAddress: 168
147 SymbolName: main
148 Type: IMAGE_REL_AMD64_SECTION
149 - VirtualAddress: 220
150 SymbolName: main
151 Type: IMAGE_REL_AMD64_SECREL
152 - VirtualAddress: 224
153 SymbolName: main
154 Type: IMAGE_REL_AMD64_SECTION
155 - VirtualAddress: 284
156 SymbolName: global_foo
157 Type: IMAGE_REL_AMD64_SECREL
158 - VirtualAddress: 288
159 SymbolName: global_foo
160 Type: IMAGE_REL_AMD64_SECTION
161 - Name: '.debug$T'
162 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
163 Alignment: 1
164 Types:
165 - Kind: LF_ARGLIST
166 ArgList:
167 ArgIndices: [ 0 ]
168 - Kind: LF_PROCEDURE
169 Procedure:
170 ReturnType: 116
171 CallConv: NearC
172 Options: [ None ]
173 ParameterCount: 0
174 ArgumentList: 4096
175 - Kind: LF_FUNC_ID
176 FuncId:
177 ParentScope: 0
178 FunctionType: 4097
179 Name: main
180 - Kind: LF_STRUCTURE
181 Class:
182 MemberCount: 0
183 Options: [ None, ForwardReference, HasUniqueName ]
184 FieldList: 0
185 Name: Foo
186 UniqueName: '.?AUFoo@@'
187 DerivationList: 0
188 VTableShape: 0
189 Size: 0
190 - Kind: LF_FIELDLIST
191 FieldList:
192 - Kind: LF_MEMBER
193 DataMember:
194 Attrs: 3
195 Type: 116
196 FieldOffset: 0
197 Name: x
198 - Kind: LF_STRUCTURE
199 Class:
200 MemberCount: 1
201 Options: [ None, HasUniqueName ]
202 FieldList: 4100
203 Name: Foo
204 UniqueName: '.?AUFoo@@'
205 DerivationList: 0
206 VTableShape: 0
207 Size: 4
208 - Kind: LF_STRING_ID
209 StringId:
210 Id: 0
211 String: 'c:\src\llvm-project\build\symbol-types.c'
212 - Kind: LF_UDT_SRC_LINE
213 UdtSourceLine:
214 UDT: 4101
215 SourceFile: 4102
216 LineNumber: 1
217 - Kind: LF_STRING_ID
218 StringId:
219 Id: 0
220 String: 'C:\src\llvm-project\build'
221 - Kind: LF_STRING_ID
222 StringId:
223 Id: 0
224 String: 'C:\PROGRA~2\MICROS~1.0\VC\Bin\amd64\cl.exe'
225 - Kind: LF_STRING_ID
226 StringId:
227 Id: 0
228 String: '-c -Z7 -MT -IC:\PROGRA~2\MICROS~1.0\VC\include -IC:\PROGRA~2\MICROS~1.0\VC\atlmfc\include -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\ucrt -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\shared -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\um'
229 - Kind: LF_SUBSTR_LIST
230 StringList:
231 StringIndices: [ 4106 ]
232 - Kind: LF_STRING_ID
233 StringId:
234 Id: 4107
235 String: ' -IC:\PROGRA~2\WI3CF2~1\10\include\10.0.14393.0\winrt -TC -X'
236 - Kind: LF_STRING_ID
237 StringId:
238 Id: 0
239 String: symbol-types.c
240 - Kind: LF_STRING_ID
241 StringId:
242 Id: 0
243 String: 'C:\src\llvm-project\build\vc140.pdb'
244 - Kind: LF_BUILDINFO
245 BuildInfo:
246 ArgIndices: [ 4104, 4105, 4109, 4110, 4108 ]
247 - Name: .data
248 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
249 Alignment: 4
250 SectionData: 2A000000
251 - Name: '.text$mn'
252 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
253 Alignment: 16
254 SectionData: 8B0500000000C3
255 Relocations:
256 - VirtualAddress: 2
257 SymbolName: global_foo
258 Type: IMAGE_REL_AMD64_REL32
259symbols:
260 - Name: '@comp.id'
261 Value: 17063575
262 SectionNumber: -1
263 SimpleType: IMAGE_SYM_TYPE_NULL
264 ComplexType: IMAGE_SYM_DTYPE_NULL
265 StorageClass: IMAGE_SYM_CLASS_STATIC
266 - Name: '@feat.00'
267 Value: 2147484048
268 SectionNumber: -1
269 SimpleType: IMAGE_SYM_TYPE_NULL
270 ComplexType: IMAGE_SYM_DTYPE_NULL
271 StorageClass: IMAGE_SYM_CLASS_STATIC
272 - Name: .drectve
273 Value: 0
274 SectionNumber: 1
275 SimpleType: IMAGE_SYM_TYPE_NULL
276 ComplexType: IMAGE_SYM_DTYPE_NULL
277 StorageClass: IMAGE_SYM_CLASS_STATIC
278 SectionDefinition:
279 Length: 47
280 NumberOfRelocations: 0
281 NumberOfLinenumbers: 0
282 CheckSum: 0
283 Number: 0
284 - Name: '.debug$S'
285 Value: 0
286 SectionNumber: 2
287 SimpleType: IMAGE_SYM_TYPE_NULL
288 ComplexType: IMAGE_SYM_DTYPE_NULL
289 StorageClass: IMAGE_SYM_CLASS_STATIC
290 SectionDefinition:
291 Length: 432
292 NumberOfRelocations: 6
293 NumberOfLinenumbers: 0
294 CheckSum: 0
295 Number: 0
296 - Name: '.debug$T'
297 Value: 0
298 SectionNumber: 3
299 SimpleType: IMAGE_SYM_TYPE_NULL
300 ComplexType: IMAGE_SYM_DTYPE_NULL
301 StorageClass: IMAGE_SYM_CLASS_STATIC
302 SectionDefinition:
303 Length: 732
304 NumberOfRelocations: 0
305 NumberOfLinenumbers: 0
306 CheckSum: 0
307 Number: 0
308 - Name: .data
309 Value: 0
310 SectionNumber: 4
311 SimpleType: IMAGE_SYM_TYPE_NULL
312 ComplexType: IMAGE_SYM_DTYPE_NULL
313 StorageClass: IMAGE_SYM_CLASS_STATIC
314 SectionDefinition:
315 Length: 4
316 NumberOfRelocations: 0
317 NumberOfLinenumbers: 0
318 CheckSum: 3482275674
319 Number: 0
320 - Name: global_foo
321 Value: 0
322 SectionNumber: 4
323 SimpleType: IMAGE_SYM_TYPE_NULL
324 ComplexType: IMAGE_SYM_DTYPE_NULL
325 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
326 - Name: '.text$mn'
327 Value: 0
328 SectionNumber: 5
329 SimpleType: IMAGE_SYM_TYPE_NULL
330 ComplexType: IMAGE_SYM_DTYPE_NULL
331 StorageClass: IMAGE_SYM_CLASS_STATIC
332 SectionDefinition:
333 Length: 7
334 NumberOfRelocations: 1
335 NumberOfLinenumbers: 0
336 CheckSum: 3635526833
337 Number: 0
338 - Name: main
339 Value: 0
340 SectionNumber: 5
341 SimpleType: IMAGE_SYM_TYPE_NULL
342 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
343 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
344...
deps/lld/test/COFF/pdb-type-server-missing.yaml created+132
......@@ -0,0 +1,132 @@
1# This is an object compiled with /Zi (see the LF_TYPESERVER2 record) without an
2# adjacent type server PDB. Test that LLD fails gracefully on it.
3
4# FIXME: Ideally we'd do what MSVC does, which is to warn and drop all debug
5# info in the object with the missing PDB.
6
7# RUN: yaml2obj %s -o %t.obj
8# RUN: not lld-link %t.obj -out:%t.exe -debug -pdb:%t.pdb -nodefaultlib -entry:main 2>&1 | FileCheck %s
9
10# CHECK: error: Type server PDB was not found
11
12--- !COFF
13header:
14 Machine: IMAGE_FILE_MACHINE_AMD64
15 Characteristics: [ ]
16sections:
17 - Name: '.debug$S'
18 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
19 Alignment: 1
20 Subsections:
21 - !Symbols
22 Records:
23 - Kind: S_GPROC32_ID
24 ProcSym:
25 CodeSize: 3
26 DbgStart: 0
27 DbgEnd: 2
28 FunctionType: 4199
29 Flags: [ ]
30 DisplayName: main
31 - Kind: S_FRAMEPROC
32 FrameProcSym:
33 TotalFrameBytes: 0
34 PaddingFrameBytes: 0
35 OffsetToPadding: 0
36 BytesOfCalleeSavedRegisters: 0
37 OffsetOfExceptionHandler: 0
38 SectionIdOfExceptionHandler: 0
39 Flags: [ AsynchronousExceptionHandling, OptimizedForSpeed ]
40 - Kind: S_PROC_ID_END
41 ScopeEndSym:
42 - !Lines
43 CodeSize: 3
44 Flags: [ ]
45 RelocOffset: 0
46 RelocSegment: 0
47 Blocks:
48 - FileName: 'c:\src\llvm-project\build\t.c'
49 Lines:
50 - Offset: 0
51 LineStart: 1
52 IsStatement: true
53 EndDelta: 0
54 Columns:
55 - !FileChecksums
56 Checksums:
57 - FileName: 'c:\src\llvm-project\build\t.c'
58 Kind: MD5
59 Checksum: 270A878DCC1B845655B162F56C4F5020
60 - !StringTable
61 Strings:
62 - 'c:\src\llvm-project\build\t.c'
63 Relocations:
64 - VirtualAddress: 44
65 SymbolName: main
66 Type: IMAGE_REL_AMD64_SECREL
67 - VirtualAddress: 48
68 SymbolName: main
69 Type: IMAGE_REL_AMD64_SECTION
70 - VirtualAddress: 100
71 SymbolName: main
72 Type: IMAGE_REL_AMD64_SECREL
73 - VirtualAddress: 104
74 SymbolName: main
75 Type: IMAGE_REL_AMD64_SECTION
76 - Name: '.debug$T'
77 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
78 Alignment: 1
79 Types:
80 - Kind: LF_TYPESERVER2
81 TypeServer2:
82 Guid: '{01DF191B-22BF-6B42-96CE-5258B8329FE5}'
83 Age: 18
84 Name: 'C:\src\llvm-project\build\definitely_not_found_for_sure.pdb'
85 - Name: '.text$mn'
86 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
87 Alignment: 16
88 SectionData: 33C0C3
89symbols:
90 - Name: '.debug$S'
91 Value: 0
92 SectionNumber: 1
93 SimpleType: IMAGE_SYM_TYPE_NULL
94 ComplexType: IMAGE_SYM_DTYPE_NULL
95 StorageClass: IMAGE_SYM_CLASS_STATIC
96 SectionDefinition:
97 Length: 328
98 NumberOfRelocations: 4
99 NumberOfLinenumbers: 0
100 CheckSum: 0
101 Number: 0
102 - Name: '.debug$T'
103 Value: 0
104 SectionNumber: 2
105 SimpleType: IMAGE_SYM_TYPE_NULL
106 ComplexType: IMAGE_SYM_DTYPE_NULL
107 StorageClass: IMAGE_SYM_CLASS_STATIC
108 SectionDefinition:
109 Length: 564
110 NumberOfRelocations: 0
111 NumberOfLinenumbers: 0
112 CheckSum: 0
113 Number: 0
114 - Name: '.text$mn'
115 Value: 0
116 SectionNumber: 3
117 SimpleType: IMAGE_SYM_TYPE_NULL
118 ComplexType: IMAGE_SYM_DTYPE_NULL
119 StorageClass: IMAGE_SYM_CLASS_STATIC
120 SectionDefinition:
121 Length: 3
122 NumberOfRelocations: 0
123 NumberOfLinenumbers: 0
124 CheckSum: 4021952397
125 Number: 0
126 - Name: main
127 Value: 0
128 SectionNumber: 3
129 SimpleType: IMAGE_SYM_TYPE_NULL
130 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
131 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
132...
deps/lld/test/COFF/pdb-type-server-simple.test created+91
......@@ -0,0 +1,91 @@
1Replicate this scenario:
2
3$ cat a.c
4struct Foo { int x; };
5int g(struct Foo *p);
6int main() {
7 struct Foo f = {42};
8 return g(&f);
9}
10
11$ cat b.c
12struct Foo { int x; };
13int g(struct Foo *p) { return p->x; }
14
15$ cl -c a.c b.c -Zi -Fdts.pdb
16
17$ lld-link a.obj b.obj -debug -entry:main -nodefaultlib -out:t.exe
18
19RUN: rm -rf %t && mkdir -p %t && cd %t
20RUN: yaml2obj %S/Inputs/pdb-type-server-simple-a.yaml -o a.obj
21RUN: yaml2obj %S/Inputs/pdb-type-server-simple-b.yaml -o b.obj
22RUN: llvm-pdbutil yaml2pdb %S/Inputs/pdb-type-server-simple-ts.yaml -pdb ts.pdb
23RUN: lld-link a.obj b.obj -entry:main -debug -out:t.exe -pdb:t.pdb -nodefaultlib
24RUN: llvm-pdbutil dump -symbols -types -ids %t/t.pdb | FileCheck %s
25
26
27CHECK-LABEL: Types (TPI Stream)
28CHECK: ============================================================
29
30CHECK: [[FOO_DECL:[^ ]*]] | LF_STRUCTURE [size = 36] `Foo`
31
32CHECK: [[FOO_PTR:[^ ]*]] | LF_POINTER [size = 12]
33CHECK-NEXT: referent = [[FOO_DECL]]
34
35CHECK: [[G_ARGS:[^ ]*]] | LF_ARGLIST [size = 12]
36CHECK-NEXT: [[FOO_PTR]]: `Foo*`
37
38CHECK: [[G_PROTO:[^ ]*]] | LF_PROCEDURE [size = 16]
39CHECK-NEXT: return type = 0x0074 (int), # args = 1, param list = [[G_ARGS]]
40CHECK-NEXT: calling conv = cdecl, options = None
41
42CHECK: [[FOO_COMPLETE:[^ ]*]] | LF_STRUCTURE [size = 36] `Foo`
43CHECK-NEXT: unique name: `.?AUFoo@@`
44CHECK-NEXT: vtable: <no type>, base list: <no type>, field list: 0x{{.*}}
45CHECK: options: has unique name
46CHECK: [[MAIN_PROTO:[^ ]*]] | LF_PROCEDURE [size = 16]
47CHECK: return type = 0x0074 (int), # args = 0, param list = 0x{{.*}}
48CHECK: calling conv = cdecl, options = None
49
50
51CHECK-LABEL: Types (IPI Stream)
52CHECK: ============================================================
53CHECK: [[MAIN_ID:[^ ]*]] | LF_FUNC_ID [size = 20]
54CHECK: name = main, type = [[MAIN_PROTO]], parent scope = <no type>
55CHECK: [[G_ID:[^ ]*]] | LF_FUNC_ID [size = 16]
56CHECK: name = g, type = [[G_PROTO]], parent scope = <no type>
57CHECK: [[A_BUILD:[^ ]*]] | LF_BUILDINFO [size = 28]
58CHECK: {{.*}}: `a.c`
59CHECK: [[B_BUILD:[^ ]*]] | LF_BUILDINFO [size = 28]
60CHECK: {{.*}}: `b.c`
61
62CHECK-LABEL: Symbols
63CHECK: ============================================================
64CHECK-LABEL: Mod 0000 | `{{.*}}a.obj`:
65CHECK: 4 | S_OBJNAME [size = 40] sig=0, `C:\src\llvm-project\build\a.obj`
66CHECK: 104 | S_GPROC32_ID [size = 44] `main`
67CHECK: parent = 0, end = 196, addr = 0002:0000, code size = 27
68CHECK: type = {{.*}}, debug start = 4, debug end = 22, flags = none
69CHECK: 200 | S_UDT [size = 12] `Foo`
70CHECK: original type = [[FOO_COMPLETE]]
71CHECK: 212 | S_BUILDINFO [size = 8] BuildId = `[[A_BUILD]]`
72CHECK-LABEL: Mod 0001 | `{{.*}}b.obj`:
73CHECK: 4 | S_OBJNAME [size = 40] sig=0, `C:\src\llvm-project\build\b.obj`
74CHECK: 44 | S_COMPILE3 [size = 60]
75CHECK: machine = intel x86-x64, Ver = Microsoft (R) Optimizing Compiler, language = c
76CHECK: frontend = 19.0.24215.1, backend = 19.0.24215.1
77CHECK: flags = security checks | hot patchable
78CHECK: 104 | S_GPROC32_ID [size = 44] `g`
79CHECK: parent = 0, end = 196, addr = 0002:0032, code size = 13
80CHECK: type = {{.*}}, debug start = 5, debug end = 12, flags = none
81CHECK: 148 | S_FRAMEPROC [size = 32]
82CHECK: size = 0, padding size = 0, offset to padding = 0
83CHECK: bytes of callee saved registers = 0, exception handler addr = 0000:0000
84CHECK: flags = has async eh | opt speed
85CHECK: 180 | S_REGREL32 [size = 16] `p`
86CHECK: type = [[FOO_PTR]] (Foo*), register = rsp, offset = 8
87CHECK: 196 | S_END [size = 4]
88CHECK: 200 | S_UDT [size = 12] `Foo`
89CHECK: original type = [[FOO_COMPLETE]]
90CHECK: 212 | S_BUILDINFO [size = 8] BuildId = `[[B_BUILD]]`
91CHECK-LABEL: Mod 0002 | `* Linker *`:
deps/lld/test/COFF/pdb.test created+202
......@@ -0,0 +1,202 @@
1# RUN: yaml2obj < %p/Inputs/pdb1.yaml > %t1.obj
2# RUN: yaml2obj < %p/Inputs/pdb2.yaml > %t2.obj
3# RUN: lld-link /debug /pdb:%t.pdb /dll /out:%t.dll /entry:main /nodefaultlib \
4# RUN: %t1.obj %t2.obj
5
6# RUN: llvm-pdbutil pdb2yaml -stream-metadata -stream-directory -pdb-stream \
7# RUN: -dbi-stream -ipi-stream -tpi-stream %t.pdb | FileCheck %s
8
9# RUN: llvm-pdbutil dump -modules -section-map -section-contribs \
10# RUN: -types -ids %t.pdb | FileCheck -check-prefix RAW %s
11
12# CHECK: MSF:
13# CHECK-NEXT: SuperBlock:
14# CHECK-NEXT: BlockSize: 4096
15# CHECK-NEXT: FreeBlockMap: 1
16# CHECK-NEXT: NumBlocks:
17# CHECK-NEXT: NumDirectoryBytes:
18# CHECK-NEXT: Unknown1: 0
19# CHECK-NEXT: BlockMapAddr:
20# CHECK-NEXT: NumDirectoryBlocks:
21# CHECK-NEXT: DirectoryBlocks:
22# CHECK-NEXT: NumStreams:
23# CHECK-NEXT: FileSize:
24# CHECK-NEXT: StreamSizes:
25# CHECK: StreamMap:
26# CHECK: PdbStream:
27# CHECK-NEXT: Age: 1
28# CHECK-NEXT: Guid:
29# CHECK-NEXT: Signature:
30# CHECK-NEXT: Features: [ VC140 ]
31# CHECK-NEXT: Version: VC70
32# CHECK-NEXT: DbiStream:
33# CHECK-NEXT: VerHeader: V70
34# CHECK-NEXT: Age: 1
35# CHECK-NEXT: BuildNumber: 0
36# CHECK-NEXT: PdbDllVersion: 0
37# CHECK-NEXT: PdbDllRbld: 0
38# CHECK-NEXT: Flags: 0
39# CHECK-NEXT: MachineType: x86
40# CHECK-NEXT: TpiStream:
41# CHECK-NEXT: Version: VC80
42# CHECK-NEXT: Records:
43# CHECK-NEXT: - Kind: LF_ARGLIST
44# CHECK-NEXT: ArgList:
45# CHECK-NEXT: ArgIndices: [ ]
46# CHECK-NEXT: - Kind: LF_PROCEDURE
47# CHECK-NEXT: Procedure:
48# CHECK-NEXT: ReturnType: 116
49# CHECK-NEXT: CallConv: NearC
50# CHECK-NEXT: Options: [ None ]
51# CHECK-NEXT: ParameterCount: 0
52# CHECK-NEXT: ArgumentList: 4096
53# CHECK-NEXT: - Kind: LF_POINTER
54# CHECK-NEXT: Pointer:
55# CHECK-NEXT: ReferentType: 4097
56# CHECK-NEXT: Attrs: 65548
57# CHECK-NEXT: - Kind: LF_ARGLIST
58# CHECK-NEXT: ArgList:
59# CHECK-NEXT: ArgIndices: [ 0 ]
60# CHECK-NEXT: - Kind: LF_PROCEDURE
61# CHECK-NEXT: Procedure:
62# CHECK-NEXT: ReturnType: 116
63# CHECK-NEXT: CallConv: NearC
64# CHECK-NEXT: Options: [ None ]
65# CHECK-NEXT: ParameterCount: 0
66# CHECK-NEXT: ArgumentList: 4099
67# CHECK-NEXT: IpiStream:
68# CHECK-NEXT: Version: VC80
69# CHECK-NEXT: Records:
70# CHECK-NEXT: - Kind: LF_FUNC_ID
71# CHECK-NEXT: FuncId:
72# CHECK-NEXT: ParentScope: 0
73# CHECK-NEXT: FunctionType: 4100
74# CHECK-NEXT: Name: main
75# CHECK-NEXT: - Kind: LF_FUNC_ID
76# CHECK-NEXT: FuncId:
77# CHECK-NEXT: ParentScope: 0
78# CHECK-NEXT: FunctionType: 4097
79# CHECK-NEXT: Name: foo
80# CHECK-NEXT: - Kind: LF_STRING_ID
81# CHECK-NEXT: StringId:
82# CHECK-NEXT: Id: 0
83# CHECK-NEXT: String: 'D:\b'
84# CHECK-NEXT: - Kind: LF_STRING_ID
85# CHECK-NEXT: StringId:
86# CHECK-NEXT: Id: 0
87# CHECK-NEXT: String: 'C:\vs14\VC\BIN\amd64\cl.exe'
88# CHECK-NEXT: - Kind: LF_STRING_ID
89# CHECK-NEXT: StringId:
90# CHECK-NEXT: Id: 0
91# CHECK-NEXT: String: '-Z7 -c -MT -IC:\vs14\VC\INCLUDE -IC:\vs14\VC\ATLMFC\INCLUDE -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.10150.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\shared"'
92# CHECK-NEXT: - Kind: LF_SUBSTR_LIST
93# CHECK-NEXT: StringList:
94# CHECK-NEXT: StringIndices: [ 4100 ]
95# CHECK-NEXT: - Kind: LF_STRING_ID
96# CHECK-NEXT: StringId:
97# CHECK-NEXT: Id: 4101
98# CHECK-NEXT: String: ' -I"C:\Program Files (x86)\Windows Kits\8.1\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\winrt" -TC -X'
99# CHECK-NEXT: - Kind: LF_STRING_ID
100# CHECK-NEXT: StringId:
101# CHECK-NEXT: Id: 0
102# CHECK-NEXT: String: ret42-main.c
103# CHECK-NEXT: - Kind: LF_STRING_ID
104# CHECK-NEXT: StringId:
105# CHECK-NEXT: Id: 0
106# CHECK-NEXT: String: 'D:\b\vc140.pdb'
107# CHECK-NEXT: - Kind: LF_BUILDINFO
108# CHECK-NEXT: BuildInfo:
109# CHECK-NEXT: ArgIndices: [ 4098, 4099, 4103, 4104, 4102 ]
110# CHECK-NEXT: - Kind: LF_STRING_ID
111# CHECK-NEXT: StringId:
112# CHECK-NEXT: Id: 0
113# CHECK-NEXT: String: ret42-sub.c
114# CHECK-NEXT: - Kind: LF_BUILDINFO
115# CHECK-NEXT: BuildInfo:
116# CHECK-NEXT: ArgIndices: [ 4098, 4099, 4106, 4104, 4102 ]
117
118RAW: Modules
119RAW-NEXT: ============================================================
120RAW-NEXT: Mod 0000 | Name: `{{.*}}pdb.test.tmp1.obj`:
121RAW-NEXT: Obj: `{{.*}}pdb.test.tmp1.obj`:
122RAW-NEXT: debug stream: 9, # files: 1, has ec info: false
123RAW-NEXT: pdb file ni: 0 ``, src file ni: 0 ``
124RAW-NEXT: Mod 0001 | Name: `{{.*}}pdb.test.tmp2.obj`:
125RAW-NEXT: Obj: `{{.*}}pdb.test.tmp2.obj`:
126RAW-NEXT: debug stream: 10, # files: 1, has ec info: false
127RAW-NEXT: pdb file ni: 0 ``, src file ni: 0 ``
128RAW-NEXT: Mod 0002 | Name: `* Linker *`:
129RAW-NEXT: Obj: ``:
130RAW-NEXT: debug stream: 11, # files: 0, has ec info: false
131RAW-NEXT: pdb file ni: 1 `{{.*pdb.test.tmp.pdb}}`, src file ni: 0 ``
132RAW: Types (TPI Stream)
133RAW-NEXT: ============================================================
134RAW-NEXT: Showing 5 records
135RAW-NEXT: 0x1000 | LF_ARGLIST [size = 8]
136RAW-NEXT: 0x1001 | LF_PROCEDURE [size = 16]
137RAW-NEXT: return type = 0x0074 (int), # args = 0, param list = 0x1000
138RAW-NEXT: calling conv = cdecl, options = None
139RAW-NEXT: 0x1002 | LF_POINTER [size = 12]
140RAW-NEXT: referent = 0x1001, mode = pointer, opts = None, kind = ptr64
141RAW-NEXT: 0x1003 | LF_ARGLIST [size = 12]
142RAW-NEXT: <no type>: ``
143RAW-NEXT: 0x1004 | LF_PROCEDURE [size = 16]
144RAW-NEXT: return type = 0x0074 (int), # args = 0, param list = 0x1003
145RAW-NEXT: calling conv = cdecl, options = None
146RAW: Types (IPI Stream)
147RAW-NEXT: ============================================================
148RAW-NEXT: Showing 12 records
149RAW-NEXT: 0x1000 | LF_FUNC_ID [size = 20]
150RAW-NEXT: name = main, type = 0x1004, parent scope = <no type>
151RAW-NEXT: 0x1001 | LF_FUNC_ID [size = 16]
152RAW-NEXT: name = foo, type = 0x1001, parent scope = <no type>
153RAW-NEXT: 0x1002 | LF_STRING_ID [size = 16] ID: <no type>, String: D:\b
154RAW-NEXT: 0x1003 | LF_STRING_ID [size = 36] ID: <no type>, String: C:\vs14\VC\BIN\amd64\cl.exe
155RAW-NEXT: 0x1004 | LF_STRING_ID [size = 260] ID: <no type>, String: -Z7 -c -MT -IC:\vs14\VC\INCLUDE -IC:\vs14\VC\ATLMFC\INCLUDE -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.10150.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\shared"
156RAW-NEXT: 0x1005 | LF_SUBSTR_LIST [size = 12]
157RAW-NEXT: 0x1004: `-Z7 -c -MT -IC:\vs14\VC\INCLUDE -IC:\vs14\VC\ATLMFC\INCLUDE -I"C:\Program Files (x86)\Windows Kits\10\include\10.0.10150.0\ucrt" -I"C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\shared"`
158RAW-NEXT: 0x1006 | LF_STRING_ID [size = 132] ID: 0x1005, String: -I"C:\Program Files (x86)\Windows Kits\8.1\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\winrt" -TC -X
159RAW-NEXT: 0x1007 | LF_STRING_ID [size = 24] ID: <no type>, String: ret42-main.c
160RAW-NEXT: 0x1008 | LF_STRING_ID [size = 24] ID: <no type>, String: D:\b\vc140.pdb
161RAW-NEXT: 0x1009 | LF_BUILDINFO [size = 28]
162RAW-NEXT: 0x1002: `D:\b`
163RAW-NEXT: 0x1003: `C:\vs14\VC\BIN\amd64\cl.exe`
164RAW-NEXT: 0x1007: `ret42-main.c`
165RAW-NEXT: 0x1008: `D:\b\vc140.pdb`
166RAW-NEXT: 0x1006: ` -I"C:\Program Files (x86)\Windows Kits\8.1\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\winrt" -TC -X`
167RAW-NEXT: 0x100A | LF_STRING_ID [size = 20] ID: <no type>, String: ret42-sub.c
168RAW-NEXT: 0x100B | LF_BUILDINFO [size = 28]
169RAW-NEXT: 0x1002: `D:\b`
170RAW-NEXT: 0x1003: `C:\vs14\VC\BIN\amd64\cl.exe`
171RAW-NEXT: 0x100A: `ret42-sub.c`
172RAW-NEXT: 0x1008: `D:\b\vc140.pdb`
173RAW-NEXT: 0x1006: ` -I"C:\Program Files (x86)\Windows Kits\8.1\include\um" -I"C:\Program Files (x86)\Windows Kits\8.1\include\winrt" -TC -X`
174RAW: Section Contributions
175RAW-NEXT: ============================================================
176RAW-NEXT: SC | mod = 0, 65535:1288, size = 14, data crc = 0, reloc crc = 0
177RAW-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_ALIGN_16BYTES | IMAGE_SCN_MEM_EXECUTE |
178RAW-NEXT: IMAGE_SCN_MEM_READ
179RAW-NEXT: SC | mod = 0, 65535:1312, size = 8, data crc = 0, reloc crc = 0
180RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_READ
181RAW-NEXT: SC | mod = 0, 65535:1320, size = 12, data crc = 0, reloc crc = 0
182RAW-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_ALIGN_4BYTES | IMAGE_SCN_MEM_READ
183RAW-NEXT: SC | mod = 1, 65535:1144, size = 6, data crc = 0, reloc crc = 0
184RAW-NEXT: IMAGE_SCN_CNT_CODE | IMAGE_SCN_ALIGN_16BYTES | IMAGE_SCN_MEM_EXECUTE |
185RAW-NEXT: IMAGE_SCN_MEM_READ
186RAW: Section Map
187RAW-NEXT: ============================================================
188RAW-NEXT: Section 0000 | ovl = 0, group = 0, frame = 0, name = 1
189RAW-NEXT: class = 65535, offset = 0, size =
190RAW-NEXT: flags = read | 32 bit addr | selector
191RAW-NEXT: Section 0001 | ovl = 1, group = 0, frame = 0, name = 2
192RAW-NEXT: class = 65535, offset = 0, size =
193RAW-NEXT: flags = read | execute | 32 bit addr | selector
194RAW-NEXT: Section 0002 | ovl = 2, group = 0, frame = 0, name = 3
195RAW-NEXT: class = 65535, offset = 0, size =
196RAW-NEXT: flags = read | 32 bit addr | selector
197RAW-NEXT: Section 0003 | ovl = 3, group = 0, frame = 0, name = 4
198RAW-NEXT: class = 65535, offset = 0, size =
199RAW-NEXT: flags = read | 32 bit addr | selector
200RAW-NEXT: Section 0004 | ovl = 4, group = 0, frame = 0, name = 5
201RAW-NEXT: class = 65535, offset = 0, size =
202RAW-NEXT: flags = 32 bit addr | absolute addr
deps/lld/test/COFF/reloc-arm.test created+84
......@@ -0,0 +1,84 @@
1# RUN: yaml2obj < %s > %t.obj
2# RUN: lld-link /out:%t.exe /entry:main %t.obj
3# RUN: llvm-objdump -s %t.exe | FileCheck %s
4
5# CHECK: .text:
6# CHECK: 402000 01104000 00000000 00000000 00000000
7# CHECK: 402010 01100000 00000000 00000000 00000000
8# CHECK: 402020 41f20009 c0f24009 00000000 00000000
9# CHECK: 402030 fe07e62f 00000000 00000000 00000000
10# CHECK: 402040 3e04de2f 00000000 00000000 00000000
11# CHECK: 402050 fe07d62f 00000000 00000000 00000000
12# CHECK: 402060 fef0cef7 00000000 00000000 00000000
13# CHECK: 402070 00005000 00000000 00000000 00000000
14
15--- !COFF
16header:
17 Machine: IMAGE_FILE_MACHINE_ARMNT
18 Characteristics: []
19sections:
20 - Name: .aaa
21 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_PURGEABLE, IMAGE_SCN_MEM_16BIT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
22 Alignment: 4096
23 SectionData: 0000000000000000
24 - Name: .text
25 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_PURGEABLE, IMAGE_SCN_MEM_16BIT, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
26 Alignment: 4096
27 SectionData: 00000000000000000000000000000000000000000000000000000000000000004ff6ff79cff6ff79000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f000f800000000000000000000000000000000000000000000000000000000
28 Relocations:
29 - VirtualAddress: 0
30 SymbolName: foo
31 Type: 1 # IMAGE_REL_ARM_ADDR32
32 - VirtualAddress: 16
33 SymbolName: foo
34 Type: 2 # IMAGE_REL_ARM_ADDR32NB
35 - VirtualAddress: 32
36 SymbolName: foo
37 Type: 17 # IMAGE_REL_ARM_MOV32T
38 - VirtualAddress: 48
39 SymbolName: foo
40 Type: 20 # IMAGE_REL_ARM_BRANCH24T
41 - VirtualAddress: 64
42 SymbolName: foo
43 Type: 18 # IMAGE_REL_ARM_BRANCH20T
44 - VirtualAddress: 80
45 SymbolName: foo
46 Type: 21 # IMAGE_REL_ARM_BLX23T
47 - VirtualAddress: 96
48 SymbolName: bar
49 Type: 20 # IMAGE_REL_ARM_BRANCH24T
50 - VirtualAddress: 112
51 SymbolName: bar
52 Type: 15 # IMAGE_REL_ARM_SECREL
53symbols:
54 - Name: .aaa
55 Value: 0
56 SectionNumber: 1
57 SimpleType: IMAGE_SYM_TYPE_NULL
58 ComplexType: IMAGE_SYM_DTYPE_NULL
59 StorageClass: IMAGE_SYM_CLASS_STATIC
60 - Name: .text
61 Value: 0
62 SectionNumber: 2
63 SimpleType: IMAGE_SYM_TYPE_NULL
64 ComplexType: IMAGE_SYM_DTYPE_NULL
65 StorageClass: IMAGE_SYM_CLASS_STATIC
66 - Name: main
67 Value: 0
68 SectionNumber: 1
69 SimpleType: IMAGE_SYM_TYPE_NULL
70 ComplexType: IMAGE_SYM_DTYPE_NULL
71 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
72 - Name: foo
73 Value: 0
74 SectionNumber: 1
75 SimpleType: IMAGE_SYM_TYPE_NULL
76 ComplexType: IMAGE_SYM_DTYPE_NULL
77 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
78 - Name: bar
79 Value: 0x500000
80 SectionNumber: 1
81 SimpleType: IMAGE_SYM_TYPE_NULL
82 ComplexType: IMAGE_SYM_DTYPE_NULL
83 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
84...
deps/lld/test/COFF/reloc-discarded-dwarf.s created+15
......@@ -0,0 +1,15 @@
1# RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t1.obj %s
2# RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t2.obj %s
3
4# LLD should not error on relocations in DWARF debug sections against symbols in
5# discarded sections.
6# RUN: lld-link -entry:main -debug %t1.obj %t2.obj
7
8 .section .text,"xr",discard,main
9 .globl main
10main:
11f:
12 retq
13
14 .section .debug_info,"dr"
15 .quad f
deps/lld/test/COFF/reloc-discarded.s created+30
......@@ -0,0 +1,30 @@
1# RUN: echo -e '.section .bss,"bw",discard,main_global\n.global main_global\n main_global:\n .long 0' | \
2# RUN: llvm-mc - -filetype=obj -o %t1.obj -triple x86_64-windows-msvc
3# RUN: llvm-mc %s -filetype=obj -o %t2.obj -triple x86_64-windows-msvc
4
5# LLD should report an error and not assert regardless of whether we are doing
6# GC.
7
8# RUN: not lld-link -entry:main -nodefaultlib %t1.obj %t2.obj -out:%t.exe -opt:ref 2>&1 | FileCheck %s
9# RUN: not lld-link -entry:main -nodefaultlib %t1.obj %t2.obj -out:%t.exe -opt:noref 2>&1 | FileCheck %s
10
11# CHECK: error: relocation against symbol in discarded section: assoc_global
12
13 .section .bss,"bw",discard,main_global
14 .globl main_global
15 .p2align 2
16main_global:
17 .long 0
18
19 .section .CRT$XCU,"dr",associative,main_global
20 .p2align 3
21 .globl assoc_global
22assoc_global:
23 .quad main_global
24
25 .text
26 .globl main
27main:
28 movq assoc_global(%rip), %rax
29 movl (%rax), %eax
30 retq
deps/lld/test/COFF/reloc-oob.yaml created+62
......@@ -0,0 +1,62 @@
1# Make sure LLD does some light relocation bounds checking.
2
3# RUN: yaml2obj %s -o %t.obj
4# RUN: not lld-link %t.obj -entry:main -nodefaultlib -out:%t.exe 2>&1 | FileCheck %s
5
6# CHECK: error: relocation points beyond the end of its parent section
7
8--- !COFF
9header:
10 Machine: IMAGE_FILE_MACHINE_I386
11 Characteristics: [ ]
12sections:
13 - Name: .text
14 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
15 Alignment: 16
16 SectionData: 5589E550C745FC00000000A10000000083C4045DC3
17 Relocations:
18 - VirtualAddress: 24
19 SymbolName: _g
20 Type: IMAGE_REL_I386_DIR32
21 - Name: .data
22 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
23 Alignment: 4
24 SectionData: 2A000000
25symbols:
26 - Name: .text
27 Value: 0
28 SectionNumber: 1
29 SimpleType: IMAGE_SYM_TYPE_NULL
30 ComplexType: IMAGE_SYM_DTYPE_NULL
31 StorageClass: IMAGE_SYM_CLASS_STATIC
32 SectionDefinition:
33 Length: 21
34 NumberOfRelocations: 1
35 NumberOfLinenumbers: 0
36 CheckSum: 662775349
37 Number: 1
38 - Name: .data
39 Value: 0
40 SectionNumber: 2
41 SimpleType: IMAGE_SYM_TYPE_NULL
42 ComplexType: IMAGE_SYM_DTYPE_NULL
43 StorageClass: IMAGE_SYM_CLASS_STATIC
44 SectionDefinition:
45 Length: 4
46 NumberOfRelocations: 0
47 NumberOfLinenumbers: 0
48 CheckSum: 3482275674
49 Number: 2
50 - Name: _main
51 Value: 0
52 SectionNumber: 1
53 SimpleType: IMAGE_SYM_TYPE_NULL
54 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
55 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
56 - Name: _g
57 Value: 0
58 SectionNumber: 2
59 SimpleType: IMAGE_SYM_TYPE_NULL
60 ComplexType: IMAGE_SYM_DTYPE_NULL
61 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
62...
deps/lld/test/COFF/reloc-x64.test created+102
......@@ -0,0 +1,102 @@
1# RUN: yaml2obj < %s > %t.obj
2# RUN: lld-link /out:%t.exe /entry:main %t.obj
3# RUN: llvm-objdump -d %t.exe | FileCheck %s
4
5# CHECK: .text:
6# CHECK: 1000: a1 03 20 00 40 00 00 00 00
7# CHECK: 1009: a1 03 20 00 40 01 00 00 00
8# CHECK: 1012: a1 03 20 00 00 00 00 00 00
9# CHECK: 101b: a1 e3 0f 00 00 00 00 00 00
10# CHECK: 1024: a1 d9 0f 00 00 00 00 00 00
11# CHECK: 102d: a1 cf 0f 00 00 00 00 00 00
12# CHECK: 1036: a1 c5 0f 00 00 00 00 00 00
13# CHECK: 103f: a1 bb 0f 00 00 00 00 00 00
14# CHECK: 1048: a1 b1 0f 00 00 00 00 00 00
15# CHECK: 1051: a1 02 00 00 00 00 00 00 00
16# CHECK: 105a: a1 03 00 00 00 00 00 00 00
17
18--- !COFF
19header:
20 Machine: IMAGE_FILE_MACHINE_AMD64
21 Characteristics: []
22sections:
23 - Name: .text
24 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
25 Alignment: 4096
26 SectionData: A10000000000000000A10000000000000000A10000000000000000A10000000000000000A10000000000000000A10000000000000000A10000000000000000A10000000000000000A10000000000000000A10000000000000000A10000000000000000
27 Relocations:
28 - VirtualAddress: 1
29 SymbolName: foo
30 Type: IMAGE_REL_AMD64_ADDR32
31 - VirtualAddress: 10
32 SymbolName: foo
33 Type: IMAGE_REL_AMD64_ADDR64
34 - VirtualAddress: 19
35 SymbolName: foo
36 Type: IMAGE_REL_AMD64_ADDR32NB
37 - VirtualAddress: 28
38 SymbolName: foo
39 Type: IMAGE_REL_AMD64_REL32
40 - VirtualAddress: 37
41 SymbolName: foo
42 Type: IMAGE_REL_AMD64_REL32_1
43 - VirtualAddress: 46
44 SymbolName: foo
45 Type: IMAGE_REL_AMD64_REL32_2
46 - VirtualAddress: 55
47 SymbolName: foo
48 Type: IMAGE_REL_AMD64_REL32_3
49 - VirtualAddress: 64
50 SymbolName: foo
51 Type: IMAGE_REL_AMD64_REL32_4
52 - VirtualAddress: 73
53 SymbolName: foo
54 Type: IMAGE_REL_AMD64_REL32_5
55 - VirtualAddress: 82
56 SymbolName: foo
57 Type: IMAGE_REL_AMD64_SECTION
58 - VirtualAddress: 91
59 SymbolName: foo
60 Type: IMAGE_REL_AMD64_SECREL
61 - Name: .zzz
62 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
63 Alignment: 4096
64 SectionData: 0000000000000000
65symbols:
66 - Name: .text
67 Value: 0
68 SectionNumber: 1
69 SimpleType: IMAGE_SYM_TYPE_NULL
70 ComplexType: IMAGE_SYM_DTYPE_NULL
71 StorageClass: IMAGE_SYM_CLASS_STATIC
72 SectionDefinition:
73 Length: 6
74 NumberOfRelocations: 0
75 NumberOfLinenumbers: 0
76 CheckSum: 0
77 Number: 0
78 - Name: .zzz
79 Value: 0
80 SectionNumber: 2
81 SimpleType: IMAGE_SYM_TYPE_NULL
82 ComplexType: IMAGE_SYM_DTYPE_NULL
83 StorageClass: IMAGE_SYM_CLASS_STATIC
84 SectionDefinition:
85 Length: 8
86 NumberOfRelocations: 0
87 NumberOfLinenumbers: 0
88 CheckSum: 0
89 Number: 0
90 - Name: main
91 Value: 0
92 SectionNumber: 1
93 SimpleType: IMAGE_SYM_TYPE_NULL
94 ComplexType: IMAGE_SYM_DTYPE_NULL
95 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
96 - Name: foo
97 Value: 3
98 SectionNumber: 2
99 SimpleType: IMAGE_SYM_TYPE_NULL
100 ComplexType: IMAGE_SYM_DTYPE_NULL
101 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
102...
deps/lld/test/COFF/reloc-x86.test created+82
......@@ -0,0 +1,82 @@
1# RUN: yaml2obj < %s > %t.obj
2# RUN: lld-link /out:%t.exe /entry:main /base:0x400000 %t.obj
3# RUN: llvm-objdump -d %t.exe | FileCheck %s
4
5# CHECK: .text:
6# CHECK: 1000: a1 00 00 00 00
7# CHECK: 1005: a1 03 20 40 00
8# CHECK: 100a: a1 03 20 00 00
9# CHECK: 100f: a1 ef 0f 00 00
10# CHECK: 1014: a1 00 00 02 00
11# CHECK: 1019: a1 03 00 00 00
12
13--- !COFF
14header:
15 Machine: IMAGE_FILE_MACHINE_I386
16 Characteristics: []
17sections:
18 - Name: .text
19 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
20 Alignment: 4096
21 SectionData: A100000000A100000000A100000000A100000000A100000000A100000000
22 Relocations:
23 - VirtualAddress: 1
24 SymbolName: _foo
25 Type: IMAGE_REL_I386_ABSOLUTE
26 - VirtualAddress: 6
27 SymbolName: _foo
28 Type: IMAGE_REL_I386_DIR32
29 - VirtualAddress: 11
30 SymbolName: _foo
31 Type: IMAGE_REL_I386_DIR32NB
32 - VirtualAddress: 16
33 SymbolName: _foo
34 Type: IMAGE_REL_I386_REL32
35 - VirtualAddress: 23
36 SymbolName: _foo
37 Type: IMAGE_REL_I386_SECTION
38 - VirtualAddress: 26
39 SymbolName: _foo
40 Type: IMAGE_REL_I386_SECREL
41 - Name: .zzz
42 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
43 Alignment: 4096
44 SectionData: 0000000000000000
45symbols:
46 - Name: .text
47 Value: 0
48 SectionNumber: 1
49 SimpleType: IMAGE_SYM_TYPE_NULL
50 ComplexType: IMAGE_SYM_DTYPE_NULL
51 StorageClass: IMAGE_SYM_CLASS_STATIC
52 SectionDefinition:
53 Length: 6
54 NumberOfRelocations: 0
55 NumberOfLinenumbers: 0
56 CheckSum: 0
57 Number: 0
58 - Name: .zzz
59 Value: 0
60 SectionNumber: 2
61 SimpleType: IMAGE_SYM_TYPE_NULL
62 ComplexType: IMAGE_SYM_DTYPE_NULL
63 StorageClass: IMAGE_SYM_CLASS_STATIC
64 SectionDefinition:
65 Length: 8
66 NumberOfRelocations: 0
67 NumberOfLinenumbers: 0
68 CheckSum: 0
69 Number: 0
70 - Name: _main
71 Value: 0
72 SectionNumber: 1
73 SimpleType: IMAGE_SYM_TYPE_NULL
74 ComplexType: IMAGE_SYM_DTYPE_NULL
75 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
76 - Name: _foo
77 Value: 3
78 SectionNumber: 2
79 SimpleType: IMAGE_SYM_TYPE_NULL
80 ComplexType: IMAGE_SYM_DTYPE_NULL
81 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
82...
deps/lld/test/COFF/resource.test created+44
......@@ -0,0 +1,44 @@
1# RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj
2# RUN: lld-link /out:%t.exe /entry:main %t.obj %p/Inputs/resource.res
3
4# Check if the binary contains UTF-16LE string "Hello" copied from resource.res.
5# RUN: FileCheck --check-prefix=EXE %s < %t.exe
6
7EXE: {{H.e.l.l.o}}
8
9# Verify the resource tree layout in the final executable.
10# RUN: llvm-readobj -file-headers -coff-resources -section-data %t.exe | \
11# RUN: FileCheck --check-prefix=RESOURCE_INFO %s
12
13RESOURCE_INFO: ResourceTableRVA: 0x1000
14RESOURCE_INFO-NEXT: ResourceTableSize: 0x88
15RESOURCE_INFO-DAG: Resources [
16RESOURCE_INFO-NEXT: Total Number of Resources: 1
17RESOURCE_INFO-NEXT: Base Table Address: 0x400
18RESOURCE_INFO-DAG: Number of String Entries: 0
19RESOURCE_INFO-NEXT: Number of ID Entries: 1
20RESOURCE_INFO-NEXT: Type: kRT_STRING (ID 6) [
21RESOURCE_INFO-NEXT: Table Offset: 0x18
22RESOURCE_INFO-NEXT: Number of String Entries: 0
23RESOURCE_INFO-NEXT: Number of ID Entries: 1
24RESOURCE_INFO-NEXT: Name: (ID 1) [
25RESOURCE_INFO-NEXT: Table Offset: 0x30
26RESOURCE_INFO-NEXT: Number of String Entries: 0
27RESOURCE_INFO-NEXT: Number of ID Entries: 1
28RESOURCE_INFO-NEXT: Language: (ID 1033) [
29RESOURCE_INFO-NEXT: Entry Offset: 0x48
30RESOURCE_INFO-NEXT: Time/Date Stamp: 1970-01-01 00:00:00 (0x0)
31RESOURCE_INFO-NEXT: Major Version: 0
32RESOURCE_INFO-NEXT: Minor Version: 0
33RESOURCE_INFO-NEXT: Characteristics: 0
34RESOURCE_INFO-DAG: .rsrc Data (
35RESOURCE_INFO-NEXT: 0000: 00000000 00000000 00000000 00000100 |................|
36RESOURCE_INFO-NEXT: 0010: 06000000 18000080 00000000 00000000 |................|
37RESOURCE_INFO-NEXT: 0020: 00000000 00000100 01000000 30000080 |............0...|
38RESOURCE_INFO-NEXT: 0030: 00000000 00000000 00000000 00000100 |................|
39RESOURCE_INFO-NEXT: 0040: 09040000 48000000 58100000 2A000000 |....H...X...*...|
40RESOURCE_INFO-NEXT: 0050: 00000000 00000000 00000500 48006500 |............H.e.|
41RESOURCE_INFO-NEXT: 0060: 6C006C00 6F000000 00000000 00000000 |l.l.o...........|
42RESOURCE_INFO-NEXT: 0070: 00000000 00000000 00000000 00000000 |................|
43RESOURCE_INFO-NEXT: 0080: 00000000 00000000 |........|
44RESOURCE_INFO-NEXT: )
deps/lld/test/COFF/responsefile.test created+7
......@@ -0,0 +1,7 @@
1# RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj
2
3# RUN: echo /out:%t.exe /entry:main %t.obj > %t.rsp
4# RUN: lld-link @%t.rsp /heap:0x3000
5# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
6
7CHECK: SizeOfHeapReserve: 12288
deps/lld/test/COFF/rsds.test created+94
......@@ -0,0 +1,94 @@
1# RUN: yaml2obj %s > %t.obj
2
3# RUN: lld-link /debug /dll /out:%t.dll /entry:DllMain %t.obj
4# RUN: llvm-readobj -coff-debug-directory %t.dll | FileCheck %s
5
6# RUN: lld-link /debug /pdb:%t.pdb /dll /out:%t.dll /entry:DllMain %t.obj
7# RUN: llvm-readobj -coff-debug-directory %t.dll | FileCheck %s
8
9# CHECK: DebugDirectory [
10# CHECK: DebugEntry {
11# CHECK: Characteristics: 0x0
12# CHECK: TimeDateStamp: 1970-01-01 00:00:00 (0x0)
13# CHECK: MajorVersion: 0x0
14# CHECK: MinorVersion: 0x0
15# CHECK: Type: CodeView (0x2)
16# CHECK: SizeOfData:
17# CHECK: AddressOfRawData:
18# CHECK: PointerToRawData:
19# CHECK: PDBInfo {
20# CHECK: PDBSignature: 0x53445352
21# CHECK: PDBGUID:
22# CHECK: PDBAge: 1
23# CHECK: PDBFileName: {{.*}}.pdb
24# CHECK: }
25# CHECK: }
26# CHECK: ]
27
28--- !COFF
29header:
30 Machine: IMAGE_FILE_MACHINE_I386
31 Characteristics: [ ]
32sections:
33 - Name: .text
34 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
35 Alignment: 4
36 SectionData: 31C0C3
37 - Name: .data
38 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
39 Alignment: 4
40 SectionData: ''
41 - Name: .bss
42 Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
43 Alignment: 4
44 SectionData: ''
45symbols:
46 - Name: .text
47 Value: 0
48 SectionNumber: 1
49 SimpleType: IMAGE_SYM_TYPE_NULL
50 ComplexType: IMAGE_SYM_DTYPE_NULL
51 StorageClass: IMAGE_SYM_CLASS_STATIC
52 SectionDefinition:
53 Length: 3
54 NumberOfRelocations: 0
55 NumberOfLinenumbers: 0
56 CheckSum: 3963538403
57 Number: 1
58 - Name: .data
59 Value: 0
60 SectionNumber: 2
61 SimpleType: IMAGE_SYM_TYPE_NULL
62 ComplexType: IMAGE_SYM_DTYPE_NULL
63 StorageClass: IMAGE_SYM_CLASS_STATIC
64 SectionDefinition:
65 Length: 0
66 NumberOfRelocations: 0
67 NumberOfLinenumbers: 0
68 CheckSum: 0
69 Number: 2
70 - Name: .bss
71 Value: 0
72 SectionNumber: 3
73 SimpleType: IMAGE_SYM_TYPE_NULL
74 ComplexType: IMAGE_SYM_DTYPE_NULL
75 StorageClass: IMAGE_SYM_CLASS_STATIC
76 SectionDefinition:
77 Length: 0
78 NumberOfRelocations: 0
79 NumberOfLinenumbers: 0
80 CheckSum: 0
81 Number: 3
82 - Name: '@feat.00'
83 Value: 1
84 SectionNumber: -1
85 SimpleType: IMAGE_SYM_TYPE_NULL
86 ComplexType: IMAGE_SYM_DTYPE_NULL
87 StorageClass: IMAGE_SYM_CLASS_STATIC
88 - Name: _DllMain
89 Value: 0
90 SectionNumber: 1
91 SimpleType: IMAGE_SYM_TYPE_NULL
92 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
93 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
94...
deps/lld/test/COFF/safeseh-diag-feat.test created+51
......@@ -0,0 +1,51 @@
1# RUN: sed s/FEAT_VALUE/1/ %s | yaml2obj > %t.obj
2# RUN: lld-link /out:%t.exe /subsystem:console /entry:main /safeseh %t.obj
3
4# RUN: sed s/FEAT_VALUE/0/ %s | yaml2obj > %t.obj
5# RUN: not lld-link /out:%t.exe /subsystem:console /entry:main \
6# RUN: /safeseh %t.obj >& %t.log
7# RUN: FileCheck %s < %t.log
8
9# CHECK: /safeseh: {{.*}} is not compatible with SEH
10
11--- !COFF
12header:
13 Machine: IMAGE_FILE_MACHINE_I386
14 Characteristics: [ ]
15sections:
16 - Name: .text
17 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
18 Alignment: 1
19 SectionData: 0000000000000000
20symbols:
21 - Name: '@comp.id'
22 Value: 14766605
23 SectionNumber: 65535
24 SimpleType: IMAGE_SYM_TYPE_NULL
25 ComplexType: IMAGE_SYM_DTYPE_NULL
26 StorageClass: IMAGE_SYM_CLASS_STATIC
27 - Name: '@feat.00'
28 Value: FEAT_VALUE
29 SectionNumber: 65535
30 SimpleType: IMAGE_SYM_TYPE_NULL
31 ComplexType: IMAGE_SYM_DTYPE_NULL
32 StorageClass: IMAGE_SYM_CLASS_STATIC
33 - Name: .text
34 Value: 0
35 SectionNumber: 1
36 SimpleType: IMAGE_SYM_TYPE_NULL
37 ComplexType: IMAGE_SYM_DTYPE_NULL
38 StorageClass: IMAGE_SYM_CLASS_STATIC
39 SectionDefinition:
40 Length: 8
41 NumberOfRelocations: 0
42 NumberOfLinenumbers: 0
43 CheckSum: 0
44 Number: 0
45 - Name: _main
46 Value: 0
47 SectionNumber: 1
48 SimpleType: IMAGE_SYM_TYPE_NULL
49 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
50 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
51...
deps/lld/test/COFF/safeseh.s created+60
......@@ -0,0 +1,60 @@
1# RUN: llvm-mc -triple i686-windows-msvc %s -filetype=obj -o %t.obj
2# RUN: lld-link %t.obj -safeseh -out:%t.exe -opt:noref -entry:main
3# RUN: llvm-readobj -coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK-NOGC
4# RUN: lld-link %t.obj -safeseh -out:%t.exe -opt:ref -entry:main
5# RUN: llvm-readobj -coff-load-config %t.exe | FileCheck %s --check-prefix=CHECK-GC
6
7# CHECK-NOGC: LoadConfig [
8# CHECK-NOGC: Size: 0x48
9# CHECK-NOGC: SEHandlerTable: 0x401048
10# CHECK-NOGC: SEHandlerCount: 1
11# CHECK-NOGC: ]
12# CHECK-NOGC: SEHTable [
13# CHECK-NOGC-NEXT: 0x402006
14# CHECK-NOGC-NEXT: ]
15
16# CHECK-GC: LoadConfig [
17# CHECK-GC: Size: 0x48
18# CHECK-GC: SEHandlerTable: 0x0
19# CHECK-GC: SEHandlerCount: 0
20# CHECK-GC: ]
21# CHECK-GC-NOT: SEHTable
22
23
24 .def @feat.00;
25 .scl 3;
26 .type 0;
27 .endef
28 .globl @feat.00
29@feat.00 = 1
30
31 .def _main;
32 .scl 2;
33 .type 32;
34 .endef
35 .section .text,"xr",one_only,_main
36 .globl _main
37_main:
38 movl $42, %eax
39 ret
40
41# This handler can be GCd, which will make the safeseh table empty, so it should
42# appear null.
43 .def _my_handler;
44 .scl 3;
45 .type 32;
46 .endef
47 .section .text,"xr",one_only,_my_handler
48_my_handler:
49 ret
50
51.safeseh _my_handler
52
53
54 .section .rdata,"dr"
55.globl __load_config_used
56__load_config_used:
57 .long 72
58 .fill 60, 1, 0
59 .long ___safe_se_handler_table
60 .long ___safe_se_handler_count
deps/lld/test/COFF/savetemps.ll created+29
......@@ -0,0 +1,29 @@
1; REQUIRES: x86
2; RUN: rm -fr %T/savetemps
3; RUN: mkdir %T/savetemps
4; RUN: llvm-as -o %T/savetemps/savetemps.obj %s
5; RUN: lld-link /out:%T/savetemps/savetemps.exe /entry:main \
6; RUN: /subsystem:console %T/savetemps/savetemps.obj
7; RUN: not llvm-dis -o - %T/savetemps/savetemps.exe.0.0.preopt.bc
8; RUN: not llvm-dis -o - %T/savetemps/savetemps.exe.0.2.internalize.bc
9; RUN: not llvm-dis -o - %T/savetemps/savetemps.exe.0.4.opt.bc
10; RUN: not llvm-dis -o - %T/savetemps/savetemps.exe.0.5.precodegen.bc
11; RUN: not llvm-objdump -s %T/savetemps/savetemps.exe.lto.obj
12; RUN: lld-link /lldsavetemps /out:%T/savetemps/savetemps.exe /entry:main \
13; RUN: /subsystem:console %T/savetemps/savetemps.obj
14; RUN: llvm-dis -o - %T/savetemps/savetemps.exe.0.0.preopt.bc | FileCheck %s
15; RUN: llvm-dis -o - %T/savetemps/savetemps.exe.0.2.internalize.bc | FileCheck %s
16; RUN: llvm-dis -o - %T/savetemps/savetemps.exe.0.4.opt.bc | FileCheck %s
17; RUN: llvm-dis -o - %T/savetemps/savetemps.exe.0.5.precodegen.bc | FileCheck %s
18; RUN: llvm-objdump -s %T/savetemps/savetemps.exe.lto.obj | \
19; RUN: FileCheck --check-prefix=CHECK-OBJDUMP %s
20
21; CHECK: define i32 @main()
22; CHECK-OBJDUMP: file format COFF
23
24target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
25target triple = "x86_64-pc-windows-msvc"
26
27define i32 @main() {
28 ret i32 0
29}
deps/lld/test/COFF/secidx-absolute.s created+33
......@@ -0,0 +1,33 @@
1# RUN: llvm-mc %s -filetype=obj -triple=x86_64-windows-msvc -o %t.obj
2# RUN: lld-link -entry:main -nodefaultlib %t.obj -out:%t.exe
3# RUN: llvm-readobj %t.exe -sections -section-data | FileCheck %s
4
5# Section relocations against absolute symbols resolve to the last real ouput
6# section index plus one.
7
8.text
9.global main
10main:
11ret
12
13.section .rdata,"dr"
14.secidx __guard_fids_table
15
16# CHECK: Sections [
17# CHECK: Section {
18# CHECK: Number: 1
19# CHECK: Name: .rdata (2E 72 64 61 74 61 00 00)
20# CHECK: SectionData (
21# CHECK: 0000: 0300 |..|
22# CHECK: )
23# CHECK: }
24# CHECK: Section {
25# CHECK: Number: 2
26# CHECK: Name: .text (2E 74 65 78 74 00 00 00)
27# CHECK: VirtualSize: 0x1
28# CHECK: SectionData (
29# CHECK: 0000: C3 |.|
30# CHECK: )
31# CHECK: }
32# CHECK-NOT: Section
33# CHECK: ]
deps/lld/test/COFF/secrel-absolute.s created+14
......@@ -0,0 +1,14 @@
1# RUN: llvm-mc %s -filetype=obj -triple=x86_64-windows-msvc -o %t.obj
2# RUN: not lld-link -entry:main -nodefaultlib %t.obj -out:%t.exe 2>&1 | FileCheck %s
3
4# secrel relocations against absolute symbols are errors.
5
6# CHECK: SECREL relocation cannot be applied to absolute symbols
7
8.text
9.global main
10main:
11ret
12
13.section .rdata,"dr"
14.secrel32 __guard_fids_table
deps/lld/test/COFF/secrel-common.s created+41
......@@ -0,0 +1,41 @@
1# RUN: llvm-mc %s -filetype=obj -triple=x86_64-windows-msvc -o %t.obj
2# RUN: lld-link -entry:main -nodefaultlib %t.obj -out:%t.exe
3# RUN: llvm-readobj %t.exe -sections -section-data | FileCheck %s
4
5# Section relocations against common symbols resolve to .bss.
6
7# CHECK: Sections [
8# CHECK: Section {
9# CHECK: Number: 1
10# CHECK: Name: .bss (2E 62 73 73 00 00 00 00)
11# CHECK: VirtualSize: 0x4
12# CHECK: }
13# CHECK: Section {
14# CHECK: Number: 2
15# CHECK: Name: .rdata (2E 72 64 61 74 61 00 00)
16# CHECK: SectionData (
17# CHECK: 0000: 00000000 01000000 |........|
18# CHECK: )
19# CHECK: }
20# CHECK: Section {
21# CHECK: Number: 3
22# CHECK: Name: .text (2E 74 65 78 74 00 00 00)
23# CHECK: VirtualSize: 0x1
24# CHECK: SectionData (
25# CHECK: 0000: C3 |.|
26# CHECK: )
27# CHECK: }
28# CHECK-NOT: Section
29# CHECK: ]
30
31.text
32.global main
33main:
34ret
35
36.comm common_global,4,2
37
38.section .rdata,"dr"
39.secrel32 common_global
40.secidx common_global
41.short 0
deps/lld/test/COFF/section.test created+62
......@@ -0,0 +1,62 @@
1# RUN: yaml2obj < %s > %t.obj
2# RUN: lld-link /out:%t.exe /entry:main /subsystem:console /force \
3# RUN: /section:.foo,r %t.obj
4# RUN: llvm-readobj -sections %t.exe | FileCheck -check-prefix=R %s
5
6# RUN: lld-link /out:%t.exe /entry:main /subsystem:console /force \
7# RUN: /section:.foo,w %t.obj
8# RUN: llvm-readobj -sections %t.exe | FileCheck -check-prefix=W %s
9
10# RUN: lld-link /out:%t.exe /entry:main /subsystem:console /force \
11# RUN: /section:.foo,e %t.obj
12# RUN: llvm-readobj -sections %t.exe | FileCheck -check-prefix=E %s
13
14# RUN: lld-link /out:%t.exe /entry:main /subsystem:console /force \
15# RUN: /section:.foo,s %t.obj
16# RUN: llvm-readobj -sections %t.exe | FileCheck -check-prefix=S %s
17
18# R: Characteristics [
19# R-NEXT: IMAGE_SCN_MEM_READ
20# R-NEXT: ]
21
22# W: Characteristics [
23# W-NEXT: IMAGE_SCN_MEM_WRITE
24# W-NEXT: ]
25
26# E: Characteristics [
27# E-NEXT: IMAGE_SCN_MEM_EXECUTE
28# E-NEXT: ]
29
30# S: Characteristics [
31# S-NEXT: IMAGE_SCN_MEM_SHARED
32# S-NEXT: ]
33
34--- !COFF
35header:
36 Machine: IMAGE_FILE_MACHINE_AMD64
37 Characteristics: []
38sections:
39 - Name: .foo
40 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
41 Alignment: 4
42 SectionData: 000000000000
43symbols:
44 - Name: .foo
45 Value: 0
46 SectionNumber: 1
47 SimpleType: IMAGE_SYM_TYPE_NULL
48 ComplexType: IMAGE_SYM_DTYPE_NULL
49 StorageClass: IMAGE_SYM_CLASS_STATIC
50 SectionDefinition:
51 Length: 6
52 NumberOfRelocations: 0
53 NumberOfLinenumbers: 0
54 CheckSum: 0
55 Number: 0
56 - Name: main
57 Value: 0
58 SectionNumber: 1
59 SimpleType: IMAGE_SYM_TYPE_NULL
60 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
61 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
62...
deps/lld/test/COFF/seh.test created+70
......@@ -0,0 +1,70 @@
1# RUN: yaml2obj < %s > %t.obj
2# RUN: lld-link /out:%t.exe /subsystem:console /entry:main %t.obj
3# RUN: llvm-objdump -s %t.exe | FileCheck %s
4
5# CHECK: Contents of section .rdata:
6# CHECK: 1000 00200000 02200000
7
8--- !COFF
9header:
10 Machine: IMAGE_FILE_MACHINE_I386
11 Characteristics: [ ]
12sections:
13 - Name: .text
14 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
15 Alignment: 1
16 SectionData: 0000000000000000
17 - Name: .sxdata
18 Characteristics: [ IMAGE_SCN_LNK_INFO ]
19 Alignment: 4
20 SectionData: 0600000007000000
21symbols:
22 - Name: '@comp.id'
23 Value: 14766605
24 SectionNumber: 65535
25 SimpleType: IMAGE_SYM_TYPE_NULL
26 ComplexType: IMAGE_SYM_DTYPE_NULL
27 StorageClass: IMAGE_SYM_CLASS_STATIC
28 - Name: '@feat.00'
29 Value: 2147484049
30 SectionNumber: 65535
31 SimpleType: IMAGE_SYM_TYPE_NULL
32 ComplexType: IMAGE_SYM_DTYPE_NULL
33 StorageClass: IMAGE_SYM_CLASS_STATIC
34 - Name: .text
35 Value: 0
36 SectionNumber: 1
37 SimpleType: IMAGE_SYM_TYPE_NULL
38 ComplexType: IMAGE_SYM_DTYPE_NULL
39 StorageClass: IMAGE_SYM_CLASS_STATIC
40 SectionDefinition:
41 Length: 8
42 NumberOfRelocations: 0
43 NumberOfLinenumbers: 0
44 CheckSum: 0
45 Number: 0
46 - Name: .sxdata
47 Value: 0
48 SectionNumber: 2
49 SimpleType: IMAGE_SYM_TYPE_NULL
50 ComplexType: IMAGE_SYM_DTYPE_NULL
51 StorageClass: IMAGE_SYM_CLASS_STATIC
52 SectionDefinition:
53 Length: 8
54 NumberOfRelocations: 0
55 NumberOfLinenumbers: 0
56 CheckSum: 0
57 Number: 0
58 - Name: _main
59 Value: 0
60 SectionNumber: 1
61 SimpleType: IMAGE_SYM_TYPE_NULL
62 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
63 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
64 - Name: _foo
65 Value: 2
66 SectionNumber: 1
67 SimpleType: IMAGE_SYM_TYPE_NULL
68 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
69 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
70...
deps/lld/test/COFF/sort-debug.test created+335
......@@ -0,0 +1,335 @@
1# RUN: yaml2obj < %s > %t.obj
2# RUN: lld-link /debug /out:%t.exe /entry:main %t.obj
3# RUN: llvm-readobj -sections %t.exe | FileCheck %s
4
5# CHECK: Name: .text
6# CHECK: Name: .debug_abbrev
7# CHECK: Name: .debug_info
8# CHECK: Name: .debug_line
9# CHECK: Name: .debug_pubnames
10# CHECK: Name: .debug_pubtypes
11# CHECK: Name: .reloc
12
13
14--- !COFF
15header:
16 Machine: IMAGE_FILE_MACHINE_I386
17 Characteristics: [ ]
18sections:
19 - Name: .text
20 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
21 Alignment: 16
22 SectionData: 508D0500000000C70424000000005AC3
23 Relocations:
24 - VirtualAddress: 3
25 SymbolName: '?x@@3HA'
26 Type: IMAGE_REL_I386_DIR32
27 - Name: .data
28 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
29 Alignment: 4
30 SectionData: ''
31 - Name: .bss
32 Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
33 Alignment: 4
34 SectionData: ''
35 - Name: '.debug$S'
36 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
37 Alignment: 1
38 Subsections:
39 - !Symbols
40 Records:
41 - Kind: S_GPROC32_ID
42 ProcSym:
43 PtrParent: 0
44 PtrEnd: 0
45 PtrNext: 0
46 CodeSize: 16
47 DbgStart: 0
48 DbgEnd: 0
49 FunctionType: 0
50 Segment: 0
51 Flags: [ ]
52 DisplayName: main
53 - Kind: S_PROC_ID_END
54 ScopeEndSym:
55 - !Lines
56 CodeSize: 16
57 Flags: [ HasColumnInfo ]
58 RelocOffset: 0
59 RelocSegment: 0
60 Blocks:
61 - FileName: '\usr\local\google\home\majnemer\llvm\src\tools\lld\<stdin>'
62 Lines:
63 - Offset: 0
64 LineStart: 1
65 IsStatement: false
66 EndDelta: 0
67 Columns:
68 - StartColumn: 0
69 EndColumn: 0
70 - !FileChecksums
71 Checksums:
72 - FileName: '\usr\local\google\home\majnemer\llvm\src\tools\lld\<stdin>'
73 Kind: None
74 Checksum: ''
75 - !StringTable
76 Strings:
77 - '\usr\local\google\home\majnemer\llvm\src\tools\lld\<stdin>'
78 Relocations:
79 - VirtualAddress: 44
80 SymbolName: _main
81 Type: IMAGE_REL_I386_SECREL
82 - VirtualAddress: 48
83 SymbolName: _main
84 Type: IMAGE_REL_I386_SECTION
85 - VirtualAddress: 68
86 SymbolName: _main
87 Type: IMAGE_REL_I386_SECREL
88 - VirtualAddress: 72
89 SymbolName: _main
90 Type: IMAGE_REL_I386_SECTION
91 - Name: .debug_str
92 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
93 Alignment: 1
94 SectionData: ''
95 - Name: .debug_loc
96 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
97 Alignment: 1
98 SectionData: ''
99 - Name: .debug_abbrev
100 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
101 Alignment: 1
102 SectionData: 011101250E1305030E10171B0E110112060000023400030E49133F193A0B3B0B02186E0E0000032400030E3E0B0B0B0000042E0011011206E77F194018030E3A0B3B0B49133F19000000
103 - Name: .debug_info
104 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
105 Alignment: 1
106 SectionData: 54000000040000000000040100000000040037000000000000003F000000000000001000000002720000003B0000000101050300000000780000000374000000050404000000001000000001548000000001013B00000000
107 Relocations:
108 - VirtualAddress: 6
109 SymbolName: .debug_abbrev
110 Type: IMAGE_REL_I386_SECREL
111 - VirtualAddress: 12
112 SymbolName: .debug_str
113 Type: IMAGE_REL_I386_SECREL
114 - VirtualAddress: 18
115 SymbolName: .debug_str
116 Type: IMAGE_REL_I386_SECREL
117 - VirtualAddress: 22
118 SymbolName: .debug_line
119 Type: IMAGE_REL_I386_SECREL
120 - VirtualAddress: 26
121 SymbolName: .debug_str
122 Type: IMAGE_REL_I386_SECREL
123 - VirtualAddress: 30
124 SymbolName: .text
125 Type: IMAGE_REL_I386_DIR32
126 - VirtualAddress: 39
127 SymbolName: .debug_str
128 Type: IMAGE_REL_I386_SECREL
129 - VirtualAddress: 51
130 SymbolName: '?x@@3HA'
131 Type: IMAGE_REL_I386_DIR32
132 - VirtualAddress: 55
133 SymbolName: .debug_str
134 Type: IMAGE_REL_I386_SECREL
135 - VirtualAddress: 60
136 SymbolName: .debug_str
137 Type: IMAGE_REL_I386_SECREL
138 - VirtualAddress: 67
139 SymbolName: .text
140 Type: IMAGE_REL_I386_DIR32
141 - VirtualAddress: 77
142 SymbolName: .debug_str
143 Type: IMAGE_REL_I386_SECREL
144 - Name: .debug_ranges
145 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
146 Alignment: 1
147 SectionData: ''
148 - Name: .debug_pubnames
149 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
150 Alignment: 1
151 SectionData: 1D00000002000000000058000000420000006D61696E0026000000780000000000
152 Relocations:
153 - VirtualAddress: 6
154 SymbolName: .debug_info
155 Type: IMAGE_REL_I386_SECREL
156 - Name: .debug_pubtypes
157 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
158 Alignment: 1
159 SectionData: 16000000020000000000580000003B000000696E740000000000
160 Relocations:
161 - VirtualAddress: 6
162 SymbolName: .debug_info
163 Type: IMAGE_REL_I386_SECREL
164 - Name: .debug_line
165 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE, IMAGE_SCN_MEM_READ ]
166 Alignment: 1
167 SectionData: 3300000002001E0000000101FB0E0D000101010100000001000001003C737464696E3E000000000000050200000000010AD60202000101
168 Relocations:
169 - VirtualAddress: 43
170 SymbolName: .text
171 Type: IMAGE_REL_I386_DIR32
172symbols:
173 - Name: .text
174 Value: 0
175 SectionNumber: 1
176 SimpleType: IMAGE_SYM_TYPE_NULL
177 ComplexType: IMAGE_SYM_DTYPE_NULL
178 StorageClass: IMAGE_SYM_CLASS_STATIC
179 SectionDefinition:
180 Length: 16
181 NumberOfRelocations: 1
182 NumberOfLinenumbers: 0
183 CheckSum: 0
184 Number: 1
185 - Name: .data
186 Value: 0
187 SectionNumber: 2
188 SimpleType: IMAGE_SYM_TYPE_NULL
189 ComplexType: IMAGE_SYM_DTYPE_NULL
190 StorageClass: IMAGE_SYM_CLASS_STATIC
191 SectionDefinition:
192 Length: 0
193 NumberOfRelocations: 0
194 NumberOfLinenumbers: 0
195 CheckSum: 0
196 Number: 2
197 - Name: .bss
198 Value: 0
199 SectionNumber: 3
200 SimpleType: IMAGE_SYM_TYPE_NULL
201 ComplexType: IMAGE_SYM_DTYPE_NULL
202 StorageClass: IMAGE_SYM_CLASS_STATIC
203 SectionDefinition:
204 Length: 4
205 NumberOfRelocations: 0
206 NumberOfLinenumbers: 0
207 CheckSum: 0
208 Number: 3
209 - Name: '.debug$S'
210 Value: 0
211 SectionNumber: 4
212 SimpleType: IMAGE_SYM_TYPE_NULL
213 ComplexType: IMAGE_SYM_DTYPE_NULL
214 StorageClass: IMAGE_SYM_CLASS_STATIC
215 SectionDefinition:
216 Length: 188
217 NumberOfRelocations: 4
218 NumberOfLinenumbers: 0
219 CheckSum: 0
220 Number: 4
221 - Name: .debug_str
222 Value: 0
223 SectionNumber: 5
224 SimpleType: IMAGE_SYM_TYPE_NULL
225 ComplexType: IMAGE_SYM_DTYPE_NULL
226 StorageClass: IMAGE_SYM_CLASS_STATIC
227 SectionDefinition:
228 Length: 133
229 NumberOfRelocations: 0
230 NumberOfLinenumbers: 0
231 CheckSum: 0
232 Number: 5
233 - Name: .debug_loc
234 Value: 0
235 SectionNumber: 6
236 SimpleType: IMAGE_SYM_TYPE_NULL
237 ComplexType: IMAGE_SYM_DTYPE_NULL
238 StorageClass: IMAGE_SYM_CLASS_STATIC
239 SectionDefinition:
240 Length: 0
241 NumberOfRelocations: 0
242 NumberOfLinenumbers: 0
243 CheckSum: 0
244 Number: 6
245 - Name: .debug_abbrev
246 Value: 0
247 SectionNumber: 7
248 SimpleType: IMAGE_SYM_TYPE_NULL
249 ComplexType: IMAGE_SYM_DTYPE_NULL
250 StorageClass: IMAGE_SYM_CLASS_STATIC
251 SectionDefinition:
252 Length: 74
253 NumberOfRelocations: 0
254 NumberOfLinenumbers: 0
255 CheckSum: 0
256 Number: 7
257 - Name: .debug_info
258 Value: 0
259 SectionNumber: 8
260 SimpleType: IMAGE_SYM_TYPE_NULL
261 ComplexType: IMAGE_SYM_DTYPE_NULL
262 StorageClass: IMAGE_SYM_CLASS_STATIC
263 SectionDefinition:
264 Length: 88
265 NumberOfRelocations: 12
266 NumberOfLinenumbers: 0
267 CheckSum: 0
268 Number: 8
269 - Name: .debug_ranges
270 Value: 0
271 SectionNumber: 9
272 SimpleType: IMAGE_SYM_TYPE_NULL
273 ComplexType: IMAGE_SYM_DTYPE_NULL
274 StorageClass: IMAGE_SYM_CLASS_STATIC
275 SectionDefinition:
276 Length: 0
277 NumberOfRelocations: 0
278 NumberOfLinenumbers: 0
279 CheckSum: 0
280 Number: 9
281 - Name: .debug_pubnames
282 Value: 0
283 SectionNumber: 10
284 SimpleType: IMAGE_SYM_TYPE_NULL
285 ComplexType: IMAGE_SYM_DTYPE_NULL
286 StorageClass: IMAGE_SYM_CLASS_STATIC
287 SectionDefinition:
288 Length: 33
289 NumberOfRelocations: 1
290 NumberOfLinenumbers: 0
291 CheckSum: 0
292 Number: 10
293 - Name: .debug_pubtypes
294 Value: 0
295 SectionNumber: 11
296 SimpleType: IMAGE_SYM_TYPE_NULL
297 ComplexType: IMAGE_SYM_DTYPE_NULL
298 StorageClass: IMAGE_SYM_CLASS_STATIC
299 SectionDefinition:
300 Length: 26
301 NumberOfRelocations: 1
302 NumberOfLinenumbers: 0
303 CheckSum: 0
304 Number: 11
305 - Name: .debug_line
306 Value: 0
307 SectionNumber: 12
308 SimpleType: IMAGE_SYM_TYPE_NULL
309 ComplexType: IMAGE_SYM_DTYPE_NULL
310 StorageClass: IMAGE_SYM_CLASS_STATIC
311 SectionDefinition:
312 Length: 55
313 NumberOfRelocations: 1
314 NumberOfLinenumbers: 0
315 CheckSum: 0
316 Number: 12
317 - Name: '@feat.00'
318 Value: 1
319 SectionNumber: -1
320 SimpleType: IMAGE_SYM_TYPE_NULL
321 ComplexType: IMAGE_SYM_DTYPE_NULL
322 StorageClass: IMAGE_SYM_CLASS_STATIC
323 - Name: _main
324 Value: 0
325 SectionNumber: 1
326 SimpleType: IMAGE_SYM_TYPE_NULL
327 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
328 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
329 - Name: '?x@@3HA'
330 Value: 0
331 SectionNumber: 3
332 SimpleType: IMAGE_SYM_TYPE_NULL
333 ComplexType: IMAGE_SYM_DTYPE_NULL
334 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
335...
deps/lld/test/COFF/stack.test created+25
......@@ -0,0 +1,25 @@
1# RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj
2
3# RUN: lld-link /out:%t.exe /entry:main %t.obj
4# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=DEFAULT %s
5
6DEFAULT: SizeOfStackReserve: 1048576
7DEFAULT: SizeOfStackCommit: 4096
8
9# RUN: lld-link /out:%t.exe /entry:main %t.obj /stack:0x3000
10# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK1 %s
11# RUN: echo "STACKSIZE 12288" > %t.def
12# RUN: lld-link /out:%t.exe /entry:main /def:%t.def %t.obj
13# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK1 %s
14
15CHECK1: SizeOfStackReserve: 12288
16CHECK1: SizeOfStackCommit: 4096
17
18# RUN: lld-link /out:%t.exe /entry:main %t.obj /stack:0x5000,0x3000
19# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK2 %s
20# RUN: echo "STACKSIZE 20480,12288" > %t.def
21# RUN: lld-link /out:%t.exe /entry:main /def:%t.def %t.obj
22# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK2 %s
23
24CHECK2: SizeOfStackReserve: 20480
25CHECK2: SizeOfStackCommit: 12288
deps/lld/test/COFF/subsystem-inference.test created+74
......@@ -0,0 +1,74 @@
1# RUN: sed -e s/ENTRYNAME/main/ %s | yaml2obj > %t.obj
2# RUN: lld-link /out:%t.exe %t.obj
3# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=MAIN %s
4
5# RUN: sed s/ENTRYNAME/wmain/ %s | yaml2obj > %t.obj
6# RUN: lld-link /out:%t.exe %t.obj
7# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=WMAIN %s
8
9# RUN: sed s/ENTRYNAME/WinMain/ %s | yaml2obj > %t.obj
10# RUN: lld-link /out:%t.exe %t.obj
11# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=WINMAIN %s
12
13# RUN: sed s/ENTRYNAME/wWinMain/ %s | yaml2obj > %t.obj
14# RUN: lld-link /out:%t.exe %t.obj
15# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=WWINMAIN %s
16
17# MAIN: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI
18# WMAIN: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI
19# WINMAIN: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_GUI
20# WWINMAIN: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_GUI
21
22--- !COFF
23header:
24 Machine: IMAGE_FILE_MACHINE_AMD64
25 Characteristics: []
26sections:
27 - Name: .text
28 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
29 Alignment: 4
30 SectionData: B82A000000C3
31symbols:
32 - Name: .text
33 Value: 0
34 SectionNumber: 1
35 SimpleType: IMAGE_SYM_TYPE_NULL
36 ComplexType: IMAGE_SYM_DTYPE_NULL
37 StorageClass: IMAGE_SYM_CLASS_STATIC
38 SectionDefinition:
39 Length: 6
40 NumberOfRelocations: 0
41 NumberOfLinenumbers: 0
42 CheckSum: 0
43 Number: 0
44 - Name: ENTRYNAME
45 Value: 0
46 SectionNumber: 1
47 SimpleType: IMAGE_SYM_TYPE_NULL
48 ComplexType: IMAGE_SYM_DTYPE_NULL
49 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
50 - Name: mainCRTStartup
51 Value: 0
52 SectionNumber: 1
53 SimpleType: IMAGE_SYM_TYPE_NULL
54 ComplexType: IMAGE_SYM_DTYPE_NULL
55 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
56 - Name: wmainCRTStartup
57 Value: 0
58 SectionNumber: 1
59 SimpleType: IMAGE_SYM_TYPE_NULL
60 ComplexType: IMAGE_SYM_DTYPE_NULL
61 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
62 - Name: WinMainCRTStartup
63 Value: 0
64 SectionNumber: 1
65 SimpleType: IMAGE_SYM_TYPE_NULL
66 ComplexType: IMAGE_SYM_DTYPE_NULL
67 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
68 - Name: wWinMainCRTStartup
69 Value: 0
70 SectionNumber: 1
71 SimpleType: IMAGE_SYM_TYPE_NULL
72 ComplexType: IMAGE_SYM_DTYPE_NULL
73 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
74...
deps/lld/test/COFF/subsystem.test created+19
......@@ -0,0 +1,19 @@
1# RUN: lld-link /entry:main /out:%t.exe /subsystem:windows \
2# RUN: %p/Inputs/ret42.obj
3# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK1 %s
4
5CHECK1: MajorOperatingSystemVersion: 6
6CHECK1: MinorOperatingSystemVersion: 0
7CHECK1: MajorSubsystemVersion: 6
8CHECK1: MinorSubsystemVersion: 0
9CHECK1: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_GUI
10
11# RUN: lld-link /entry:main /out:%t.exe /subsystem:windows,8.9 \
12# RUN: %p/Inputs/ret42.obj
13# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK2 %s
14
15CHECK2: MajorOperatingSystemVersion: 8
16CHECK2: MinorOperatingSystemVersion: 9
17CHECK2: MajorSubsystemVersion: 8
18CHECK2: MinorSubsystemVersion: 9
19CHECK2: Subsystem: IMAGE_SUBSYSTEM_WINDOWS_GUI
deps/lld/test/COFF/symtab.test created+236
......@@ -0,0 +1,236 @@
1# RUN: yaml2obj < %s > %t.obj
2# RUN: lld-link /debug /out:%t.exe /entry:main %t.obj %p/Inputs/std64.lib
3# RUN: llvm-readobj -symbols %t.exe | FileCheck %s
4# RUN: lld-link /debug /opt:noref /out:%t.exe /entry:main %t.obj %p/Inputs/std64.lib
5# RUN: llvm-readobj -symbols %t.exe | FileCheck %s
6
7# RUN: lld-link /debug /nosymtab /out:%t.exe /entry:main %t.obj %p/Inputs/std64.lib
8# RUN: llvm-readobj -symbols %t.exe | FileCheck -check-prefix=NO %s
9
10# CHECK: Symbols [
11# CHECK-NEXT: Symbol {
12# CHECK-NEXT: Name: .text
13# CHECK-NEXT: Value: 0
14# CHECK-NEXT: Section: .text (2)
15# CHECK-NEXT: BaseType: Null (0x0)
16# CHECK-NEXT: ComplexType: Null (0x0)
17# CHECK-NEXT: StorageClass: Static (0x3)
18# CHECK-NEXT: AuxSymbolCount: 0
19# CHECK-NEXT: }
20# CHECK-NEXT: Symbol {
21# CHECK-NEXT: Name: .text2
22# CHECK-NEXT: Value: 0
23# CHECK-NEXT: Section: .text (2)
24# CHECK-NEXT: BaseType: Null (0x0)
25# CHECK-NEXT: ComplexType: Null (0x0)
26# CHECK-NEXT: StorageClass: Static (0x3)
27# CHECK-NEXT: AuxSymbolCount: 0
28# CHECK-NEXT: }
29# CHECK-NEXT: Symbol {
30# CHECK-NEXT: Name: .data
31# CHECK-NEXT: Value: 0
32# CHECK-NEXT: Section: .data (1)
33# CHECK-NEXT: BaseType: Null (0x0)
34# CHECK-NEXT: ComplexType: Null (0x0)
35# CHECK-NEXT: StorageClass: Static (0x3)
36# CHECK-NEXT: AuxSymbolCount: 0
37# CHECK-NEXT: }
38# CHECK-NEXT: Symbol {
39# CHECK-NEXT: Name: MessageBoxA
40# CHECK-NEXT: Value: 80
41# CHECK-NEXT: Section: .text (2)
42# CHECK-NEXT: BaseType: Null (0x0)
43# CHECK-NEXT: ComplexType: Null (0x0)
44# CHECK-NEXT: StorageClass: External (0x2)
45# CHECK-NEXT: AuxSymbolCount: 0
46# CHECK-NEXT: }
47# CHECK-NEXT: Symbol {
48# CHECK-NEXT: Name: ExitProcess
49# CHECK-NEXT: Value: 64
50# CHECK-NEXT: Section: .text (2)
51# CHECK-NEXT: BaseType: Null (0x0)
52# CHECK-NEXT: ComplexType: Null (0x0)
53# CHECK-NEXT: StorageClass: External (0x2)
54# CHECK-NEXT: AuxSymbolCount: 0
55# CHECK-NEXT: }
56# CHECK-NEXT: Symbol {
57# CHECK-NEXT: Name: message
58# CHECK-NEXT: Value: 6
59# CHECK-NEXT: Section: .text2 (3)
60# CHECK-NEXT: BaseType: Null (0x0)
61# CHECK-NEXT: ComplexType: Null (0x0)
62# CHECK-NEXT: StorageClass: Static (0x3)
63# CHECK-NEXT: AuxSymbolCount: 0
64# CHECK-NEXT: }
65# CHECK-NEXT: Symbol {
66# CHECK-NEXT: Name: main
67# CHECK-NEXT: Value: 0
68# CHECK-NEXT: Section: .text (2)
69# CHECK-NEXT: BaseType: Null (0x0)
70# CHECK-NEXT: ComplexType: Null (0x0)
71# CHECK-NEXT: StorageClass: External (0x2)
72# CHECK-NEXT: AuxSymbolCount: 0
73# CHECK-NEXT: }
74# CHECK-NEXT: Symbol {
75# CHECK-NEXT: Name: caption
76# CHECK-NEXT: Value: 0
77# CHECK-NEXT: Section: .text2 (3)
78# CHECK-NEXT: BaseType: Null (0x0)
79# CHECK-NEXT: ComplexType: Null (0x0)
80# CHECK-NEXT: StorageClass: Static (0x3)
81# CHECK-NEXT: AuxSymbolCount: 0
82# CHECK-NEXT: }
83# CHECK-NEXT: Symbol {
84# CHECK-NEXT: Name: abs_symbol
85# CHECK-NEXT: Value: 2662186735
86# CHECK-NEXT: Section: IMAGE_SYM_ABSOLUTE (-1)
87# CHECK-NEXT: BaseType: Null (0x0)
88# CHECK-NEXT: ComplexType: Null (0x0)
89# CHECK-NEXT: StorageClass: External (0x2)
90# CHECK-NEXT: AuxSymbolCount: 0
91# CHECK-NEXT: }
92# CHECK-NEXT: ]
93
94# NO: Symbols [
95
96--- !COFF
97header:
98 Machine: IMAGE_FILE_MACHINE_AMD64
99 Characteristics: []
100sections:
101 - Name: .text
102 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
103 Alignment: 4096
104 SectionData: B800000000000000005068000000000000000068000000000000000050E8000000000000000050E8000000000000000050E80000000000000000
105 Relocations:
106 - VirtualAddress: 0
107 SymbolName: abs_symbol
108 Type: IMAGE_REL_AMD64_ADDR64
109 - VirtualAddress: 7
110 SymbolName: caption
111 Type: IMAGE_REL_AMD64_ADDR64
112 - VirtualAddress: 12
113 SymbolName: message
114 Type: IMAGE_REL_AMD64_ADDR64
115 - VirtualAddress: 18
116 SymbolName: MessageBoxA
117 Type: IMAGE_REL_AMD64_REL32
118 - VirtualAddress: 24
119 SymbolName: ExitProcess
120 Type: IMAGE_REL_AMD64_REL32
121 - VirtualAddress: 30
122 SymbolName: __ImageBase
123 Type: IMAGE_REL_AMD64_ADDR64
124 - Name: .text2
125 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
126 Alignment: 4096
127 SectionData: B800000000000000005068000000000000000068000000000000000050E8000000000000000050E8000000000000000050E80000000000000000
128 Relocations:
129 - VirtualAddress: 0
130 SymbolName: abs_symbol
131 Type: IMAGE_REL_AMD64_ADDR64
132 - VirtualAddress: 7
133 SymbolName: caption
134 Type: IMAGE_REL_AMD64_ADDR64
135 - VirtualAddress: 12
136 SymbolName: message
137 Type: IMAGE_REL_AMD64_ADDR64
138 - VirtualAddress: 18
139 SymbolName: MessageBoxA
140 Type: IMAGE_REL_AMD64_REL32
141 - VirtualAddress: 24
142 SymbolName: ExitProcess
143 Type: IMAGE_REL_AMD64_REL32
144 - VirtualAddress: 30
145 SymbolName: __ImageBase
146 Type: IMAGE_REL_AMD64_ADDR64
147 - Name: .data
148 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
149 Alignment: 4
150 SectionData: 48656C6C6F0048656C6C6F20576F726C6400
151symbols:
152 - Name: "@comp.id"
153 Value: 10394907
154 SectionNumber: 65535
155 SimpleType: IMAGE_SYM_TYPE_NULL
156 ComplexType: IMAGE_SYM_DTYPE_NULL
157 StorageClass: IMAGE_SYM_CLASS_STATIC
158 - Name: .text
159 Value: 0
160 SectionNumber: 1
161 SimpleType: IMAGE_SYM_TYPE_NULL
162 ComplexType: IMAGE_SYM_DTYPE_NULL
163 StorageClass: IMAGE_SYM_CLASS_STATIC
164 SectionDefinition:
165 Length: 28
166 NumberOfRelocations: 6
167 NumberOfLinenumbers: 0
168 CheckSum: 0
169 Number: 0
170 - Name: .text2
171 Value: 0
172 SectionNumber: 1
173 SimpleType: IMAGE_SYM_TYPE_NULL
174 ComplexType: IMAGE_SYM_DTYPE_NULL
175 StorageClass: IMAGE_SYM_CLASS_STATIC
176 SectionDefinition:
177 Length: 28
178 NumberOfRelocations: 6
179 NumberOfLinenumbers: 0
180 CheckSum: 0
181 Number: 0
182 - Name: .data
183 Value: 0
184 SectionNumber: 3
185 SimpleType: IMAGE_SYM_TYPE_NULL
186 ComplexType: IMAGE_SYM_DTYPE_NULL
187 StorageClass: IMAGE_SYM_CLASS_STATIC
188 SectionDefinition:
189 Length: 18
190 NumberOfRelocations: 0
191 NumberOfLinenumbers: 0
192 CheckSum: 0
193 Number: 0
194 - Name: MessageBoxA
195 Value: 0
196 SectionNumber: 0
197 SimpleType: IMAGE_SYM_TYPE_NULL
198 ComplexType: IMAGE_SYM_DTYPE_NULL
199 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
200 - Name: ExitProcess
201 Value: 0
202 SectionNumber: 0
203 SimpleType: IMAGE_SYM_TYPE_NULL
204 ComplexType: IMAGE_SYM_DTYPE_NULL
205 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
206 - Name: message
207 Value: 6
208 SectionNumber: 2
209 SimpleType: IMAGE_SYM_TYPE_NULL
210 ComplexType: IMAGE_SYM_DTYPE_NULL
211 StorageClass: IMAGE_SYM_CLASS_STATIC
212 - Name: main
213 Value: 0
214 SectionNumber: 1
215 SimpleType: IMAGE_SYM_TYPE_NULL
216 ComplexType: IMAGE_SYM_DTYPE_NULL
217 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
218 - Name: caption
219 Value: 0
220 SectionNumber: 2
221 SimpleType: IMAGE_SYM_TYPE_NULL
222 ComplexType: IMAGE_SYM_DTYPE_NULL
223 StorageClass: IMAGE_SYM_CLASS_STATIC
224 - Name: abs_symbol
225 Value: 0xDEADBEEF
226 SectionNumber: -1
227 SimpleType: IMAGE_SYM_TYPE_NULL
228 ComplexType: IMAGE_SYM_DTYPE_NULL
229 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
230 - Name: __ImageBase
231 Value: 0
232 SectionNumber: 0
233 SimpleType: IMAGE_SYM_TYPE_NULL
234 ComplexType: IMAGE_SYM_DTYPE_NULL
235 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
236...
deps/lld/test/COFF/thinlto-archives.ll created+23
......@@ -0,0 +1,23 @@
1; REQUIRES: x86
2; RUN: rm -fr %T/thinlto-archives
3; RUN: mkdir %T/thinlto-archives %T/thinlto-archives/a %T/thinlto-archives/b
4; RUN: opt -thinlto-bc -o %T/thinlto-archives/main.obj %s
5; RUN: opt -thinlto-bc -o %T/thinlto-archives/a/bar.obj %S/Inputs/lto-dep.ll
6; RUN: opt -thinlto-bc -o %T/thinlto-archives/b/bar.obj %S/Inputs/bar.ll
7; RUN: llvm-ar crs %T/thinlto-archives/a.lib %T/thinlto-archives/a/bar.obj
8; RUN: llvm-ar crs %T/thinlto-archives/b.lib %T/thinlto-archives/b/bar.obj
9; RUN: lld-link /out:%T/thinlto-archives/main.exe -entry:main \
10; RUN: -subsystem:console %T/thinlto-archives/main.obj \
11; RUN: %T/thinlto-archives/a.lib %T/thinlto-archives/b.lib
12
13target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
14target triple = "x86_64-pc-windows-msvc"
15
16declare void @bar()
17declare void @foo()
18
19define i32 @main() {
20 call void @foo()
21 call void @bar()
22 ret i32 0
23}
deps/lld/test/COFF/thinlto-mangled.ll created+17
......@@ -0,0 +1,17 @@
1; REQUIRES: x86
2; RUN: opt -thinlto-bc %s -o %t.obj
3; RUN: opt -thinlto-bc %S/Inputs/thinlto-mangled-qux.ll -o %T/thinlto-mangled-qux.obj
4; RUN: lld-link -out:%t.exe -entry:main %t.obj %T/thinlto-mangled-qux.obj
5
6target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
7target triple = "x86_64-pc-windows-msvc19.0.24215"
8
9%"class.bar" = type { i32 (...)**, i8*, i8*, i8*, i32 }
10
11define i32 @main() {
12 ret i32 0
13}
14
15define available_externally zeroext i1 @"\01?x@bar@@UEBA_NXZ"(%"class.bar"* %this) unnamed_addr align 2 {
16 ret i1 false
17}
deps/lld/test/COFF/thinlto.ll created+19
......@@ -0,0 +1,19 @@
1; REQUIRES: x86
2; RUN: rm -fr %T/thinlto
3; RUN: mkdir %T/thinlto
4; RUN: opt -thinlto-bc -o %T/thinlto/main.obj %s
5; RUN: opt -thinlto-bc -o %T/thinlto/foo.obj %S/Inputs/lto-dep.ll
6; RUN: lld-link /lldsavetemps /out:%T/thinlto/main.exe /entry:main /subsystem:console %T/thinlto/main.obj %T/thinlto/foo.obj
7; RUN: llvm-nm %T/thinlto/main.exe.lto.obj | FileCheck %s
8
9; CHECK-NOT: U foo
10
11target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
12target triple = "x86_64-pc-windows-msvc"
13
14define i32 @main() {
15 call void @foo()
16 ret i32 0
17}
18
19declare void @foo()
deps/lld/test/COFF/tls.test created+43
......@@ -0,0 +1,43 @@
1# RUN: yaml2obj < %s > %t.obj
2# RUN: lld-link /out:%t.exe /entry:main %t.obj
3# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
4
5# CHECK: TLSTableRVA: 0x1000
6# CHECK: TLSTableSize: 0x28
7
8--- !COFF
9header:
10 Machine: IMAGE_FILE_MACHINE_AMD64
11 Characteristics: []
12sections:
13 - Name: .text
14 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
15 Alignment: 4
16 SectionData: 00000000
17symbols:
18 - Name: .text
19 Value: 0
20 SectionNumber: 1
21 SimpleType: IMAGE_SYM_TYPE_NULL
22 ComplexType: IMAGE_SYM_DTYPE_NULL
23 StorageClass: IMAGE_SYM_CLASS_STATIC
24 SectionDefinition:
25 Length: 4
26 NumberOfRelocations: 0
27 NumberOfLinenumbers: 0
28 CheckSum: 0
29 Number: 0
30 Selection: IMAGE_COMDAT_SELECT_ANY
31 - Name: main
32 Value: 0
33 SectionNumber: 1
34 SimpleType: IMAGE_SYM_TYPE_NULL
35 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
36 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
37 - Name: _tls_used
38 Value: 0
39 SectionNumber: 1
40 SimpleType: IMAGE_SYM_TYPE_NULL
41 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
42 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
43...
deps/lld/test/COFF/tls32.test created+43
......@@ -0,0 +1,43 @@
1# RUN: yaml2obj < %s > %t.obj
2# RUN: lld-link /out:%t.exe /entry:main %t.obj
3# RUN: llvm-readobj -file-headers %t.exe | FileCheck %s
4
5# CHECK: TLSTableRVA: 0x1000
6# CHECK: TLSTableSize: 0x18
7
8--- !COFF
9header:
10 Machine: IMAGE_FILE_MACHINE_I386
11 Characteristics: []
12sections:
13 - Name: .text
14 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
15 Alignment: 4
16 SectionData: 00000000
17symbols:
18 - Name: .text
19 Value: 0
20 SectionNumber: 1
21 SimpleType: IMAGE_SYM_TYPE_NULL
22 ComplexType: IMAGE_SYM_DTYPE_NULL
23 StorageClass: IMAGE_SYM_CLASS_STATIC
24 SectionDefinition:
25 Length: 4
26 NumberOfRelocations: 0
27 NumberOfLinenumbers: 0
28 CheckSum: 0
29 Number: 0
30 Selection: IMAGE_COMDAT_SELECT_ANY
31 - Name: _main
32 Value: 0
33 SectionNumber: 1
34 SimpleType: IMAGE_SYM_TYPE_NULL
35 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
36 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
37 - Name: __tls_used
38 Value: 0
39 SectionNumber: 1
40 SimpleType: IMAGE_SYM_TYPE_NULL
41 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
42 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
43...
deps/lld/test/COFF/unwind.test created+198
......@@ -0,0 +1,198 @@
1# RUN: yaml2obj < %s > %t.obj
2#
3# RUN: lld-link /out:%t.exe /entry:main %t.obj
4# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=HEADER %s
5# RUN: llvm-objdump -unwind-info %t.exe | FileCheck -check-prefix=UNWIND %s
6#
7# HEADER: ExceptionTableRVA: 0x1000
8#
9# UNWIND: Function Table:
10# UNWIND: Start Address: 0x2000
11# UNWIND: End Address: 0x201b
12# UNWIND: Unwind Info Address: 0x3000
13# UNWIND: Version: 1
14# UNWIND: Flags: 1 UNW_ExceptionHandler
15# UNWIND: Size of prolog: 18
16# UNWIND: Number of Codes: 8
17# UNWIND: Frame register: RBX
18# UNWIND: Frame offset: 0
19# UNWIND: Unwind Codes:
20# UNWIND: 0x12: UOP_SetFPReg
21# UNWIND: 0x0f: UOP_PushNonVol RBX
22# UNWIND: 0x0e: UOP_SaveXMM128 XMM8 [0x0000]
23# UNWIND: 0x09: UOP_SaveNonVol RSI [0x0010]
24# UNWIND: 0x04: UOP_AllocSmall 24
25# UNWIND: 0x00: UOP_PushMachFrame w/o error code
26# UNWIND: Function Table:
27# UNWIND: Start Address: 0x2012
28# UNWIND: End Address: 0x2012
29# UNWIND: Unwind Info Address: 0x301c
30# UNWIND: Version: 1
31# UNWIND: Flags: 4 UNW_ChainInfo
32# UNWIND: Size of prolog: 0
33# UNWIND: Number of Codes: 0
34# UNWIND: No frame pointer used
35# UNWIND: Function Table:
36# UNWIND: Start Address: 0x201b
37# UNWIND: End Address: 0x201c
38# UNWIND: Unwind Info Address: 0x302c
39# UNWIND: Version: 1
40# UNWIND: Flags: 0
41# UNWIND: Size of prolog: 0
42# UNWIND: Number of Codes: 0
43# UNWIND: No frame pointer used
44# UNWIND: Function Table:
45# UNWIND: Start Address: 0x201c
46# UNWIND: End Address: 0x2039
47# UNWIND: Unwind Info Address: 0x3034
48# UNWIND: Version: 1
49# UNWIND: Flags: 0
50# UNWIND: Size of prolog: 14
51# UNWIND: Number of Codes: 6
52# UNWIND: No frame pointer used
53# UNWIND: Unwind Codes:
54# UNWIND: 0x0e: UOP_AllocLarge 8454128
55# UNWIND: 0x07: UOP_AllocLarge 8190
56# UNWIND: 0x00: UOP_PushMachFrame w/o error code
57
58--- !COFF
59header:
60 Machine: IMAGE_FILE_MACHINE_AMD64
61 Characteristics: [ ]
62sections:
63 - Name: .text
64 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
65 Alignment: 4
66 SectionData: 4883EC184889742410440F110424534889E3488D235B4883C418C3C34881ECF0FF00004881ECF0FF80004881C4F0FF80004881C4F0FF0000C3
67 - Name: .xdata
68 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
69 Alignment: 4
70 SectionData: 0912080312030F300E880000096402000422001A000000000000000021000000000000001B000000000000000100000000000000010E06000E11F0FF80000701FE1F001A
71 Relocations:
72 - VirtualAddress: 20
73 SymbolName: __C_specific_handler
74 Type: IMAGE_REL_AMD64_ADDR32NB
75 - VirtualAddress: 32
76 SymbolName: func
77 Type: IMAGE_REL_AMD64_ADDR32NB
78 - VirtualAddress: 36
79 SymbolName: func
80 Type: IMAGE_REL_AMD64_ADDR32NB
81 - VirtualAddress: 40
82 SymbolName: .xdata
83 Type: IMAGE_REL_AMD64_ADDR32NB
84 - Name: .pdata
85 Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ ]
86 Alignment: 4
87 SectionData: 000000001B0000000000000012000000120000001C00000000000000010000002C000000000000001D00000034000000
88 Relocations:
89 - VirtualAddress: 0
90 SymbolName: func
91 Type: IMAGE_REL_AMD64_ADDR32NB
92 - VirtualAddress: 4
93 SymbolName: func
94 Type: IMAGE_REL_AMD64_ADDR32NB
95 - VirtualAddress: 8
96 SymbolName: .xdata
97 Type: IMAGE_REL_AMD64_ADDR32NB
98 - VirtualAddress: 12
99 SymbolName: func
100 Type: IMAGE_REL_AMD64_ADDR32NB
101 - VirtualAddress: 16
102 SymbolName: func
103 Type: IMAGE_REL_AMD64_ADDR32NB
104 - VirtualAddress: 20
105 SymbolName: .xdata
106 Type: IMAGE_REL_AMD64_ADDR32NB
107 - VirtualAddress: 24
108 SymbolName: smallFunc
109 Type: IMAGE_REL_AMD64_ADDR32NB
110 - VirtualAddress: 28
111 SymbolName: smallFunc
112 Type: IMAGE_REL_AMD64_ADDR32NB
113 - VirtualAddress: 32
114 SymbolName: .xdata
115 Type: IMAGE_REL_AMD64_ADDR32NB
116 - VirtualAddress: 36
117 SymbolName: allocFunc
118 Type: IMAGE_REL_AMD64_ADDR32NB
119 - VirtualAddress: 40
120 SymbolName: allocFunc
121 Type: IMAGE_REL_AMD64_ADDR32NB
122 - VirtualAddress: 44
123 SymbolName: .xdata
124 Type: IMAGE_REL_AMD64_ADDR32NB
125symbols:
126 - Name: .text
127 Value: 0
128 SectionNumber: 1
129 SimpleType: IMAGE_SYM_TYPE_NULL
130 ComplexType: IMAGE_SYM_DTYPE_NULL
131 StorageClass: IMAGE_SYM_CLASS_STATIC
132 SectionDefinition:
133 Length: 57
134 NumberOfRelocations: 0
135 NumberOfLinenumbers: 0
136 CheckSum: 0
137 Number: 1
138 - Name: .xdata
139 Value: 0
140 SectionNumber: 2
141 SimpleType: IMAGE_SYM_TYPE_NULL
142 ComplexType: IMAGE_SYM_DTYPE_NULL
143 StorageClass: IMAGE_SYM_CLASS_STATIC
144 SectionDefinition:
145 Length: 68
146 NumberOfRelocations: 4
147 NumberOfLinenumbers: 0
148 CheckSum: 0
149 Number: 2
150 - Name: .pdata
151 Value: 0
152 SectionNumber: 3
153 SimpleType: IMAGE_SYM_TYPE_NULL
154 ComplexType: IMAGE_SYM_DTYPE_NULL
155 StorageClass: IMAGE_SYM_CLASS_STATIC
156 SectionDefinition:
157 Length: 48
158 NumberOfRelocations: 12
159 NumberOfLinenumbers: 0
160 CheckSum: 0
161 Number: 3
162 - Name: func
163 Value: 0
164 SectionNumber: 1
165 SimpleType: IMAGE_SYM_TYPE_NULL
166 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
167 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
168 - Name: __C_specific_handler
169 Value: 0
170 SectionNumber: 0
171 SimpleType: IMAGE_SYM_TYPE_NULL
172 ComplexType: IMAGE_SYM_DTYPE_NULL
173 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
174 - Name: smallFunc
175 Value: 27
176 SectionNumber: 1
177 SimpleType: IMAGE_SYM_TYPE_NULL
178 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
179 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
180 - Name: allocFunc
181 Value: 28
182 SectionNumber: 1
183 SimpleType: IMAGE_SYM_TYPE_NULL
184 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
185 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
186 - Name: main
187 Value: 0
188 SectionNumber: 1
189 SimpleType: IMAGE_SYM_TYPE_NULL
190 ComplexType: IMAGE_SYM_DTYPE_NULL
191 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
192 - Name: __C_specific_handler
193 Value: 0
194 SectionNumber: 1
195 SimpleType: IMAGE_SYM_TYPE_NULL
196 ComplexType: IMAGE_SYM_DTYPE_NULL
197 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
198...
deps/lld/test/COFF/version.test created+19
......@@ -0,0 +1,19 @@
1# RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj
2
3# RUN: lld-link /out:%t.exe /entry:main %t.obj
4# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=DEFAULT %s
5
6DEFAULT: MajorImageVersion: 0
7DEFAULT: MinorImageVersion: 0
8
9# RUN: lld-link /out:%t.exe /entry:main %t.obj /version:11
10# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK1 %s
11
12CHECK1: MajorImageVersion: 11
13CHECK1: MinorImageVersion: 0
14
15# RUN: lld-link /out:%t.exe /entry:main %t.obj /version:11.22
16# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=CHECK2 %s
17
18CHECK2: MajorImageVersion: 11
19CHECK2: MinorImageVersion: 22
deps/lld/test/COFF/weak-external.test created+35
......@@ -0,0 +1,35 @@
1# RUN: yaml2obj %s > %t.obj
2# RUN: llvm-as -o %t.lto.obj %S/Inputs/weak-external.ll
3# RUN: lld-link /out:%t1.exe /entry:g /subsystem:console %t.obj
4# RUN: lld-link /out:%t2.exe /entry:g /subsystem:console /lldmap:%t2.map %t.obj %t.lto.obj
5# RUN: FileCheck %s < %t2.map
6
7# CHECK: lto.tmp
8# CHECK-NEXT: 0 g
9
10--- !COFF
11header:
12 Machine: IMAGE_FILE_MACHINE_AMD64
13 Characteristics: [ ]
14sections:
15 - Name: '.text'
16 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
17 Alignment: 16
18 SectionData: 00
19symbols:
20 - Name: 'g'
21 Value: 0
22 SectionNumber: 0
23 SimpleType: IMAGE_SYM_TYPE_NULL
24 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
25 StorageClass: IMAGE_SYM_CLASS_WEAK_EXTERNAL
26 WeakExternal:
27 TagIndex: 2
28 Characteristics: IMAGE_WEAK_EXTERN_SEARCH_LIBRARY
29 - Name: 'f'
30 Value: 0
31 SectionNumber: 1
32 SimpleType: IMAGE_SYM_TYPE_NULL
33 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
34 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
35...
deps/lld/test/COFF/weak-external2.test created+30
......@@ -0,0 +1,30 @@
1# RUN: yaml2obj %s > %t.obj
2# RUN: llvm-as -o %t.lto.obj %S/Inputs/weak-external2.ll
3# RUN: lld-link /out:%t.exe /entry:g /subsystem:console %t.obj %t.lto.obj
4
5--- !COFF
6header:
7 Machine: IMAGE_FILE_MACHINE_AMD64
8 Characteristics: [ ]
9sections:
10 - Name: '.text'
11 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
12 Alignment: 16
13 SectionData: 00
14symbols:
15 - Name: 'f'
16 Value: 0
17 SectionNumber: 0
18 SimpleType: IMAGE_SYM_TYPE_NULL
19 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
20 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
21 - Name: 'g'
22 Value: 0
23 SectionNumber: 0
24 SimpleType: IMAGE_SYM_TYPE_NULL
25 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
26 StorageClass: IMAGE_SYM_CLASS_WEAK_EXTERNAL
27 WeakExternal:
28 TagIndex: 0
29 Characteristics: IMAGE_WEAK_EXTERN_SEARCH_LIBRARY
30...
deps/lld/test/COFF/weak-external3.test created+30
......@@ -0,0 +1,30 @@
1# RUN: yaml2obj %s > %t.obj
2# RUN: llvm-as -o %t.lto.obj %S/Inputs/weak-external3.ll
3# RUN: lld-link /out:%t1.exe /entry:f /subsystem:console /lldmap:%t1.map %t.lto.obj
4# RUN: FileCheck --check-prefix=CHECK1 %s < %t1.map
5# RUN: lld-link /out:%t2.exe /entry:f /subsystem:console /lldmap:%t2.map %t.obj %t.lto.obj
6# RUN: FileCheck --check-prefix=CHECK2 %s < %t2.map
7
8# CHECK1: lto.tmp
9# CHECK1-NEXT: 0 g
10
11# CHECK2: weak-external3.test.tmp.obj
12# CHECK2-NEXT: 0 f
13
14--- !COFF
15header:
16 Machine: IMAGE_FILE_MACHINE_AMD64
17 Characteristics: [ ]
18sections:
19 - Name: '.text'
20 Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
21 Alignment: 16
22 SectionData: 00
23symbols:
24 - Name: 'f'
25 Value: 0
26 SectionNumber: 1
27 SimpleType: IMAGE_SYM_TYPE_NULL
28 ComplexType: IMAGE_SYM_DTYPE_FUNCTION
29 StorageClass: IMAGE_SYM_CLASS_EXTERNAL
30...
deps/lld/test/Driver/Inputs/libtest.a created+1
......@@ -0,0 +1 @@
1!<arch>
deps/lld/test/Driver/Inputs/usr/lib/i386/libtest.a created+1
......@@ -0,0 +1 @@
1!<arch>
deps/lld/test/Driver/Inputs/usr/lib/libtest.a created+1
......@@ -0,0 +1 @@
1!<arch>
deps/lld/test/ELF/Inputs/aarch64-condb-reloc.s created+17
......@@ -0,0 +1,17 @@
1.globl _foo
2_foo:
3 nop
4 nop
5 nop
6 nop
7
8.globl _bar
9_bar:
10 nop
11 nop
12 nop
13
14.globl _dah
15_dah:
16 nop
17 nop
deps/lld/test/ELF/Inputs/aarch64-copy2.s created+5
......@@ -0,0 +1,5 @@
1 .global foo
2 .type foo, @function
3foo:
4 .global bar
5bar:
deps/lld/test/ELF/Inputs/aarch64-tls-gdie.s created+4
......@@ -0,0 +1,4 @@
1 .section .tdata,"awT",@progbits
2 .globl a
3a:
4 .word 42
deps/lld/test/ELF/Inputs/aarch64-tls-ie.s created+19
......@@ -0,0 +1,19 @@
1.text
2 .global foo
3 .section .tdata,"awT",%progbits
4 .align 2
5 .type foo, %object
6 .size foo, 4
7foo:
8 .word 5
9 .text
10
11.text
12 .global bar
13 .section .tdata,"awT",%progbits
14 .align 2
15 .type bar, %object
16 .size bar, 4
17bar:
18 .word 5
19 .text
deps/lld/test/ELF/Inputs/aarch64-tstbr14-reloc.s created+12
......@@ -0,0 +1,12 @@
1.globl _foo
2_foo:
3 nop
4 nop
5 nop
6 nop
7
8.globl _bar
9_bar:
10 nop
11 nop
12 nop
deps/lld/test/ELF/Inputs/abs-hidden.s created+3
......@@ -0,0 +1,3 @@
1.global foo
2.hidden foo
3foo = 0x42
deps/lld/test/ELF/Inputs/abs.s created+4
......@@ -0,0 +1,4 @@
1.global abs
2abs = 0x42
3.global big
4big = 0x1000000000
deps/lld/test/ELF/Inputs/abs255.s created+2
......@@ -0,0 +1,2 @@
1.global foo
2foo = 255
deps/lld/test/ELF/Inputs/abs256.s created+2
......@@ -0,0 +1,2 @@
1.global foo
2foo = 256
deps/lld/test/ELF/Inputs/abs257.s created+2
......@@ -0,0 +1,2 @@
1.global foo
2foo = 257
deps/lld/test/ELF/Inputs/allow-multiple-definition.s created+4
......@@ -0,0 +1,4 @@
1.globl _bar
2.type _bar, @function
3_bar:
4 mov $2, %eax
deps/lld/test/ELF/Inputs/allow-shlib-undefined.s created+3
......@@ -0,0 +1,3 @@
1.globl _shared
2_shared:
3 callq _unresolved@PLT
deps/lld/test/ELF/Inputs/archive.s created+5
......@@ -0,0 +1,5 @@
1.globl _start
2_start:
3
4.globl end
5end:
deps/lld/test/ELF/Inputs/archive2.s created+2
......@@ -0,0 +1,2 @@
1.global foo
2foo:
deps/lld/test/ELF/Inputs/archive3.s created+2
......@@ -0,0 +1,2 @@
1.global bar
2bar:
deps/lld/test/ELF/Inputs/archive4.s created+1
......@@ -0,0 +1 @@
1.quad bar
deps/lld/test/ELF/Inputs/arm-attributes1.s created+29
......@@ -0,0 +1,29 @@
1// Input that generates an object with a populated SHT_ARM_ATTRIBUTES section
2 .text
3 .syntax unified
4 .eabi_attribute 67, "2.09" @ Tag_conformance
5 .cpu cortex-a8
6 .eabi_attribute 6, 10 @ Tag_CPU_arch
7 .eabi_attribute 7, 65 @ Tag_CPU_arch_profile
8 .eabi_attribute 8, 1 @ Tag_ARM_ISA_use
9 .eabi_attribute 9, 2 @ Tag_THUMB_ISA_use
10 .fpu neon
11 .eabi_attribute 15, 1 @ Tag_ABI_PCS_RW_data
12 .eabi_attribute 16, 1 @ Tag_ABI_PCS_RO_data
13 .eabi_attribute 17, 2 @ Tag_ABI_PCS_GOT_use
14 .eabi_attribute 20, 1 @ Tag_ABI_FP_denormal
15 .eabi_attribute 21, 1 @ Tag_ABI_FP_exceptions
16 .eabi_attribute 23, 3 @ Tag_ABI_FP_number_model
17 .eabi_attribute 34, 1 @ Tag_CPU_unaligned_access
18 .eabi_attribute 24, 1 @ Tag_ABI_align_needed
19 .eabi_attribute 25, 1 @ Tag_ABI_align_preserved
20 .eabi_attribute 38, 1 @ Tag_ABI_FP_16bit_format
21 .eabi_attribute 18, 4 @ Tag_ABI_PCS_wchar_t
22 .eabi_attribute 26, 2 @ Tag_ABI_enum_size
23 .eabi_attribute 14, 0 @ Tag_ABI_PCS_R9_use
24 .eabi_attribute 68, 1 @ Tag_Virtualization_use
25 .globl func
26 .p2align 2
27 .type func,%function
28func:
29 bx lr
deps/lld/test/ELF/Inputs/arm-exidx-cantunwind.s created+40
......@@ -0,0 +1,40 @@
1// Functions that will generate a .ARM.exidx section with SHF_LINK_ORDER
2// dependency on the progbits section containing the .cantunwind directive
3 .syntax unified
4 .section .func1, "ax",%progbits
5 .globl func1
6func1:
7 .fnstart
8 bx lr
9 .cantunwind
10 .fnend
11
12 .section .func2, "ax", %progbits
13 .globl func2
14func2:
15 .fnstart
16 bx lr
17 .cantunwind
18 .fnend
19
20 .section .func3, "ax",%progbits
21 .globl func3
22func3:
23 .fnstart
24 bx lr
25 .cantunwind
26 .fnend
27
28 .section .text, "ax",%progbits
29 .globl func4
30func4:
31 .fnstart
32 bx lr
33 .cantunwind
34 .fnend
35 .globl func5
36func5:
37 .fnstart
38 bx lr
39 .cantunwind
40 .fnend
deps/lld/test/ELF/Inputs/arm-plt-reloc.s created+14
......@@ -0,0 +1,14 @@
1.text
2 .align 2
3 .globl func1
4 .type func1,%function
5func1:
6 bx lr
7 .globl func2
8 .type func2,%function
9func2:
10 bx lr
11 .globl func3
12 .type func3,%function
13func3:
14 bx lr
deps/lld/test/ELF/Inputs/arm-shared.s created+8
......@@ -0,0 +1,8 @@
1.syntax unified
2.global bar2
3.type bar2, %function
4bar2:
5
6.global zed2
7.type zed2, %function
8zed2:
deps/lld/test/ELF/Inputs/arm-thumb-blx-targets.s created+36
......@@ -0,0 +1,36 @@
1 .syntax unified
2 .arm
3 .section .R_ARM_CALL24_callee_low, "ax",%progbits
4 .align 2
5 .globl callee_low
6 .type callee_low,%function
7callee_low:
8 bx lr
9
10 .section .R_ARM_CALL24_callee_thumb_low, "ax",%progbits
11 .balign 0x100
12 .thumb
13 .type callee_thumb_low,%function
14 .globl callee_thumb_low
15callee_thumb_low:
16 bx lr
17
18 .section .R_ARM_CALL24_callee_high, "ax",%progbits
19 .balign 0x100
20 .arm
21 .globl callee_high
22 .type callee_high,%function
23callee_high:
24 bx lr
25
26 .section .R_ARM_CALL24_callee_thumb_high, "ax",%progbits
27 .balign 0x100
28 .thumb
29 .type callee_thumb_high,%function
30 .globl callee_thumb_high
31callee_thumb_high:
32 bx lr
33
34 .globl blx_far
35 .type blx_far, %function
36blx_far = 0x1010018
deps/lld/test/ELF/Inputs/arm-thumb-narrow-branch.o created
Binary files /dev/null and b/deps/lld/test/ELF/Inputs/arm-thumb-narrow-branch.o differ
deps/lld/test/ELF/Inputs/arm-thumb-narrow-branch.s created+18
......@@ -0,0 +1,18 @@
1// This input must be assembled by the GNU assembler, as llvm-mc does not emit
2// the R_ARM_JUMP11 relocation for a Thumb narrow branch. This is permissible
3// by the ABI for the ARM architecture as the range of the Thumb narrow branch
4// is short enough (+- 2048 bytes) that widespread use would be impractical.
5//
6// The test case will use a pre compiled object arm-thumb-narrow-branch.o
7 .syntax unified
8 .section .caller, "ax",%progbits
9 .thumb
10 .align 2
11 .type callers,%function
12 .globl callers
13callers:
14 b.n callee_low_far
15 b.n callee_low
16 b.n callee_high
17 b.n callee_high_far
18 bx lr
deps/lld/test/ELF/Inputs/arm-tls-get-addr.s created+13
......@@ -0,0 +1,13 @@
1 .syntax unified
2 .text
3 .globl __tls_get_addr
4 .type __tls_get_addr,%function
5__tls_get_addr:
6 bx lr
7
8.section .tbss,"awT",%nobits
9 .p2align 2
10y:
11 .space 4
12 .globl y
13 .type y, %object
deps/lld/test/ELF/Inputs/bad-archive.a created+2
......@@ -0,0 +1,2 @@
1!<arch>
2this is malformed archive used in bad-archive.s
deps/lld/test/ELF/Inputs/comdat.s created+3
......@@ -0,0 +1,3 @@
1 .section .text3,"axG",@progbits,zed,comdat,unique,0
2 .global abc
3abc:
deps/lld/test/ELF/Inputs/comment-gc.s created+1
......@@ -0,0 +1 @@
1.ident "bar"
deps/lld/test/ELF/Inputs/common.s created+3
......@@ -0,0 +1,3 @@
1.comm sym1,8,4
2.comm sym2,4,4
3.comm sym4,4,16
deps/lld/test/ELF/Inputs/conflict-debug.s created+5
......@@ -0,0 +1,5 @@
1.file 1 "conflict-debug.s"
2.globl zed
3.loc 1 4
4zed:
5 nop
deps/lld/test/ELF/Inputs/conflict.s created+7
......@@ -0,0 +1,7 @@
1.globl _Z3muldd, foo, baz
2_Z3muldd:
3foo:
4baz:
5 mov $60, %rax
6 mov $42, %rdi
7 syscall
deps/lld/test/ELF/Inputs/copy-in-shared.s created+4
......@@ -0,0 +1,4 @@
1.type foo, @object
2.global foo
3foo:
4.size foo, 4
deps/lld/test/ELF/Inputs/copy-rel-corrupted.s created+4
......@@ -0,0 +1,4 @@
1.type x,@object
2.globl x
3x:
4.size x, 0
deps/lld/test/ELF/Inputs/copy-rel-pie.s created+11
......@@ -0,0 +1,11 @@
1.data
2.global foo
3.type foo, @object
4.size foo, 4
5foo:
6.long 0
7
8.text
9.global bar
10.type bar, @function
11bar:
deps/lld/test/ELF/Inputs/ctors_dtors_priority1.s created+5
......@@ -0,0 +1,5 @@
1.section .ctors, "aw", @progbits
2 .quad 0xA1
3
4.section .dtors, "aw", @progbits
5 .quad 0xA2
deps/lld/test/ELF/Inputs/ctors_dtors_priority2.s created+5
......@@ -0,0 +1,5 @@
1.section .ctors, "aw", @progbits
2 .quad 0xB1
3
4.section .dtors, "aw", @progbits
5 .quad 0xB2
deps/lld/test/ELF/Inputs/ctors_dtors_priority3.s created+5
......@@ -0,0 +1,5 @@
1.section .ctors, "aw", @progbits
2 .quad 0xC1
3
4.section .dtors, "aw", @progbits
5 .quad 0xC2
deps/lld/test/ELF/Inputs/discard-merge-unnamed.o created
Binary files /dev/null and b/deps/lld/test/ELF/Inputs/discard-merge-unnamed.o differ
deps/lld/test/ELF/Inputs/dso-undef-size.s created+4
......@@ -0,0 +1,4 @@
1.text
2.global foo
3.size foo, 4
4foo:
deps/lld/test/ELF/Inputs/dtrace-r.o created
Binary files /dev/null and b/deps/lld/test/ELF/Inputs/dtrace-r.o differ
deps/lld/test/ELF/Inputs/duplicated-plt-entry.s created+3
......@@ -0,0 +1,3 @@
1.global bar
2.type bar, @gnu_indirect_function
3bar:
deps/lld/test/ELF/Inputs/dynamic-reloc-weak.s created+11
......@@ -0,0 +1,11 @@
1 .type sym1,@function
2 .global sym1
3sym1:
4
5 .type sym2,@function
6 .global sym2
7sym2:
8
9 .type sym3,@function
10 .global sym3
11sym3:
deps/lld/test/ELF/Inputs/dynamic-reloc.s created+2
......@@ -0,0 +1,2 @@
1.global main
2main:
deps/lld/test/ELF/Inputs/eh-frame-end.s created+2
......@@ -0,0 +1,2 @@
1 .section ".eh_frame", "a", @progbits
2 .long 0
deps/lld/test/ELF/Inputs/ehframe-relocation.s created+2
......@@ -0,0 +1,2 @@
1 .cfi_startproc
2 .cfi_endproc
deps/lld/test/ELF/Inputs/empty-ver.ver created+2
......@@ -0,0 +1,2 @@
1ver {
2};
deps/lld/test/ELF/Inputs/exclude-libs.s created+3
......@@ -0,0 +1,3 @@
1.globl fn
2fn:
3 nop
deps/lld/test/ELF/Inputs/far-arm-abs.s created+13
......@@ -0,0 +1,13 @@
1.global far
2.type far,%function
3far = 0x201001c
4
5.global too_far1
6.type too_far1,%function
7too_far1 = 0x2020008
8.global too_far2
9.type too_far2,%function
10too_far2 = 0x202000c
11.global too_far3
12.type too_far3,%function
13too_far3 = 0x2020010
deps/lld/test/ELF/Inputs/far-arm-thumb-abs.s created+24
......@@ -0,0 +1,24 @@
1.global far_cond
2.type far_cond,%function
3far_cond = 0x110023
4.global far_uncond
5.type far_uncond,%function
6far_uncond = 0x101001b
7
8.global too_far1
9.type too_far1,%function
10too_far1 = 0x1020005
11.global too_far2
12.type too_far1,%function
13too_far2 = 0x1020009
14.global too_far3
15.type too_far3,%function
16too_far3 = 0x12000d
17
18.global blx_far
19.type blx_far, %function
20blx_far = 0x2010025
21
22.global blx_far2
23.type blx_far2, %function
24blx_far2 = 0x2010029
deps/lld/test/ELF/Inputs/gc-sections-weak.s created+8
......@@ -0,0 +1,8 @@
1.weak foo
2foo:
3 nop
4
5.data
6.global bar2
7bar2:
8.quad foo
deps/lld/test/ELF/Inputs/gdb-index.s created+73
......@@ -0,0 +1,73 @@
1.text
2.Ltext0:
3.globl main2
4.type main2, @function
5main2:
6 nop
7 nop
8.Letext0:
9
10.section .debug_info,"",@progbits
11.long 0x30
12.value 0x4
13.long 0
14.byte 0x8
15.uleb128 0x1
16.quad .Ltext0
17.quad .Letext0-.Ltext0
18.long 0
19.long 0
20.long 0
21.long 0
22.byte 0x63
23.byte 0x88
24.byte 0xb4
25.byte 0x61
26.byte 0xaa
27.byte 0xb6
28.byte 0xb0
29.byte 0x67
30
31.section .debug_abbrev,"",@progbits
32.uleb128 0x1
33.uleb128 0x11
34.byte 0
35.uleb128 0x11
36.uleb128 0x1
37.uleb128 0x12
38.uleb128 0x7
39.uleb128 0x10
40.uleb128 0x17
41.uleb128 0x2130
42.uleb128 0xe
43.uleb128 0x1b
44.uleb128 0xe
45.uleb128 0x2134
46.uleb128 0x19
47.uleb128 0x2133
48.uleb128 0x17
49.uleb128 0x2131
50.uleb128 0x7
51.byte 0
52.byte 0
53.byte 0
54
55.section .debug_gnu_pubnames,"",@progbits
56.long 0x18
57.value 0x2
58.long 0
59.long 0x33
60.long 0x18
61.byte 0x30
62.string "main2"
63.long 0
64
65.section .debug_gnu_pubtypes,"",@progbits
66.long 0x17
67.value 0x2
68.long 0
69.long 0x33
70.long 0x2b
71.byte 0x90
72.string "int"
73.long 0
deps/lld/test/ELF/Inputs/gnu-ifunc-dso.s created+3
......@@ -0,0 +1,3 @@
1.type foo STT_GNU_IFUNC
2.globl foo
3foo:
deps/lld/test/ELF/Inputs/gnu-ifunc-gotpcrel.s created+4
......@@ -0,0 +1,4 @@
1.type foo STT_GNU_IFUNC
2.globl foo
3foo:
4ret
deps/lld/test/ELF/Inputs/gotpc-relax-und-dso.s created+4
......@@ -0,0 +1,4 @@
1.globl dsofoo
2.type dsofoo, @function
3dsofoo:
4 nop
deps/lld/test/ELF/Inputs/i386-got32x-baseless.elf created
Binary files /dev/null and b/deps/lld/test/ELF/Inputs/i386-got32x-baseless.elf differ
deps/lld/test/ELF/Inputs/i386-reloc-16-error.s created+3
......@@ -0,0 +1,3 @@
1.globl foo
2.hidden foo
3foo = 65536
deps/lld/test/ELF/Inputs/i386-reloc-16.s created+3
......@@ -0,0 +1,3 @@
1.globl foo
2.hidden foo
3foo = 0xffff
deps/lld/test/ELF/Inputs/i386-reloc-8-error.s created+3
......@@ -0,0 +1,3 @@
1.globl foo
2.hidden foo
3foo = 256
deps/lld/test/ELF/Inputs/i386-reloc-8.s created+3
......@@ -0,0 +1,3 @@
1.globl foo
2.hidden foo
3foo = 0xff
deps/lld/test/ELF/Inputs/i386-tls-got.s created+5
......@@ -0,0 +1,5 @@
1 .type foobar,@object
2 .section .tdata,"awT",@progbits
3 .globl foobar
4foobar:
5 .long 42
deps/lld/test/ELF/Inputs/icf-absolute.s created+3
......@@ -0,0 +1,3 @@
1.globl a1, a2
2a1 = 1
3a2 = 1
deps/lld/test/ELF/Inputs/icf-merge-sec.s created+9
......@@ -0,0 +1,9 @@
1.section .rodata.str,"aMS",@progbits,1
2.asciz "bar"
3.asciz "baz"
4.asciz "foo"
5
6.section .text.f2,"ax"
7.globl f2
8f2:
9.quad .rodata.str+8
deps/lld/test/ELF/Inputs/icf-merge.s created+10
......@@ -0,0 +1,10 @@
1.section .rodata.str,"aMS",@progbits,1
2.asciz "bar"
3.asciz "baz"
4foo:
5.asciz "foo"
6
7.section .text.f2,"ax"
8.globl f2
9f2:
10lea foo+42(%rip), %rax
deps/lld/test/ELF/Inputs/icf-merge2.s created+10
......@@ -0,0 +1,10 @@
1.section .rodata.str,"aMS",@progbits,1
2.asciz "bar"
3.asciz "baz"
4boo:
5.asciz "boo"
6
7.section .text.f2,"ax"
8.globl f2
9f2:
10lea boo+42(%rip), %rax
deps/lld/test/ELF/Inputs/icf-merge3.s created+10
......@@ -0,0 +1,10 @@
1.section .rodata.str,"aMS",@progbits,1
2.asciz "bar"
3.asciz "baz"
4foo:
5.asciz "foo"
6
7.section .text.f2,"ax"
8.globl f2
9f2:
10lea foo+43(%rip), %rax
deps/lld/test/ELF/Inputs/icf-non-mergeable.s created+8
......@@ -0,0 +1,8 @@
1.globl d1, d2
2.section .data.d1, "aw"
3d1:
4 .quad 0
5
6.section .data.d2, "aw"
7d2:
8 .quad 0
deps/lld/test/ELF/Inputs/icf2.s created+5
......@@ -0,0 +1,5 @@
1.globl f1, f2
2.section .text.f2, "ax"
3f2:
4 mov $60, %rdi
5 call f1
deps/lld/test/ELF/Inputs/libsearch-dyn.s created+3
......@@ -0,0 +1,3 @@
1.globl _bar,_dynamic
2_bar:
3_dynamic:
deps/lld/test/ELF/Inputs/libsearch-st.s created+3
......@@ -0,0 +1,3 @@
1.globl _bar,_static
2_bar:
3_static:
deps/lld/test/ELF/Inputs/llvm33-rela-outside-group.o created
Binary files /dev/null and b/deps/lld/test/ELF/Inputs/llvm33-rela-outside-group.o differ
deps/lld/test/ELF/Inputs/map-file2.s created+8
......@@ -0,0 +1,8 @@
1foo:
2nop
3.global bar
4bar:
5nop
6.section .text.zed,"ax",@progbits
7.global zed
8zed:
deps/lld/test/ELF/Inputs/map-file3.s created+2
......@@ -0,0 +1,2 @@
1.global bah
2bah:
deps/lld/test/ELF/Inputs/map-file4.s created+3
......@@ -0,0 +1,3 @@
1.global baz
2baz:
3 retq
deps/lld/test/ELF/Inputs/merge.s created+6
......@@ -0,0 +1,6 @@
1 .section .mysec,"aM",@progbits,4
2 .align 4
3 .long 0x42
4
5 .text
6 movl .mysec, %eax
deps/lld/test/ELF/Inputs/mips-align-err.s created+2
......@@ -0,0 +1,2 @@
1 .global _foo
2_foo:
deps/lld/test/ELF/Inputs/mips-concatenated-abiflags.o created
Binary files /dev/null and b/deps/lld/test/ELF/Inputs/mips-concatenated-abiflags.o differ
deps/lld/test/ELF/Inputs/mips-dynamic.s created+28
......@@ -0,0 +1,28 @@
1 .option pic2
2 .text
3 .globl _foo
4_foo:
5 nop
6
7 .globl foo0
8 .type foo0, @function
9foo0:
10 nop
11
12 .globl foo1
13 .type foo1, @function
14foo1:
15 nop
16
17 .data
18 .globl data0
19 .type data0, @object
20 .size data0, 4
21data0:
22 .word 0
23
24 .globl data1
25 .type data1, @object
26 .size data1, 4
27data1:
28 .word 0
deps/lld/test/ELF/Inputs/mips-fnpic.s created+6
......@@ -0,0 +1,6 @@
1 .option pic0
2 .text
3 .global fnpic
4 .type fnpic, @function
5fnpic:
6 nop
deps/lld/test/ELF/Inputs/mips-fpic.s created+6
......@@ -0,0 +1,6 @@
1 .option pic2
2 .text
3 .global fpic
4 .type fpic, @function
5fpic:
6 nop
deps/lld/test/ELF/Inputs/mips-gp-disp.so created
Binary files /dev/null and b/deps/lld/test/ELF/Inputs/mips-gp-disp.so differ
deps/lld/test/ELF/Inputs/mips-gp0-non-zero.o created
Binary files /dev/null and b/deps/lld/test/ELF/Inputs/mips-gp0-non-zero.o differ
deps/lld/test/ELF/Inputs/mips-n32-rels.o created
Binary files /dev/null and b/deps/lld/test/ELF/Inputs/mips-n32-rels.o differ
deps/lld/test/ELF/Inputs/mips-nonalloc.s created+2
......@@ -0,0 +1,2 @@
1 .section .debug_info
2 .word __start
deps/lld/test/ELF/Inputs/mips-options.o created
Binary files /dev/null and b/deps/lld/test/ELF/Inputs/mips-options.o differ
deps/lld/test/ELF/Inputs/mips-pic.s created+19
......@@ -0,0 +1,19 @@
1 .option pic2
2
3 .section .text.1,"ax",@progbits
4 .align 4
5 .globl foo1a
6 .type foo1a, @function
7foo1a:
8 nop
9 .globl foo1b
10 .type foo1b, @function
11foo1b:
12 nop
13
14 .section .text.2,"ax",@progbits
15 .align 4
16 .globl foo2
17 .type foo2, @function
18foo2:
19 nop
deps/lld/test/ELF/Inputs/mips-tls.s created+5
......@@ -0,0 +1,5 @@
1 .globl foo
2 .section .tdata,"awT",%progbits
3 .type foo, %object
4foo:
5 .word 0
deps/lld/test/ELF/Inputs/no-symtab.o created
Binary files /dev/null and b/deps/lld/test/ELF/Inputs/no-symtab.o differ
deps/lld/test/ELF/Inputs/plt-aarch64.s created+5
......@@ -0,0 +1,5 @@
1.global bar
2bar:
3
4.global weak
5weak:
deps/lld/test/ELF/Inputs/ppc64-addr16-error.s created+3
......@@ -0,0 +1,3 @@
1.global sym
2.hidden sym
3sym = 0
deps/lld/test/ELF/Inputs/progname-ver.s created+3
......@@ -0,0 +1,3 @@
1.global bar
2bar:
3.quad __progname@GOT
deps/lld/test/ELF/Inputs/protected-shared.s created+10
......@@ -0,0 +1,10 @@
1 .global foo
2 .protected foo
3foo:
4
5 .global bar
6 .protected bar
7bar:
8
9 .global zed
10zed:
deps/lld/test/ELF/Inputs/relocatable-comdat-multiple.s created+2
......@@ -0,0 +1,2 @@
1.section .text.c,"axG",@progbits,bbb,comdat
2.section .text.d,"axG",@progbits,bbb,comdat
deps/lld/test/ELF/Inputs/relocatable-ehframe.s created+14
......@@ -0,0 +1,14 @@
1.section foo1,"ax",@progbits
2.cfi_startproc
3 nop
4.cfi_endproc
5
6.section bar1,"ax",@progbits
7.cfi_startproc
8 nop
9.cfi_endproc
10
11.section dah1,"ax",@progbits
12.cfi_startproc
13 nop
14.cfi_endproc
deps/lld/test/ELF/Inputs/relocatable-non-alloc.s created+6
......@@ -0,0 +1,6 @@
1.section .text.foo,"axG",@progbits,foo,comdat,unique,0
2foo:
3 nop
4
5.section .debug_info
6.long .text.foo
deps/lld/test/ELF/Inputs/relocatable-tls.s created+1
......@@ -0,0 +1 @@
1callq __tls_get_addr@PLT
deps/lld/test/ELF/Inputs/relocatable.s created+22
......@@ -0,0 +1,22 @@
1.text
2.type xx,@object
3.bss
4.globl xx
5.align 4
6xx:
7.long 0
8.size xx, 4
9.type yy,@object
10.globl yy
11.align 4
12yy:
13.long 0
14.size yy, 4
15
16.text
17.globl foo
18.align 16, 0x90
19.type foo,@function
20foo:
21movl $1, xx
22movl $2, yy
deps/lld/test/ELF/Inputs/relocatable2.s created+22
......@@ -0,0 +1,22 @@
1.text
2.type xxx,@object
3.bss
4.globl xxx
5.align 4
6xxx:
7.long 0
8.size xxx, 4
9.type yyy,@object
10.globl yyy
11.align 4
12yyy:
13.long 0
14.size yyy, 4
15
16.text
17.globl bar
18.align 16, 0x90
19.type bar,@function
20bar:
21movl $8, xxx
22movl $9, yyy
deps/lld/test/ELF/Inputs/relocation-copy-alias.s created+25
......@@ -0,0 +1,25 @@
1.data
2
3.globl a1
4.type a1, @object
5.size a1, 1
6a1:
7.weak a2
8.type a2, @object
9.size a2, 1
10a2:
11.byte 1
12
13.weak b1
14.type b1, @object
15.size b1, 1
16b1:
17.weak b2
18.type b2, @object
19.size b2, 1
20b2:
21.globl b3
22.type b3, @object
23.size b3, 1
24b3:
25.byte 1
deps/lld/test/ELF/Inputs/relocation-copy-align-common.s created+7
......@@ -0,0 +1,7 @@
1.data
2.global foo
3.type foo, @object
4.align 8
5.size foo, 8
6foo:
7.quad 0
deps/lld/test/ELF/Inputs/relocation-copy-align.s created+9
......@@ -0,0 +1,9 @@
1.data
2 .balign 16
3 .zero 12
4
5 .type x,@object
6 .globl x
7x:
8 .long 0
9 .size x, 4
deps/lld/test/ELF/Inputs/relocation-copy-arm.s created+22
......@@ -0,0 +1,22 @@
1.bss
2
3.type x,%object
4.globl x
5.balign 16
6x:
7.long 0
8.size x, 4
9
10.type y,%object
11.globl y
12.balign 16
13y:
14.long 0
15.size y, 4
16
17.type z,%object
18.globl z
19.balign 4
20z:
21.long 0
22.size z, 4
deps/lld/test/ELF/Inputs/relocation-copy-relro.s created+13
......@@ -0,0 +1,13 @@
1.rodata
2.globl a
3.size a, 4
4.type a, @object
5a:
6.word 1
7
8.section .data.rel.ro,"aw",%progbits
9.globl b
10.size b, 4
11.type b, @object
12b:
13.word 2
deps/lld/test/ELF/Inputs/relocation-copy.s created+22
......@@ -0,0 +1,22 @@
1.bss
2
3.type x,@object
4.globl x
5.balign 16
6x:
7.long 0
8.size x, 4
9
10.type y,@object
11.globl y
12.balign 16
13y:
14.long 0
15.size y, 4
16
17.type z,@object
18.globl z
19.balign 4
20z:
21.long 0
22.size z, 4
deps/lld/test/ELF/Inputs/relocation-relative-absolute.s created+2
......@@ -0,0 +1,2 @@
1.globl answer
2answer = 42
deps/lld/test/ELF/Inputs/relocation-size-shared.s created+6
......@@ -0,0 +1,6 @@
1.data
2.global fooshared
3.type fooshared,%object
4.size fooshared,26
5fooshared:
6.zero 26
deps/lld/test/ELF/Inputs/resolution-end.s created+3
......@@ -0,0 +1,3 @@
1.data
2 .quad _end
3 .quad end
deps/lld/test/ELF/Inputs/resolution-shared.s created+2
......@@ -0,0 +1,2 @@
1 .global foo
2foo:
deps/lld/test/ELF/Inputs/resolution.s created+107
......@@ -0,0 +1,107 @@
1local:
2
3.weak RegularWeak_with_RegularWeak
4.size RegularWeak_with_RegularWeak, 32
5RegularWeak_with_RegularWeak:
6
7.global RegularWeak_with_RegularStrong
8.size RegularWeak_with_RegularStrong, 33
9RegularWeak_with_RegularStrong:
10
11.weak RegularStrong_with_RegularWeak
12.size RegularStrong_with_RegularWeak, 34
13RegularStrong_with_RegularWeak:
14
15.weak RegularWeak_with_UndefWeak
16.size RegularWeak_with_UndefWeak, 35
17.quad RegularWeak_with_UndefWeak
18
19.size RegularWeak_with_UndefStrong, 36
20.quad RegularWeak_with_UndefStrong
21
22.weak RegularStrong_with_UndefWeak
23.size RegularStrong_with_UndefWeak, 37
24.quad RegularStrong_with_UndefWeak
25
26.size RegularStrong_with_UndefStrong, 38
27.quad RegularStrong_with_UndefStrong
28
29.weak RegularWeak_with_CommonWeak
30.comm RegularWeak_with_CommonWeak,39,4
31
32.comm RegularWeak_with_CommonStrong,40,4
33
34.weak RegularStrong_with_CommonWeak
35.comm RegularStrong_with_CommonWeak,41,4
36
37.comm RegularStrong_with_CommonStrong,42,4
38
39.weak UndefWeak_with_RegularWeak
40.size UndefWeak_with_RegularWeak, 43
41UndefWeak_with_RegularWeak:
42
43.global UndefWeak_with_RegularStrong
44.size UndefWeak_with_RegularStrong, 44
45UndefWeak_with_RegularStrong:
46
47.weak UndefStrong_with_RegularWeak
48.size UndefStrong_with_RegularWeak, 45
49UndefStrong_with_RegularWeak:
50
51.global UndefStrong_with_RegularStrong
52.size UndefStrong_with_RegularStrong, 46
53UndefStrong_with_RegularStrong:
54
55.weak UndefWeak_with_UndefWeak
56.size UndefWeak_with_UndefWeak, 47
57.quad UndefWeak_with_UndefWeak
58
59.weak UndefWeak_with_CommonWeak
60.comm UndefWeak_with_CommonWeak,48,4
61
62.comm UndefWeak_with_CommonStrong,49,4
63
64.weak UndefStrong_with_CommonWeak
65.comm UndefStrong_with_CommonWeak,50,4
66
67.comm UndefStrong_with_CommonStrong,51,4
68
69.weak CommonWeak_with_RegularWeak
70.size CommonWeak_with_RegularWeak, 52
71CommonWeak_with_RegularWeak:
72
73.global CommonWeak_with_RegularStrong
74.size CommonWeak_with_RegularStrong, 53
75CommonWeak_with_RegularStrong:
76
77.weak CommonStrong_with_RegularWeak
78.size CommonStrong_with_RegularWeak, 54
79CommonStrong_with_RegularWeak:
80
81.global CommonStrong_with_RegularStrong
82.size CommonStrong_with_RegularStrong, 55
83CommonStrong_with_RegularStrong:
84
85.weak CommonWeak_with_UndefWeak
86.size CommonWeak_with_UndefWeak, 56
87.quad CommonWeak_with_UndefWeak
88
89.size CommonWeak_with_UndefStrong, 57
90.quad CommonWeak_with_UndefStrong
91
92.weak CommonStrong_with_UndefWeak
93.size CommonStrong_with_UndefWeak, 58
94.quad CommonStrong_with_UndefWeak
95
96.size CommonStrong_with_UndefStrong, 59
97.quad CommonStrong_with_UndefStrong
98
99.weak CommonWeak_with_CommonWeak
100.comm CommonWeak_with_CommonWeak,60,4
101
102.comm CommonWeak_with_CommonStrong,61,4
103
104.weak CommonStrong_with_CommonWeak
105.comm CommonStrong_with_CommonWeak,62,4
106
107.comm CommonStrong_with_CommonStrong,63,4
deps/lld/test/ELF/Inputs/rodynamic.s created+4
......@@ -0,0 +1,4 @@
1.global foo
2.type foo, @function
3foo:
4 ret
deps/lld/test/ELF/Inputs/shared-ppc64.s created+9
......@@ -0,0 +1,9 @@
1.section ".opd","aw"
2.global bar
3bar:
4.quad .Lbar,.TOC.@tocbase,0
5.quad .Lbar,0,0
6
7.text
8.Lbar:
9 blr
deps/lld/test/ELF/Inputs/shared.s created+10
......@@ -0,0 +1,10 @@
1.global bar
2.type bar, @function
3bar:
4
5.global bar2
6.type bar2, @function
7bar2:
8
9.global zed
10zed:
deps/lld/test/ELF/Inputs/shared2-x86-64.s created+9
......@@ -0,0 +1,9 @@
1.global bar2
2.type bar2, @function
3bar2:
4 ret
5
6.global zed2
7.type zed2, @function
8zed2:
9 ret
deps/lld/test/ELF/Inputs/shared2.s created+6
......@@ -0,0 +1,6 @@
1.global bar2
2.type bar2, @function
3bar2:
4
5.global zed2
6zed2:
deps/lld/test/ELF/Inputs/shared3.s created+3
......@@ -0,0 +1,3 @@
1.global baz
2.type barz, @function
3baz:
deps/lld/test/ELF/Inputs/shf-info-link.test created+21
......@@ -0,0 +1,21 @@
1--- !ELF
2FileHeader:
3 Class: ELFCLASS64
4 Data: ELFDATA2LSB
5 Type: ET_REL
6 Machine: EM_X86_64
7Sections:
8 - Name: .text
9 Type: SHT_PROGBITS
10 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
11 - Name: .rela.text
12 Type: SHT_RELA
13 Link: .symtab
14 Info: .text
15 Relocations:
16 - Offset: 0x0000000000000000
17 Symbol: foo
18 Type: R_X86_64_64
19Symbols:
20 Global:
21 - Name: foo
deps/lld/test/ELF/Inputs/sht-group-gold-r.elf created
Binary files /dev/null and b/deps/lld/test/ELF/Inputs/sht-group-gold-r.elf differ
deps/lld/test/ELF/Inputs/sht-group-gold-r.s created+14
......@@ -0,0 +1,14 @@
1# sht-group-gold-r.elf is produced by
2#
3# llvm-mc -filetype=obj -triple=x86_64-pc-linux sht-group-gold-r.s -o sht-group-gold-r.o
4# ld.gold -o sht-group-gold-r.elf -r sht-group-gold-r.o
5
6.global foo, bar
7
8.section .text.foo,"aG",@progbits,group_foo,comdat
9foo:
10 nop
11
12.section .text.bar,"aG",@progbits,group_bar,comdat
13bar:
14 nop
deps/lld/test/ELF/Inputs/start-lib-comdat.s created+5
......@@ -0,0 +1,5 @@
1 .global bar
2bar:
3 .section .sec,"aG",@progbits,zed,comdat
4 .global zed
5zed:
deps/lld/test/ELF/Inputs/start-lib1.s created+3
......@@ -0,0 +1,3 @@
1.globl foo
2foo:
3 call bar
deps/lld/test/ELF/Inputs/start-lib2.s created+2
......@@ -0,0 +1,2 @@
1.globl bar
2bar:
deps/lld/test/ELF/Inputs/startstop-shared2.s created+2
......@@ -0,0 +1,2 @@
1.globl __start_foo
2__start_foo:
deps/lld/test/ELF/Inputs/symbol-override.s created+16
......@@ -0,0 +1,16 @@
1.text
2.globl foo
3.type foo,@function
4foo:
5nop
6
7.globl bar
8.type bar,@function
9bar:
10nop
11
12.globl do
13.type do,@function
14do:
15callq foo@PLT
16callq bar@PLT
deps/lld/test/ELF/Inputs/symver-archive1.s created+6
......@@ -0,0 +1,6 @@
1.text
2.globl x
3.type x, @function
4x:
5
6.symver x, xx@@VER
deps/lld/test/ELF/Inputs/symver-archive2.s created+1
......@@ -0,0 +1 @@
1call xx@PLT
deps/lld/test/ELF/Inputs/tls-got-entry.s created+13
......@@ -0,0 +1,13 @@
1.globl __tls_get_addr
2.align 16, 0x90
3.type __tls_get_addr,@function
4__tls_get_addr:
5
6.type tlsshared0,@object
7.section .tbss,"awT",@nobits
8.globl tlsshared0
9.align 4
10tlsshared0:
11 .long 0
12 .size tlsshared0, 4
13
deps/lld/test/ELF/Inputs/tls-got.s created+14
......@@ -0,0 +1,14 @@
1.type tls0,@object
2.section .tbss,"awT",@nobits
3.globl tls0
4.align 4
5tls0:
6 .long 0
7 .size tls0, 4
8
9.type tls1,@object
10.globl tls1
11.align 4
12tls1:
13 .long 0
14 .size tls1, 4
deps/lld/test/ELF/Inputs/tls-in-archive.s created+3
......@@ -0,0 +1,3 @@
1 .type foo, @tls_object
2 .globl foo
3foo:
deps/lld/test/ELF/Inputs/tls-mismatch.s created+4
......@@ -0,0 +1,4 @@
1.tbss
2.globl tlsvar
3tlsvar:
4 .space 4
deps/lld/test/ELF/Inputs/tls-opt-gdie.s created+20
......@@ -0,0 +1,20 @@
1.type tlsshared0,@object
2.section .tbss,"awT",@nobits
3.globl tlsshared0
4.align 4
5tlsshared0:
6 .long 0
7 .size tlsshared0, 4
8
9.type tlsshared1,@object
10.globl tlsshared1
11.align 4
12tlsshared1:
13 .long 0
14 .size tlsshared1, 4
15
16.text
17.globl __tls_get_addr
18.align 16, 0x90
19.type __tls_get_addr,@function
20__tls_get_addr:
deps/lld/test/ELF/Inputs/tls-opt-gdiele-i686.s created+20
......@@ -0,0 +1,20 @@
1.type tlsshared0,@object
2.section .tbss,"awT",@nobits
3.globl tlsshared0
4.align 4
5tlsshared0:
6 .long 0
7 .size tlsshared0, 4
8
9.type tlsshared1,@object
10.globl tlsshared1
11.align 4
12tlsshared1:
13 .long 0
14 .size tlsshared1, 4
15
16.text
17 .globl __tls_get_addr
18 .align 16, 0x90
19 .type __tls_get_addr,@function
20__tls_get_addr:
deps/lld/test/ELF/Inputs/tls-opt-iele-i686-nopic.s created+15
......@@ -0,0 +1,15 @@
1.type tlsshared0,@object
2.section .tbss,"awT",@nobits
3.globl tlsshared0
4.align 4
5tlsshared0:
6 .long 0
7 .size tlsshared0, 4
8
9.type tlsshared1,@object
10.section .tbss,"awT",@nobits
11.globl tlsshared1
12.align 4
13tlsshared1:
14 .long 0
15 .size tlsshared1, 4
deps/lld/test/ELF/Inputs/trace-ar1.s created+2
......@@ -0,0 +1,2 @@
1.globl _used
2_used:
deps/lld/test/ELF/Inputs/trace-ar2.s created+2
......@@ -0,0 +1,2 @@
1.globl _notused
2_notused:
deps/lld/test/ELF/Inputs/trace-symbols-foo-strong.s created+14
......@@ -0,0 +1,14 @@
1.text
2.globl foo
3.type foo, @function
4foo:
5nop
6
7.globl bar
8.type bar, @function
9bar:
10nop
11
12.global func2
13.type func2, @function
14func2:
deps/lld/test/ELF/Inputs/trace-symbols-foo-weak.s created+12
......@@ -0,0 +1,12 @@
1.comm common,4,4
2.text
3.weak foo
4.type foo, @function
5foo:
6callq bar@PLT
7
8.globl func1
9.type func1, @function
10func1:
11call func2@PLT
12
deps/lld/test/ELF/Inputs/uabs_label.s created+4
......@@ -0,0 +1,4 @@
1# Sample label to test R_AARCH64_MOVW_UABS relocations
2
3.globl uabs_label
4uabs_label = 0xF000E000D000C
deps/lld/test/ELF/Inputs/undef-debug.s created+11
......@@ -0,0 +1,11 @@
1.file 1 "dir/undef-debug.s"
2.loc 1 3
3 .quad zed3
4
5.section .text.1,"ax"
6.loc 1 7
7 .quad zed4
8
9.section .text.2,"ax"
10.loc 1 11
11 .quad zed5
deps/lld/test/ELF/Inputs/undef-with-plt-addr.s created+7
......@@ -0,0 +1,7 @@
1 .globl set_data
2 .type set_data,@function
3set_data:
4
5 .globl foo
6 .type foo,@function
7foo:
deps/lld/test/ELF/Inputs/undef.s created+3
......@@ -0,0 +1,3 @@
1 .global zed1
2zed1:
3 .quad zed2
deps/lld/test/ELF/Inputs/unknown-reloc.s created+2
......@@ -0,0 +1,2 @@
1.global und
2und:
deps/lld/test/ELF/Inputs/unresolved-symbols.s created+3
......@@ -0,0 +1,3 @@
1.globl _shared
2_shared:
3 callq undef@PLT
deps/lld/test/ELF/Inputs/use-bar.s created+2
......@@ -0,0 +1,2 @@
1.section .bar,"a"
2 .quad _bar
deps/lld/test/ELF/Inputs/verdef-defaultver.s created+22
......@@ -0,0 +1,22 @@
1b@V1 = b_1
2b@@V2 = b_2
3
4.globl a
5.type a,@function
6a:
7retq
8
9.globl b_1
10.type b_1,@function
11b_1:
12retq
13
14.globl b_2
15.type b_2,@function
16b_2:
17retq
18
19.globl c
20.type c,@function
21c:
22retq
deps/lld/test/ELF/Inputs/verdef.s created+6
......@@ -0,0 +1,6 @@
1.text
2.globl _start
3_start:
4 callq a
5 callq b
6 callq c
deps/lld/test/ELF/Inputs/verneed.so.sh created+58
......@@ -0,0 +1,58 @@
1#!/bin/sh -eu
2
3# This script was used to produce the verneed{1,2}.so files.
4
5tmp=$(mktemp -d)
6
7echo "v1 {}; v2 {}; v3 {}; { local: *; };" > $tmp/verneed.script
8
9cat > $tmp/verneed1.s <<eof
10.globl f1_v1
11f1_v1:
12ret
13
14.globl f1_v2
15f1_v2:
16ret
17
18.globl f1_v3
19f1_v3:
20ret
21
22.symver f1_v1, f1@v1
23.symver f1_v2, f1@v2
24.symver f1_v3, f1@@v3
25
26.globl f2_v1
27f2_v1:
28ret
29
30.globl f2_v2
31f2_v2:
32ret
33
34.symver f2_v1, f2@v1
35.symver f2_v2, f2@@v2
36
37.globl f3_v1
38f3_v1:
39ret
40
41.symver f3_v1, f3@v1
42eof
43
44as -o $tmp/verneed1.o $tmp/verneed1.s
45ld.gold -shared -o verneed1.so $tmp/verneed1.o --version-script $tmp/verneed.script -soname verneed1.so.0
46
47cat > $tmp/verneed2.s <<eof
48.globl g1_v1
49g1_v1:
50ret
51
52.symver g1_v1, g1@@v1
53eof
54
55as -o $tmp/verneed2.o $tmp/verneed2.s
56ld.gold -shared -o verneed2.so $tmp/verneed2.o --version-script $tmp/verneed.script -soname verneed2.so.0
57
58rm -rf $tmp
deps/lld/test/ELF/Inputs/verneed1.so created
Binary files /dev/null and b/deps/lld/test/ELF/Inputs/verneed1.so differ
deps/lld/test/ELF/Inputs/verneed2.so created
Binary files /dev/null and b/deps/lld/test/ELF/Inputs/verneed2.so differ
deps/lld/test/ELF/Inputs/version-script-err.script created+4
......@@ -0,0 +1,4 @@
1{
2 global:
3 foo
4};
deps/lld/test/ELF/Inputs/version-script-no-warn2.s created+1
......@@ -0,0 +1 @@
1call foo@plt
deps/lld/test/ELF/Inputs/version-script-weak.s created+4
......@@ -0,0 +1,4 @@
1.text
2.globl foo
3.type foo,@function
4foo:
deps/lld/test/ELF/Inputs/version-undef-sym.so created
Binary files /dev/null and b/deps/lld/test/ELF/Inputs/version-undef-sym.so differ
deps/lld/test/ELF/Inputs/version-use.script created+6
......@@ -0,0 +1,6 @@
1ABC {
2global:
3foo;
4local:
5*;
6};
deps/lld/test/ELF/Inputs/version-use.so created
Binary files /dev/null and b/deps/lld/test/ELF/Inputs/version-use.so differ
deps/lld/test/ELF/Inputs/visibility.s created+14
......@@ -0,0 +1,14 @@
1.data
2.quad default
3
4.protected protected
5.quad protected
6
7.hidden hidden
8.quad hidden
9
10.internal internal
11.quad internal
12
13.hidden protected_with_hidden
14.quad protected_with_hidden
deps/lld/test/ELF/Inputs/warn-common.s created+2
......@@ -0,0 +1,2 @@
1.type arr,@object
2.comm arr,8,4
deps/lld/test/ELF/Inputs/warn-common2.s created+8
......@@ -0,0 +1,8 @@
1.type arr,@object
2.data
3.globl arr
4.p2align 2
5arr:
6 .long 1
7 .long 0
8 .size arr, 8
deps/lld/test/ELF/Inputs/weak-and-strong-undef.s created+1
......@@ -0,0 +1 @@
1 .weak foo
deps/lld/test/ELF/Inputs/whole-archive.s created+2
......@@ -0,0 +1,2 @@
1.globl _bar
2_bar:
deps/lld/test/ELF/Inputs/wrap-dynamic-undef.s created+2
......@@ -0,0 +1,2 @@
1.global foo
2foo:
deps/lld/test/ELF/Inputs/wrap.s created+4
......@@ -0,0 +1,4 @@
1.globl foo, __wrap_foo, __real_foo
2foo = 0x11000
3__wrap_foo = 0x11010
4__real_foo = 0x11020
deps/lld/test/ELF/Inputs/x86-64-relax-offset.s created+7
......@@ -0,0 +1,7 @@
1.global foo
2.hidden foo
3foo:
4 nop
5 nop
6 nop
7 nop
deps/lld/test/ELF/Inputs/x86-64-reloc-16-error.s created+3
......@@ -0,0 +1,3 @@
1.globl foo
2.hidden foo
3foo = 65536
deps/lld/test/ELF/Inputs/x86-64-reloc-16.s created+3
......@@ -0,0 +1,3 @@
1.globl foo
2.hidden foo
3foo = 0x42
deps/lld/test/ELF/Inputs/x86-64-reloc-8-error.s created+3
......@@ -0,0 +1,3 @@
1.globl foo
2.hidden foo
3foo = 256
deps/lld/test/ELF/Inputs/x86-64-reloc-8.s created+3
......@@ -0,0 +1,3 @@
1.globl foo
2.hidden foo
3foo = 0x42
deps/lld/test/ELF/Inputs/x86-64-reloc-error.s created+7
......@@ -0,0 +1,7 @@
1.global big
2.hidden big
3big = 0x1000000000
4
5.global foo
6.hidden foo
7foo = 0
deps/lld/test/ELF/Inputs/x86-64-tls-gd-got.s created+6
......@@ -0,0 +1,6 @@
1 .globl bar
2 .section .tdata,"awT",@progbits
3 .align 4
4 .type bar, @object
5bar:
6 .long 42
deps/lld/test/ELF/Inputs/ztext-text-notext.s created+10
......@@ -0,0 +1,10 @@
1 .global bar
2 .type bar, @object
3 .size bar, 8
4bar:
5 .quad 0
6
7 .global zed
8 .type zed, @function
9zed:
10 nop
deps/lld/test/ELF/aarch64-abs16.s created+27
......@@ -0,0 +1,27 @@
1// REQUIRES: aarch64
2// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o
3// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %S/Inputs/abs255.s -o %t255.o
4// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %S/Inputs/abs256.s -o %t256.o
5// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %S/Inputs/abs257.s -o %t257.o
6
7.globl _start
8_start:
9.data
10 .hword foo + 0xfeff
11 .hword foo - 0x8100
12
13// RUN: ld.lld %t.o %t256.o -o %t2
14// RUN: llvm-objdump -s -section=.data %t2 | FileCheck %s
15
16// CHECK: Contents of section .data:
17// 11000: S = 0x100, A = 0xfeff
18// S + A = 0xffff
19// 11002: S = 0x100, A = -0x8100
20// S + A = 0x8000
21// CHECK-NEXT: 20000 ffff0080
22
23// RUN: not ld.lld %t.o %t255.o -o %t2
24// | FileCheck %s --check-prefix=OVERFLOW
25// RUN: not ld.lld %t.o %t257.o -o %t2
26// | FileCheck %s --check-prefix=OVERFLOW
27// OVERFLOW: Relocation R_AARCH64_ABS16 out of range
deps/lld/test/ELF/aarch64-abs32.s created+27
......@@ -0,0 +1,27 @@
1// REQUIRES: aarch64
2// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o
3// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %S/Inputs/abs255.s -o %t255.o
4// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %S/Inputs/abs256.s -o %t256.o
5// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %S/Inputs/abs257.s -o %t257.o
6
7.globl _start
8_start:
9.data
10 .word foo + 0xfffffeff
11 .word foo - 0x80000100
12
13// RUN: ld.lld %t.o %t256.o -o %t2
14// RUN: llvm-objdump -s -section=.data %t2 | FileCheck %s
15
16// CHECK: Contents of section .data:
17// 20000: S = 0x100, A = 0xfffffeff
18// S + A = 0xffffffff
19// 20004: S = 0x100, A = -0x80000100
20// S + A = 0x80000000
21// CHECK-NEXT: 20000 ffffffff 00000080
22
23// RUN: not ld.lld %t.o %t255.o -o %t2
24// | FileCheck %s --check-prefix=OVERFLOW
25// RUN: not ld.lld %t.o %t257.o -o %t2
26// | FileCheck %s --check-prefix=OVERFLOW
27// OVERFLOW: Relocation R_AARCH64_ABS32 out of range
deps/lld/test/ELF/aarch64-abs64-dyn.s created+27
......@@ -0,0 +1,27 @@
1// REQUIRES: aarch64
2// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o
3
4// Creates a R_AARCH64_ABS64 relocation against foo and bar
5 .globl foo
6foo:
7
8 .global bar
9 .hidden bar
10bar:
11
12 .data
13 .xword foo
14 .xword bar
15
16// RUN: ld.lld -shared -o %t.so %t.o
17// RUN: llvm-readobj -symbols -dyn-relocations %t.so | FileCheck %s
18
19// CHECK: Dynamic Relocations {
20// CHECK-NEXT: {{.*}} R_AARCH64_RELATIVE - [[BAR_ADDR:.*]]
21// CHECK-NEXT: {{.*}} R_AARCH64_ABS64 foo 0x0
22// CHECK-NEXT: }
23
24// CHECK: Symbols [
25// CHECK: Symbol {
26// CHECK: Name: bar
27// CHECK-NEXT: Value: [[BAR_ADDR]]
deps/lld/test/ELF/aarch64-call26-error.s created+11
......@@ -0,0 +1,11 @@
1// RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %S/Inputs/abs.s -o %tabs
2// RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %s -o %t
3// RUN: not ld.lld %t %tabs -o %t2 2>&1 | FileCheck %s
4// REQUIRES: aarch64
5
6.text
7.globl _start
8_start:
9 bl big
10
11// CHECK: R_AARCH64_CALL26 out of range
deps/lld/test/ELF/aarch64-condb-reloc.s created+99
......@@ -0,0 +1,99 @@
1# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %p/Inputs/aarch64-condb-reloc.s -o %t1
2# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %t2
3# RUN: ld.lld %t1 %t2 -o %t
4# RUN: llvm-objdump -d %t | FileCheck %s
5# RUN: ld.lld -shared %t1 %t2 -o %t3
6# RUN: llvm-objdump -d %t3 | FileCheck -check-prefix=DSO %s
7# RUN: llvm-readobj -s -r %t3 | FileCheck -check-prefix=DSOREL %s
8# REQUIRES: aarch64
9
10# 0x11024 - 36 = 0x11000
11# 0x11028 - 24 = 0x11010
12# 0x1102c - 16 = 0x1101c
13# CHECK: Disassembly of section .text:
14# CHECK-NEXT: _foo:
15# CHECK-NEXT: 20000: {{.*}} nop
16# CHECK-NEXT: 20004: {{.*}} nop
17# CHECK-NEXT: 20008: {{.*}} nop
18# CHECK-NEXT: 2000c: {{.*}} nop
19# CHECK: _bar:
20# CHECK-NEXT: 20010: {{.*}} nop
21# CHECK-NEXT: 20014: {{.*}} nop
22# CHECK-NEXT: 20018: {{.*}} nop
23# CHECK: _dah:
24# CHECK-NEXT: 2001c: {{.*}} nop
25# CHECK-NEXT: 20020: {{.*}} nop
26# CHECK: _start:
27# CHECK-NEXT: 20024: {{.*}} b.eq #-36
28# CHECK-NEXT: 20028: {{.*}} b.eq #-24
29# CHECK-NEXT: 2002c: {{.*}} b.eq #-16
30
31#DSOREL: Section {
32#DSOREL: Index:
33#DSOREL: Name: .got.plt
34#DSOREL-NEXT: Type: SHT_PROGBITS
35#DSOREL-NEXT: Flags [
36#DSOREL-NEXT: SHF_ALLOC
37#DSOREL-NEXT: SHF_WRITE
38#DSOREL-NEXT: ]
39#DSOREL-NEXT: Address: 0x20000
40#DSOREL-NEXT: Offset: 0x20000
41#DSOREL-NEXT: Size: 48
42#DSOREL-NEXT: Link: 0
43#DSOREL-NEXT: Info: 0
44#DSOREL-NEXT: AddressAlignment: 8
45#DSOREL-NEXT: EntrySize: 0
46#DSOREL-NEXT: }
47#DSOREL: Relocations [
48#DSOREL-NEXT: Section ({{.*}}) .rela.plt {
49#DSOREL-NEXT: 0x20018 R_AARCH64_JUMP_SLOT _foo
50#DSOREL-NEXT: 0x20020 R_AARCH64_JUMP_SLOT _bar
51#DSOREL-NEXT: 0x20028 R_AARCH64_JUMP_SLOT _dah
52#DSOREL-NEXT: }
53#DSOREL-NEXT:]
54
55#DSO: Disassembly of section .text:
56#DSO-NEXT: _foo:
57#DSO-NEXT: 10000: {{.*}} nop
58#DSO-NEXT: 10004: {{.*}} nop
59#DSO-NEXT: 10008: {{.*}} nop
60#DSO-NEXT: 1000c: {{.*}} nop
61#DSO: _bar:
62#DSO-NEXT: 10010: {{.*}} nop
63#DSO-NEXT: 10014: {{.*}} nop
64#DSO-NEXT: 10018: {{.*}} nop
65#DSO: _dah:
66#DSO-NEXT: 1001c: {{.*}} nop
67#DSO-NEXT: 10020: {{.*}} nop
68#DSO: _start:
69#DSO-NEXT: 10024: {{.*}} b.eq #44
70#DSO-NEXT: 10028: {{.*}} b.eq #56
71#DSO-NEXT: 1002c: {{.*}} b.eq #68
72#DSO-NEXT: Disassembly of section .plt:
73#DSO-NEXT: .plt:
74#DSO-NEXT: 10030: {{.*}} stp x16, x30, [sp, #-16]!
75#DSO-NEXT: 10034: {{.*}} adrp x16, #65536
76#DSO-NEXT: 10038: {{.*}} ldr x17, [x16, #16]
77#DSO-NEXT: 1003c: {{.*}} add x16, x16, #16
78#DSO-NEXT: 10040: {{.*}} br x17
79#DSO-NEXT: 10044: {{.*}} nop
80#DSO-NEXT: 10048: {{.*}} nop
81#DSO-NEXT: 1004c: {{.*}} nop
82#DSO-NEXT: 10050: {{.*}} adrp x16, #65536
83#DSO-NEXT: 10054: {{.*}} ldr x17, [x16, #24]
84#DSO-NEXT: 10058: {{.*}} add x16, x16, #24
85#DSO-NEXT: 1005c: {{.*}} br x17
86#DSO-NEXT: 10060: {{.*}} adrp x16, #65536
87#DSO-NEXT: 10064: {{.*}} ldr x17, [x16, #32]
88#DSO-NEXT: 10068: {{.*}} add x16, x16, #32
89#DSO-NEXT: 1006c: {{.*}} br x17
90#DSO-NEXT: 10070: {{.*}} adrp x16, #65536
91#DSO-NEXT: 10074: {{.*}} ldr x17, [x16, #40]
92#DSO-NEXT: 10078: {{.*}} add x16, x16, #40
93#DSO-NEXT: 1007c: {{.*}} br x17
94
95.globl _start
96_start:
97 b.eq _foo
98 b.eq _bar
99 b.eq _dah
deps/lld/test/ELF/aarch64-copy.s created+93
......@@ -0,0 +1,93 @@
1// REQUIRES: aarch64
2// RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %s -o %t.o
3// RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %p/Inputs/relocation-copy.s -o %t2.o
4// RUN: ld.lld -shared %t2.o -o %t2.so
5// RUN: ld.lld %t.o %t2.so -o %t3
6// RUN: llvm-readobj -s -r --expand-relocs -symbols %t3 | FileCheck %s
7// RUN: llvm-objdump -d %t3 | FileCheck -check-prefix=CODE %s
8// RUN: llvm-objdump -s -section=.rodata %t3 | FileCheck -check-prefix=RODATA %s
9
10.text
11.globl _start
12_start:
13 adr x1, x
14 adrp x2, y
15 add x2, x2, :lo12:y
16.rodata
17 .word z
18
19// CHECK: Name: .bss
20// CHECK-NEXT: Type: SHT_NOBITS
21// CHECK-NEXT: Flags [
22// CHECK-NEXT: SHF_ALLOC
23// CHECK-NEXT: SHF_WRITE
24// CHECK-NEXT: ]
25// CHECK-NEXT: Address: 0x40000
26// CHECK-NEXT: Offset:
27// CHECK-NEXT: Size: 24
28// CHECK-NEXT: Link:
29// CHECK-NEXT: Info:
30// CHECK-NEXT: AddressAlignment: 16
31
32// CHECK: Relocations [
33// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
34// CHECK-NEXT: Relocation {
35// CHECK-NEXT: Offset: 0x40000
36// CHECK-NEXT: Type: R_AARCH64_COPY
37// CHECK-NEXT: Symbol: x
38// CHECK-NEXT: Addend: 0x0
39// CHECK-NEXT: }
40// CHECK-NEXT: Relocation {
41// CHECK-NEXT: Offset: 0x40010
42// CHECK-NEXT: Type: R_AARCH64_COPY
43// CHECK-NEXT: Symbol: y
44// CHECK-NEXT: Addend: 0x0
45// CHECK-NEXT: }
46// CHECK-NEXT: Relocation {
47// CHECK-NEXT: Offset: 0x40014
48// CHECK-NEXT: Type: R_AARCH64_COPY
49// CHECK-NEXT: Symbol: z
50// CHECK-NEXT: Addend: 0x0
51// CHECK-NEXT: }
52// CHECK-NEXT: }
53// CHECK-NEXT: ]
54
55// CHECK: Symbols [
56// CHECK: Name: x
57// CHECK-NEXT: Value: 0x40000
58// CHECK-NEXT: Size: 4
59// CHECK-NEXT: Binding: Global
60// CHECK-NEXT: Type: Object
61// CHECK-NEXT: Other:
62// CHECK-NEXT: Section: .bss
63// CHECK: Name: y
64// CHECK-NEXT: Value: 0x40010
65// CHECK-NEXT: Size: 4
66// CHECK-NEXT: Binding: Global
67// CHECK-NEXT: Type: Object
68// CHECK-NEXT: Other:
69// CHECK-NEXT: Section: .bss
70// CHECK: Name: z
71// CHECK-NEXT: Value: 0x40014
72// CHECK-NEXT: Size: 4
73// CHECK-NEXT: Binding: Global
74// CHECK-NEXT: Type: Object
75// CHECK-NEXT: Other:
76// CHECK-NEXT: Section: .bss
77// CHECK: ]
78
79// CODE: Disassembly of section .text:
80// CODE-NEXT: _start:
81// S(x) = 0x40000, A = 0, P = 0x20000
82// S + A - P = 0x20000 = 131072
83// CODE-NEXT: 20000: {{.*}} adr x1, #131072
84// S(y) = 0x40010, A = 0, P = 0x20004
85// Page(S + A) - Page(P) = 0x40000 - 0x20000 = 0x20000 = 131072
86// CODE-NEXT: 20004: {{.*}} adrp x2, #131072
87// S(y) = 0x40010, A = 0
88// (S + A) & 0xFFF = 0x10 = 16
89// CODE-NEXT: 20008: {{.*}} add x2, x2, #16
90
91// RODATA: Contents of section .rodata:
92// S(z) = 0x40014
93// RODATA-NEXT: 101c8 14000400
deps/lld/test/ELF/aarch64-copy2.s created+27
......@@ -0,0 +1,27 @@
1// REQUIRES: aarch64
2// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=aarch64-pc-linux
3// RUN: llvm-mc %p/Inputs/aarch64-copy2.s -o %t2.o -filetype=obj -triple=aarch64-pc-linux
4// RUN: ld.lld %t2.o -o %t2.so -shared
5// RUN: ld.lld %t.o %t2.so -o %t
6// RUN: llvm-readobj -t %t | FileCheck %s
7
8 .global _start
9_start:
10 adrp x8, foo
11 bl bar
12
13// CHECK: Name: bar
14// CHECK-NEXT: Value: 0x0
15// CHECK-NEXT: Size: 0
16// CHECK-NEXT: Binding: Global
17// CHECK-NEXT: Type: None
18// CHECK-NEXT: Other: 0
19// CHECK-NEXT: Section: Undefined
20
21// CHECK: Name: foo
22// CHECK-NEXT: Value: 0x20030
23// CHECK-NEXT: Size: 0
24// CHECK-NEXT: Binding: Global
25// CHECK-NEXT: Type: Function
26// CHECK-NEXT: Other: 0
27// CHECK-NEXT: Section: Undefined
deps/lld/test/ELF/aarch64-data-relocs.s created+23
......@@ -0,0 +1,23 @@
1// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t
2// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %S/Inputs/abs256.s -o %t256.o
3// RUN: ld.lld %t %t256.o -o %t2
4// RUN: llvm-objdump -s %t2 | FileCheck %s
5// REQUIRES: aarch64
6
7.globl _start
8_start:
9.section .R_AARCH64_ABS64, "ax",@progbits
10 .xword foo + 0x24
11
12// S = 0x100, A = 0x24
13// S + A = 0x124
14// CHECK: Contents of section .R_AARCH64_ABS64:
15// CHECK-NEXT: 20000 24010000 00000000
16
17.section .R_AARCH64_PREL64, "ax",@progbits
18 .xword foo - . + 0x24
19
20// S = 0x100, A = 0x24, P = 0x20008
21// S + A - P = 0xfffffffffffe011c
22// CHECK: Contents of section .R_AARCH64_PREL64:
23// CHECK-NEXT: 20008 1c01feff ffffffff
deps/lld/test/ELF/aarch64-fpic-abs16.s created+9
......@@ -0,0 +1,9 @@
1// REQUIRES: aarch64
2// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o
3// RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s
4// CHECK: relocation R_AARCH64_ABS16 cannot be used against shared object; recompile with -fPIC
5// CHECK-NEXT: >>> defined in {{.*}}.o
6// CHECK-NEXT: >>> referenced by {{.*}}.o:(.data+0x0)
7
8.data
9 .hword foo
deps/lld/test/ELF/aarch64-fpic-add_abs_lo12_nc.s created+12
......@@ -0,0 +1,12 @@
1// REQUIRES: aarch64
2// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o
3// RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s
4// CHECK: can't create dynamic relocation R_AARCH64_ADD_ABS_LO12_NC against symbol: dat
5// CHECK: >>> defined in {{.*}}.o
6// CHECK: >>> referenced by {{.*}}.o:(.text+0x0)
7
8 add x0, x0, :lo12:dat
9.data
10.globl dat
11dat:
12 .word 0
deps/lld/test/ELF/aarch64-fpic-adr_prel_lo21.s created+12
......@@ -0,0 +1,12 @@
1// REQUIRES: aarch64
2// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o
3// RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s
4// CHECK: can't create dynamic relocation R_AARCH64_ADR_PREL_LO21 against symbol: dat
5// CHECK: >>> defined in {{.*}}.o
6// CHECK: >>> referenced by {{.*}}.o:(.text+0x0)
7
8 adr x0, dat
9.data
10.globl dat
11dat:
12 .word 0
deps/lld/test/ELF/aarch64-fpic-adr_prel_pg_hi21.s created+12
......@@ -0,0 +1,12 @@
1// REQUIRES: aarch64
2// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o
3// RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s
4// CHECK: can't create dynamic relocation R_AARCH64_ADR_PREL_PG_HI21 against symbol: dat
5// CHECK: >>> defined in {{.*}}.o
6// CHECK: >>> referenced by {{.*}}.o:(.text+0x0)
7
8 adrp x0, dat
9.data
10.globl dat
11dat:
12 .word 0
deps/lld/test/ELF/aarch64-fpic-got.s created+18
......@@ -0,0 +1,18 @@
1# REQUIRES: aarch64
2
3# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t.o
4# RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %p/Inputs/shared.s -o %t-lib.o
5# RUN: ld.lld -shared %t-lib.o -o %t-lib.so
6# RUN: ld.lld %t-lib.so %t.o -o %t.exe
7# RUN: llvm-readobj -dyn-relocations %t.exe | FileCheck %s
8
9## Checks if got access to dynamic objects is done through a got relative
10## dynamic relocation and not using plt relative (R_AARCH64_JUMP_SLOT).
11# CHECK: Dynamic Relocations {
12# CHECK-NEXT: 0x{{[0-9A-F]+}} R_AARCH64_GLOB_DAT bar 0x0
13# CHECK-NEXT: }
14
15.globl _start
16_start:
17 adrp x0, :got:bar
18 ldr x0, [x0, :got_lo12:bar]
deps/lld/test/ELF/aarch64-fpic-ldst32_abs_lo12_nc.s created+12
......@@ -0,0 +1,12 @@
1// REQUIRES: aarch64
2// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o
3// RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s
4// CHECK: can't create dynamic relocation R_AARCH64_LDST32_ABS_LO12_NC against symbol: dat
5// CHECK: >>> defined in {{.*}}.o
6// CHECK: >>> referenced by {{.*}}.o:(.text+0x0)
7
8 ldr s4, [x0, :lo12:dat]
9.data
10.globl dat
11dat:
12 .word 0
deps/lld/test/ELF/aarch64-fpic-ldst64_abs_lo12_nc.s created+12
......@@ -0,0 +1,12 @@
1// REQUIRES: aarch64
2// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o
3// RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s
4// CHECK: can't create dynamic relocation R_AARCH64_LDST64_ABS_LO12_NC against symbol: dat
5// CHECK: >>> defined in {{.*}}.o
6// CHECK: >>> referenced by {{.*}}.o:(.text+0x0)
7
8 ldr x0, [x0, :lo12:dat]
9.data
10.globl dat
11dat:
12 .word 0
deps/lld/test/ELF/aarch64-fpic-ldst8_abs_lo12_nc.s created+12
......@@ -0,0 +1,12 @@
1// REQUIRES: aarch64
2// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o
3// RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s
4// CHECK: can't create dynamic relocation R_AARCH64_LDST8_ABS_LO12_NC against symbol: dat
5// CHECK: >>> defined in {{.*}}.o
6// CHECK: >>> referenced by {{.*}}.o:(.text+0x0)
7
8 ldrsb x0, [x1, :lo12:dat]
9.data
10.globl dat
11dat:
12 .word 0
deps/lld/test/ELF/aarch64-fpic-prel16.s created+9
......@@ -0,0 +1,9 @@
1// REQUIRES: aarch64
2// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o
3// RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s
4// CHECK: R_AARCH64_PREL16 cannot be used against shared object; recompile with -fPIC
5// CHECK: >>> defined in {{.*}}
6// CHECK: >>> referenced by {{.*}}:(.data+0x0)
7
8.data
9 .hword foo - .
deps/lld/test/ELF/aarch64-fpic-prel32.s created+9
......@@ -0,0 +1,9 @@
1// REQUIRES: aarch64
2// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o
3// RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s
4// CHECK: relocation R_AARCH64_PREL32 cannot be used against shared object; recompile with -fPIC
5// CHECK: >>> defined in {{.*}}
6// CHECK: >>> referenced by {{.*}}:(.data+0x0)
7
8.data
9 .word foo - .
deps/lld/test/ELF/aarch64-fpic-prel64.s created+9
......@@ -0,0 +1,9 @@
1// REQUIRES: aarch64
2// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o
3// RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s
4// CHECK: relocation R_AARCH64_PREL64 cannot be used against shared object; recompile with -fPIC
5// CHECK: >>> defined in {{.*}}
6// CHECK: >>> referenced by {{.*}}:(.data+0x0)
7
8.data
9 .xword foo - .
deps/lld/test/ELF/aarch64-gnu-ifunc-nosym.s created+27
......@@ -0,0 +1,27 @@
1// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o
2// RUN: ld.lld -static %t.o -o %tout
3// RUN: llvm-readobj -symbols %tout | FileCheck %s
4// REQUIRES: aarch64
5
6// Check that no __rela_iplt_end/__rela_iplt_start
7// appear in symtab if there is no references to them.
8// CHECK: Symbols [
9// CHECK-NOT: __rela_iplt_end
10// CHECK-NOT: __rela_iplt_start
11// CHECK: ]
12
13.text
14.type foo STT_GNU_IFUNC
15.globl foo
16foo:
17 ret
18
19.type bar STT_GNU_IFUNC
20.globl bar
21bar:
22 ret
23
24.globl _start
25_start:
26 bl foo
27 bl bar
deps/lld/test/ELF/aarch64-gnu-ifunc-plt.s created+85
......@@ -0,0 +1,85 @@
1// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %S/Inputs/shared2.s -o %t1.o
2// RUN: ld.lld %t1.o --shared -o %t.so
3// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o
4// RUN: ld.lld %t.so %t.o -o %tout
5// RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM
6// RUN: llvm-objdump -s %tout | FileCheck %s --check-prefix=GOTPLT
7// RUN: llvm-readobj -r -dynamic-table %tout | FileCheck %s
8// REQUIRES: aarch64
9
10// Check that the IRELATIVE relocations are after the JUMP_SLOT in the plt
11// CHECK: Relocations [
12// CHECK-NEXT: Section (4) .rela.plt {
13// CHECK: 0x30018 R_AARCH64_JUMP_SLOT bar2 0x0
14// CHECK-NEXT: 0x30020 R_AARCH64_JUMP_SLOT zed2 0x0
15// CHECK-NEXT: 0x30028 R_AARCH64_IRELATIVE - 0x20000
16// CHECK-NEXT: 0x30030 R_AARCH64_IRELATIVE - 0x20004
17// CHECK-NEXT: }
18// CHECK-NEXT: ]
19
20// Check that .got.plt entries point back to PLT header
21// GOTPLT: Contents of section .got.plt:
22// GOTPLT-NEXT: 30000 00000000 00000000 00000000 00000000
23// GOTPLT-NEXT: 30010 00000000 00000000 20000200 00000000
24// GOTPLT-NEXT: 30020 20000200 00000000 20000200 00000000
25// GOTPLT-NEXT: 30030 20000200 00000000
26
27// Check that the PLTRELSZ tag includes the IRELATIVE relocations
28// CHECK: DynamicSection [
29// CHECK: 0x0000000000000002 PLTRELSZ 96 (bytes)
30
31// Check that a PLT header is written and the ifunc entries appear last
32// DISASM: Disassembly of section .text:
33// DISASM-NEXT: foo:
34// DISASM-NEXT: 20000: {{.*}} ret
35// DISASM: bar:
36// DISASM-NEXT: 20004: {{.*}} ret
37// DISASM: _start:
38// DISASM-NEXT: 20008: {{.*}} bl #88
39// DISASM-NEXT: 2000c: {{.*}} bl #100
40// DISASM-NEXT: 20010: {{.*}} bl #48
41// DISASM-NEXT: 20014: {{.*}} bl #60
42// DISASM-NEXT: Disassembly of section .plt:
43// DISASM-NEXT: .plt:
44// DISASM-NEXT: 20020: {{.*}} stp x16, x30, [sp, #-16]!
45// DISASM-NEXT: 20024: {{.*}} adrp x16, #65536
46// DISASM-NEXT: 20028: {{.*}} ldr x17, [x16, #16]
47// DISASM-NEXT: 2002c: {{.*}} add x16, x16, #16
48// DISASM-NEXT: 20030: {{.*}} br x17
49// DISASM-NEXT: 20034: {{.*}} nop
50// DISASM-NEXT: 20038: {{.*}} nop
51// DISASM-NEXT: 2003c: {{.*}} nop
52// DISASM-NEXT: 20040: {{.*}} adrp x16, #65536
53// DISASM-NEXT: 20044: {{.*}} ldr x17, [x16, #24]
54// DISASM-NEXT: 20048: {{.*}} add x16, x16, #24
55// DISASM-NEXT: 2004c: {{.*}} br x17
56// DISASM-NEXT: 20050: {{.*}} adrp x16, #65536
57// DISASM-NEXT: 20054: {{.*}} ldr x17, [x16, #32]
58// DISASM-NEXT: 20058: {{.*}} add x16, x16, #32
59// DISASM-NEXT: 2005c: {{.*}} br x17
60// DISASM-NEXT: 20060: {{.*}} adrp x16, #65536
61// DISASM-NEXT: 20064: {{.*}} ldr x17, [x16, #40]
62// DISASM-NEXT: 20068: {{.*}} add x16, x16, #40
63// DISASM-NEXT: 2006c: {{.*}} br x17
64// DISASM-NEXT: 20070: {{.*}} adrp x16, #65536
65// DISASM-NEXT: 20074: {{.*}} ldr x17, [x16, #48]
66// DISASM-NEXT: 20078: {{.*}} add x16, x16, #48
67// DISASM-NEXT: 2007c: {{.*}} br x17
68
69.text
70.type foo STT_GNU_IFUNC
71.globl foo
72foo:
73 ret
74
75.type bar STT_GNU_IFUNC
76.globl bar
77bar:
78 ret
79
80.globl _start
81_start:
82 bl foo
83 bl bar
84 bl bar2
85 bl zed2
deps/lld/test/ELF/aarch64-gnu-ifunc.s created+139
......@@ -0,0 +1,139 @@
1// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux-gnu %s -o %t.o
2// RUN: ld.lld -static %t.o -o %tout
3// RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM
4// RUN: llvm-readobj -r -symbols -sections %tout | FileCheck %s
5// REQUIRES: aarch64
6
7// CHECK: Sections [
8// CHECK: Section {
9// CHECK: Index: 1
10// CHECK-NEXT: Name: .rela.plt
11// CHECK-NEXT: Type: SHT_RELA
12// CHECK-NEXT: Flags [
13// CHECK-NEXT: SHF_ALLOC
14// CHECK-NEXT: ]
15// CHECK-NEXT: Address: [[RELA:.*]]
16// CHECK-NEXT: Offset: 0x158
17// CHECK-NEXT: Size: 48
18// CHECK-NEXT: Link: 6
19// CHECK-NEXT: Info: 0
20// CHECK-NEXT: AddressAlignment: 8
21// CHECK-NEXT: EntrySize: 24
22// CHECK-NEXT: }
23// CHECK: Relocations [
24// CHECK-NEXT: Section ({{.*}}) .rela.plt {
25// CHECK-NEXT: 0x30000 R_AARCH64_IRELATIVE
26// CHECK-NEXT: 0x30008 R_AARCH64_IRELATIVE
27// CHECK-NEXT: }
28// CHECK-NEXT: ]
29// CHECK: Symbols [
30// CHECK-NEXT: Symbol {
31// CHECK-NEXT: Name:
32// CHECK-NEXT: Value: 0x0
33// CHECK-NEXT: Size: 0
34// CHECK-NEXT: Binding: Local
35// CHECK-NEXT: Type: None
36// CHECK-NEXT: Other: 0
37// CHECK-NEXT: Section: Undefined
38// CHECK-NEXT: }
39// CHECK-NEXT: Symbol {
40// CHECK-NEXT: Name: $x.0
41// CHECK-NEXT: Value: 0x20000
42// CHECK-NEXT: Size: 0
43// CHECK-NEXT: Binding: Local
44// CHECK-NEXT: Type: None
45// CHECK-NEXT: Other: 0
46// CHECK-NEXT: Section: .text
47// CHECK-NEXT: }
48// CHECK-NEXT: Symbol {
49// CHECK-NEXT: Name: __rela_iplt_end
50// CHECK-NEXT: Value: 0x10188
51// CHECK-NEXT: Size: 0
52// CHECK-NEXT: Binding: Local
53// CHECK-NEXT: Type: None
54// CHECK-NEXT: Other [
55// CHECK-NEXT: STV_HIDDEN
56// CHECK-NEXT: ]
57// CHECK-NEXT: Section: .rela.plt
58// CHECK-NEXT: }
59// CHECK-NEXT: Symbol {
60// CHECK-NEXT: Name: __rela_iplt_start
61// CHECK-NEXT: Value: 0x10158
62// CHECK-NEXT: Size: 0
63// CHECK-NEXT: Binding: Local
64// CHECK-NEXT: Type: None
65// CHECK-NEXT: Other [
66// CHECK-NEXT: STV_HIDDEN
67// CHECK-NEXT: ]
68// CHECK-NEXT: Section: .rela.plt
69// CHECK-NEXT: }
70// CHECK-NEXT: Symbol {
71// CHECK-NEXT: Name: _start
72// CHECK-NEXT: Value: 0x20008
73// CHECK-NEXT: Size: 0
74// CHECK-NEXT: Binding: Global
75// CHECK-NEXT: Type: None
76// CHECK-NEXT: Other: 0
77// CHECK-NEXT: Section: .text
78// CHECK-NEXT: }
79// CHECK-NEXT: Symbol {
80// CHECK-NEXT: Name: bar
81// CHECK-NEXT: Value: 0x20004
82// CHECK-NEXT: Size: 0
83// CHECK-NEXT: Binding: Global
84// CHECK-NEXT: Type: GNU_IFunc
85// CHECK-NEXT: Other: 0
86// CHECK-NEXT: Section: .text
87// CHECK-NEXT: }
88// CHECK-NEXT: Symbol {
89// CHECK-NEXT: Name: foo
90// CHECK-NEXT: Value: 0x20000
91// CHECK-NEXT: Size: 0
92// CHECK-NEXT: Binding: Global
93// CHECK-NEXT: Type: GNU_IFunc
94// CHECK-NEXT: Other: 0
95// CHECK-NEXT: Section: .text
96// CHECK-NEXT: }
97// CHECK-NEXT: ]
98
99// 344 = 0x158
100// 392 = 0x188
101
102// DISASM: Disassembly of section .text:
103// DISASM-NEXT: foo:
104// DISASM-NEXT: 20000: c0 03 5f d6 ret
105// DISASM: bar:
106// DISASM-NEXT: 20004: c0 03 5f d6 ret
107// DISASM: _start:
108// DISASM-NEXT: 20008: 06 00 00 94 bl #24
109// DISASM-NEXT: 2000c: 09 00 00 94 bl #36
110// DISASM-NEXT: 20010: 42 60 05 91 add x2, x2, #344
111// DISASM-NEXT: 20014: 42 20 06 91 add x2, x2, #392
112// DISASM-NEXT: Disassembly of section .plt:
113// DISASM-NEXT: .plt:
114// DISASM-NEXT: 20020: 90 00 00 90 adrp x16, #65536
115// DISASM-NEXT: 20024: 11 02 40 f9 ldr x17, [x16]
116// DISASM-NEXT: 20028: 10 02 00 91 add x16, x16, #0
117// DISASM-NEXT: 2002c: 20 02 1f d6 br x17
118// DISASM-NEXT: 20030: 90 00 00 90 adrp x16, #65536
119// DISASM-NEXT: 20034: 11 06 40 f9 ldr x17, [x16, #8]
120// DISASM-NEXT: 20038: 10 22 00 91 add x16, x16, #8
121// DISASM-NEXT: 2003c: 20 02 1f d6 br x17
122
123.text
124.type foo STT_GNU_IFUNC
125.globl foo
126foo:
127 ret
128
129.type bar STT_GNU_IFUNC
130.globl bar
131bar:
132 ret
133
134.globl _start
135_start:
136 bl foo
137 bl bar
138 add x2, x2, :lo12:__rela_iplt_start
139 add x2, x2, :lo12:__rela_iplt_end
deps/lld/test/ELF/aarch64-got-reloc.s created+30
......@@ -0,0 +1,30 @@
1// REQUIRES: aarch64
2// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o
3// RUN: ld.lld %t.o -o %t
4// RUN: llvm-readobj -s --section-data %t | FileCheck %s
5
6// CHECK: Name: .got
7// CHECK-NEXT: Type: SHT_PROGBITS
8// CHECK-NEXT: Flags [
9// CHECK-NEXT: SHF_ALLOC
10// CHECK-NEXT: SHF_WRITE
11// CHECK-NEXT: ]
12// CHECK-NEXT: Address: 0x30000
13// CHECK-NEXT: Offset: 0x20000
14// CHECK-NEXT: Size: 8
15// CHECK-NEXT: Link: 0
16// CHECK-NEXT: Info: 0
17// CHECK-NEXT: AddressAlignment: 8
18// CHECK-NEXT: EntrySize: 0
19// CHECK-NEXT: SectionData (
20// CHECK-NEXT: 0000: 00000000 00000000 |........|
21// CHECK-NEXT: )
22
23 .globl _start
24_start:
25 adrp x8, :got:foo
26 ldr x8, [x8, :got_lo12:foo]
27 ldr w0, [x8]
28 ret
29
30 .weak foo
deps/lld/test/ELF/aarch64-got-relocations.s created+21
......@@ -0,0 +1,21 @@
1# REQUIRES: aarch64
2# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-cloudabi %s -o %t.o
3# RUN: ld.lld -pie %t.o -o %t
4# RUN: llvm-readobj -r %t | FileCheck %s
5
6# If we're addressing a global relatively through the GOT, we still need to
7# emit a relocation for the entry in the GOT itself.
8# CHECK: Relocations [
9# CHECK: Section (4) .rela.dyn {
10# CHECK: 0x{{[0-9A-F]+}} R_AARCH64_RELATIVE - 0x{{[0-9A-F]+}}
11# CHECK: }
12# CHECK: ]
13
14 .globl _start
15 .type _start,@function
16_start:
17 adrp x8, :got:i
18 ldr x8, [x8, :got_lo12:i]
19
20 .type i,@object
21 .comm i,4,4
deps/lld/test/ELF/aarch64-got.s created+18
......@@ -0,0 +1,18 @@
1# REQUIRES: aarch64
2# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %t.o
3# RUN: ld.lld %t.o -o %t
4# RUN: llvm-readobj -s %t | FileCheck %s
5
6# CHECK-NOT: Name: .got
7
8.globl _start
9_start:
10 adrp x0, :gottprel:foo
11
12 .global foo
13 .section .tdata,"awT",%progbits
14 .align 2
15 .type foo, %object
16 .size foo, 4
17foo:
18 .word 5
deps/lld/test/ELF/aarch64-hi21-error.s created+10
......@@ -0,0 +1,10 @@
1// RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %S/Inputs/abs.s -o %tabs
2// RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %s -o %t
3// RUN: not ld.lld %tabs %t -o %t2 2>&1 | FileCheck %s
4// REQUIRES: aarch64
5
6.globl _start
7_start:
8adrp x0, big
9
10#CHECK: R_AARCH64_ADR_PREL_PG_HI21 out of range
deps/lld/test/ELF/aarch64-jump26-error.s created+11
......@@ -0,0 +1,11 @@
1// RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %S/Inputs/abs.s -o %tabs
2// RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %s -o %t
3// RUN: not ld.lld %t %tabs -o %t2 2>&1 | FileCheck %s
4// REQUIRES: aarch64
5
6.text
7.globl _start
8_start:
9 b big
10
11// CHECK: R_AARCH64_JUMP26 out of range
deps/lld/test/ELF/aarch64-lo21-error.s created+10
......@@ -0,0 +1,10 @@
1// RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %S/Inputs/abs.s -o %tabs
2// RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %s -o %t
3// RUN: not ld.lld %tabs %t -o %t2 2>&1 | FileCheck %s
4// REQUIRES: aarch64
5
6.globl _start
7_start:
8adr x0, big
9
10#CHECK: R_AARCH64_ADR_PREL_LO21 out of range
deps/lld/test/ELF/aarch64-prel16.s created+31
......@@ -0,0 +1,31 @@
1// REQUIRES: aarch64
2// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o
3// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %S/Inputs/abs255.s -o %t255.o
4// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %S/Inputs/abs256.s -o %t256.o
5// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %S/Inputs/abs257.s -o %t257.o
6
7.globl _start
8_start:
9.data
10 .hword foo - . + 0x20eff
11 .hword foo - . + 0x8f02
12
13// Note: If this test fails, it probably happens because of
14// the change of the address of the .data section.
15// You may found the correct address in the aarch64_abs16.s test,
16// if it is already fixed. Then, update addends accordingly.
17// RUN: ld.lld -z max-page-size=4096 %t.o %t256.o -o %t2
18// RUN: llvm-objdump -s -section=.data %t2 | FileCheck %s
19
20// CHECK: Contents of section .data:
21// 11000: S = 0x100, A = 0x20eff, P = 0x11000
22// S + A - P = 0xffff
23// 11002: S = 0x100, A = 0x8f02, P = 0x11002
24// S + A - P = 0x8000
25// CHECK-NEXT: 11000 ffff0080
26
27// RUN: not ld.lld %t.o %t255.o -o %t2
28// | FileCheck %s --check-prefix=OVERFLOW
29// RUN: not ld.lld %t.o %t257.o -o %t2
30// | FileCheck %s --check-prefix=OVERFLOW
31// OVERFLOW: Relocation R_AARCH64_PREL16 out of range
deps/lld/test/ELF/aarch64-prel32.s created+31
......@@ -0,0 +1,31 @@
1// REQUIRES: aarch64
2// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %s -o %t.o
3// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %S/Inputs/abs255.s -o %t255.o
4// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %S/Inputs/abs256.s -o %t256.o
5// RUN: llvm-mc -filetype=obj -triple=aarch64-none-freebsd %S/Inputs/abs257.s -o %t257.o
6
7.globl _start
8_start:
9.data
10 .word foo - . + 0x100010eff
11 .word foo - . - 0x7ffef0fc
12
13// Note: If this test fails, it probably happens because of
14// the change of the address of the .data section.
15// You may found the correct address in the aarch64_abs32.s test,
16// if it is already fixed. Then, update addends accordingly.
17// RUN: ld.lld -z max-page-size=4096 %t.o %t256.o -o %t2
18// RUN: llvm-objdump -s -section=.data %t2 | FileCheck %s
19
20// CHECK: Contents of section .data:
21// 11000: S = 0x100, A = 0x100010eff, P = 0x11000
22// S + A - P = 0xffffffff
23// 11004: S = 0x100, A = -0x7ffef0fc, P = 0x11004
24// S + A - P = 0x80000000
25// CHECK-NEXT: 11000 ffffffff 00000080
26
27// RUN: not ld.lld %t.o %t255.o -o %t2
28// | FileCheck %s --check-prefix=OVERFLOW
29// RUN: not ld.lld %t.o %t257.o -o %t2
30// | FileCheck %s --check-prefix=OVERFLOW
31// OVERFLOW: Relocation R_AARCH64_PREL32 out of range
deps/lld/test/ELF/aarch64-relative.s created+26
......@@ -0,0 +1,26 @@
1// REQUIRES: aarch64
2// RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %t.o
3// RUN: ld.lld %t.o -o %t.so -shared
4// RUN: llvm-readobj -r %t.so | FileCheck %s
5
6 adr x8, .Lfoo // R_AARCH64_ADR_PREL_LO21
7 adrp x8, .Lfoo // R_AARCH64_ADR_PREL_PG_HI21
8 strb w9, [x8, :lo12:.Lfoo] // R_AARCH64_LDST8_ABS_LO12_NC
9 ldr h17, [x19, :lo12:.Lfoo] // R_AARCH64_LDST16_ABS_LO12_NC
10 ldr w0, [x8, :lo12:.Lfoo] // R_AARCH64_LDST32_ABS_LO12_NC
11 ldr x0, [x8, :lo12:.Lfoo] // R_AARCH64_LDST64_ABS_LO12_NC
12 ldr q20, [x19, #:lo12:.Lfoo] // R_AARCH64_LDST128_ABS_LO12_NC
13 add x0, x0, :lo12:.Lfoo // R_AARCH64_ADD_ABS_LO12_NC
14 bl .Lfoo // R_AARCH64_CALL26
15 b .Lfoo // R_AARCH64_JUMP26
16 beq .Lfoo // R_AARCH64_CONDBR19
17.Lbranch:
18 tbz x1, 7, .Lbranch // R_AARCH64_TSTBR14
19.data
20.Lfoo:
21
22.rodata
23.long .Lfoo - .
24.xword .Lfoo - . // R_AARCH64_PREL64
25// CHECK: Relocations [
26// CHECK-NEXT: ]
deps/lld/test/ELF/aarch64-relocs.s created+174
......@@ -0,0 +1,174 @@
1# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %t
2# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %p/Inputs/uabs_label.s -o %t2.o
3# RUN: ld.lld %t %t2.o -o %t2
4# RUN: llvm-objdump -d %t2 | FileCheck %s
5# REQUIRES: aarch64
6
7.section .R_AARCH64_ADR_PREL_LO21,"ax",@progbits
8.globl _start
9_start:
10 adr x1,msg
11msg: .asciz "Hello, world\n"
12msgend:
13
14# CHECK: Disassembly of section .R_AARCH64_ADR_PREL_LO21:
15# CHECK: _start:
16# CHECK: 0: 21 00 00 10 adr x1, #4
17# CHECK: msg:
18# CHECK: 4:
19# #4 is the adr immediate value.
20
21.section .R_AARCH64_ADR_PREL_PG_H121,"ax",@progbits
22 adrp x1,mystr
23mystr:
24 .asciz "blah"
25 .size mystr, 4
26
27# S = 0x20012, A = 0x4, P = 0x20012
28# PAGE(S + A) = 0x11000
29# PAGE(P) = 0x11000
30#
31# CHECK: Disassembly of section .R_AARCH64_ADR_PREL_PG_H121:
32# CHECK-NEXT: $x.2:
33# CHECK-NEXT: 20012: 01 00 00 90 adrp x1, #0
34
35.section .R_AARCH64_ADD_ABS_LO12_NC,"ax",@progbits
36 add x0, x0, :lo12:.L.str
37.L.str:
38 .asciz "blah"
39 .size mystr, 4
40
41# S = 0x2001b, A = 0x4
42# R = (S + A) & 0xFFF = 0x1f
43# R << 10 = 0x7c00
44#
45# CHECK: Disassembly of section .R_AARCH64_ADD_ABS_LO12_NC:
46# CHECK-NEXT: $x.4:
47# CHECK-NEXT: 2001b: 00 7c 00 91 add x0, x0, #31
48
49.section .R_AARCH64_LDST64_ABS_LO12_NC,"ax",@progbits
50 ldr x28, [x27, :lo12:foo]
51foo:
52 .asciz "foo"
53 .size mystr, 3
54
55# S = 0x20024, A = 0x4
56# R = ((S + A) & 0xFFF) << 7 = 0x00001400
57# 0x00001400 | 0xf940177c = 0xf940177c
58# CHECK: Disassembly of section .R_AARCH64_LDST64_ABS_LO12_NC:
59# CHECK-NEXT: $x.6:
60# CHECK-NEXT: 20024: 7c 17 40 f9 ldr x28, [x27, #40]
61
62.section .SUB,"ax",@progbits
63 nop
64sub:
65 nop
66
67# CHECK: Disassembly of section .SUB:
68# CHECK-NEXT: $x.8:
69# CHECK-NEXT: 2002c: 1f 20 03 d5 nop
70# CHECK: sub:
71# CHECK-NEXT: 20030: 1f 20 03 d5 nop
72
73.section .R_AARCH64_CALL26,"ax",@progbits
74call26:
75 bl sub
76
77# S = 0x2002c, A = 0x4, P = 0x20034
78# R = S + A - P = -0x4 = 0xfffffffc
79# (R & 0x0ffffffc) >> 2 = 0x03ffffff
80# 0x94000000 | 0x03ffffff = 0x97ffffff
81# CHECK: Disassembly of section .R_AARCH64_CALL26:
82# CHECK-NEXT: call26:
83# CHECK-NEXT: 20034: ff ff ff 97 bl #-4
84
85.section .R_AARCH64_JUMP26,"ax",@progbits
86jump26:
87 b sub
88
89# S = 0x2002c, A = 0x4, P = 0x20038
90# R = S + A - P = -0x8 = 0xfffffff8
91# (R & 0x0ffffffc) >> 2 = 0x03fffffe
92# 0x14000000 | 0x03fffffe = 0x17fffffe
93# CHECK: Disassembly of section .R_AARCH64_JUMP26:
94# CHECK-NEXT: jump26:
95# CHECK-NEXT: 20038: fe ff ff 17 b #-8
96
97.section .R_AARCH64_LDST32_ABS_LO12_NC,"ax",@progbits
98ldst32:
99 ldr s4, [x5, :lo12:foo32]
100foo32:
101 .asciz "foo"
102 .size mystr, 3
103
104# S = 0x2003c, A = 0x4
105# R = ((S + A) & 0xFFC) << 8 = 0x00004000
106# 0x00004000 | 0xbd4000a4 = 0xbd4040a4
107# CHECK: Disassembly of section .R_AARCH64_LDST32_ABS_LO12_NC:
108# CHECK-NEXT: ldst32:
109# CHECK-NEXT: 2003c: a4 40 40 bd ldr s4, [x5, #64]
110
111.section .R_AARCH64_LDST8_ABS_LO12_NC,"ax",@progbits
112ldst8:
113 ldrsb x11, [x13, :lo12:foo8]
114foo8:
115 .asciz "foo"
116 .size mystr, 3
117
118# S = 0x20044, A = 0x4
119# R = ((S + A) & 0xFFF) << 10 = 0x00012000
120# 0x00012000 | 0x398001ab = 0x398121ab
121# CHECK: Disassembly of section .R_AARCH64_LDST8_ABS_LO12_NC:
122# CHECK-NEXT: ldst8:
123# CHECK-NEXT: 20044: ab 21 81 39 ldrsb x11, [x13, #72]
124
125.section .R_AARCH64_LDST128_ABS_LO12_NC,"ax",@progbits
126ldst128:
127 ldr q20, [x19, #:lo12:foo128]
128foo128:
129 .asciz "foo"
130 .size mystr, 3
131
132# S = 0x2004c, A = 0x4
133# R = ((S + A) & 0xFF8) << 6 = 0x00001400
134# 0x00001400 | 0x3dc00274 = 0x3dc01674
135# CHECK: Disassembly of section .R_AARCH64_LDST128_ABS_LO12_NC:
136# CHECK: ldst128:
137# CHECK: 2004c: 74 16 c0 3d ldr q20, [x19, #80]
138#foo128:
139# 20050: 66 6f 6f 00 .word
140
141.section .R_AARCH64_LDST16_ABS_LO12_NC,"ax",@progbits
142ldst16:
143 ldr h17, [x19, :lo12:foo16]
144 ldrh w1, [x19, :lo12:foo16]
145 ldrh w2, [x19, :lo12:foo16 + 2]
146foo16:
147 .asciz "foo"
148 .size mystr, 4
149
150# S = 0x20054, A = 0x4
151# R = ((S + A) & 0x0FFC) << 9 = 0xb000
152# 0xb000 | 0x7d400271 = 0x7d40b271
153# CHECK: Disassembly of section .R_AARCH64_LDST16_ABS_LO12_NC:
154# CHECK-NEXT: ldst16:
155# CHECK-NEXT: 20054: 71 c2 40 7d ldr h17, [x19, #96]
156# CHECK-NEXT: 20058: 61 c2 40 79 ldrh w1, [x19, #96]
157# CHECK-NEXT: 2005c: 62 c6 40 79 ldrh w2, [x19, #98]
158
159.section .R_AARCH64_MOVW_UABS,"ax",@progbits
160movz1:
161 movk x12, #:abs_g0_nc:uabs_label
162 movk x13, #:abs_g1_nc:uabs_label
163 movk x14, #:abs_g2_nc:uabs_label
164 movz x15, #:abs_g3:uabs_label
165 movk x16, #:abs_g3:uabs_label
166
167## 4222124650659840 == (0xF << 48)
168# CHECK: Disassembly of section .R_AARCH64_MOVW_UABS:
169# CHECK-NEXT: movz1:
170# CHECK-NEXT: 8c 01 80 f2 movk x12, #12
171# CHECK-NEXT: ad 01 a0 f2 movk x13, #13, lsl #16
172# CHECK-NEXT: ce 01 c0 f2 movk x14, #14, lsl #32
173# CHECK-NEXT: ef 01 e0 d2 mov x15, #4222124650659840
174# CHECK-NEXT: f0 01 e0 f2 movk x16, #15, lsl #48
deps/lld/test/ELF/aarch64-relro.s created+14
......@@ -0,0 +1,14 @@
1# REQUIRES: aarch64
2# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %t
3# RUN: ld.lld %t -o %t2
4# RUN: llvm-readobj -program-headers %t2 | FileCheck %s
5
6# CHECK: Type: PT_GNU_RELRO
7# CHECK-NEXT: Offset:
8# CHECK-NEXT: VirtualAddress:
9# CHECK-NEXT: PhysicalAddress:
10# CHECK-NEXT: FileSize:
11# CHECK-NEXT: MemSize: 4096
12
13.section .data.rel.ro,"aw",%progbits
14.byte 1
deps/lld/test/ELF/aarch64-tls-gdie.s created+34
......@@ -0,0 +1,34 @@
1// REQUIRES: aarch64
2// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=aarch64-pc-linux
3// RUN: llvm-mc %p/Inputs/aarch64-tls-gdie.s -o %t2.o -filetype=obj -triple=aarch64-pc-linux
4// RUN: ld.lld %t2.o -o %t2.so -shared
5// RUN: ld.lld %t.o %t2.so -o %t
6// RUN: llvm-readobj -s %t | FileCheck --check-prefix=SEC %s
7// RUN: llvm-objdump -d %t | FileCheck %s
8
9 .globl _start
10_start:
11 nop
12 adrp x0, :tlsdesc:a
13 ldr x1, [x0, :tlsdesc_lo12:a]
14 add x0, x0, :tlsdesc_lo12:a
15 .tlsdesccall a
16 blr x1
17
18// SEC: Name: .got
19// SEC-NEXT: Type: SHT_PROGBITS
20// SEC-NEXT: Flags [
21// SEC-NEXT: SHF_ALLOC
22// SEC-NEXT: SHF_WRITE
23// SEC-NEXT: ]
24// SEC-NEXT: Address: 0x300B0
25
26// page(0x300B0) - page(0x20004) = 65536
27// 0x0B0 = 176
28
29// CHECK: _start:
30// CHECK-NEXT: 20000: {{.*}} nop
31// CHECK-NEXT: 20004: {{.*}} adrp x0, #65536
32// CHECK-NEXT: 20008: {{.*}} ldr x0, [x0, #176]
33// CHECK-NEXT: 2000c: {{.*}} nop
34// CHECK-NEXT: 20010: {{.*}} nop
deps/lld/test/ELF/aarch64-tls-gdle.s created+26
......@@ -0,0 +1,26 @@
1# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %p/Inputs/aarch64-tls-ie.s -o %ttlsie.o
2# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %tmain.o
3# RUN: ld.lld %tmain.o %ttlsie.o -o %tout
4# RUN: llvm-objdump -d %tout | FileCheck %s
5# RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s
6# REQUIRES: aarch64
7
8#Local-Dynamic to Initial-Exec relax creates no
9#RELOC: Relocations [
10#RELOC-NEXT: ]
11
12# TCB size = 0x16 and foo is first element from TLS register.
13# CHECK: Disassembly of section .text:
14# CHECK: _start:
15# CHECK: 20000: 00 00 a0 d2 movz x0, #0, lsl #16
16# CHECK: 20004: 00 02 80 f2 movk x0, #16
17# CHECK: 20008: 1f 20 03 d5 nop
18# CHECK: 2000c: 1f 20 03 d5 nop
19
20.globl _start
21_start:
22 adrp x0, :tlsdesc:foo
23 ldr x1, [x0, :tlsdesc_lo12:foo]
24 add x0, x0, :tlsdesc_lo12:foo
25 .tlsdesccall foo
26 blr x1
deps/lld/test/ELF/aarch64-tls-ie.s created+50
......@@ -0,0 +1,50 @@
1// REQUIRES: aarch64
2# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %p/Inputs/aarch64-tls-ie.s -o %tdso.o
3# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %tmain.o
4# RUN: ld.lld -shared %tdso.o -o %tdso.so
5# RUN: ld.lld %tmain.o %tdso.so -o %tout
6# RUN: llvm-objdump -d %tout | FileCheck %s
7# RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s
8# REQUIRES: aarch64
9
10#RELOC: Section {
11#RELOC: Index:
12#RELOC: Name: .got
13#RELOC-NEXT: Type: SHT_PROGBITS
14#RELOC-NEXT: Flags [
15#RELOC-NEXT: SHF_ALLOC
16#RELOC-NEXT: SHF_WRITE
17#RELOC-NEXT: ]
18#RELOC-NEXT: Address: 0x300B0
19#RELOC-NEXT: Offset: 0x200B0
20#RELOC-NEXT: Size: 16
21#RELOC-NEXT: Link: 0
22#RELOC-NEXT: Info: 0
23#RELOC-NEXT: AddressAlignment: 8
24#RELOC-NEXT: EntrySize: 0
25#RELOC-NEXT: }
26#RELOC: Relocations [
27#RELOC-NEXT: Section ({{.*}}) .rela.dyn {
28#RELOC-NEXT: 0x300B8 R_AARCH64_TLS_TPREL64 bar 0x0
29#RELOC-NEXT: 0x300B0 R_AARCH64_TLS_TPREL64 foo 0x0
30#RELOC-NEXT: }
31#RELOC-NEXT:]
32
33# Page(0x300B0) - Page(0x20000) = 0x10000 = 65536
34# 0x300B0 & 0xff8 = 0xB0 = 176
35# Page(0x300B8) - Page(0x20000) = 0x10000 = 65536
36# 0x300B8 & 0xff8 = 0xB8 = 184
37#CHECK: Disassembly of section .text:
38#CHECK: _start:
39#CHECK: 20000: 80 00 00 90 adrp x0, #65536
40#CHECK: 20004: 00 58 40 f9 ldr x0, [x0, #176]
41#CHECK: 20008: 80 00 00 90 adrp x0, #65536
42#CHECK: 2000c: 00 5c 40 f9 ldr x0, [x0, #184]
43
44.globl _start
45_start:
46 adrp x0, :gottprel:foo
47 ldr x0, [x0, #:gottprel_lo12:foo]
48
49 adrp x0, :gottprel:bar
50 ldr x0, [x0, #:gottprel_lo12:bar]
deps/lld/test/ELF/aarch64-tls-iele.s created+33
......@@ -0,0 +1,33 @@
1# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %p/Inputs/aarch64-tls-ie.s -o %ttlsie.o
2# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %tmain.o
3# RUN: ld.lld %tmain.o %ttlsie.o -o %tout
4# RUN: llvm-objdump -d %tout | FileCheck %s
5# RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s
6# REQUIRES: aarch64
7
8# Initial-Exec to Local-Exec relax creates no dynamic relocations.
9# RELOC: Relocations [
10# RELOC-NEXT: ]
11
12# TCB size = 0x16 and foo is first element from TLS register.
13# CHECK: Disassembly of section .text:
14# CHECK: _start:
15# CHECK-NEXT: 20000: 00 00 a0 d2 movz x0, #0, lsl #16
16# CHECK-NEXT: 20004: 80 02 80 f2 movk x0, #20
17# CHECK-NEXT: 20008: 00 00 a0 d2 movz x0, #0, lsl #16
18# CHECK-NEXT: 2000c: 00 02 80 f2 movk x0, #16
19
20.section .tdata
21.align 2
22.type foo_local, %object
23.size foo_local, 4
24foo_local:
25.word 5
26.text
27
28.globl _start
29_start:
30 adrp x0, :gottprel:foo
31 ldr x0, [x0, :gottprel_lo12:foo]
32 adrp x0, :gottprel:foo_local
33 ldr x0, [x0, :gottprel_lo12:foo_local]
deps/lld/test/ELF/aarch64-tls-le.s created+31
......@@ -0,0 +1,31 @@
1# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %tmain.o
2# RUN: ld.lld %tmain.o -o %tout
3# RUN: llvm-objdump -d %tout | FileCheck %s
4# RUN: llvm-readobj -s -r %tout | FileCheck -check-prefix=RELOC %s
5# REQUIRES: aarch64
6
7#Local-Dynamic to Initial-Exec relax creates no
8#RELOC: Relocations [
9#RELOC-NEXT: ]
10
11.globl _start
12_start:
13 mrs x0, TPIDR_EL0
14 add x0, x0, :tprel_hi12:v1
15 add x0, x0, :tprel_lo12_nc:v1
16
17# TCB size = 0x16 and foo is first element from TLS register.
18#CHECK: Disassembly of section .text:
19#CHECK: _start:
20#CHECK: 20000: 40 d0 3b d5 mrs x0, TPIDR_EL0
21#CHECK: 20004: 00 00 40 91 add x0, x0, #0, lsl #12
22#CHECK: 20008: 00 40 00 91 add x0, x0, #16
23
24.type v1,@object
25.section .tbss,"awT",@nobits
26.globl v1
27.p2align 2
28v1:
29.word 0
30.size v1, 4
31
deps/lld/test/ELF/aarch64-tls-pie.s created+28
......@@ -0,0 +1,28 @@
1# REQUIRES: aarch64
2# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-cloudabi %s -o %t1.o
3# RUN: ld.lld -pie %t1.o -o %t
4# RUN: llvm-readobj -r %t | FileCheck %s
5
6# Similar to bug 27174: R_AARCH64_TLSLE_*TPREL* relocations should be
7# eliminated when building a PIE executable, as the static TLS layout is
8# fixed.
9#
10# CHECK: Relocations [
11# CHECK-NEXT: ]
12
13 .globl _start
14_start:
15 # Accessing the variable directly.
16 add x11, x8, :tprel_hi12:i
17 add x11, x11, :tprel_lo12_nc:i
18
19 # Accessing the variable through the GOT.
20 adrp x10, :gottprel:i
21 mrs x8, TPIDR_EL0
22 ldr x10, [x10, :gottprel_lo12:i]
23
24 .section .tbss.i,"awT",@nobits
25 .globl i
26i:
27 .word 0
28 .size i, 4
deps/lld/test/ELF/aarch64-tls-static.s created+37
......@@ -0,0 +1,37 @@
1// REQUIRES: aarch64
2// RUN: llvm-mc %s -o %t.o -triple aarch64-pc-linux -filetype=obj
3// RUN: ld.lld %t.o -o %t.so -shared
4// RUN: llvm-readobj -s %t.so | FileCheck --check-prefix=SEC %s
5// RUN: llvm-objdump -d %t.so | FileCheck %s
6
7foo:
8 adrp x0, :tlsdesc:bar
9 ldr x1, [x0, :tlsdesc_lo12:bar]
10 add x0, x0, :tlsdesc_lo12:bar
11 .tlsdesccall bar
12 blr x1
13
14
15 .section .tdata,"awT",@progbits
16bar:
17 .word 42
18
19
20// SEC: Name: .got
21// SEC-NEXT: Type: SHT_PROGBITS
22// SEC-NEXT: Flags [
23// SEC-NEXT: SHF_ALLOC
24// SEC-NEXT: SHF_WRITE
25// SEC-NEXT: ]
26// SEC-NEXT: Address: 0x20098
27// SEC-NEXT: Offset: 0x20098
28// SEC-NEXT: Size: 16
29
30// page(0x20098) - page(0x10000) = 65536
31// 0x98 = 152
32
33// CHECK: foo:
34// CHECK-NEXT: 10000: {{.*}} adrp x0, #65536
35// CHECK-NEXT: 10004: {{.*}} ldr x1, [x0, #152]
36// CHECK-NEXT: 10008: {{.*}} add x0, x0, #152
37// CHECK-NEXT: 1000c: {{.*}} blr x1
deps/lld/test/ELF/aarch64-tlsdesc.s created+72
......@@ -0,0 +1,72 @@
1// REQUIRES: aarch64
2// RUN: llvm-mc -filetype=obj -triple=aarch64-pc-linux %s -o %t.o
3// RUN: ld.lld -shared %t.o -o %t.so
4// RUN: llvm-objdump -d %t.so | FileCheck %s
5// RUN: llvm-readobj -r %t.so | FileCheck --check-prefix=REL %s
6
7 .text
8 adrp x0, :tlsdesc:a
9 ldr x1, [x0, :tlsdesc_lo12:a]
10 add x0, x0, :tlsdesc_lo12:a
11 .tlsdesccall a
12 blr x1
13
14// Create relocation against local TLS symbols where linker should
15// create target specific dynamic TLSDESC relocation where addend is
16// the symbol VMA in tls block.
17
18// CHECK: 10000: {{.*}} adrp x0, #65536
19// CHECK-NEXT: 10004: {{.*}} ldr x1, [x0, #144]
20// CHECK-NEXT: 10008: {{.*}} add x0, x0, #144
21// CHECK-NEXT: 1000c: {{.*}} blr x1
22
23 adrp x0, :tlsdesc:local1
24 ldr x1, [x0, :tlsdesc_lo12:local1]
25 add x0, x0, :tlsdesc_lo12:local1
26 .tlsdesccall a
27 blr x1
28
29// CHECK: 10010: {{.*}} adrp x0, #65536
30// CHECK-NEXT: 10014: {{.*}} ldr x1, [x0, #160]
31// CHECK-NEXT: 10018: {{.*}} add x0, x0, #160
32// CHECK-NEXT: 1001c: {{.*}} blr x1
33
34 adrp x0, :tlsdesc:local2
35 ldr x1, [x0, :tlsdesc_lo12:local2]
36 add x0, x0, :tlsdesc_lo12:local2
37 .tlsdesccall a
38 blr x1
39
40// CHECK: 10020: {{.*}} adrp x0, #65536
41// CHECK-NEXT: 10024: {{.*}} ldr x1, [x0, #176]
42// CHECK-NEXT: 10028: {{.*}} add x0, x0, #176
43// CHECK-NEXT: 1002c: {{.*}} blr x1
44
45 .section .tbss,"awT",@nobits
46 .type local1,@object
47 .p2align 2
48local1:
49 .word 0
50 .size local1, 4
51
52 .type local2,@object
53 .p2align 3
54local2:
55 .xword 0
56 .size local2, 8
57
58
59// 0x1000 + 4096 + 160 = 0x20A0
60// 0x1000 + 4096 + 176 = 0x20B0
61// 0x1000 + 4096 + 144 = 0x2090
62
63// R_AARCH64_TLSDESC - 0x0 -> start of tls block
64// R_AARCH64_TLSDESC - 0x8 -> align (sizeof (local1), 8)
65
66// REL: Relocations [
67// REL-NEXT: Section (4) .rela.dyn {
68// REL-NEXT: 0x200A0 R_AARCH64_TLSDESC - 0x0
69// REL-NEXT: 0x200B0 R_AARCH64_TLSDESC - 0x8
70// REL-NEXT: 0x20090 R_AARCH64_TLSDESC a 0x0
71// REL-NEXT: }
72// REL-NEXT: ]
deps/lld/test/ELF/aarch64-tstbr14-reloc.s created+96
......@@ -0,0 +1,96 @@
1# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %p/Inputs/aarch64-tstbr14-reloc.s -o %t1
2# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %t2
3# RUN: ld.lld %t1 %t2 -o %t
4# RUN: llvm-objdump -d %t | FileCheck %s
5# RUN: ld.lld -shared %t1 %t2 -o %t3
6# RUN: llvm-objdump -d %t3 | FileCheck -check-prefix=DSO %s
7# RUN: llvm-readobj -s -r %t3 | FileCheck -check-prefix=DSOREL %s
8# REQUIRES: aarch64
9
10# 0x1101c - 28 = 0x20000
11# 0x11020 - 16 = 0x20010
12# 0x11024 - 36 = 0x20000
13# 0x11028 - 24 = 0x20010
14# CHECK: Disassembly of section .text:
15# CHECK-NEXT: _foo:
16# CHECK-NEXT: 20000: {{.*}} nop
17# CHECK-NEXT: 20004: {{.*}} nop
18# CHECK-NEXT: 20008: {{.*}} nop
19# CHECK-NEXT: 2000c: {{.*}} nop
20# CHECK: _bar:
21# CHECK-NEXT: 20010: {{.*}} nop
22# CHECK-NEXT: 20014: {{.*}} nop
23# CHECK-NEXT: 20018: {{.*}} nop
24# CHECK: _start:
25# CHECK-NEXT: 2001c: {{.*}} tbnz w3, #15, #-28
26# CHECK-NEXT: 20020: {{.*}} tbnz w3, #15, #-16
27# CHECK-NEXT: 20024: {{.*}} tbz x6, #45, #-36
28# CHECK-NEXT: 20028: {{.*}} tbz x6, #45, #-24
29
30#DSOREL: Section {
31#DSOREL: Index:
32#DSOREL: Name: .got.plt
33#DSOREL-NEXT: Type: SHT_PROGBITS
34#DSOREL-NEXT: Flags [
35#DSOREL-NEXT: SHF_ALLOC
36#DSOREL-NEXT: SHF_WRITE
37#DSOREL-NEXT: ]
38#DSOREL-NEXT: Address: 0x20000
39#DSOREL-NEXT: Offset: 0x20000
40#DSOREL-NEXT: Size: 40
41#DSOREL-NEXT: Link: 0
42#DSOREL-NEXT: Info: 0
43#DSOREL-NEXT: AddressAlignment: 8
44#DSOREL-NEXT: EntrySize: 0
45#DSOREL-NEXT: }
46#DSOREL: Relocations [
47#DSOREL-NEXT: Section ({{.*}}) .rela.plt {
48#DSOREL-NEXT: 0x20018 R_AARCH64_JUMP_SLOT _foo
49#DSOREL-NEXT: 0x20020 R_AARCH64_JUMP_SLOT _bar
50#DSOREL-NEXT: }
51#DSOREL-NEXT:]
52
53#DSO: Disassembly of section .text:
54#DSO-NEXT: _foo:
55#DSO-NEXT: 10000: {{.*}} nop
56#DSO-NEXT: 10004: {{.*}} nop
57#DSO-NEXT: 10008: {{.*}} nop
58#DSO-NEXT: 1000c: {{.*}} nop
59#DSO: _bar:
60#DSO-NEXT: 10010: {{.*}} nop
61#DSO-NEXT: 10014: {{.*}} nop
62#DSO-NEXT: 10018: {{.*}} nop
63#DSO: _start:
64# 0x1001c + 52 = 0x10050 = PLT[1]
65# 0x10020 + 64 = 0x10060 = PLT[2]
66# 0x10024 + 44 = 0x10050 = PLT[1]
67# 0x10028 + 56 = 0x10060 = PLT[2]
68#DSO-NEXT: 1001c: {{.*}} tbnz w3, #15, #52
69#DSO-NEXT: 10020: {{.*}} tbnz w3, #15, #64
70#DSO-NEXT: 10024: {{.*}} tbz x6, #45, #44
71#DSO-NEXT: 10028: {{.*}} tbz x6, #45, #56
72#DSO-NEXT: Disassembly of section .plt:
73#DSO-NEXT: .plt:
74#DSO-NEXT: 10030: {{.*}} stp x16, x30, [sp, #-16]!
75#DSO-NEXT: 10034: {{.*}} adrp x16, #65536
76#DSO-NEXT: 10038: {{.*}} ldr x17, [x16, #16]
77#DSO-NEXT: 1003c: {{.*}} add x16, x16, #16
78#DSO-NEXT: 10040: {{.*}} br x17
79#DSO-NEXT: 10044: {{.*}} nop
80#DSO-NEXT: 10048: {{.*}} nop
81#DSO-NEXT: 1004c: {{.*}} nop
82#DSO-NEXT: 10050: {{.*}} adrp x16, #65536
83#DSO-NEXT: 10054: {{.*}} ldr x17, [x16, #24]
84#DSO-NEXT: 10058: {{.*}} add x16, x16, #24
85#DSO-NEXT: 1005c: {{.*}} br x17
86#DSO-NEXT: 10060: {{.*}} adrp x16, #65536
87#DSO-NEXT: 10064: {{.*}} ldr x17, [x16, #32]
88#DSO-NEXT: 10068: {{.*}} add x16, x16, #32
89#DSO-NEXT: 1006c: {{.*}} br x17
90
91.globl _start
92_start:
93 tbnz w3, #15, _foo
94 tbnz w3, #15, _bar
95 tbz x6, #45, _foo
96 tbz x6, #45, _bar
deps/lld/test/ELF/aarch64-undefined-weak.s created+45
......@@ -0,0 +1,45 @@
1// RUN: llvm-mc -filetype=obj -triple=aarch64-none-linux %s -o %t
2// RUN: ld.lld %t -o %t2 2>&1
3// RUN: llvm-objdump -triple=aarch64-none-linux -d %t2 | FileCheck %s
4// REQUIRES: aarch64
5
6// Check that the ARM 64-bit ABI rules for undefined weak symbols are applied.
7// Branch instructions are resolved to the next instruction. Undefined
8// Symbols in relative are resolved to the place so S - P + A = A.
9
10 .weak target
11
12 .text
13 .global _start
14_start:
15// R_AARCH64_JUMP26
16 b target
17// R_AARCH64_CALL26
18 bl target
19// R_AARCH64_CONDBR19
20 b.eq target
21// R_AARCH64_TSTBR14
22 cbz x1, target
23// R_AARCH64_ADR_PREL_LO21
24 adr x0, target
25// R_AARCH64_ADR_PREL_PG_HI21
26 adrp x0, target
27// R_AARCH64_PREL32
28 .word target - .
29// R_AARCH64_PREL64
30 .xword target - .
31// R_AARCH64_PREL16
32 .hword target - .
33
34// CHECK: Disassembly of section .text:
35// 131076 = 0x20004
36// CHECK: 20000: {{.*}} b #4
37// CHECK-NEXT: 20004: {{.*}} bl #4
38// CHECK-NEXT: 20008: {{.*}} b.eq #4
39// CHECK-NEXT: 2000c: {{.*}} cbz x1, #4
40// CHECK-NEXT: 20010: {{.*}} adr x0, #0
41// CHECK-NEXT: 20014: {{.*}} adrp x0, #-131072
42// CHECK: 20018: {{.*}} .word 0x00000000
43// CHECK-NEXT: 2001c: {{.*}} .word 0x00000000
44// CHECK-NEXT: 20020: {{.*}} .word 0x00000000
45// CHECK-NEXT: 20024: {{.*}} .short 0x0000
deps/lld/test/ELF/abs-conflict.s created+18
......@@ -0,0 +1,18 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: ld.lld %t.o %t.o -o %t.so -shared
4// RUN: llvm-readobj --dyn-symbols %t.so | FileCheck %s
5
6// CHECK: Name: foo
7// CHECK-NEXT: Value: 0x123
8
9.global foo
10foo = 0x123
11
12// RUN: echo ".global foo; foo = 0x124" > %t2.s
13// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %t2.s -o %t2.o
14// RUN: not ld.lld %t.o %t2.o -o %t.so -shared 2>&1 | FileCheck --check-prefix=DUP %s
15
16// DUP: duplicate symbol: foo
17// DUP-NEXT: >>> defined in {{.*}}.o
18// DUP-NEXT: >>> defined in <internal>
deps/lld/test/ELF/abs-hidden.s created+46
......@@ -0,0 +1,46 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/abs-hidden.s -o %t2.o
4// RUN: ld.lld %t.o %t2.o -o %t.so -shared
5// RUN: llvm-readobj -r -s -section-data %t.so | FileCheck %s
6
7 .quad foo
8 .long foo@gotpcrel
9
10// CHECK: Name: .text
11// CHECK-NEXT: Type: SHT_PROGBITS
12// CHECK-NEXT: Flags [
13// CHECK-NEXT: SHF_ALLOC
14// CHECK-NEXT: SHF_EXECINSTR
15// CHECK-NEXT: ]
16// CHECK-NEXT: Address: 0x1000
17// CHECK-NEXT: Offset:
18// CHECK-NEXT: Size: 12
19// CHECK-NEXT: Link: 0
20// CHECK-NEXT: Info: 0
21// CHECK-NEXT: AddressAlignment: 4
22// CHECK-NEXT: EntrySize: 0
23// CHECK-NEXT: SectionData (
24// CHECK-NEXT: 0000: 42000000 00000000 58100000
25// 0x2060 - (0x1000 + 8) = 1058
26// CHECK-NEXT: )
27
28// CHECK: Name: .got
29// CHECK-NEXT: Type: SHT_PROGBITS
30// CHECK-NEXT: Flags [
31// CHECK-NEXT: SHF_ALLOC
32// CHECK-NEXT: SHF_WRITE
33// CHECK-NEXT: ]
34// CHECK-NEXT: Address: 0x2060
35// CHECK-NEXT: Offset:
36// CHECK-NEXT: Size: 8
37// CHECK-NEXT: Link: 0
38// CHECK-NEXT: Info: 0
39// CHECK-NEXT: AddressAlignment: 8
40// CHECK-NEXT: EntrySize: 0
41// CHECK-NEXT: SectionData (
42// CHECK-NEXT: 0000: 42000000 00000000
43// CHECK-NEXT: )
44
45// CHECK: Relocations [
46// CHECK-NEXT: ]
deps/lld/test/ELF/allow-multiple-definition.s created+29
......@@ -0,0 +1,29 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1
4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/allow-multiple-definition.s -o %t2
5# RUN: not ld.lld %t1 %t2 -o %t3
6# RUN: ld.lld --allow-multiple-definition %t1 %t2 -o %t3
7# RUN: ld.lld --allow-multiple-definition %t2 %t1 -o %t4
8# RUN: llvm-objdump -d %t3 | FileCheck %s
9# RUN: llvm-objdump -d %t4 | FileCheck -check-prefix=REVERT %s
10
11# inputs contain different constants for instuction movl.
12# Tests below checks that order of files in command line
13# affects on what symbol will be used.
14# If flag allow-multiple-definition is enabled the first
15# meet symbol should be used.
16
17# CHECK: _bar:
18# CHECK-NEXT: 201000: b8 01 00 00 00 movl $1, %eax
19
20# REVERT: _bar:
21# REVERT-NEXT: 201000: b8 02 00 00 00 movl $2, %eax
22
23.globl _bar
24.type _bar, @function
25_bar:
26 mov $1, %eax
27
28.globl _start
29_start:
deps/lld/test/ELF/allow-shlib-undefined.s created+26
......@@ -0,0 +1,26 @@
1# REQUIRES: x86
2# --allow-shlib-undefined and --no-allow-shlib-undefined are fully
3# ignored in linker implementation.
4# --allow-shlib-undefined is set by default
5# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
6# RUN: %p/Inputs/allow-shlib-undefined.s -o %t
7# RUN: ld.lld -shared %t -o %t.so
8# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1
9
10# Executable: should link with DSO containing undefined symbols in any case.
11# RUN: ld.lld %t1 %t.so -o %t2
12# RUN: ld.lld --no-allow-shlib-undefined %t1 %t.so -o %t2
13# RUN: ld.lld --allow-shlib-undefined %t1 %t.so -o %t2
14
15# DSO with undefines:
16# should link with or without any of these options.
17# RUN: ld.lld -shared %t -o %t.so
18# RUN: ld.lld -shared --allow-shlib-undefined %t -o %t.so
19# RUN: ld.lld -shared --no-allow-shlib-undefined %t -o %t.so
20
21# Executable still should not link when have undefines inside.
22# RUN: not ld.lld %t -o %t.so
23
24.globl _start
25_start:
26 callq _shared@PLT
deps/lld/test/ELF/amdgpu-globals.s created+64
......@@ -0,0 +1,64 @@
1# RUN: llvm-mc -filetype=obj -triple amdgcn--amdhsa -mcpu=kaveri %s -o %t.o
2# RUN: ld.lld -shared %t.o -o %t
3# RUN: llvm-readobj -sections -symbols -program-headers %t | FileCheck %s
4
5# REQUIRES: amdgpu
6
7.type glob0, @object
8.data
9 .globl glob0
10glob0:
11 .long 1
12 .size glob0, 4
13
14.type glob1, @object
15.section .rodata, #alloc
16 .globl glob1
17glob1:
18 .long 2
19 .size glob1, 4
20
21# CHECK: Section {
22# CHECK: Name: .rodata
23# CHECK: Type: SHT_PROGBITS
24# CHECK: Flags [ (0x2)
25# CHECK: SHF_ALLOC (0x2)
26# CHECK: ]
27# CHECK: Address: [[RODATA_ADDR:[0-9xa-f]+]]
28# CHECK: }
29
30# CHECK: Section {
31# CHECK: Name: .data
32# CHECK: Type: SHT_PROGBITS
33# CHECK: Flags [ (0x3)
34# CHECK: SHF_ALLOC (0x2)
35# CHECK: SHF_WRITE (0x1)
36# CHECK: ]
37# CHECK: Address: [[DATA_ADDR:[0-9xa-f]+]]
38# CHECK: }
39
40# CHECK: Symbol {
41# CHECK: Name: glob0
42# CHECK: Value: [[DATA_ADDR]]
43# CHECK: Size: 4
44# CHECK: Type: Object
45# CHECK: Section: .data
46# CHECK: }
47
48# CHECK: Symbol {
49# CHECK: Name: glob1
50# CHECK: Value: [[RODATA_ADDR]]
51# CHECK: Size: 4
52# CHECK: Type: Object
53# CHECK: Section: .rodata
54# CHECK: }
55
56# CHECK: ProgramHeader {
57# CHECK: Type: PT_LOAD
58# CHECK: VirtualAddress:
59# CHECK: }
60
61# CHECK: ProgramHeader {
62# CHECK: Type: PT_LOAD
63# CHECK: VirtualAddress:
64# CHECK: }
deps/lld/test/ELF/amdgpu-kernels.s created+59
......@@ -0,0 +1,59 @@
1# RUN: llvm-mc -filetype=obj -triple amdgcn--amdhsa -mcpu=kaveri %s -o %t.o
2# RUN: ld.lld -shared %t.o -o %t
3# RUN: llvm-readobj -sections -symbols -program-headers %t | FileCheck %s
4
5# REQUIRES: amdgpu
6
7.hsa_code_object_version 1,0
8.hsa_code_object_isa 7,0,0,"AMD","AMDGPU"
9
10.text
11.globl kernel0
12.align 256
13.amdgpu_hsa_kernel kernel0
14kernel0:
15 s_endpgm
16.Lfunc_end0:
17 .size kernel0, .Lfunc_end0-kernel0
18
19.globl kernel1
20.align 256
21.amdgpu_hsa_kernel kernel1
22kernel1:
23 s_endpgm
24 s_endpgm
25.Lfunc_end1:
26 .size kernel1, .Lfunc_end1-kernel1
27
28
29# CHECK: Section {
30# CHECK: Name: .text
31# CHECK: Type: SHT_PROGBITS
32# CHECK: Flags [ (0x6)
33# CHECK: SHF_ALLOC (0x2)
34# CHECK: SHF_EXECINSTR (0x4)
35# CHECK: ]
36# CHECK: }
37
38# CHECK: Symbol {
39# CHECK: Name: kernel0
40# CHECK: Value:
41# CHECK: Size: 4
42# CHECK: Binding: Global
43# CHECK: Type: AMDGPU_HSA_KERNEL
44# CHECK: Section: .text
45# CHECK: }
46
47# CHECK: Symbol {
48# CHECK: Name: kernel1
49# CHECK: Value:
50# CHECK: Size: 8
51# CHECK: Binding: Global
52# CHECK: Type: AMDGPU_HSA_KERNEL
53# CHECK: Section: .text
54# CHECK: }
55
56# CHECK: ProgramHeader {
57# CHECK: Type: PT_LOAD
58# CHECK: VirtualAddress:
59# CHECK: }
deps/lld/test/ELF/amdgpu-relocs.s created+93
......@@ -0,0 +1,93 @@
1# RUN: llvm-mc -filetype=obj -triple=amdgcn--amdhsa -mcpu=fiji %s -o %t.o
2# RUN: ld.lld -shared %t.o -o %t.so
3# RUN: llvm-readobj -r %t.so | FileCheck %s
4# RUN: llvm-objdump -s %t.so | FileCheck %s --check-prefix=OBJDUMP
5
6# REQUIRES: amdgpu
7
8.text
9
10kernel0:
11 s_mov_b32 s0, common_var0@GOTPCREL+4
12 s_mov_b32 s0, common_var1@gotpcrel32@lo+4
13 s_mov_b32 s0, common_var2@gotpcrel32@hi+4
14
15 s_mov_b32 s0, global_var0@GOTPCREL+4
16 s_mov_b32 s0, global_var1@gotpcrel32@lo+4
17 s_mov_b32 s0, global_var2@gotpcrel32@hi+4
18
19 s_mov_b32 s0, extern_var0@GOTPCREL+4
20 s_mov_b32 s0, extern_var1@gotpcrel32@lo+4
21 s_mov_b32 s0, extern_var2@gotpcrel32@hi+4
22
23 s_mov_b32 s0, weak_var0@GOTPCREL+4
24 s_mov_b32 s0, weak_var1@gotpcrel32@lo+4
25 s_mov_b32 s0, weak_var2@gotpcrel32@hi+4
26
27 s_mov_b32 s0, weakref_var0@GOTPCREL+4
28 s_mov_b32 s0, weakref_var1@gotpcrel32@lo+4
29 s_mov_b32 s0, weakref_var2@gotpcrel32@hi+4
30
31 s_mov_b32 s0, local_var0+4
32 s_mov_b32 s0, local_var1@rel32@lo+4
33 s_mov_b32 s0, local_var2@rel32@hi+4
34
35 s_endpgm
36
37 .comm common_var0,1024,4
38 .comm common_var1,1024,4
39 .comm common_var2,1024,4
40 .globl global_var0
41 .globl global_var1
42 .globl global_var1
43 .weak weak_var0
44 .weak weak_var1
45 .weak weak_var2
46 .weakref weakref_var0, weakref_alias_var0
47 .weakref weakref_var1, weakref_alias_var1
48 .weakref weakref_var2, weakref_alias_var2
49 .local local_var0
50 .local local_var1
51 .local local_var2
52
53# R_AMDGPU_ABS32:
54.section nonalloc, "w", @progbits
55 .long var0, common_var2+4
56 .long var1, common_var1+8
57 .long var2, common_var0+12
58
59# R_AMDGPU_ABS64:
60.type ptr, @object
61.data
62 .globl ptr
63 .p2align 3
64ptr:
65 .quad temp
66 .size ptr, 8
67
68# The relocation for local_var{0, 1, 2} and var should be resolved by the
69# linker.
70# CHECK: Relocations [
71# CHECK: .rela.dyn {
72# CHECK-NEXT: R_AMDGPU_ABS64 common_var0 0x0
73# CHECK-NEXT: R_AMDGPU_ABS64 common_var1 0x0
74# CHECK-NEXT: R_AMDGPU_ABS64 common_var2 0x0
75# CHECK-NEXT: R_AMDGPU_ABS64 extern_var0 0x0
76# CHECK-NEXT: R_AMDGPU_ABS64 extern_var1 0x0
77# CHECK-NEXT: R_AMDGPU_ABS64 extern_var2 0x0
78# CHECK-NEXT: R_AMDGPU_ABS64 global_var0 0x0
79# CHECK-NEXT: R_AMDGPU_ABS64 global_var1 0x0
80# CHECK-NEXT: R_AMDGPU_ABS64 global_var2 0x0
81# CHECK-NEXT: R_AMDGPU_ABS64 temp 0x0
82# CHECK-NEXT: R_AMDGPU_ABS64 weak_var0 0x0
83# CHECK-NEXT: R_AMDGPU_ABS64 weak_var1 0x0
84# CHECK-NEXT: R_AMDGPU_ABS64 weak_var2 0x0
85# CHECK-NEXT: R_AMDGPU_ABS64 weakref_alias_var0 0x0
86# CHECK-NEXT: R_AMDGPU_ABS64 weakref_alias_var1 0x0
87# CHECK-NEXT: R_AMDGPU_ABS64 weakref_alias_var2 0x0
88# CHECK-NEXT: }
89# CHECK-NEXT: ]
90
91# OBJDUMP: Contents of section nonalloc:
92# OBJDUMP-NEXT: 0000 00000000 04480000 00000000 08440000
93# OBJDUMP-NEXT: 00000000 0c400000
deps/lld/test/ELF/archive.s created+40
......@@ -0,0 +1,40 @@
1# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/archive.s -o %t2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/archive2.s -o %t3
4# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/archive3.s -o %t4
5# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/archive4.s -o %t5
6# RUN: llvm-ar rcs %tar %t2 %t3 %t4
7# RUN: ld.lld %t %tar %t5 -o %tout
8# RUN: llvm-nm %tout | FileCheck %s
9# RUN: rm -f %tarthin
10# RUN: llvm-ar --format=gnu rcsT %tarthin %t2 %t3 %t4
11# RUN: ld.lld %t %tarthin %t5 -o %tout
12# RUN: llvm-nm %tout | FileCheck %s
13# REQUIRES: x86
14
15# Nothing here. Just needed for the linker to create a undefined _start symbol.
16
17.quad end
18
19.weak foo
20.quad foo
21
22.weak bar
23.quad bar
24
25
26# CHECK: T _start
27# CHECK-NEXT: T bar
28# CHECK-NEXT: T end
29# CHECK-NEXT: w foo
30
31
32# Test that the hitting the first object file after having a lazy symbol for
33# _start is handled correctly.
34# RUN: ld.lld %tar %t -o %tout
35# RUN: llvm-nm %tout | FileCheck --check-prefix=AR-FIRST %s
36
37# AR-FIRST: T _start
38# AR-FIRST-NEXT: w bar
39# AR-FIRST-NEXT: T end
40# AR-FIRST-NEXT: w foo
deps/lld/test/ELF/arm-abs32-dyn.s created+32
......@@ -0,0 +1,32 @@
1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux %s -o %t.o
3
4// Creates a R_ARM_ABS32 relocation against foo and bar, bar has hidden
5// visibility so we expect a R_ARM_RELATIVE
6 .syntax unified
7 .globl foo
8foo:
9 .globl bar
10 .hidden bar
11bar:
12
13 .data
14 .word foo
15 .word bar
16
17// RUN: ld.lld -shared -o %t.so %t.o
18// RUN: llvm-readobj -symbols -dyn-relocations %t.so | FileCheck %s
19
20// CHECK: Dynamic Relocations {
21// CHECK-NEXT: 0x1004 R_ARM_RELATIVE
22// CHECK-NEXT: 0x1000 R_ARM_ABS32 foo 0x0
23// CHECK-NEXT: }
24
25// CHECK: Symbols [
26// CHECK: Symbol {
27// CHECK: Name: bar
28// CHECK-NEXT: Value: 0x1000
29
30// CHECK: Symbol {
31// CHECK: Name: foo
32// CHECK-NEXT: Value: 0x1000
deps/lld/test/ELF/arm-attributes.s created+183
......@@ -0,0 +1,183 @@
1// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-attributes1.s -o %t1.o
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t2.o
3
4// RUN: ld.lld %t1.o %t2.o -o %t
5// RUN: llvm-readobj -arm-attributes %t | FileCheck %s
6// RUN: ld.lld %t1.o %t2.o -shared -o %t2
7// RUN: llvm-readobj -arm-attributes %t2 | FileCheck %s
8// RUN: ld.lld %t1.o %t2.o -r -o %t3
9// RUN: llvm-readobj -arm-attributes %t3 | FileCheck %s
10// REQUIRES: arm
11
12// Check that we retain only 1 SHT_ARM_ATTRIBUTES section. At present we do not
13// try and merge or use the contents of SHT_ARM_ATTRIBUTES sections. We just
14// pass the first one through.
15 .text
16 .syntax unified
17 .eabi_attribute 67, "2.09" @ Tag_conformance
18 .cpu cortex-a8
19 .eabi_attribute 6, 10 @ Tag_CPU_arch
20 .eabi_attribute 7, 65 @ Tag_CPU_arch_profile
21 .eabi_attribute 8, 1 @ Tag_ARM_ISA_use
22 .eabi_attribute 9, 2 @ Tag_THUMB_ISA_use
23 .fpu neon
24 .eabi_attribute 15, 1 @ Tag_ABI_PCS_RW_data
25 .eabi_attribute 16, 1 @ Tag_ABI_PCS_RO_data
26 .eabi_attribute 17, 2 @ Tag_ABI_PCS_GOT_use
27 .eabi_attribute 20, 1 @ Tag_ABI_FP_denormal
28 .eabi_attribute 21, 1 @ Tag_ABI_FP_exceptions
29 .eabi_attribute 23, 3 @ Tag_ABI_FP_number_model
30 .eabi_attribute 34, 1 @ Tag_CPU_unaligned_access
31 .eabi_attribute 24, 1 @ Tag_ABI_align_needed
32 .eabi_attribute 25, 1 @ Tag_ABI_align_preserved
33 .eabi_attribute 38, 1 @ Tag_ABI_FP_16bit_format
34 .eabi_attribute 18, 4 @ Tag_ABI_PCS_wchar_t
35 .eabi_attribute 26, 2 @ Tag_ABI_enum_size
36 .eabi_attribute 14, 0 @ Tag_ABI_PCS_R9_use
37 .eabi_attribute 68, 1 @ Tag_Virtualization_use
38 .globl _start
39 .p2align 2
40 .type _start,%function
41_start:
42 .globl func
43 bl func
44 bx lr
45
46// CHECK: BuildAttributes {
47// CHECK-NEXT: FormatVersion: 0x41
48// CHECK-NEXT: Section 1 {
49// CHECK-NEXT: SectionLength: 72
50// CHECK-NEXT: Vendor: aeabi
51// CHECK-NEXT: Tag: Tag_File (0x1)
52// CHECK-NEXT: Size: 62
53// CHECK-NEXT: FileAttributes {
54// CHECK-NEXT: Attribute {
55// CHECK-NEXT: Tag: 67
56// CHECK-NEXT: TagName: conformance
57// CHECK-NEXT: Value: 2.09
58// CHECK-NEXT: }
59// CHECK-NEXT: Attribute {
60// CHECK-NEXT: Tag: 5
61// CHECK-NEXT: TagName: CPU_name
62// CHECK-NEXT: Value: cortex-a8
63// CHECK-NEXT: }
64// CHECK-NEXT: Attribute {
65// CHECK-NEXT: Tag: 6
66// CHECK-NEXT: Value: 10
67// CHECK-NEXT: TagName: CPU_arch
68// CHECK-NEXT: Description: ARM v7
69// CHECK-NEXT: }
70// CHECK-NEXT: Attribute {
71// CHECK-NEXT: Tag: 7
72// CHECK-NEXT: Value: 65
73// CHECK-NEXT: TagName: CPU_arch_profile
74// CHECK-NEXT: Description: Application
75// CHECK-NEXT: }
76// CHECK-NEXT: Attribute {
77// CHECK-NEXT: Tag: 8
78// CHECK-NEXT: Value: 1
79// CHECK-NEXT: TagName: ARM_ISA_use
80// CHECK-NEXT: Description: Permitted
81// CHECK-NEXT: }
82// CHECK-NEXT: Attribute {
83// CHECK-NEXT: Tag: 9
84// CHECK-NEXT: Value: 2
85// CHECK-NEXT: TagName: THUMB_ISA_use
86// CHECK-NEXT: Description: Thumb-2
87// CHECK-NEXT: }
88// CHECK-NEXT: Attribute {
89// CHECK-NEXT: Tag: 10
90// CHECK-NEXT: Value: 3
91// CHECK-NEXT: TagName: FP_arch
92// CHECK-NEXT: Description: VFPv3
93// CHECK-NEXT: }
94// CHECK-NEXT: Attribute {
95// CHECK-NEXT: Tag: 12
96// CHECK-NEXT: Value: 1
97// CHECK-NEXT: TagName: Advanced_SIMD_arch
98// CHECK-NEXT: Description: NEONv1
99// CHECK-NEXT: }
100// CHECK-NEXT: Attribute {
101// CHECK-NEXT: Tag: 14
102// CHECK-NEXT: Value: 0
103// CHECK-NEXT: TagName: ABI_PCS_R9_use
104// CHECK-NEXT: Description: v6
105// CHECK-NEXT: }
106// CHECK-NEXT: Attribute {
107// CHECK-NEXT: Tag: 15
108// CHECK-NEXT: Value: 1
109// CHECK-NEXT: TagName: ABI_PCS_RW_data
110// CHECK-NEXT: Description: PC-relative
111// CHECK-NEXT: }
112// CHECK-NEXT: Attribute {
113// CHECK-NEXT: Tag: 16
114// CHECK-NEXT: Value: 1
115// CHECK-NEXT: TagName: ABI_PCS_RO_data
116// CHECK-NEXT: Description: PC-relative
117// CHECK-NEXT: }
118// CHECK-NEXT: Attribute {
119// CHECK-NEXT: Tag: 17
120// CHECK-NEXT: Value: 2
121// CHECK-NEXT: TagName: ABI_PCS_GOT_use
122// CHECK-NEXT: Description: GOT-Indirect
123// CHECK-NEXT: }
124// CHECK-NEXT: Attribute {
125// CHECK-NEXT: Tag: 18
126// CHECK-NEXT: Value: 4
127// CHECK-NEXT: TagName: ABI_PCS_wchar_t
128// CHECK-NEXT: Description: 4-byte
129// CHECK-NEXT: }
130// CHECK-NEXT: Attribute {
131// CHECK-NEXT: Tag: 20
132// CHECK-NEXT: Value: 1
133// CHECK-NEXT: TagName: ABI_FP_denormal
134// CHECK-NEXT: Description: IEEE-754
135// CHECK-NEXT: }
136// CHECK-NEXT: Attribute {
137// CHECK-NEXT: Tag: 21
138// CHECK-NEXT: Value: 1
139// CHECK-NEXT: TagName: ABI_FP_exceptions
140// CHECK-NEXT: Description: IEEE-754
141// CHECK-NEXT: }
142// CHECK-NEXT: Attribute {
143// CHECK-NEXT: Tag: 23
144// CHECK-NEXT: Value: 3
145// CHECK-NEXT: TagName: ABI_FP_number_model
146// CHECK-NEXT: Description: IEEE-754
147// CHECK-NEXT: }
148// CHECK-NEXT: Attribute {
149// CHECK-NEXT: Tag: 24
150// CHECK-NEXT: Value: 1
151// CHECK-NEXT: TagName: ABI_align_needed
152// CHECK-NEXT: Description: 8-byte alignment
153// CHECK-NEXT: }
154// CHECK-NEXT: Attribute {
155// CHECK-NEXT: Tag: 25
156// CHECK-NEXT: Value: 1
157// CHECK-NEXT: TagName: ABI_align_preserved
158// CHECK-NEXT: Description: 8-byte data alignment
159// CHECK-NEXT: }
160// CHECK-NEXT: Attribute {
161// CHECK-NEXT: Tag: 26
162// CHECK-NEXT: Value: 2
163// CHECK-NEXT: TagName: ABI_enum_size
164// CHECK-NEXT: Description: Int32
165// CHECK-NEXT: }
166// CHECK-NEXT: Attribute {
167// CHECK-NEXT: Tag: 34
168// CHECK-NEXT: Value: 1
169// CHECK-NEXT: TagName: CPU_unaligned_access
170// CHECK-NEXT: Description: v6-style
171// CHECK-NEXT: }
172// CHECK-NEXT: Attribute {
173// CHECK-NEXT: Tag: 38
174// CHECK-NEXT: Value: 1
175// CHECK-NEXT: TagName: ABI_FP_16bit_format
176// CHECK-NEXT: Description: IEEE-754
177// CHECK-NEXT: }
178// CHECK-NEXT: Attribute {
179// CHECK-NEXT: Tag: 68
180// CHECK-NEXT: Value: 1
181// CHECK-NEXT: TagName: Virtualization_use
182// CHECK-NEXT: Description: TrustZone
183// CHECK-NEXT: }
deps/lld/test/ELF/arm-blx.s created+114
......@@ -0,0 +1,114 @@
1// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/far-arm-thumb-abs.s -o %tfar
3// RUN: echo "SECTIONS { \
4// RUN: . = 0xb4; \
5// RUN: .callee1 : { *(.callee_low) } \
6// RUN: .callee2 : { *(.callee_arm_low) } \
7// RUN: .caller : { *(.text) } \
8// RUN: .callee3 : { *(.callee_high) } \
9// RUN: .callee4 : { *(.callee_arm_high) } } " > %t.script
10// RUN: ld.lld --script %t.script %t %tfar -o %t2 2>&1
11// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-ARM %s
12// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-THUMB %s
13// REQUIRES: arm
14
15// Test BLX instruction is chosen for ARM BL/BLX instruction and Thumb callee
16// Using two callees to ensure at least one has 2-byte alignment.
17 .syntax unified
18 .thumb
19 .section .callee_low, "ax",%progbits
20 .align 2
21 .type callee_low,%function
22callee_low:
23 bx lr
24 .type callee_low2, %function
25callee_low2:
26 bx lr
27
28 .section .callee_arm_low, "ax",%progbits
29 .arm
30 .balign 0x100
31 .type callee_arm_low,%function
32 .align 2
33callee_arm_low:
34 bx lr
35
36.section .text, "ax",%progbits
37 .arm
38 .globl _start
39 .balign 0x10000
40 .type _start,%function
41_start:
42 bl callee_low
43 blx callee_low
44 bl callee_low2
45 blx callee_low2
46 bl callee_high
47 blx callee_high
48 bl callee_high2
49 blx callee_high2
50 bl blx_far
51 blx blx_far2
52// blx to ARM instruction should be written as a BL
53 bl callee_arm_low
54 blx callee_arm_low
55 bl callee_arm_high
56 blx callee_arm_high
57 bx lr
58
59 .section .callee_high, "ax",%progbits
60 .balign 0x100
61 .thumb
62 .type callee_high,%function
63callee_high:
64 bx lr
65 .type callee_high2,%function
66callee_high2:
67 bx lr
68
69 .section .callee_arm_high, "ax",%progbits
70 .arm
71 .balign 0x100
72 .type callee_arm_high,%function
73callee_arm_high:
74 bx lr
75
76// CHECK-THUMB: Disassembly of section .callee1:
77// CHECK-THUMB-NEXT: callee_low:
78// CHECK-THUMB-NEXT: b4: 70 47 bx lr
79// CHECK-THUMB: callee_low2:
80// CHECK-THUMB-NEXT: b6: 70 47 bx lr
81
82// CHECK-ARM: Disassembly of section .callee2:
83// CHECK-ARM-NEXT: callee_arm_low:
84// CHECK-ARM-NEXT: 100: 1e ff 2f e1 bx lr
85
86// CHECK-ARM: Disassembly of section .caller:
87// CHECK-ARM-NEXT: _start:
88// CHECK-ARM-NEXT: 10000: 2b c0 ff fa blx #-65364 <callee_low>
89// CHECK-ARM-NEXT: 10004: 2a c0 ff fa blx #-65368 <callee_low>
90// CHECK-ARM-NEXT: 10008: 29 c0 ff fb blx #-65370 <callee_low2>
91// CHECK-ARM-NEXT: 1000c: 28 c0 ff fb blx #-65374 <callee_low2>
92// CHECK-ARM-NEXT: 10010: 3a 00 00 fa blx #232 <callee_high>
93// CHECK-ARM-NEXT: 10014: 39 00 00 fa blx #228 <callee_high>
94// CHECK-ARM-NEXT: 10018: 38 00 00 fb blx #226 <callee_high2>
95// CHECK-ARM-NEXT: 1001c: 37 00 00 fb blx #222 <callee_high2>
96// 10020 + 1FFFFFC + 8 = 0x2010024 = blx_far
97// CHECK-ARM-NEXT: 10020: ff ff 7f fa blx #33554428
98// 10024 + 1FFFFFC + 8 = 0x2010028 = blx_far2
99// CHECK-ARM-NEXT: 10024: ff ff 7f fa blx #33554428
100// CHECK-ARM-NEXT: 10028: 34 c0 ff eb bl #-65328 <callee_arm_low>
101// CHECK-ARM-NEXT: 1002c: 33 c0 ff eb bl #-65332 <callee_arm_low>
102// CHECK-ARM-NEXT: 10030: 72 00 00 eb bl #456 <callee_arm_high>
103// CHECK-ARM-NEXT: 10034: 71 00 00 eb bl #452 <callee_arm_high>
104// CHECK-ARM-NEXT: 10038: 1e ff 2f e1 bx lr
105
106// CHECK-THUMB: Disassembly of section .callee3:
107// CHECK-THUMB: callee_high:
108// CHECK-THUMB-NEXT: 10100: 70 47 bx lr
109// CHECK-THUMB: callee_high2:
110// CHECK-THUMB-NEXT: 10102: 70 47 bx lr
111
112// CHECK-ARM: Disassembly of section .callee4:
113// CHECK-NEXT-ARM: callee_arm_high:
114// CHECK-NEXT-ARM: 10200: 1e ff 2f e1 bx lr
deps/lld/test/ELF/arm-branch-error.s created+19
......@@ -0,0 +1,19 @@
1// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/far-arm-abs.s -o %tfar
3// RUN: not ld.lld %t %tfar -o %t2 2>&1 | FileCheck %s
4// REQUIRES: arm
5 .syntax unified
6 .section .text, "ax",%progbits
7 .globl _start
8 .balign 0x10000
9 .type _start,%function
10_start:
11 // address of too_far symbols are just out of range of ARM branch with
12 // 26-bit immediate field and an addend of -8
13 bl too_far1
14 b too_far2
15 beq too_far3
16
17// CHECK: R_ARM_CALL out of range
18// CHECK-NEXT: R_ARM_JUMP24 out of range
19// CHECK-NEXT: R_ARM_JUMP24 out of range
deps/lld/test/ELF/arm-branch.s created+60
......@@ -0,0 +1,60 @@
1// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/far-arm-abs.s -o %tfar
3// RUN: echo "SECTIONS { \
4// RUN: . = 0xb4; \
5// RUN: .callee1 : { *(.callee_low) } \
6// RUN: .caller : { *(.text) } \
7// RUN: .callee2 : { *(.callee_high) } } " > %t.script
8// RUN: ld.lld --script %t.script %t %tfar -o %t2 2>&1
9// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s
10// REQUIRES: arm
11 .syntax unified
12 .section .callee_low, "ax",%progbits
13 .align 2
14 .type callee_low,%function
15callee_low:
16 bx lr
17
18 .section .text, "ax",%progbits
19 .globl _start
20 .balign 0x10000
21 .type _start,%function
22_start:
23 bl callee_low
24 b callee_low
25 beq callee_low
26 bl callee_high
27 b callee_high
28 bne callee_high
29 bl far
30 b far
31 bgt far
32 bx lr
33
34 .section .callee_high, "ax",%progbits
35 .align 2
36 .type callee_high,%function
37callee_high:
38 bx lr
39
40// CHECK: Disassembly of section .caller:
41// CHECK-NEXT: _start:
42// S(callee_low) = 0xb4 P = 0x10000 A = -8 = -0xff54 = -65364
43// CHECK-NEXT: 10000: 2b c0 ff eb bl #-65364 <callee_low>
44// S(callee_low) = 0xb4 P = 0x10004 A = -8 = -0xff58 = -65368
45// CHECK-NEXT: 10004: 2a c0 ff ea b #-65368 <callee_low>
46// S(callee_low) = 0xb4 P = 0x10008 A = -8 = -0xff5c -65372
47// CHECK-NEXT: 10008: 29 c0 ff 0a beq #-65372 <callee_low>
48// S(callee_high) = 0x10028 P = 0x1000c A = -8 = 0x14 = 20
49// CHECK-NEXT: 1000c: 05 00 00 eb bl #20 <callee_high>
50// S(callee_high) = 0x10028 P = 0x10010 A = -8 = 0x10 = 16
51// CHECK-NEXT: 10010: 04 00 00 ea b #16 <callee_high>
52// S(callee_high) = 0x10028 P = 0x10014 A = -8 = 0x0c =12
53// CHECK-NEXT: 10014: 03 00 00 1a bne #12 <callee_high>
54// S(far) = 0x201001c P = 0x10018 A = -8 = 0x1fffffc = 33554428
55// CHECK-NEXT: 10018: ff ff 7f eb bl #33554428
56// S(far) = 0x201001c P = 0x1001c A = -8 = 0x1fffff8 = 33554424
57// CHECK-NEXT: 1001c: fe ff 7f ea b #33554424
58// S(far) = 0x201001c P = 0x10020 A = -8 = 0x1fffff4 = 33554420
59// CHECK-NEXT: 10020: fd ff 7f ca bgt #33554420
60// CHECK-NEXT: 10024: 1e ff 2f e1 bx lr
deps/lld/test/ELF/arm-copy.s created+81
......@@ -0,0 +1,81 @@
1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
3// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/relocation-copy-arm.s -o %t2.o
4// RUN: ld.lld -shared %t2.o -o %t2.so
5// RUN: ld.lld %t.o %t2.so -o %t3
6// RUN: llvm-readobj -s -r --expand-relocs -symbols %t3 | FileCheck %s
7// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t3 | FileCheck -check-prefix=CODE %s
8// RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi -section=.rodata %t3 | FileCheck -check-prefix=RODATA %s
9
10// Copy relocations R_ARM_COPY are required for y and z
11 .syntax unified
12 .text
13 .globl _start
14_start:
15 movw r2,:lower16: y
16 movt r2,:upper16: y
17 ldr r3,[pc,#4]
18 ldr r3,[r3,#0]
19 .rodata
20 .word z
21
22// CHECK: Name: .bss
23// CHECK-NEXT: Type: SHT_NOBITS
24// CHECK-NEXT: Flags [
25// CHECK-NEXT: SHF_ALLOC
26// CHECK-NEXT: SHF_WRITE
27// CHECK-NEXT: ]
28// CHECK-NEXT: Address: 0x13000
29// CHECK-NEXT: Offset:
30// CHECK-NEXT: Size: 8
31// CHECK-NEXT: Link:
32// CHECK-NEXT: Info:
33// CHECK-NEXT: AddressAlignment: 16
34
35// CHECK: Relocations [
36// CHECK-NEXT: Section (5) .rel.dyn {
37// CHECK-NEXT: Relocation {
38// CHECK-NEXT: Offset: 0x13000
39// CHECK-NEXT: Type: R_ARM_COPY
40// CHECK-NEXT: Symbol: y
41// CHECK-NEXT: Addend: 0x0
42// CHECK-NEXT: }
43// CHECK-NEXT: Relocation {
44// CHECK-NEXT: Offset: 0x13004
45// CHECK-NEXT: Type: R_ARM_COPY
46// CHECK-NEXT: Symbol: z
47// CHECK-NEXT: Addend: 0x0
48// CHECK-NEXT: }
49// CHECK-NEXT: }
50
51// CHECK: Symbols [
52// CHECK: Name: y
53// CHECK-NEXT: Value: 0x13000
54// CHECK-NEXT: Size: 4
55// CHECK-NEXT: Binding: Global
56// CHECK-NEXT: Type: Object
57// CHECK-NEXT: Other:
58// CHECK-NEXT: Section: .bss
59// CHECK: Name: z
60// CHECK-NEXT: Value: 0x13004
61// CHECK-NEXT: Size: 4
62// CHECK-NEXT: Binding: Global
63// CHECK-NEXT: Type: Object
64// CHECK-NEXT: Other: 0
65// CHECK-NEXT: Section: .bss
66
67// CODE: Disassembly of section .text:
68// CODE-NEXT: _start:
69// S(y) = 0x13000, A = 0
70// (S + A) & 0x0000ffff = 0x3000 = #12288
71// CODE-NEXT: 11000: 00 20 03 e3 movw r2, #12288
72// S(y) = 0x13000, A = 0
73// ((S + A) & 0xffff0000) >> 16 = 0x1
74// CODE-NEXT: 11004: 01 20 40 e3 movt r2, #1
75// CODE-NEXT: 11008: 04 30 9f e5 ldr r3, [pc, #4]
76// CODE-NEXT: 1100c: 00 30 93 e5 ldr r3, [r3]
77
78
79// RODATA: Contents of section .rodata:
80// S(z) = 0x13004
81// RODATA-NEXT: 10114 04300100
deps/lld/test/ELF/arm-data-prel.s created+63
......@@ -0,0 +1,63 @@
1// RUN: llvm-mc %s -triple=armv7-unknown-linux-gnueabi -filetype=obj -o %t.o
2// RUN: echo "SECTIONS { \
3// RUN: .text : { *(.text) } \
4// RUN: .prel.test : { *(.ARM.exidx) } \
5// RUN: .prel.test.TEST1 : { *(.ARM.exidx.TEST1) } \
6// RUN: .TEST1 : { *(.TEST1) } } " > %t.script
7// RUN: ld.lld --script %t.script %t.o -o %t
8// RUN: llvm-readobj -s -sd %t | FileCheck --check-prefix=CHECK %s
9// REQUIRES: arm
10
11// The R_ARM_PREL31 relocation is used in by the .ARM.exidx exception tables
12// bit31 of the place denotes whether the field is an inline table entry
13// (bit31=1) or relocation (bit31=0)
14// The linker must preserve the value of bit31
15
16// This test case is adapted from llvm/test/MC/ARM/eh-compact-pr0.s
17// We use a linker script to place the .ARM.exidx sections in between
18// the code sections so that we can test positive and negative offsets
19 .syntax unified
20
21 .section .TEST1, "ax",%progbits
22 .globl _start
23 .align 2
24 .type _start,%function
25_start:
26 .fnstart
27 .save {r11, lr}
28 push {r11, lr}
29 .setfp r11, sp
30 mov r11, sp
31 pop {r11, lr}
32 mov pc, lr
33 .fnend
34
35 .section .text, "ax",%progbits
36// The generated .ARM.exidx section will refer to the personality
37// routine __aeabi_unwind_cpp_pr0. Provide a dummy implementation
38// to stop an undefined symbol error
39 .globl __aeabi_unwind_cpp_pr0
40 .align 2
41 .type __aeabi_unwind_cpp_pr0,%function
42__aeabi_unwind_cpp_pr0:
43 .fnstart
44 bx lr
45 .fnend
46
47// The expected value of the exception table is
48// Word0 0 in bit 31, -4 encoded in 31-bit signed offset
49// Word1 Inline table entry EHT Inline Personality Routine #0
50// CHECK: Name: .prel.test
51// CHECK: SectionData (
52// CHECK: 0000: FCFFFF7F B0B0B080
53// CHECK: )
54
55// The expected value of the exception table is
56// Word0 0 in bit 31, +8 encoded in 31-bit signed offset
57// Word1 Inline table entry EHT Inline Personality Routine #0
58// set vsp = r11
59// pop r11, r14
60// CHECK: Name: .prel.test.TEST1
61// CHECK: SectionData (
62// CHECK: 0000: 08000000 80849B80
63// CHECK: )
deps/lld/test/ELF/arm-data-relocs.s created+20
......@@ -0,0 +1,20 @@
1// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/abs256.s -o %t256.o
3// RUN: ld.lld %t %t256.o -o %t2
4// RUN: llvm-objdump -d %t2 | FileCheck %s
5// REQUIRES: arm
6 .syntax unified
7 .globl _start
8_start:
9 .section .R_ARM_ABS32POS, "ax",%progbits
10 .word foo + 0x24
11
12// S = 0x100, A = 0x24
13// S + A = 0x124
14// CHECK: Disassembly of section .R_ARM_ABS32POS:
15// CHECK: 11000: 24 01 00 00
16 .section .R_ARM_ABS32NEG, "ax",%progbits
17 .word foo - 0x24
18// S = 0x100, A = -0x24
19// CHECK: Disassembly of section .R_ARM_ABS32NEG:
20// CHECK: 11004: dc 00 00 00
deps/lld/test/ELF/arm-eabi-version.s created+14
......@@ -0,0 +1,14 @@
1// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
2// RUN: ld.lld -static %t.o -o %tout
3// RUN: llvm-readobj -file-headers %tout | FileCheck %s
4// REQUIRES: arm
5 .syntax unified
6 .text
7 .globl _start
8_start:
9 bx lr
10
11// CHECK: Flags [
12// CHECK-NEXT: 0x1000000
13// CHECK-NEXT: 0x4000000
14// CHECK-NEXT: ]
deps/lld/test/ELF/arm-exidx-canunwind.s created+99
......@@ -0,0 +1,99 @@
1// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
2// RUN: ld.lld %t -o %t2 2>&1
3// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s
4// RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-EXIDX %s
5// RUN: llvm-readobj --program-headers --sections %t2 | FileCheck -check-prefix=CHECK-PT %s
6// REQUIRES: arm
7
8// Test that inline unwinding table entries and references to .ARM.extab
9// entries survive the re-ordering of the .ARM.exidx section
10
11 .syntax unified
12 // Will produce an ARM.exidx entry with inline unwinding instructions
13 .section .text.func1, "ax",%progbits
14 .global func1
15func1:
16 .fnstart
17 bx lr
18 .save {r7, lr}
19 .setfp r7, sp, #0
20 .fnend
21
22 // Unwinding instructions for .text2 too large for an inline entry ARM.exidx
23 // entry. A separate .ARM.extab section is created to hold the unwind entries
24 // The .ARM.exidx table entry has a reference to the .ARM.extab section.
25 .section .text.func2, "ax",%progbits
26 .global func2
27func2:
28 .fnstart
29 bx lr
30 .personality __gxx_personality_v0
31 .handlerdata
32 .long 0
33 .section .text.func2
34 .fnend
35
36 // Dummy implementation of personality routines to satisfy reference from
37 // exception tables
38 .section .text.__gcc_personality_v0, "ax", %progbits
39 .global __gxx_personality_v0
40__gxx_personality_v0:
41 bx lr
42
43 .section .text.__aeabi_unwind_cpp_pr0, "ax", %progbits
44 .global __aeabi_unwind_cpp_pr0
45__aeabi_unwind_cpp_pr0:
46 bx lr
47
48 .text
49 .global _start
50_start:
51 bl func1
52 bl func2
53 bx lr
54
55// CHECK: Disassembly of section .text:
56// CHECK-NEXT: _start:
57// CHECK-NEXT: 11000: 01 00 00 eb bl #4 <func1>
58// CHECK-NEXT: 11004: 01 00 00 eb bl #4 <func2>
59// CHECK-NEXT: 11008: 1e ff 2f e1 bx lr
60// CHECK: func1:
61// CHECK-NEXT: 1100c: 1e ff 2f e1 bx lr
62// CHECK: func2:
63// CHECK-NEXT: 11010: 1e ff 2f e1 bx lr
64// CHECK: __gxx_personality_v0:
65// CHECK-NEXT: 11014: 1e ff 2f e1 bx lr
66// CHECK: __aeabi_unwind_cpp_pr0:
67// CHECK-NEXT: 11018: 1e ff 2f e1 bx lr
68
69// CHECK-EXIDX: Contents of section .ARM.exidx:
70// 100d4 + f38 = 1100c = func1 (inline unwinding data)
71// 100dc + f34 = 11010 = func2 (100e0 + c = 100ec = .ARM.extab entry)
72// CHECK-EXIDX-NEXT: 100d4 380f0000 08849780 340f0000 0c000000
73// 100e4 + f30 = 11014 = terminate = func2 + sizeof(func2)
74// CHECK-EXIDX-NEXT: 100e4 300f0000 01000000
75// CHECK-EXIDX-NEXT: Contents of section .ARM.extab:
76// 100ec + f28 = 11014 = __gxx_personality_v0
77// CHECK-EXIDX-NEXT: 100ec 280f0000 b0b0b000 00000000
78
79// CHECK-PT: Name: .ARM.exidx
80// CHECK-PT-NEXT: Type: SHT_ARM_EXIDX (0x70000001)
81// CHECK-PT-NEXT: Flags [
82// CHECK-PT-NEXT: SHF_ALLOC
83// CHECK-PT-NEXT: SHF_LINK_ORDER
84// CHECK-PT-NEXT: ]
85// CHECK-PT-NEXT: Address: 0x100D4
86// CHECK-PT-NEXT: Offset: 0xD4
87// CHECK-PT-NEXT: Size: 24
88
89// CHECK-PT: Type: PT_ARM_EXIDX (0x70000001)
90// CHECK-PT-NEXT: Offset: 0xD4
91// CHECK-PT-NEXT: VirtualAddress: 0x100D4
92// CHECK-PT-NEXT: PhysicalAddress: 0x100D4
93// CHECK-PT-NEXT: FileSize: 24
94// CHECK-PT-NEXT: MemSize: 24
95// CHECK-PT-NEXT: Flags [ (0x4)
96// CHECK-PT-NEXT: PF_R (0x4)
97// CHECK-PT-NEXT: ]
98// CHECK-PT-NEXT: Alignment: 4
99// CHECK-PT-NEXT: }
deps/lld/test/ELF/arm-exidx-gc.s created+124
......@@ -0,0 +1,124 @@
1// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
2// RUN: ld.lld %t -o %t2 --gc-sections 2>&1
3// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s
4// RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-EXIDX %s
5// REQUIRES: arm
6
7// Test the behavior of .ARM.exidx sections under garbage collection
8// A .ARM.exidx section is live if it has a relocation to a live executable
9// section.
10// A .ARM.exidx section may have a relocation to a .ARM.extab section, if the
11// .ARM.exidx is live then the .ARM.extab section is live
12
13 .syntax unified
14 .section .text.func1, "ax",%progbits
15 .global func1
16func1:
17 .fnstart
18 bx lr
19 .save {r7, lr}
20 .setfp r7, sp, #0
21 .fnend
22
23 .section .text.unusedfunc1, "ax",%progbits
24 .global unusedfunc1
25unusedfunc1:
26 .fnstart
27 bx lr
28 .cantunwind
29 .fnend
30
31 // Unwinding instructions for .text2 too large for an inline entry ARM.exidx
32 // entry. A separate .ARM.extab section is created to hold the unwind entries
33 // The .ARM.exidx table entry has a reference to the .ARM.extab section.
34 .section .text.func2, "ax",%progbits
35 .global func2
36func2:
37 .fnstart
38 bx lr
39 .personality __gxx_personality_v0
40 .handlerdata
41 .section .text.func2
42 .fnend
43
44 // An unused function with a reference to a .ARM.extab section. Both should
45 // be removed by gc.
46 .section .text.unusedfunc2, "ax",%progbits
47 .global unusedfunc2
48unusedfunc2:
49 .fnstart
50 bx lr
51 .personality __gxx_personality_v1
52 .handlerdata
53 .section .text.unusedfunc2
54 .fnend
55
56 // Dummy implementation of personality routines to satisfy reference from
57 // exception tables
58 .section .text.__gcc_personality_v0, "ax", %progbits
59 .global __gxx_personality_v0
60__gxx_personality_v0:
61 .fnstart
62 bx lr
63 .cantunwind
64 .fnend
65
66 .section .text.__gcc_personality_v1, "ax", %progbits
67 .global __gxx_personality_v1
68__gxx_personality_v1:
69 .fnstart
70 bx lr
71 .cantunwind
72 .fnend
73
74 .section .text.__aeabi_unwind_cpp_pr0, "ax", %progbits
75 .global __aeabi_unwind_cpp_pr0
76__aeabi_unwind_cpp_pr0:
77 .fnstart
78 bx lr
79 .cantunwind
80 .fnend
81
82// Entry point for GC
83 .text
84 .global _start
85_start:
86 bl func1
87 bl func2
88 bx lr
89
90// GC should have only removed unusedfunc1 and unusedfunc2 the personality
91// routines are kept alive by references from live .ARM.exidx and .ARM.extab
92// sections
93// CHECK: Disassembly of section .text:
94// CHECK-NEXT: _start:
95// CHECK-NEXT: 11000: 01 00 00 eb bl #4 <func1>
96// CHECK-NEXT: 11004: 01 00 00 eb bl #4 <func2>
97// CHECK-NEXT: 11008: 1e ff 2f e1 bx lr
98// CHECK: func1:
99// CHECK-NEXT: 1100c: 1e ff 2f e1 bx lr
100// CHECK: func2:
101// CHECK-NEXT: 11010: 1e ff 2f e1 bx lr
102// CHECK: __gxx_personality_v0:
103// CHECK-NEXT: 11014: 1e ff 2f e1 bx lr
104// CHECK: __aeabi_unwind_cpp_pr0:
105// CHECK-NEXT: 11018: 1e ff 2f e1 bx lr
106
107// GC should have removed table entries for unusedfunc1, unusedfunc2
108// and __gxx_personality_v1
109// CHECK-NOT: unusedfunc1
110// CHECK-NOT: unusedfunc2
111// CHECK-NOT: __gxx_personality_v1
112
113// CHECK-EXIDX: Contents of section .ARM.exidx:
114// 100d4 + f38 = 1100c = func1
115// 100dc + f34 = 11010 = func2 (100e0 + 1c = 100fc = .ARM.extab)
116// CHECK-EXIDX-NEXT: 100d4 380f0000 08849780 340f0000 1c000000
117// 100e4 + f30 = 11014 = __gxx_personality_v0
118// 100ec + f2c = 11018 = __aeabi_unwind_cpp_pr0
119// CHECK-EXIDX-NEXT: 100e4 300f0000 01000000 2c0f0000 01000000
120// 100f4 + f28 = 1101c = __aeabi_unwind_cpp_pr0 + sizeof(__aeabi_unwind_cpp_pr0)
121// CHECK-EXIDX-NEXT: 100f4 280f0000 01000000
122// CHECK-EXIDX-NEXT: Contents of section .ARM.extab:
123// 100fc + f18 = 11014 = __gxx_personality_v0
124// CHECK-EXIDX-NEXT: 100fc 180f0000 b0b0b000
deps/lld/test/ELF/arm-exidx-link.s created+25
......@@ -0,0 +1,25 @@
1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
3// RUN: ld.lld %t.o -o %t.so -shared
4// RUN: llvm-readobj -s %t.so | FileCheck %s
5
6// CHECK: Name: .ARM.exidx
7// CHECK-NEXT: Type: SHT_ARM_EXIDX
8// CHECK-NEXT: Flags [
9// CHECK-NEXT: SHF_ALLOC
10// CHECK-NEXT: SHF_LINK_ORDER
11// CHECK-NEXT: ]
12// CHECK-NEXT: Address:
13// CHECK-NEXT: Offset:
14// CHECK-NEXT: Size:
15// CHECK-NEXT: Link: [[INDEX:.*]]
16
17// CHECK: Index: [[INDEX]]
18// CHECK-NEXT: Name: .text
19
20
21 f:
22 .fnstart
23 bx lr
24 .cantunwind
25 .fnend
deps/lld/test/ELF/arm-exidx-order.s created+169
......@@ -0,0 +1,169 @@
1// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-exidx-cantunwind.s -o %tcantunwind
3// RUN: ld.lld %t %tcantunwind -o %t2 2>&1
4// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s
5// RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-EXIDX %s
6// RUN: llvm-readobj --program-headers --sections %t2 | FileCheck -check-prefix=CHECK-PT %s
7// Use Linker script to place .ARM.exidx in between .text and orphan sections
8// RUN: echo "SECTIONS { \
9// RUN: .text 0x11000 : { *(.text*) } \
10// RUN: .ARM.exidx : { *(.ARM.exidx) } } " > %t.script
11// RUN: ld.lld --script %t.script %tcantunwind %t -o %t3 2>&1
12// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t3 | FileCheck -check-prefix=CHECK-SCRIPT %s
13// RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t3 | FileCheck -check-prefix=CHECK-SCRIPT-EXIDX %s
14// REQUIRES: arm
15
16// Each assembler created .ARM.exidx section has the SHF_LINK_ORDER flag set
17// with the sh_link containing the section index of the executable section
18// containing the function it describes. The linker must combine the .ARM.exidx
19// InputSections in the same order that it has combined the executable section,
20// such that the combined .ARM.exidx OutputSection can be used as a binary
21// search table.
22
23 .syntax unified
24 .section .text, "ax",%progbits
25 .globl _start
26_start:
27 .fnstart
28 bx lr
29 .cantunwind
30 .fnend
31
32 .section .text.f1, "ax", %progbits
33 .globl f1
34f1:
35 .fnstart
36 bx lr
37 .cantunwind
38 .fnend
39
40 .section .text.f2, "ax", %progbits
41 .globl f2
42f2:
43 .fnstart
44 bx lr
45 .cantunwind
46 .fnend
47 .globl f3
48f3:
49 .fnstart
50 bx lr
51 .cantunwind
52 .fnend
53
54// Check default no linker script order.
55
56// CHECK: Disassembly of section .text:
57// CHECK: _start:
58// CHECK-NEXT: 11000: 1e ff 2f e1 bx lr
59// CHECK: f1:
60// CHECK-NEXT: 11004: 1e ff 2f e1 bx lr
61// CHECK: f2:
62// CHECK-NEXT: 11008: 1e ff 2f e1 bx lr
63// CHECK: f3:
64// CHECK-NEXT: 1100c: 1e ff 2f e1 bx lr
65// CHECK: func4:
66// CHECK-NEXT: 11010: 1e ff 2f e1 bx lr
67// CHECK: func5:
68// CHECK-NEXT: 11014: 1e ff 2f e1 bx lr
69// CHECK: Disassembly of section .func1:
70// CHECK-NEXT: func1:
71// CHECK-NEXT: 11018: 1e ff 2f e1 bx lr
72// CHECK: Disassembly of section .func2:
73// CHECK-NEXT: func2:
74// CHECK-NEXT: 1101c: 1e ff 2f e1 bx lr
75// CHECK: Disassembly of section .func3:
76// CHECK-NEXT: func3:
77// CHECK-NEXT: 11020: 1e ff 2f e1 bx lr
78
79// Each .ARM.exidx section has two 4 byte fields
80// Field 1 is the 31-bit offset to the function. The top bit is used to
81// indicate whether Field 2 is a pointer or an inline table entry.
82// Field 2 is either a pointer to a .ARM.extab section or an inline table
83// In this example all Field 2 entries are inline can't unwind (0x1)
84// We expect to see the entries in the same order as the functions
85
86// CHECK-EXIDX: Contents of section .ARM.exidx:
87// 100d4 + f2c = 11000 = _start
88// 100dc + f28 = 11004 = f1
89// CHECK-EXIDX-NEXT: 100d4 2c0f0000 01000000 280f0000 01000000
90// 100e4 + f24 = 11008 = f2
91// 100ec + f20 = 1100c = f3
92// CHECK-EXIDX-NEXT: 100e4 240f0000 01000000 200f0000 01000000
93// 100f4 + f1c = 11010 = func4
94// 100fc + f18 = 11014 = func5
95// CHECK-EXIDX-NEXT: 100f4 1c0f0000 01000000 180f0000 01000000
96// 10104 + f14 = 11018 = func1
97// 1010c + f10 = 1101c = func2
98// CHECK-EXIDX-NEXT: 10104 140f0000 01000000 100f0000 01000000
99// 10114 + f0c = 11020 = func3
100// CHECK-EXIDX-NEXT: 10114 0c0f0000 01000000
101
102// Check that PT_ARM_EXIDX program header has been generated that describes
103// the .ARM.exidx output section
104// CHECK-PT: Name: .ARM.exidx
105// CHECK-PT-NEXT: Type: SHT_ARM_EXIDX (0x70000001)
106// CHECK-PT-NEXT: Flags [
107// CHECK-PT-NEXT: SHF_ALLOC
108// CHECK-PT-NEXT: SHF_LINK_ORDER
109// CHECK-PT-NEXT: ]
110// CHECK-PT-NEXT: Address: 0x100D4
111// CHECK-PT-NEXT: Offset: 0xD4
112// CHECK-PT-NEXT: Size: 80
113
114// CHECK-PT: Type: PT_ARM_EXIDX (0x70000001)
115// CHECK-PT-NEXT: Offset: 0xD4
116// CHECK-PT-NEXT: VirtualAddress: 0x100D4
117// CHECK-PT-NEXT: PhysicalAddress: 0x100D4
118// CHECK-PT-NEXT: FileSize: 80
119// CHECK-PT-NEXT: MemSize: 80
120// CHECK-PT-NEXT: Flags [ (0x4)
121// CHECK-PT-NEXT: PF_R (0x4)
122// CHECK-PT-NEXT: ]
123// CHECK-PT-NEXT: Alignment: 4
124// CHECK-PT-NEXT: }
125
126
127// Check linker script order. The .ARM.exidx section will be inserted after
128// the .text section but before the orphan sections
129
130// CHECK-SCRIPT: Disassembly of section .text:
131// CHECK-SCRIPT-NEXT: func4:
132// CHECK-SCRIPT-NEXT: 11000: 1e ff 2f e1 bx lr
133// CHECK-SCRIPT: func5:
134// CHECK-SCRIPT-NEXT: 11004: 1e ff 2f e1 bx lr
135// CHECK-SCRIPT: _start:
136// CHECK-SCRIPT-NEXT: 11008: 1e ff 2f e1 bx lr
137// CHECK-SCRIPT: f1:
138// CHECK-SCRIPT-NEXT: 1100c: 1e ff 2f e1 bx lr
139// CHECK-SCRIPT: f2:
140// CHECK-SCRIPT-NEXT: 11010: 1e ff 2f e1 bx lr
141// CHECK-SCRIPT: f3:
142// CHECK-SCRIPT-NEXT: 11014: 1e ff 2f e1 bx lr
143// CHECK-SCRIPT-NEXT: Disassembly of section .func1:
144// CHECK-SCRIPT-NEXT: func1:
145// CHECK-SCRIPT-NEXT: 11068: 1e ff 2f e1 bx lr
146// CHECK-SCRIPT-NEXT: Disassembly of section .func2:
147// CHECK-SCRIPT-NEXT: func2:
148// CHECK-SCRIPT-NEXT: 1106c: 1e ff 2f e1 bx lr
149// CHECK-SCRIPT-NEXT: Disassembly of section .func3:
150// CHECK-SCRIPT-NEXT: func3:
151// CHECK-SCRIPT-NEXT: 11070: 1e ff 2f e1 bx lr
152
153// Check that the .ARM.exidx section is sorted in order as the functions
154// The offset in field 1, is 32-bit so in the binary the most significant bit
155// 11018 - 18 = 11000 func4
156// 11020 - 1c = 11004 func5
157// CHECK-SCRIPT-EXIDX: 11018 e8ffff7f 01000000 e4ffff7f 01000000
158// 11028 - 20 = 11008 _start
159// 11030 - 24 = 1100c f1
160// CHECK-SCRIPT-EXIDX-NEXT: 11028 e0ffff7f 01000000 dcffff7f 01000000
161// 11038 - 28 = 11010 f2
162// 11040 - 2c = 11014 f3
163// CHECK-SCRIPT-EXIDX-NEXT: 11038 d8ffff7f 01000000 d4ffff7f 01000000
164// 11048 + 20 = 11068 func1
165// 11050 + 1c = 1106c func2
166// CHECK-SCRIPT-EXIDX-NEXT: 11048 20000000 01000000 1c000000 01000000
167// 11058 + 18 = 11070 func3
168// 11060 + 14 = 11074 func3 + sizeof(func3)
169// CHECK-SCRIPT-EXIDX-NEXT: 11058 18000000 01000000 14000000 01000000
deps/lld/test/ELF/arm-exidx-output.s created+44
......@@ -0,0 +1,44 @@
1// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
2// RUN: ld.lld %t -o %t2 2>&1
3// RUN: llvm-readobj -sections %t2 | FileCheck %s
4// REQUIRES: arm
5
6// Check that only a single .ARM.exidx output section is created when
7// there are input sections of the form .ARM.exidx.<section-name>. The
8// assembler creates the .ARM.exidx input sections with the .cantunwind
9// directive
10 .syntax unified
11 .section .text, "ax",%progbits
12 .globl _start
13_start:
14 .fnstart
15 bx lr
16 .cantunwind
17 .fnend
18
19 .section .text.f1, "ax", %progbits
20 .globl f1
21f1:
22 .fnstart
23 bx lr
24 .cantunwind
25 .fnend
26
27 .section .text.f2, "ax", %progbits
28 .globl f2
29f2:
30 .fnstart
31 bx lr
32 .cantunwind
33 .fnend
34
35// CHECK: Section {
36// CHECK: Name: .ARM.exidx
37// CHECK-NEXT: Type: SHT_ARM_EXIDX (0x70000001)
38// CHECK-NEXT: Flags [
39// CHECK-NEXT: SHF_ALLOC
40// CHECK-NEXT: SHF_LINK_ORDER
41// CHECK-NEXT: ]
42
43// CHECK-NOT: Name: .ARM.exidx.text.f1
44// CHECK-NOT: Name: .ARM.exidx.text.f2
deps/lld/test/ELF/arm-exidx-relocatable.s created+132
......@@ -0,0 +1,132 @@
1// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %S/Inputs/arm-exidx-cantunwind.s -o %tcantunwind
3// Check that relocatable link maintains SHF_LINK_ORDER
4// RUN: ld.lld -r %t %tcantunwind -o %t4 2>&1
5// RUN: llvm-readobj -s %t4 | FileCheck %s
6// REQUIRES: arm
7
8// Each assembler created .ARM.exidx section has the SHF_LINK_ORDER flag set
9// with the sh_link containing the section index of the executable section
10// containing the function it describes. To maintain this property in
11// relocatable links we pass through the .ARM.exidx section, the section it
12// it has a sh_link to, and the associated relocation sections uncombined.
13
14 .syntax unified
15 .section .text, "ax",%progbits
16 .globl _start
17_start:
18 .fnstart
19 bx lr
20 .cantunwind
21 .fnend
22
23 .section .text.f1, "ax", %progbits
24 .globl f1
25f1:
26 .fnstart
27 bx lr
28 .cantunwind
29 .fnend
30
31 .section .text.f2, "ax", %progbits
32 .globl f2
33f2:
34 .fnstart
35 bx lr
36 .cantunwind
37 .fnend
38 .globl f3
39f3:
40 .fnstart
41 bx lr
42 .cantunwind
43 .fnend
44
45// CHECK: Index: 1
46// CHECK-NEXT: Name: .text
47
48// CHECK: Name: .ARM.exidx
49// CHECK-NEXT: Type: SHT_ARM_EXIDX (0x70000001)
50// CHECK-NEXT: Flags [ (0x82)
51// CHECK-NEXT: SHF_ALLOC (0x2)
52// CHECK-NEXT: SHF_LINK_ORDER (0x80)
53// CHECK-NEXT: ]
54// CHECK-NEXT: Address
55// CHECK-NEXT: Offset:
56// CHECK-NEXT: Size: 24
57// CHECK-NEXT: Link: 1
58
59
60// CHECK: Index: 4
61// CHECK-NEXT: Name: .text.f1
62
63// CHECK: Name: .ARM.exidx.text.f1
64// CHECK-NEXT: Type: SHT_ARM_EXIDX (0x70000001)
65// CHECK-NEXT: Flags [ (0x82)
66// CHECK-NEXT: SHF_ALLOC (0x2)
67// CHECK-NEXT: SHF_LINK_ORDER (0x80)
68// CHECK-NEXT: ]
69// CHECK-NEXT: Address
70// CHECK-NEXT: Offset:
71// CHECK-NEXT: Size: 8
72// CHECK-NEXT: Link: 4
73
74
75// CHECK: Index: 7
76// CHECK-NEXT: Name: .text.f2
77
78// CHECK: Name: .ARM.exidx.text.f2
79// CHECK-NEXT: Type: SHT_ARM_EXIDX (0x70000001)
80// CHECK-NEXT: Flags [ (0x82)
81// CHECK-NEXT: SHF_ALLOC (0x2)
82// CHECK-NEXT: SHF_LINK_ORDER (0x80)
83// CHECK-NEXT: ]
84// CHECK-NEXT: Address
85// CHECK-NEXT: Offset:
86// CHECK-NEXT: Size: 16
87// CHECK-NEXT: Link: 7
88
89
90// CHECK: Index: 10
91// CHECK-NEXT: Name: .func1
92
93// CHECK: Name: .ARM.exidx.func1
94// CHECK-NEXT: Type: SHT_ARM_EXIDX (0x70000001)
95// CHECK-NEXT: Flags [ (0x82)
96// CHECK-NEXT: SHF_ALLOC (0x2)
97// CHECK-NEXT: SHF_LINK_ORDER (0x80)
98// CHECK-NEXT: ]
99// CHECK-NEXT: Address
100// CHECK-NEXT: Offset:
101// CHECK-NEXT: Size: 8
102// CHECK-NEXT: Link: 10
103
104
105// CHECK: Index: 13
106// CHECK-NEXT: Name: .func2
107
108// CHECK: Name: .ARM.exidx.func2
109// CHECK-NEXT: Type: SHT_ARM_EXIDX (0x70000001)
110// CHECK-NEXT: Flags [ (0x82)
111// CHECK-NEXT: SHF_ALLOC (0x2)
112// CHECK-NEXT: SHF_LINK_ORDER (0x80)
113// CHECK-NEXT: ]
114// CHECK-NEXT: Address
115// CHECK-NEXT: Offset:
116// CHECK-NEXT: Size: 8
117// CHECK-NEXT: Link: 13
118
119
120// CHECK: Index: 16
121// CHECK-NEXT: Name: .func3
122
123// CHECK: Name: .ARM.exidx.func3
124// CHECK-NEXT: Type: SHT_ARM_EXIDX (0x70000001)
125// CHECK-NEXT: Flags [ (0x82)
126// CHECK-NEXT: SHF_ALLOC (0x2)
127// CHECK-NEXT: SHF_LINK_ORDER (0x80)
128// CHECK-NEXT: ]
129// CHECK-NEXT: Address
130// CHECK-NEXT: Offset:
131// CHECK-NEXT: Size: 8
132// CHECK-NEXT: Link: 16
deps/lld/test/ELF/arm-exidx-sentinel-norelocatable.s created+17
......@@ -0,0 +1,17 @@
1// RUN: llvm-mc %s -triple=armv7-unknown-linux-gnueabi -filetype=obj -o %t.o
2// RUN: ld.lld -r %t.o -o %t
3// REQUIRES: arm
4// RUN: llvm-readobj -s %t | FileCheck %s
5// Check that when doing a relocatable link we don't add a terminating entry
6// to the .ARM.exidx section
7 .syntax unified
8 .text
9_start:
10 .fnstart
11 .cantunwind
12 bx lr
13 .fnend
14
15// Expect 1 table entry of size 8
16// CHECK: Name: .ARM.exidx
17// CHECK: Size: 8
deps/lld/test/ELF/arm-exidx-sentinel-orphan.s created+23
......@@ -0,0 +1,23 @@
1// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
2// Use Linker script without .ARM.exidx Output Section so it is treated as
3// an orphan. We must still add the sentinel table entry
4// RUN: echo "SECTIONS { \
5// RUN: .text 0x11000 : { *(.text*) } \
6// RUN: } " > %t.script
7// RUN: ld.lld --script %t.script %t -o %t2
8// RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s
9// REQUIRES: arm
10
11 .syntax unified
12 .text
13 .global _start
14_start:
15 .fnstart
16 .cantunwind
17 bx lr
18 .fnend
19
20// CHECK: Contents of section .ARM.exidx:
21// 11004 - 4 = 0x11000 = _start
22// 1100c - 8 = 0x11004 = _start + sizeof(_start)
23// CHECK-NEXT: 11004 fcffff7f 01000000 f8ffff7f 01000000
deps/lld/test/ELF/arm-exidx-shared.s created+45
......@@ -0,0 +1,45 @@
1// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
2// RUN: ld.lld %t --shared -o %t2 2>&1
3// RUN: llvm-readobj --relocations %t2 | FileCheck %s
4// RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-EXTAB %s
5// REQUIRES: arm
6
7// Check that the relative R_ARM_PREL31 relocation can access a PLT entry
8// for when the personality routine is referenced from a shared library.
9// Also check that the R_ARM_NONE no-op relocation can be used in a shared
10// library.
11 .syntax unified
12// Will produce an ARM.exidx entry with an R_ARM_NONE relocation to
13// __aeabi_unwind_cpp_pr0
14 .section .text.func1, "ax",%progbits
15 .global func1
16func1:
17 .fnstart
18 bx lr
19 .fnend
20
21// Will produce a R_ARM_PREL31 relocation with respect to the PLT entry of
22// __gxx_personality_v0
23 .section .text.func2, "ax",%progbits
24 .global func2
25func2:
26 .fnstart
27 bx lr
28 .personality __gxx_personality_v0
29 .handlerdata
30 .long 0
31 .section .text.func2
32 .fnend
33
34 .section .text.__aeabi_unwind_cpp_pr0, "ax", %progbits
35 .global __aeabi_unwind_cpp_pr0
36__aeabi_unwind_cpp_pr0:
37 bx lr
38
39// CHECK: Relocations [
40// CHECK-NEXT: Section (6) .rel.plt {
41// CHECK-NEXT: 0x200C R_ARM_JUMP_SLOT __gxx_personality_v0
42
43// CHECK-EXTAB: Contents of section .ARM.extab:
44// 014c + 0ed8 = 0x1024 = __gxx_personality_v0(PLT)
45// CHECK-EXTAB-NEXT: 014c d80e0000 b0b0b000 00000000
deps/lld/test/ELF/arm-fpic-got.s created+63
......@@ -0,0 +1,63 @@
1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
3// RUN: ld.lld %t.o -o %t
4// RUN: llvm-readobj -s %t | FileCheck %s
5// RUN: llvm-readobj -s -symbols %t | FileCheck -check-prefix=SYMBOLS %s
6// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t | FileCheck -check-prefix=CODE %s
7
8// Test the R_ARM_GOT_PREL relocation
9 .syntax unified
10 .text
11 .globl _start
12 .align 2
13_start:
14 ldr r0, .LCPI0_0
15.LPC0_0:
16 ldr r0, [pc, r0]
17 ldr r0, [r0]
18 bx lr
19.LCPI0_0:
20.Ltmp0:
21 // Generate R_ARM_GOT_PREL
22 .long val(GOT_PREL)-((.LPC0_0+8)-.Ltmp0)
23
24 .data
25 .type val,%object
26 .globl val
27 .align 2
28val:
29 .long 10
30 .size val, 4
31
32// CHECK: Section {
33// CHECK: Name: .got
34// CHECK-NEXT: Type: SHT_PROGBITS
35// CHECK-NEXT: Flags [
36// CHECK-NEXT: SHF_ALLOC
37// CHECK-NEXT: SHF_WRITE
38// CHECK-NEXT: ]
39// CHECK-NEXT: Address: 0x13000
40// CHECK-NEXT: Offset:
41// CHECK-NEXT: Size: 4
42// CHECK-NEXT: Link:
43// CHECK-NEXT: Info:
44// CHECK-NEXT: AddressAlignment: 4
45// CHECK-NEXT: EntrySize:
46
47// SYMBOLS: Name: val
48// SYMBOLS-NEXT: Value: 0x12000
49// SYMBOLS-NEXT: Size: 4
50// SYMBOLS-NEXT: Binding: Global
51// SYMBOLS-NEXT: Type: Object
52// SYMBOLS-NEXT: Other:
53// SYMBOLS-NEXT: Section: .data
54
55// CODE: Disassembly of section .text:
56// CODE-NEXT: _start:
57// CODE-NEXT: 11000: 08 00 9f e5 ldr r0, [pc, #8]
58// CODE-NEXT: 11004: 00 00 9f e7 ldr r0, [pc, r0]
59// CODE-NEXT: 11008: 00 00 90 e5 ldr r0, [r0]
60// CODE-NEXT: 1100c: 1e ff 2f e1 bx lr
61// CODE: $d.1:
62// 0x11004 + 0x1ff4 + 8 = 0x13000 = .got
63// CODE-NEXT: 11010: f4 1f 00 00
deps/lld/test/ELF/arm-gnu-ifunc-nosym.s created+27
......@@ -0,0 +1,27 @@
1// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
2// RUN: ld.lld -static %t.o -o %tout
3// RUN: llvm-readobj -symbols %tout | FileCheck %s
4// REQUIRES: arm
5
6// Check that no __rel_iplt_end/__rel_iplt_start
7// appear in symtab if there are no references to them.
8// CHECK: Symbols [
9// CHECK-NOT: __rel_iplt_end
10// CHECK-NOT: __rel_iplt_start
11// CHECK: ]
12 .syntax unified
13 .text
14 .type foo STT_GNU_IFUNC
15 .globl foo
16foo:
17 bx lr
18
19 .type bar STT_GNU_IFUNC
20 .globl bar
21bar:
22 bx lr
23
24 .globl _start
25_start:
26 bl foo
27 bl bar
deps/lld/test/ELF/arm-gnu-ifunc-plt.s created+101
......@@ -0,0 +1,101 @@
1// RUN: llvm-mc -filetype=obj -triple=armv7a-linux-gnueabihf %S/Inputs/arm-shared.s -o %t1.o
2// RUN: ld.lld %t1.o --shared -o %t.so
3// RUN: llvm-mc -filetype=obj -triple=armv7a-linux-gnueabihf %s -o %t.o
4// RUN: ld.lld %t.so %t.o -o %tout
5// RUN: llvm-objdump -triple=armv7a-linux-gnueabihf -d %tout | FileCheck %s --check-prefix=DISASM
6// RUN: llvm-objdump -s %tout | FileCheck %s --check-prefix=GOTPLT
7// RUN: llvm-readobj -r -dynamic-table %tout | FileCheck %s
8// REQUIRES: arm
9
10// Check that the IRELATIVE relocations are last in the .got
11// CHECK: Relocations [
12// CHECK-NEXT: Section (4) .rel.dyn {
13// CHECK-NEXT: 0x13078 R_ARM_GLOB_DAT bar2 0x0
14// CHECK-NEXT: 0x1307C R_ARM_GLOB_DAT zed2 0x0
15// CHECK-NEXT: 0x13080 R_ARM_IRELATIVE - 0x0
16// CHECK-NEXT: 0x13084 R_ARM_IRELATIVE - 0x0
17// CHECK-NEXT: }
18// CHECK-NEXT: Section (5) .rel.plt {
19// CHECK-NEXT: 0x1200C R_ARM_JUMP_SLOT bar2 0x0
20// CHECK-NEXT: 0x12010 R_ARM_JUMP_SLOT zed2 0x0
21// CHECK-NEXT: }
22// CHECK-NEXT: ]
23
24// Check that the GOT entries refer back to the ifunc resolver
25// GOTPLT: Contents of section .got.plt:
26// GOTPLT-NEXT: 12000 00000000 00000000 00000000 20100100
27// GOTPLT-NEXT: 12010 20100100
28// GOTPLT: Contents of section .got:
29// GOTPLT-NEXT: 13078 00000000 00000000 00100100 04100100
30
31// DISASM: Disassembly of section .text:
32// DISASM-NEXT: foo:
33// DISASM-NEXT: 11000: 1e ff 2f e1 bx lr
34// DISASM: bar:
35// DISASM-NEXT: 11004: 1e ff 2f e1 bx lr
36// DISASM: _start:
37// DISASM-NEXT: 11008: 14 00 00 eb bl #80
38// DISASM-NEXT: 1100c: 17 00 00 eb bl #92
39// DISASM: 11010: 00 00 00 00 .word 0x00000000
40// DISASM-NEXT: 11014: 04 00 00 00 .word 0x00000004
41// DISASM: 11018: 05 00 00 eb bl #20
42// DISASM-NEXT: 1101c: 08 00 00 eb bl #32
43// DISASM-NEXT: Disassembly of section .plt:
44// DISASM-NEXT: $a:
45// DISASM-NEXT: 11020: 04 e0 2d e5 str lr, [sp, #-4]!
46// DISASM-NEXT: 11024: 04 e0 9f e5 ldr lr, [pc, #4]
47// DISASM-NEXT: 11028: 0e e0 8f e0 add lr, pc, lr
48// DISASM-NEXT: 1102c: 08 f0 be e5 ldr pc, [lr, #8]!
49// DISASM: $d:
50// DISASM-NEXT: 11030: d0 0f 00 00 .word 0x00000fd0
51// DISASM: $a:
52// DISASM-NEXT: 11034: 04 c0 9f e5 ldr r12, [pc, #4]
53// DISASM-NEXT: 11038: 0f c0 8c e0 add r12, r12, pc
54// DISASM-NEXT: 1103c: 00 f0 9c e5 ldr pc, [r12]
55// DISASM: $d:
56// DISASM-NEXT: 11040: cc 0f 00 00 .word 0x00000fcc
57// DISASM: $a:
58// DISASM-NEXT: 11044: 04 c0 9f e5 ldr r12, [pc, #4]
59// DISASM-NEXT: 11048: 0f c0 8c e0 add r12, r12, pc
60// DISASM-NEXT: 1104c: 00 f0 9c e5 ldr pc, [r12]
61// DISASM: $d:
62// DISASM-NEXT: 11050: c0 0f 00 00 .word 0x00000fc0
63// Alignment to 16 byte boundary not strictly necessary on ARM, but harmless
64// DISASM-NEXT: 11054: d4 d4 d4 d4 .word 0xd4d4d4d4
65// DISASM-NEXT: 11058: d4 d4 d4 d4 .word 0xd4d4d4d4
66// DISASM-NEXT: 1105c: d4 d4 d4 d4 .word 0xd4d4d4d4
67// DISASM: $a:
68// DISASM-NEXT: 11060: 04 c0 9f e5 ldr r12, [pc, #4]
69// DISASM-NEXT: 11064: 0f c0 8c e0 add r12, r12, pc
70// DISASM-NEXT: 11068: 00 f0 9c e5 ldr pc, [r12]
71// DISASM: $d:
72// DISASM-NEXT: 1106c: 14 20 00 00 .word 0x00002014
73// DISASM: $a:
74// DISASM-NEXT: 11070: 04 c0 9f e5 ldr r12, [pc, #4]
75// DISASM-NEXT: 11074: 0f c0 8c e0 add r12, r12, pc
76// DISASM-NEXT: 11078: 00 f0 9c e5 ldr pc, [r12]
77// DISASM: $d:
78// DISASM-NEXT: 1107c: 08 20 00 00 .word 0x00002008
79
80.syntax unified
81.text
82.type foo STT_GNU_IFUNC
83.globl foo
84foo:
85 bx lr
86
87.type bar STT_GNU_IFUNC
88.globl bar
89bar:
90 bx lr
91
92.globl _start
93_start:
94 bl foo
95 bl bar
96 // Create entries in the .got and .rel.dyn so that we don't just have
97 // IRELATIVE
98 .word bar2(got)
99 .word zed2(got)
100 bl bar2
101 bl zed2
deps/lld/test/ELF/arm-gnu-ifunc.s created+140
......@@ -0,0 +1,140 @@
1// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
2// RUN: ld.lld -static %t.o -o %tout
3// RUN: llvm-objdump -triple armv7a-none-linux-gnueabi -d %tout | FileCheck %s --check-prefix=DISASM
4// RUN: llvm-readobj -r -symbols -sections %tout | FileCheck %s
5// REQUIRES: arm
6 .syntax unified
7 .text
8 .type foo STT_GNU_IFUNC
9 .globl foo
10foo:
11 bx lr
12
13 .type bar STT_GNU_IFUNC
14 .globl bar
15bar:
16 bx lr
17
18 .globl _start
19_start:
20 bl foo
21 bl bar
22 movw r0,:lower16:__rel_iplt_start
23 movt r0,:upper16:__rel_iplt_start
24 movw r0,:lower16:__rel_iplt_end
25 movt r0,:upper16:__rel_iplt_end
26
27// CHECK: Sections [
28// CHECK: Section {
29// CHECK: Section {
30// CHECK: Name: .rel.dyn
31// CHECK-NEXT: Type: SHT_REL
32// CHECK-NEXT: Flags [
33// CHECK-NEXT: SHF_ALLOC
34// CHECK-NEXT: ]
35// CHECK-NEXT: Address: 0x100F4
36// CHECK-NEXT: Offset: 0xF4
37// CHECK-NEXT: Size: 16
38// CHECK: Name: .plt
39// CHECK-NEXT: Type: SHT_PROGBITS
40// CHECK-NEXT: Flags [
41// CHECK-NEXT: SHF_ALLOC
42// CHECK-NEXT: SHF_EXECINSTR
43// CHECK-NEXT: ]
44// CHECK-NEXT: Address: 0x11020
45// CHECK-NEXT: Offset: 0x1020
46// CHECK-NEXT: Size: 32
47// CHECK: Name: .got
48// CHECK-NEXT: Type: SHT_PROGBITS
49// CHECK-NEXT: Flags [
50// CHECK-NEXT: SHF_ALLOC
51// CHECK-NEXT: SHF_WRITE
52// CHECK-NEXT: ]
53// CHECK-NEXT: Address: 0x12000
54// CHECK-NEXT: Offset: 0x2000
55// CHECK-NEXT: Size: 8
56// CHECK: Relocations [
57// CHECK-NEXT: Section (1) .rel.dyn {
58// CHECK-NEXT: 0x12000 R_ARM_IRELATIVE
59// CHECK-NEXT: 0x12004 R_ARM_IRELATIVE
60// CHECK-NEXT: }
61// CHECK-NEXT: ]
62// CHECK: Symbol {
63// CHECK: Name: __rel_iplt_end
64// CHECK-NEXT: Value: 0x10104
65// CHECK-NEXT: Size: 0
66// CHECK-NEXT: Binding: Local
67// CHECK-NEXT: Type: None
68// CHECK-NEXT: Other [
69// CHECK-NEXT: STV_HIDDEN
70// CHECK-NEXT: ]
71// CHECK-NEXT: Section: .rel.dyn
72// CHECK-NEXT: }
73// CHECK-NEXT: Symbol {
74// CHECK-NEXT: Name: __rel_iplt_start
75// CHECK-NEXT: Value: 0x100F4
76// CHECK-NEXT: Size: 0
77// CHECK-NEXT: Binding: Local
78// CHECK-NEXT: Type: None
79// CHECK-NEXT: Other [
80// CHECK-NEXT: STV_HIDDEN
81// CHECK-NEXT: ]
82// CHECK-NEXT: Section: .rel.dyn
83// CHECK-NEXT: }
84// CHECK-NEXT: Symbol {
85// CHECK-NEXT: Name: _start
86// CHECK-NEXT: Value: 0x11008
87// CHECK-NEXT: Size: 0
88// CHECK-NEXT: Binding: Global
89// CHECK-NEXT: Type: None
90// CHECK-NEXT: Other:
91// CHECK-NEXT: Section: .text
92// CHECK-NEXT: }
93// CHECK-NEXT: Symbol {
94// CHECK-NEXT: Name: bar
95// CHECK-NEXT: Value: 0x11004
96// CHECK-NEXT: Size: 0
97// CHECK-NEXT: Binding: Global
98// CHECK-NEXT: Type: GNU_IFunc
99// CHECK-NEXT: Other: 0
100// CHECK-NEXT: Section: .text
101// CHECK-NEXT: }
102// CHECK-NEXT: Symbol {
103// CHECK-NEXT: Name: foo
104// CHECK-NEXT: Value: 0x11000
105// CHECK-NEXT: Size: 0
106// CHECK-NEXT: Binding: Global
107// CHECK-NEXT: Type: GNU_IFunc
108// CHECK-NEXT: Other: 0
109// CHECK-NEXT: Section: .text
110// CHECK-NEXT: }
111
112// DISASM: Disassembly of section .text:
113// DISASM-NEXT: foo:
114// DISASM-NEXT: 11000: 1e ff 2f e1 bx lr
115// DISASM: bar:
116// DISASM-NEXT: 11004: 1e ff 2f e1 bx lr
117// DISASM: _start:
118// DISASM-NEXT: 11008: 04 00 00 eb bl #16
119// DISASM-NEXT: 1100c: 07 00 00 eb bl #28
120// 1 * 65536 + 244 = 0x100f4 __rel_iplt_start
121// DISASM-NEXT: 11010: f4 00 00 e3 movw r0, #244
122// DISASM-NEXT: 11014: 01 00 40 e3 movt r0, #1
123// 1 * 65536 + 260 = 0x10104 __rel_iplt_end
124// DISASM-NEXT: 11018: 04 01 00 e3 movw r0, #260
125// DISASM-NEXT: 1101c: 01 00 40 e3 movt r0, #1
126// DISASM-NEXT: Disassembly of section .plt:
127// DISASM: $a:
128// DISASM-NEXT: 11020: 04 c0 9f e5 ldr r12, [pc, #4]
129// DISASM-NEXT: 11024: 0f c0 8c e0 add r12, r12, pc
130// 11024 + 8 + fd4 = 0x12000
131// DISASM-NEXT: 11028: 00 f0 9c e5 ldr pc, [r12]
132// DISASM: $d:
133// DISASM-NEXT: 1102c: d4 0f 00 00 .word 0x00000fd4
134// DISASM: $a:
135// DISASM-NEXT: 11030: 04 c0 9f e5 ldr r12, [pc, #4]
136// DISASM-NEXT: 11034: 0f c0 8c e0 add r12, r12, pc
137// 11034 + 8 + fc8 = 0x12004
138// DISASM-NEXT: 11038: 00 f0 9c e5 ldr pc, [r12]
139// DISASM: $d:
140// DISASM-NEXT: 1103c: c8 0f 00 00 .word 0x00000fc8
deps/lld/test/ELF/arm-got-relative.s created+53
......@@ -0,0 +1,53 @@
1// REQUIRES: arm
2// RUN: llvm-mc -position-independent -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
3// RUN: ld.lld %t.o -shared -o %t
4// RUN: llvm-readobj -s -symbols -dyn-relocations %t | FileCheck %s
5// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t | FileCheck -check-prefix=CODE %s
6 .syntax unified
7 .text
8 .globl _start
9 .align 2
10_start:
11 .type _start, %function
12 ldr r3, .LGOT
13 ldr r2, .LGOT+4
14.LPIC:
15 add r0, pc, r3
16 bx lr
17 .align 2
18.LGOT:
19 // gas implicitly uses (R_ARM_BASE_PREL) for _GLOBAL_OFFSET_TABLE_ in PIC
20 // llvm-mc generates R_ARM_REL32, this will need updating when MC changes
21 .word _GLOBAL_OFFSET_TABLE_ - (.LPIC+8)
22 .word function(GOT)
23
24 .globl function
25 .align 2
26function:
27 .type function, %function
28 bx lr
29
30// CHECK: Dynamic Relocations {
31// CHECK-NEXT: 0x2048 R_ARM_GLOB_DAT function 0x0
32
33// CHECK: Name: _GLOBAL_OFFSET_TABLE_
34// CHECK-NEXT: Value: 0x2048
35// CHECK-NEXT: Size:
36// CHECK-NEXT: Binding: Local
37// CHECK-NEXT: Type: None
38// CHECK-NEXT: Other [
39// CHECK-NEXT: STV_HIDDEN
40// CHECK-NEXT: ]
41// CHECK-NEXT: Section: .got
42
43// CODE: Disassembly of section .text:
44// CODE-NEXT: _start:
45// CODE-NEXT: 1000: 08 30 9f e5 ldr r3, [pc, #8]
46// CODE-NEXT: 1004: 08 20 9f e5 ldr r2, [pc, #8]
47// CODE-NEXT: 1008: 03 00 8f e0 add r0, pc, r3
48// CODE-NEXT: 100c: 1e ff 2f e1 bx lr
49// CODE:$d.1:
50// (_GLOBAL_OFFSET_TABLE_ = 0x2048) - (0x1008 + 8) 0x1038
51// CODE-NEXT: 1010: 38 10 00 00
52// (Got(function) - GotBase = 0x0
53// CODE-NEXT: 1014: 00 00 00 00
deps/lld/test/ELF/arm-gotoff.s created+74
......@@ -0,0 +1,74 @@
1// RUN: llvm-mc -filetype=obj -triple=armv7a-linux-gnueabi %s -o %t.o
2// RUN: ld.lld %t.o -o %t
3// RUN: llvm-readobj -s -r -t %t | FileCheck %s
4// RUN: llvm-objdump -triple=armv7a-linux-gnueabi -d %t | FileCheck --check-prefix=DISASM %s
5// REQUIRES: arm
6
7// Test the R_ARM_GOTOFF32 relocation
8
9// CHECK: Name: .got
10// CHECK-NEXT: Type: SHT_PROGBITS (0x1)
11// CHECK-NEXT: Flags [
12// CHECK-NEXT: SHF_ALLOC
13// CHECK-NEXT: SHF_WRITE
14// CHECK-NEXT: ]
15// CHECK-NEXT: Address: 0x12000
16// CHECK-NEXT: Offset: 0x2000
17// CHECK-NEXT: Size: 0
18// CHECK-NEXT: Link:
19// CHECK-NEXT: Info:
20// CHECK-NEXT: AddressAlignment:
21
22// CHECK: Name: .bss
23// CHECK-NEXT: Type: SHT_NOBITS
24// CHECK-NEXT: Flags [
25// CHECK-NEXT: SHF_ALLOC
26// CHECK-NEXT: SHF_WRITE
27// CHECK-NEXT: ]
28// CHECK-NEXT: Address: 0x12000
29// CHECK-NEXT: Offset:
30// CHECK-NEXT: Size: 20
31// CHECK-NEXT: Link:
32// CHECK-NEXT: Info:
33// CHECK-NEXT: AddressAlignment: 1
34
35// CHECK-NEXT: EntrySize: 0
36
37// CHECK: Symbol {
38// CHECK: Name: bar
39// CHECK-NEXT: Value: 0x12000
40// CHECK-NEXT: Size: 10
41// CHECK-NEXT: Binding: Global
42// CHECK-NEXT: Type: Object
43// CHECK-NEXT: Other: 0
44// CHECK-NEXT: Section: .bss
45// CHECK-NEXT: }
46// CHECK-NEXT: Symbol {
47// CHECK-NEXT: Name: obj
48// CHECK-NEXT: Value: 0x1200A
49// CHECK-NEXT: Size: 10
50// CHECK-NEXT: Binding: Global
51// CHECK-NEXT: Type: Object
52// CHECK-NEXT: Other: 0
53// CHECK-NEXT: Section: .bss
54
55// DISASM: Disassembly of section .text:
56// DISASM-NEXT :_start:
57// DISASM-NEXT 11000: 1e ff 2f e1 bx lr
58// Offset 0 from .got = bar
59// DISASM 11004: 00 00 00 00
60// Offset 10 from .got = obj
61// DISASM-NEXT 11008: 0a 00 00 00
62// Offset 15 from .got = obj +5
63// DISASM-NEXT 1100c: 0f 00 00 00
64 .syntax unified
65 .globl _start
66_start:
67 bx lr
68 .word bar(GOTOFF)
69 .word obj(GOTOFF)
70 .word obj(GOTOFF)+5
71 .type bar, %object
72 .comm bar, 10
73 .type obj, %object
74 .comm obj, 10
deps/lld/test/ELF/arm-icf-exidx.s created+33
......@@ -0,0 +1,33 @@
1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
3// RUN: ld.lld %t -o %t2 --icf=all
4// RUN: llvm-objdump -s -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s
5
6 .syntax unified
7 .section .text.f,"axG",%progbits,f,comdat
8f:
9 .fnstart
10 bx lr
11 .fnend
12
13 .section .text.g,"axG",%progbits,g,comdat
14g:
15 .fnstart
16 bx lr
17 .fnend
18
19 .section .text.h
20 .global __aeabi_unwind_cpp_pr0
21__aeabi_unwind_cpp_pr0:
22 nop
23 bx lr
24
25// CHECK: Disassembly of section .text:
26// CHECK-NEXT: f:
27// CHECK-NEXT: 11000: 1e ff 2f e1 bx lr
28// CHECK: __aeabi_unwind_cpp_pr0:
29// CHECK-NEXT: 11004: 00 f0 20 e3 nop
30// CHECK-NEXT: 11008: 1e ff 2f e1 bx lr
31
32// CHECK: Contents of section .ARM.exidx:
33// CHECK-NEXT: 100d4 2c0f0000 b0b0b080 280f0000 01000000
deps/lld/test/ELF/arm-mov-relocs.s created+89
......@@ -0,0 +1,89 @@
1// RUN: llvm-mc -filetype=obj -triple=armv7a-unknown-linux-gnueabi %s -o %t
2// RUN: ld.lld %t -o %t2
3// RUN: llvm-objdump -d %t2 -triple=armv7a-unknown-linux-gnueabi | FileCheck %s
4// RUN: llvm-mc -filetype=obj -triple=thumbv7a-unknown-linux-gnueabi %s -o %t3
5// RUN: ld.lld %t3 -o %t4
6// RUN: llvm-objdump -d %t4 -triple=thumbv7a-unknown-linux-gnueabi | FileCheck %s
7// REQUIRES: arm
8
9// Test the R_ARM_MOVW_ABS_NC and R_ARM_MOVT_ABS relocations as well as
10// the R_ARM_THM_MOVW_ABS_NC and R_ARM_THM_MOVT_ABS relocations.
11 .syntax unified
12 .globl _start
13_start:
14 .section .R_ARM_MOVW_ABS_NC, "ax",%progbits
15 movw r0, :lower16:label
16 movw r1, :lower16:label1
17 movw r2, :lower16:label2 + 4
18 movw r3, :lower16:label3
19 movw r4, :lower16:label3 + 4
20// CHECK: Disassembly of section .R_ARM_MOVW_ABS_NC
21// CHECK: movw r0, #0
22// CHECK: movw r1, #4
23// CHECK: movw r2, #12
24// CHECK: movw r3, #65532
25// CHECK: movw r4, #0
26 .section .R_ARM_MOVT_ABS, "ax",%progbits
27 movt r0, :upper16:label
28 movt r1, :upper16:label1
29 movt r2, :upper16:label2 + 4
30 movt r3, :upper16:label3
31 movt r4, :upper16:label3 + 4
32// CHECK: Disassembly of section .R_ARM_MOVT_ABS
33// CHECK: movt r0, #2
34// CHECK: movt r1, #2
35// CHECK: movt r2, #2
36// CHECK: movt r3, #2
37// CHECK: movt r4, #3
38
39.section .R_ARM_MOVW_PREL_NC, "ax",%progbits
40 movw r0, :lower16:label - .
41 movw r1, :lower16:label1 - .
42 movw r2, :lower16:label2 + 4 - .
43 movw r3, :lower16:label3 - .
44 movw r4, :lower16:label3 + 0x103c - .
45// 0x20000 - 0x11028 = :lower16:0xefd8 (61400)
46// CHECK: 11028: {{.*}} movw r0, #61400
47// 0x20004 = 0x1102c = :lower16:0xefd8 (61400)
48// CHECK: 1102c: {{.*}} movw r1, #61400
49// 0x20008 - 0x11030 + 4 = :lower16:0xefdc (61404)
50// CHECK: 11030: {{.*}} movw r2, #61404
51// 0x2fffc - 0x11034 = :lower16:0x1efc8 (61384)
52// CHECK: 11034: {{.*}} movw r3, #61384
53// 0x2fffc - 0x11038 +0x103c :lower16:0x20000 (0)
54// CHECK: 11038: {{.*}} movw r4, #0
55
56.section .R_ARM_MOVT_PREL, "ax",%progbits
57 movt r0, :upper16:label - .
58 movt r1, :upper16:label1 - .
59 movt r2, :upper16:label2 + 0x4 - .
60 movt r3, :upper16:label3 - .
61 movt r4, :upper16:label3 + 0x1050 - .
62// 0x20000 - 0x1103c = :upper16:0xefc4 = 0
63// CHECK: 1103c: {{.*}} movt r0, #0
64// 0x20004 - 0x11040 = :upper16:0xefc0 = 0
65// CHECK: 11040: {{.*}} movt r1, #0
66// 0x20008 - 0x11044 + 4 = :upper16:0xefc8 = 0
67// CHECK: 11044: {{.*}} movt r2, #0
68// 0x2fffc - 0x11048 = :upper16:0x1efb4 = 1
69// CHECK: 11048: {{.*}} movt r3, #1
70// 0x2fffc - 0x1104c + 0x1050 = :upper16:0x20000 = 2
71// CHECK: 1104c: {{.*}} movt r4, #2
72 .section .destination, "aw",%progbits
73 .balign 65536
74// 0x20000
75label:
76 .word 0
77// 0x20004
78label1:
79 .word 1
80// 0x20008
81label2:
82 .word 2
83// Test label3 is immediately below 2^16 alignment boundary
84 .space 65536 - 16
85// 0x2fffc
86label3:
87 .word 3
88// label3 + 4 is on a 2^16 alignment boundary
89 .word 4
deps/lld/test/ELF/arm-pie-relative.s created+25
......@@ -0,0 +1,25 @@
1// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
2// RUN: ld.lld %t --pie -o %t2
3// RUN: llvm-readobj -r %t2 | FileCheck %s
4// RUN: llvm-objdump -s %t2 | FileCheck %s --check-prefix=GOT
5// REQUIRES: arm
6
7// Test that a R_ARM_GOT_BREL relocation with PIE results in a R_ARM_RELATIVE
8// dynamic relocation
9 .syntax unified
10 .text
11 .global _start
12_start:
13 .word sym(GOT)
14
15 .data
16 .global sym
17sym:
18 .word 0
19
20// CHECK: Relocations [
21// CHECK-NEXT: Section (4) .rel.dyn {
22// CHECK-NEXT: 0x3058 R_ARM_RELATIVE
23
24// GOT: Contents of section .got:
25// GOT-NEXT: 3058 00200000
deps/lld/test/ELF/arm-plt-reloc.s created+98
......@@ -0,0 +1,98 @@
1// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-plt-reloc.s -o %t1
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t2
3// RUN: ld.lld %t1 %t2 -o %t
4// RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t | FileCheck %s
5// RUN: ld.lld -shared %t1 %t2 -o %t3
6// RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t3 | FileCheck -check-prefix=DSO %s
7// RUN: llvm-readobj -s -r %t3 | FileCheck -check-prefix=DSOREL %s
8// REQUIRES: arm
9//
10// Test PLT entry generation
11 .syntax unified
12 .text
13 .align 2
14 .globl _start
15 .type _start,%function
16_start:
17 b func1
18 bl func2
19 beq func3
20
21// Executable, expect no PLT
22// CHECK: Disassembly of section .text:
23// CHECK-NEXT: func1:
24// CHECK-NEXT: 11000: 1e ff 2f e1 bx lr
25// CHECK: func2:
26// CHECK-NEXT: 11004: 1e ff 2f e1 bx lr
27// CHECK: func3:
28// CHECK-NEXT: 11008: 1e ff 2f e1 bx lr
29// CHECK: _start:
30// CHECK-NEXT: 1100c: fb ff ff ea b #-20 <func1>
31// CHECK-NEXT: 11010: fb ff ff eb bl #-20 <func2>
32// CHECK-NEXT: 11014: fb ff ff 0a beq #-20 <func3>
33
34// Expect PLT entries as symbols can be preempted
35// DSO: Disassembly of section .text:
36// DSO-NEXT: func1:
37// DSO-NEXT: 1000: 1e ff 2f e1 bx lr
38// DSO: func2:
39// DSO-NEXT: 1004: 1e ff 2f e1 bx lr
40// DSO: func3:
41// DSO-NEXT: 1008: 1e ff 2f e1 bx lr
42// DSO: _start:
43// S(0x1034) - P(0x100c) + A(-8) = 0x20 = 32
44// DSO-NEXT: 100c: 08 00 00 ea b #32
45// S(0x1044) - P(0x1010) + A(-8) = 0x2c = 44
46// DSO-NEXT: 1010: 0b 00 00 eb bl #44
47// S(0x1054) - P(0x1014) + A(-8) = 0x38 = 56
48// DSO-NEXT: 1014: 0e 00 00 0a beq #56
49
50// DSO: Disassembly of section .plt:
51// DSO-NEXT: $a:
52// DSO-NEXT: 1020: 04 e0 2d e5 str lr, [sp, #-4]!
53// DSO-NEXT: 1024: 04 e0 9f e5 ldr lr, [pc, #4]
54// DSO-NEXT: 1028: 0e e0 8f e0 add lr, pc, lr
55// DSO-NEXT: 102c: 08 f0 be e5 ldr pc, [lr, #8]!
56// 0x1028 + 8 + 0fd0 = 0x2000
57// DSO: $d:
58// DSO-NEXT: 1030: d0 0f 00 00 .word 0x00000fd0
59// DSO: $a:
60// DSO-NEXT: 1034: 04 c0 9f e5 ldr r12, [pc, #4]
61// DSO-NEXT: 1038: 0f c0 8c e0 add r12, r12, pc
62// DSO-NEXT: 103c: 00 f0 9c e5 ldr pc, [r12]
63// 0x1038 + 8 + 0fcc = 0x200c
64// DSO: $d:
65// DSO-NEXT: 1040: cc 0f 00 00 .word 0x00000fcc
66// DSO: $a:
67// DSO-NEXT: 1044: 04 c0 9f e5 ldr r12, [pc, #4]
68// DSO-NEXT: 1048: 0f c0 8c e0 add r12, r12, pc
69// DSO-NEXT: 104c: 00 f0 9c e5 ldr pc, [r12]
70// 0x1048 + 8 + 0fc0 = 0x2010
71// DSO: $d:
72// DSO-NEXT: 1050: c0 0f 00 00 .word 0x00000fc0
73// DSO: $a:
74// DSO-NEXT: 1054: 04 c0 9f e5 ldr r12, [pc, #4]
75// DSO-NEXT: 1058: 0f c0 8c e0 add r12, r12, pc
76// DSO-NEXT: 105c: 00 f0 9c e5 ldr pc, [r12]
77// 0x1058 + 8 + 0fb4 = 0x2014
78// DSO: $d:
79// DSO-NEXT: 1060: b4 0f 00 00 .word 0x00000fb4
80
81// DSOREL: Name: .got.plt
82// DSOREL-NEXT: Type: SHT_PROGBITS
83// DSOREL-NEXT: Flags [
84// DSOREL-NEXT: SHF_ALLOC
85// DSOREL-NEXT: SHF_WRITE
86// DSOREL-NEXT: ]
87// DSOREL-NEXT: Address: 0x2000
88// DSOREL-NEXT: Offset:
89// DSOREL-NEXT: Size: 24
90// DSOREL-NEXT: Link:
91// DSOREL-NEXT: Info:
92// DSOREL-NEXT: AddressAlignment: 4
93// DSOREL-NEXT: EntrySize:
94// DSOREL: Relocations [
95// DSOREL-NEXT: Section (4) .rel.plt {
96// DSOREL-NEXT: 0x200C R_ARM_JUMP_SLOT func1 0x0
97// DSOREL-NEXT: 0x2010 R_ARM_JUMP_SLOT func2 0x0
98// DSOREL-NEXT: 0x2014 R_ARM_JUMP_SLOT func3 0x0
deps/lld/test/ELF/arm-sbrel32.s created+39
......@@ -0,0 +1,39 @@
1// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
2// RUN: ld.lld %t -o %t2 2>&1
3// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s
4// REQUIRES: arm
5
6// Test the R_ARM_SBREL32 relocation which calculates the offset of the Symbol
7// from the static base. We define the static base to be the address of the
8// segment containing the symbol
9 .text
10 .syntax unified
11
12 .globl _start
13 .p2align 2
14 .type _start,%function
15_start:
16 .fnstart
17 bx lr
18
19 .long foo(sbrel)
20 .long foo2(sbrel)
21 .long foo3(sbrel)
22 .long foo4(sbrel)
23// RW segment starts here
24 .data
25 .p2align 4
26foo: .word 10
27foo2: .word 20
28
29 .bss
30foo3: .space 4
31foo4: .space 4
32
33// CHECK: Disassembly of section .text:
34// CHECK-NEXT: _start:
35// CHECK-NEXT: 11000: 1e ff 2f e1 bx lr
36// CHECK: 11004: 00 00 00 00 .word 0x00000000
37// CHECK-NEXT: 11008: 04 00 00 00 .word 0x00000004
38// CHECK-NEXT: 1100c: 08 00 00 00 .word 0x00000008
39// CHECK-NEXT: 11010: 0c 00 00 00 .word 0x0000000c
deps/lld/test/ELF/arm-static-defines.s created+44
......@@ -0,0 +1,44 @@
1// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
2// RUN: ld.lld %t --static -o %t2 2>&1
3// RUN: llvm-readobj --symbols %t2 | FileCheck %s
4// REQUIRES: arm
5
6// Check that on ARM we don't get a multiply defined symbol for __tls_get_addr
7// and undefined symbols for references to __exidx_start and __exidx_end
8 .syntax unified
9.section .text
10 .global __tls_get_addr
11__tls_get_addr:
12 bx lr
13
14 .global _start
15 .global __exidx_start
16 .global __exidx_end
17_start:
18 .fnstart
19 bx lr
20 .word __exidx_start
21 .word __exidx_end
22 .cantunwind
23 .fnend
24
25// CHECK: Name: __exidx_end
26// CHECK-NEXT: Value: 0x100E4
27// CHECK-NEXT: Size: 0
28// CHECK-NEXT: Binding: Local
29// CHECK-NEXT: Type: None
30// CHECK-NEXT: Other [
31// CHECK-NEXT: STV_HIDDEN
32// CHECK-NEXT: ]
33// CHECK-NEXT: Section: .ARM.exidx
34// CHECK: Name: __exidx_start
35// CHECK-NEXT: Value: 0x100D4
36// CHECK-NEXT: Size: 0
37// CHECK-NEXT: Binding: Local
38// CHECK-NEXT: Type: None
39// CHECK-NEXT: Other [
40// CHECK-NEXT: STV_HIDDEN
41// CHECK-NEXT: ]
42// CHECK-NEXT: Section: .ARM.exidx
43// CHECK: Symbol {
44// CHECK-NEXT: Name: __tls_get_addr
deps/lld/test/ELF/arm-target1.s created+36
......@@ -0,0 +1,36 @@
1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
3// RUN: llvm-readobj -r %t.o | FileCheck %s --check-prefix=RELOC
4// RUN: ld.lld -shared %t.o -o %t2.so --target1-rel
5// RUN: llvm-objdump -t -d %t2.so | FileCheck %s \
6// RUN: --check-prefix=RELATIVE
7// RUN: not ld.lld -shared %t.o -o %t3.so 2>&1 | FileCheck %s \
8// RUN: --check-prefix=ABS
9
10// RUN: ld.lld -shared %t.o -o %t2.so --target1-abs --target1-rel
11// RUN: llvm-objdump -t -d %t2.so | FileCheck %s \
12// RUN: --check-prefix=RELATIVE
13// RUN: not ld.lld -shared %t.o -o %t3.so --target1-rel --target1-abs 2>&1 \
14// RUN: | FileCheck %s --check-prefix=ABS
15
16// RELOC: Relocations [
17// RELOC: .rel.text {
18// RELOC: 0x0 R_ARM_TARGET1 patatino 0x0
19// RELOC: }
20// RELOC: ]
21
22.text
23 .word patatino(target1)
24 patatino:
25 .word 32
26// Force generation of $d.0 as section is not all data
27 nop
28// RELATIVE: Disassembly of section .text:
29// RELATIVE: $d.0:
30// RELATIVE: 1000: 04 00 00 00 .word 0x00000004
31// RELATIVE: SYMBOL TABLE:
32// RELATIVE: 00001004 .text 00000000 patatino
33
34// ABS: can't create dynamic relocation R_ARM_TARGET1 against symbol: patatino
35// ABS: >>> defined in {{.*}}.o
36// ABS: >>> referenced by {{.*}}.o:(.text+0x0)
deps/lld/test/ELF/arm-target2.s created+60
......@@ -0,0 +1,60 @@
1// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
2// RUN: ld.lld %t.o -o %t 2>&1
3// RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t | FileCheck %s
4// RUN: ld.lld %t.o --target2=got-rel -o %t2 2>&1
5// RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t2 | FileCheck %s
6// RUN: ld.lld %t.o --target2=abs -o %t3 2>&1
7// RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t3 | FileCheck -check-prefix=CHECK-ABS %s
8// RUN: ld.lld %t.o --target2=rel -o %t4 2>&1
9// RUN: llvm-objdump -s -triple=armv7a-none-linux-gnueabi %t4 | FileCheck -check-prefix=CHECK-REL %s
10// REQUIRES: arm
11
12// The R_ARM_TARGET2 is present in .ARM.extab sections. It can be handled as
13// either R_ARM_ABS32, R_ARM_REL32 or R_ARM_GOT_PREL. For ARM linux the default
14// is R_ARM_GOT_PREL. The other two options are primarily used for bare-metal,
15// they can be selected with the --target2=abs or --target2=rel option.
16 .syntax unified
17 .text
18 .globl _start
19 .align 2
20_start:
21 .type function, %function
22 .fnstart
23 bx lr
24 .personality __gxx_personality_v0
25 .handlerdata
26 .word _ZTIi(TARGET2)
27 .text
28 .fnend
29 .global __gxx_personality_v0
30 .type function, %function
31__gxx_personality_v0:
32 bx lr
33
34 .rodata
35_ZTIi: .word 0
36
37// CHECK: Contents of section .ARM.extab:
38// 1011c + 1ee4 = 12000 = .got
39// CHECK-NEXT: 10114 f00e0000 b0b0b000 e41e0000
40
41// CHECK-ABS: Contents of section .ARM.extab:
42// 100f0 = .rodata
43// CHECK-ABS-NEXT: 100d4 300f0000 b0b0b000 f0000100
44
45// CHECK-REL: Contents of section .ARM.extab:
46// 100dc + c = 100e8 = .rodata
47// CHECK-REL-NEXT: 100d4 300f0000 b0b0b000 14000000
48
49// CHECK: Contents of section .rodata:
50// CHECK-NEXT: 10130 00000000
51
52// CHECK-ABS: Contents of section .rodata:
53// CHECK-ABS-NEXT: 100f0 00000000
54
55// CHECK-REL: Contents of section .rodata:
56// CHECK-REL-NEXT: 100f0 00000000
57
58// CHECK: Contents of section .got:
59// 10130 = _ZTIi
60// CHECK-NEXT: 12000 30010100
deps/lld/test/ELF/arm-thumb-blx.s created+85
......@@ -0,0 +1,85 @@
1// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
2// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %S/Inputs/arm-thumb-blx-targets.s -o %ttarget
3// RUN: echo "SECTIONS { \
4// RUN: .R_ARM_CALL24_callee1 : { *(.R_ARM_CALL24_callee_low) } \
5// RUN: .R_ARM_CALL24_callee2 : { *(.R_ARM_CALL24_callee_thumb_low) } \
6// RUN: .caller : { *(.text) } \
7// RUN: .R_ARM_CALL24_callee3 : { *(.R_ARM_CALL24_callee_high) } \
8// RUN: .R_ARM_CALL24_callee4 : { *(.R_ARM_CALL24_callee_thumb_high) } } " > %t.script
9// RUN: ld.lld --script %t.script %t %ttarget -o %t2 2>&1
10// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-THUMB %s
11// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-ARM %s
12// REQUIRES: arm
13// Test BLX instruction is chosen for Thumb BL/BLX instruction and ARM callee
14// 2 byte nops are used to test the pc-rounding behaviour. As a BLX from a
15// 2 byte aligned destination is defined as Align(PC,4) + immediate:00
16// FIXME: llvm-mc has problems assembling BLX unless the destination is
17// external. The targets of the BL and BLX instructions are in arm-thumb-blx-target.s
18 .syntax unified
19 .section .text, "ax",%progbits
20 .thumb
21 .globl _start
22 .balign 0x10000
23 .type _start,%function
24_start:
25 blx callee_low
26 nop
27 bl callee_low
28 nop
29 blx callee_high
30 nop
31 bl callee_high
32 nop
33 blx blx_far
34 nop
35 bl blx_far
36 nop
37// Expect BLX to thumb target to be written out as a BL
38 blx callee_thumb_low
39 nop
40 blx callee_thumb_high
41 bx lr
42
43// CHECK-ARM: Disassembly of section .R_ARM_CALL24_callee1:
44// CHECK-NEXT-ARM: callee_low:
45// CHECK-NEXT-ARM: b4: 1e ff 2f e1 bx lr
46
47// CHECK-THUMB: Disassembly of section .R_ARM_CALL24_callee2:
48// CHECK-NEXT-THUMB: callee_thumb_low:
49// CHECK-NEXT-THUMB: 100: 70 47 bx lr
50
51// CHECK-THUMB: Disassembly of section .caller:
52// CHECK-THUMB: _start:
53// Align(0x10000,4) - 0xff50 (65360) + 4 = 0xb4 = callee_low
54// CHECK-NEXT-THUMB: 10000: f0 f7 58 e8 blx #-65360
55// CHECK-NEXT-THUMB: 10004: 00 bf nop
56// Align(0x10006,4) - 0xff54 (65364) + 4 = 0xb4 = callee_low
57// CHECK-NEXT-THUMB: 10006: f0 f7 56 e8 blx #-65364
58// CHECK-NEXT-THUMB: 1000a: 00 bf nop
59// Align(0x1000c,4) + 0xf0 (240) + 4 = 0x10100 = callee_high
60// CHECK-NEXT-THUMB: 1000c: 00 f0 78 e8 blx #240
61// CHECK-NEXT-THUMB: 10010: 00 bf nop
62// Align(0x10012,4) + 0xec (236) + 4 = 0x10100 = callee_high
63// CHECK-NEXT-THUMB: 10012: 00 f0 76 e8 blx #236
64// CHECK-NEXT-THUMB: 10016: 00 bf nop
65// Align(0x10018,4) + 0xfffffc (16777212) = 0x1010018 = blx_far
66// CHECK-NEXT-THUMB: 10018: ff f3 fe c7 blx #16777212
67// CHECK-NEXT-THUMB: 1001c: 00 bf nop
68// Align(0x1001e,4) + 0xfffff8 (16777208) = 0x1010018 = blx_far
69// CHECK-NEXT-THUMB: 1001e: ff f3 fc c7 blx #16777208
70// CHECK-NEXT-THUMB: 10022: 00 bf nop
71// 10024 - 0xff28 (65320) + 4 = 0x100 = callee_thumb_low
72// CHECK-NEXT-THUMB: 10024: f0 f7 6c f8 bl #-65320
73// CHECK-NEXT-THUMB: 10028: 00 bf nop
74// 1002a + 0x1d2 (466) + 4 = 0x10200 = callee_thumb_high
75// CHECK-NEXT-THUMB: 1002a: 00 f0 e9 f8 bl #466
76// CHECK-NEXT-THUMB: 1002e: 70 47 bx lr
77
78
79// CHECK-ARM: Disassembly of section .R_ARM_CALL24_callee3:
80// CHECK-NEXT-ARM: callee_high:
81// CHECK-NEXT-ARM: 10100: 1e ff 2f e1 bx lr
82
83// CHECK: Disassembly of section .R_ARM_CALL24_callee4:
84// CHECK-NEXT-THUMB:callee_thumb_high:
85// CHECK-NEXT-THUMB: 10200: 70 47 bx lr
deps/lld/test/ELF/arm-thumb-branch-error.s created+19
......@@ -0,0 +1,19 @@
1// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
2// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %S/Inputs/far-arm-thumb-abs.s -o %tfar
3// RUN: not ld.lld %t %tfar -o %t2 2>&1 | FileCheck %s
4// REQUIRES: arm
5 .syntax unified
6 .section .text, "ax",%progbits
7 .globl _start
8 .balign 0x10000
9 .type _start,%function
10_start:
11 // address of too_far symbols are just out of range of ARM branch with
12 // 26-bit immediate field and an addend of -8
13 bl too_far1
14 b too_far2
15 beq.w too_far3
16
17// CHECK: R_ARM_THM_CALL out of range
18// CHECK-NEXT: R_ARM_THM_JUMP24 out of range
19// CHECK-NEXT: R_ARM_THM_JUMP19 out of range
deps/lld/test/ELF/arm-thumb-branch.s created+60
......@@ -0,0 +1,60 @@
1// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
2// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %S/Inputs/far-arm-thumb-abs.s -o %tfar
3// RUN: echo "SECTIONS { \
4// RUN: . = 0xb4; \
5// RUN: .callee1 : { *(.callee_low) } \
6// RUN: .caller : { *(.text) } \
7// RUN: .callee2 : { *(.callee_high) } } " > %t.script
8// RUN: ld.lld --script %t.script %t %tfar -o %t2 2>&1
9// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck %s
10// REQUIRES: arm
11
12 .syntax unified
13 .thumb
14 .section .callee_low, "ax",%progbits
15 .align 2
16 .type callee_low,%function
17callee_low:
18 bx lr
19
20 .section .text, "ax",%progbits
21 .globl _start
22 .balign 0x10000
23 .type _start,%function
24_start:
25 bl callee_low
26 b callee_low
27 beq callee_low
28 bl callee_high
29 b callee_high
30 bne callee_high
31 bl far_uncond
32 b far_uncond
33 bgt far_cond
34 bx lr
35
36 .section .callee_high, "ax",%progbits
37 .align 2
38 .type callee_high,%function
39callee_high:
40 bx lr
41
42// CHECK: Disassembly of section .callee1:
43// CHECK-NEXT: callee_low:
44// CHECK-NEXT: b4: 70 47 bx lr
45// CHECK-NEXT: Disassembly of section .caller:
46// CHECK-NEXT: _start:
47// CHECK-NEXT: 10000: f0 f7 58 f8 bl #-65360
48// CHECK-NEXT: 10004: f0 f7 56 b8 b.w #-65364
49// CHECK-NEXT: 10008: 30 f4 54 a8 beq.w #-65368
50// CHECK-NEXT: 1000c: 00 f0 0c f8 bl #24
51// CHECK-NEXT: 10010: 00 f0 0a b8 b.w #20
52// CHECK-NEXT: 10014: 40 f0 08 80 bne.w #16
53// CHECK-NEXT: 10018: ff f3 ff d7 bl #16777214
54// CHECK-NEXT: 1001c: ff f3 fd 97 b.w #16777210
55// CHECK-NEXT: 10020: 3f f3 ff af bgt.w #1048574
56// CHECK-NEXT: 10024: 70 47 bx lr
57// CHECK-NEXT: 10026:
58// CHECK-NEXT: Disassembly of section .callee2:
59// CHECK-NEXT: callee_high:
60// CHECK-NEXT: 10028: 70 47 bx lr
deps/lld/test/ELF/arm-thumb-interwork-shared.s created+52
......@@ -0,0 +1,52 @@
1// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
2// RUN: ld.lld %t --shared -o %t.so
3// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t.so | FileCheck %s
4// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t.so | FileCheck %s -check-prefix=PLT
5// REQUIRES: arm
6 .syntax unified
7 .global sym1
8 .global elsewhere
9 .weak weakref
10sym1:
11 b.w elsewhere
12 b.w weakref
13
14// Check that we generate a thunk for an undefined symbol called via a plt
15// entry.
16
17// CHECK: Disassembly of section .text:
18// CHECK-NEXT: sym1:
19// CHECK-NEXT: 1000: 00 f0 02 b8 b.w #4 <__ThumbV7PILongThunk_elsewhere>
20// CHECK-NEXT: 1004: 00 f0 06 b8 b.w #12 <__ThumbV7PILongThunk_weakref>
21// CHECK: __ThumbV7PILongThunk_elsewhere:
22// CHECK-NEXT: 1008: 40 f2 20 0c movw r12, #32
23// CHECK-NEXT: 100c: c0 f2 00 0c movt r12, #0
24// CHECK-NEXT: 1010: fc 44 add r12, pc
25// CHECK-NEXT: 1012: 60 47 bx r12
26
27// CHECK: __ThumbV7PILongThunk_weakref:
28// CHECK-NEXT: 1014: 40 f2 24 0c movw r12, #36
29// CHECK-NEXT: 1018: c0 f2 00 0c movt r12, #0
30// CHECK-NEXT: 101c: fc 44 add r12, pc
31// CHECK-NEXT: 101e: 60 47 bx r12
32
33// PLT: Disassembly of section .plt:
34// PLT: $a:
35// PLT-NEXT: 1020: 04 e0 2d e5 str lr, [sp, #-4]!
36// PLT-NEXT: 1024: 04 e0 9f e5 ldr lr, [pc, #4]
37// PLT-NEXT: 1028: 0e e0 8f e0 add lr, pc, lr
38// PLT-NEXT: 102c: 08 f0 be e5 ldr pc, [lr, #8]!
39// PLT: $d:
40// PLT-NEXT: 1030: d0 0f 00 00 .word 0x00000fd0
41// PLT: $a:
42// PLT-NEXT: 1034: 04 c0 9f e5 ldr r12, [pc, #4]
43// PLT-NEXT: 1038: 0f c0 8c e0 add r12, r12, pc
44// PLT-NEXT: 103c: 00 f0 9c e5 ldr pc, [r12]
45// PLT: $d:
46// PLT-NEXT: 1040: cc 0f 00 00 .word 0x00000fcc
47// PLT: $a:
48// PLT-NEXT: 1044: 04 c0 9f e5 ldr r12, [pc, #4]
49// PLT-NEXT: 1048: 0f c0 8c e0 add r12, r12, pc
50// PLT-NEXT: 104c: 00 f0 9c e5 ldr pc, [r12]
51// PLT: $d:
52// PLT-NEXT: 1050: c0 0f 00 00 .word 0x00000fc0
deps/lld/test/ELF/arm-thumb-interwork-thunk-range.s created+15
......@@ -0,0 +1,15 @@
1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
3// RUN: ld.lld %t.o -o %t -image-base=0x80000000
4
5// Test that when the thunk is at a high address we don't get confused with it
6// being out of range.
7
8.thumb
9.global _start
10_start:
11b.w foo
12
13.arm
14.weak foo
15foo:
deps/lld/test/ELF/arm-thumb-interwork-thunk.s created+378
......@@ -0,0 +1,378 @@
1// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
2// RUN: echo "SECTIONS { \
3// RUN: . = SIZEOF_HEADERS; \
4// RUN: .R_ARM_JUMP24_callee_1 : { *(.R_ARM_JUMP24_callee_low) } \
5// RUN: .R_ARM_THM_JUMP_callee_1 : { *(.R_ARM_THM_JUMP_callee_low)} \
6// RUN: .text : { *(.text) } \
7// RUN: .arm_caller : { *(.arm_caller) } \
8// RUN: .thumb_caller : { *(.thumb_caller) } \
9// RUN: .R_ARM_JUMP24_callee_2 : { *(.R_ARM_JUMP24_callee_high) } \
10// RUN: .R_ARM_THM_JUMP_callee_2 : { *(.R_ARM_THM_JUMP_callee_high) } \
11// RUN: .got.plt 0x1894 : { } } " > %t.script
12// RUN: ld.lld --script %t.script %t -o %t2 2>&1
13// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-THUMB -check-prefix=CHECK-ABS-THUMB %s
14// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t2 | FileCheck -check-prefix=CHECK-ARM -check-prefix=CHECK-ABS-ARM %s
15// RUN: ld.lld --script %t.script %t -pie -o %t3 2>&1
16// RUN: ld.lld --script %t.script %t --shared -o %t4 2>&1
17// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t3 | FileCheck -check-prefix=CHECK-THUMB -check-prefix=CHECK-PI-THUMB %s
18// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t3 | FileCheck -check-prefix=CHECK-ARM -check-prefix=CHECK-PI-ARM %s
19// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t4 | FileCheck -check-prefix=CHECK-THUMB -check-prefix=CHECK-PI-PLT-THUMB %s
20// RUN: llvm-objdump -d -triple=armv7a-none-linux-gnueabi %t4 | FileCheck -check-prefix=CHECK-ARM -check-prefix=CHECK-PI-PLT-ARM %s
21// RUN: llvm-readobj -s -r %t4 | FileCheck -check-prefix=CHECK-DSO-REL %s
22// REQUIRES: arm
23
24// Test ARM Thumb Interworking
25// The file is linked and checked 3 times to check the following contexts
26// - Absolute executables, absolute Thunks are used.
27// - Position independent executables, position independent Thunks are used.
28// - Shared object, position independent Thunks to PLT entries are used.
29
30 .syntax unified
31
32// Target Sections for thunks at a lower address than the callers.
33.section .R_ARM_JUMP24_callee_low, "ax", %progbits
34 .thumb
35 .balign 0x1000
36 .globl thumb_callee1
37 .type thumb_callee1, %function
38thumb_callee1:
39 bx lr
40
41// CHECK-THUMB: Disassembly of section .R_ARM_JUMP24_callee_1:
42// CHECK-THUMB: thumb_callee1:
43// CHECK-THUMB: 1000: 70 47 bx
44 .section .R_ARM_THM_JUMP_callee_low, "ax", %progbits
45 .arm
46 .balign 0x100
47 .globl arm_callee1
48 .type arm_callee1, %function
49arm_callee1:
50 bx lr
51// Disassembly of section .R_ARM_THM_JUMP_callee_1:
52// CHECK-ARM: arm_callee1:
53// CHECK-ARM-NEXT: 1100: 1e ff 2f e1 bx lr
54
55 // Calling sections
56 // At present ARM and Thumb interworking thunks are always added to the calling
57 // section.
58 .section .arm_caller, "ax", %progbits
59 .arm
60 .balign 0x100
61 .globl arm_caller
62 .type arm_caller, %function
63arm_caller:
64 // If target supports BLX and target is in range we don't need an
65 // interworking thunk for a BL or BLX instruction.
66 bl thumb_callee1
67 blx thumb_callee1
68 // A B instruction can't be transformed into a BLX and needs an interworking
69 // thunk
70 b thumb_callee1
71 // As long as the thunk is in range it can be reused
72 b thumb_callee1
73 // There can be more than one thunk associated with a section
74 b thumb_callee2
75 b thumb_callee3
76 // In range ARM targets do not require interworking thunks
77 b arm_callee1
78 beq arm_callee2
79 bne arm_callee3
80 bx lr
81// CHECK-ARM-ABS-ARM: Disassembly of section .arm_caller:
82// CHECK-ARM-ABS-ARM-NEXT: arm_caller:
83// CHECK-ARM-ABS-ARM-NEXT: 1300: 3e ff ff fa blx #-776 <thumb_callee1>
84// CHECK-ARM-ABS-ARM-NEXT: 1304: 3d ff ff fa blx #-780 <thumb_callee1>
85// CHECK-ARM-ABS-ARM-NEXT: 1308: 06 00 00 ea b #24 <__ARMv7ABSLongThunk_thumb_callee1>
86// CHECK-ARM-ABS-ARM-NEXT: 130c: 05 00 00 ea b #20 <__ARMv7ABSLongThunk_thumb_callee1>
87// CHECK-ARM-ABS-ARM-NEXT: 1310: 07 00 00 ea b #28 <__ARMv7ABSLongThunk_thumb_callee2>
88// CHECK-ARM-ABS-ARM-NEXT: 1314: 09 00 00 ea b #36 <__ARMv7ABSLongThunk_thumb_callee3>
89// CHECK-ARM-ABS-ARM-NEXT: 1318: 78 ff ff ea b #-544 <arm_callee1>
90// CHECK-ARM-ABS-ARM-NEXT: 131c: b7 00 00 0a beq #732 <arm_callee2>
91// CHECK-ARM-ABS-ARM-NEXT: 1320: b7 00 00 1a bne #732 <arm_callee3>
92// CHECK-ARM-ABS-ARM-NEXT: 1324: 1e ff 2f e1 bx lr
93// CHECK-ARM-ABS-ARM: __ARMv7ABSLongThunk_thumb_callee1:
94// 0x1001 = thumb_callee1
95// CHECK-ARM-ABS-ARM-NEXT: 1328: 01 c0 01 e3 movw r12, #4097
96// CHECK-ARM-ABS-ARM-NEXT: 132c: 00 c0 40 e3 movt r12, #0
97// CHECK-ARM-ABS-ARM-NEXT: 1330: 1c ff 2f e1 bx r12
98// 0x1501 = thumb_callee2
99// CHECK-ARM-ABS-ARM: __ARMv7ABSLongThunk_thumb_callee2:
100// CHECK-ARM-ABS-ARM-NEXT: 1334: 01 c5 01 e3 movw r12, #5377
101// CHECK-ARM-ABS-ARM-NEXT: 1338: 00 c0 40 e3 movt r12, #0
102// CHECK-ARM-ABS-ARM-NEXT: 133c: 1c ff 2f e1 bx r12
103// 0x1503 = thumb_callee3
104// CHECK-ARM-ABS-ARM: __ARMv7ABSLongThunk_thumb_callee3:
105// CHECK-ARM-ABS-ARM-NEXT: 1340: 03 c5 01 e3 movw r12, #5379
106// CHECK-ARM-ABS-ARM-NEXT: 1344: 00 c0 40 e3 movt r12, #0
107// CHECK-ARM-ABS-ARM-NEXT: 1348: 1c ff 2f e1 bx r12
108
109// CHECK-PI-ARM: Disassembly of section .arm_caller:
110// CHECK-PI-ARM-NEXT: arm_caller:
111// CHECK-PI-ARM-NEXT: 1300: 3e ff ff fa blx #-776 <thumb_callee1>
112// CHECK-PI-ARM-NEXT: 1304: 3d ff ff fa blx #-780 <thumb_callee1>
113// CHECK-PI-ARM-NEXT: 1308: 06 00 00 ea b #24 <__ARMV7PILongThunk_thumb_callee1>
114// CHECK-PI-ARM-NEXT: 130c: 05 00 00 ea b #20 <__ARMV7PILongThunk_thumb_callee1>
115// CHECK-PI-ARM-NEXT: 1310: 08 00 00 ea b #32 <__ARMV7PILongThunk_thumb_callee2>
116// CHECK-PI-ARM-NEXT: 1314: 0b 00 00 ea b #44 <__ARMV7PILongThunk_thumb_callee3>
117// CHECK-PI-ARM-NEXT: 1318: 78 ff ff ea b #-544 <arm_callee1>
118// CHECK-PI-ARM-NEXT: 131c: b7 00 00 0a beq #732 <arm_callee2>
119// CHECK-PI-ARM-NEXT: 1320: b7 00 00 1a bne #732 <arm_callee3>
120// CHECK-PI-ARM-NEXT: 1324: 1e ff 2f e1 bx lr
121// CHECK-PI-ARM: __ARMV7PILongThunk_thumb_callee1:
122// 0x1330 + 8 - 0x337 = 0x1001 = thumb_callee1
123// CHECK-PI-ARM-NEXT: 1328: c9 cc 0f e3 movw r12, #64713
124// CHECK-PI-ARM-NEXT: 132c: ff cf 4f e3 movt r12, #65535
125// CHECK-PI-ARM-NEXT: 1330: 0f c0 8c e0 add r12, r12, pc
126// CHECK-PI-ARM-NEXT: 1334: 1c ff 2f e1 bx r12
127// CHECK-PI-ARM: __ARMV7PILongThunk_thumb_callee2:
128
129// CHECK-PI-ARM-NEXT: 1338: b9 c1 00 e3 movw r12, #441
130// CHECK-PI-ARM-NEXT: 133c: 00 c0 40 e3 movt r12, #0
131// CHECK-PI-ARM-NEXT: 1340: 0f c0 8c e0 add r12, r12, pc
132// CHECK-PI-ARM-NEXT: 1344: 1c ff 2f e1 bx r12
133// CHECK-PI-ARM: __ARMV7PILongThunk_thumb_callee3:
134// 0x1340 + 8 + 0x1b9 = 0x1501
135// CHECK-PI-ARM-NEXT: 1348: ab c1 00 e3 movw r12, #427
136// CHECK-PI-ARM-NEXT: 134c: 00 c0 40 e3 movt r12, #0
137// CHECK-PI-ARM-NEXT: 1350: 0f c0 8c e0 add r12, r12, pc
138// CHECK-PI-ARM-NEXT: 1354: 1c ff 2f e1 bx r12
139// 1350 + 8 + 0x1ab = 0x1503
140
141// All PLT entries are ARM, no need for interworking thunks
142// CHECK-PI-ARM-PLT: Disassembly of section .arm_caller:
143// CHECK-PI-ARM-PLT-NEXT: arm_caller:
144// 0x17e4 PLT(thumb_callee1)
145// CHECK-PI-ARM-PLT-NEXT: 1300: 37 01 00 eb bl #1244
146// 0x17e4 PLT(thumb_callee1)
147// CHECK-PI-ARM-PLT-NEXT: 1304: 36 01 00 eb bl #1240
148// 0x17e4 PLT(thumb_callee1)
149// CHECK-PI-ARM-PLT-NEXT: 1308: 35 01 00 ea b #1236
150// 0x17e4 PLT(thumb_callee1)
151// CHECK-PI-ARM-PLT-NEXT: 130c: 34 01 00 ea b #1232
152// 0x17f4 PLT(thumb_callee2)
153// CHECK-PI-ARM-PLT-NEXT: 1310: 37 01 00 ea b #1244
154// 0x1804 PLT(thumb_callee3)
155// CHECK-PI-ARM-PLT-NEXT: 1314: 3a 01 00 ea b #1256
156// 0x1814 PLT(arm_callee1)
157// CHECK-PI-ARM-PLT-NEXT: 1318: 3d 01 00 ea b #1268
158// 0x1824 PLT(arm_callee2)
159// CHECK-PI-ARM-PLT-NEXT: 131c: 40 01 00 0a beq #1280
160// 0x1834 PLT(arm_callee3)
161// CHECK-PI-ARM-PLT-NEXT: 1320: 43 01 00 1a bne #1292
162// CHECK-PI-ARM-PLT-NEXT: 1324: 1e ff 2f e1 bx lr
163
164 .section .thumb_caller, "ax", %progbits
165 .balign 0x100
166 .thumb
167 .globl thumb_caller
168 .type thumb_caller, %function
169thumb_caller:
170 // If target supports BLX and target is in range we don't need an
171 // interworking thunk for a BL or BLX instruction.
172 bl arm_callee1
173 blx arm_callee1
174 // A B instruction can't be transformed into a BLX and needs an interworking
175 // thunk
176 b.w arm_callee1
177 // As long as the thunk is in range it can be reused
178 b.w arm_callee2
179 // There can be more than one thunk associated with a section
180 b.w arm_callee3
181 // Conditional branches also require interworking thunks, they can use the
182 // same interworking thunks.
183 beq.w arm_callee1
184 beq.w arm_callee2
185 bne.w arm_callee3
186// CHECK-ABS-THUMB: Disassembly of section .thumb_caller:
187// CHECK-ABS-THUMB-NEXT: thumb_caller:
188// CHECK-ABS-THUMB-NEXT: 1400: ff f7 7e ee blx #-772
189// CHECK-ABS-THUMB-NEXT: 1404: ff f7 7c ee blx #-776
190// CHECK-ABS-THUMB-NEXT: 1408: 00 f0 0a b8 b.w #20 <__Thumbv7ABSLongThunk_arm_callee1>
191// CHECK-ABS-THUMB-NEXT: 140c: 00 f0 0d b8 b.w #26 <__Thumbv7ABSLongThunk_arm_callee2>
192// CHECK-ABS-THUMB-NEXT: 1410: 00 f0 10 b8 b.w #32 <__Thumbv7ABSLongThunk_arm_callee3>
193// CHECK-ABS-THUMB-NEXT: 1414: 00 f0 04 80 beq.w #8 <__Thumbv7ABSLongThunk_arm_callee1>
194// CHECK-ABS-THUMB-NEXT: 1418: 00 f0 07 80 beq.w #14 <__Thumbv7ABSLongThunk_arm_callee2>
195// CHECK-ABS-THUMB-NEXT: 141c: 40 f0 0a 80 bne.w #20 <__Thumbv7ABSLongThunk_arm_callee3>
196// CHECK-ABS-THUMB: __Thumbv7ABSLongThunk_arm_callee1:
197// 0x1100 = arm_callee1
198// CHECK-ABS-THUMB-NEXT: 1420: 41 f2 00 1c movw r12, #4352
199// CHECK-ABS-THUMB-NEXT: 1424: c0 f2 00 0c movt r12, #0
200// CHECK-ABS-THUMB-NEXT: 1428: 60 47 bx r12
201// CHECK-ABS-THUMB: __Thumbv7ABSLongThunk_arm_callee2:
202// 0x1600 = arm_callee2
203// CHECK-ABS-THUMB-NEXT: 142a: 41 f2 00 6c movw r12, #5632
204// CHECK-ABS-THUMB-NEXT: 142e: c0 f2 00 0c movt r12, #0
205// CHECK-ABS-THUMB-NEXT: 1432: 60 47 bx r12
206// 0x1604 = arm_callee3
207// CHECK-ABS-THUMB: __Thumbv7ABSLongThunk_arm_callee3:
208// CHECK-ABS-THUMB-NEXT: 1434: 41 f2 04 6c movw r12, #5636
209// CHECK-ABS-THUMB-NEXT: 1438: c0 f2 00 0c movt r12, #0
210// CHECK-ABS-THUMB-NEXT: 143c: 60 47 bx r12
211
212// CHECK-PI-THUMB: Disassembly of section .thumb_caller:
213// CHECK-PI-THUMB-NEXT: thumb_caller:
214// CHECK-PI-THUMB-NEXT: 1400: ff f7 7e ee blx #-772
215// CHECK-PI-THUMB-NEXT: 1404: ff f7 7c ee blx #-776
216// CHECK-PI-THUMB-NEXT: 1408: 00 f0 0a b8 b.w #20 <__ThumbV7PILongThunk_arm_callee1>
217// CHECK-PI-THUMB-NEXT: 140c: 00 f0 0e b8 b.w #28 <__ThumbV7PILongThunk_arm_callee2>
218// CHECK-PI-THUMB-NEXT: 1410: 00 f0 12 b8 b.w #36 <__ThumbV7PILongThunk_arm_callee3>
219// CHECK-PI-THUMB-NEXT: 1414: 00 f0 04 80 beq.w #8 <__ThumbV7PILongThunk_arm_callee1>
220// CHECK-PI-THUMB-NEXT: 1418: 00 f0 08 80 beq.w #16 <__ThumbV7PILongThunk_arm_callee2>
221// CHECK-PI-THUMB-NEXT: 141c: 40 f0 0c 80 bne.w #24 <__ThumbV7PILongThunk_arm_callee3>
222// CHECK-PI-THUMB: __ThumbV7PILongThunk_arm_callee1:
223// 0x1428 + 4 - 0x32c = 0x1100 = arm_callee1
224// CHECK-PI-THUMB-NEXT: 1420: 4f f6 d4 4c movw r12, #64724
225// CHECK-PI-THUMB-NEXT: 1424: cf f6 ff 7c movt r12, #65535
226// CHECK-PI-THUMB-NEXT: 1428: fc 44 add r12, pc
227// CHECK-PI-THUMB-NEXT: 142a: 60 47 bx r12
228// CHECK-PI-THUMB: __ThumbV7PILongThunk_arm_callee2:
229// 0x1434 + 4 + 0x1c8 = 0x1600 = arm_callee2
230// CHECK-PI-THUMB-NEXT: 142c: 40 f2 c8 1c movw r12, #456
231// CHECK-PI-THUMB-NEXT: 1430: c0 f2 00 0c movt r12, #0
232// CHECK-PI-THUMB-NEXT: 1434: fc 44 add r12, pc
233// CHECK-PI-THUMB-NEXT: 1436: 60 47 bx r12
234// CHECK-PI-THUMB: __ThumbV7PILongThunk_arm_callee3:
235// 0x1440 + 4 + 0x1c0 = 0x1604 = arm_callee3
236// CHECK-PI-THUMB-NEXT: 1438: 40 f2 c0 1c movw r12, #448
237// CHECK-PI-THUMB-NEXT: 143c: c0 f2 00 0c movt r12, #0
238// CHECK-PI-THUMB-NEXT: 1440: fc 44 add r12, pc
239// CHECK-PI-THUMB-NEXT: 1442: 60 47 bx r12
240
241// CHECK-PI-THUMB-PLT: Disassembly of section .arm_caller:
242// CHECK-PI-THUMB-PLT-NEXT: thumb_caller:
243// 0x1400 + 4 + 0x410 = 0x1814 = PLT(arm_callee1)
244// CHECK-PI-THUMB-PLT-NEXT: 1400: 00 f0 08 ea blx #1040
245// 0x1404 + 4 + 0x40c = 0x1814 = PLT(arm_callee1)
246// CHECK-PI-THUMB-PLT-NEXT: 1404: 00 f0 06 ea blx #1036
247// 0x1408 + 4 + 0x14 = 0x1420 = IWV(PLT(arm_callee1)
248// CHECK-PI-THUMB-PLT-NEXT: 1408: 00 f0 0a b8 b.w #20
249// 0x140c + 4 + 0x1c = 0x142c = IWV(PLT(arm_callee2)
250// CHECK-PI-THUMB-PLT-NEXT: 140c: 00 f0 0e b8 b.w #28
251// 0x1410 + 4 + 0x24 = 0x1438 = IWV(PLT(arm_callee3)
252// CHECK-PI-THUMB-PLT-NEXT: 1410: 00 f0 12 b8 b.w #36
253// 0x1414 + 4 + 8 = 0x1420 = IWV(PLT(arm_callee1)
254// CHECK-PI-THUMB-PLT-NEXT: 1414: 00 f0 04 80 beq.w #8
255// 0x1418 + 4 + 0x10 = 0x142c = IWV(PLT(arm_callee2)
256// CHECK-PI-THUMB-PLT-NEXT: 1418: 00 f0 08 80 beq.w #16
257// 0x141c + 4 + 0x18 = 0x1438 = IWV(PLT(arm_callee3)
258// CHECK-PI-THUMB-PLT-NEXT: 141c: 40 f0 0c 80 bne.w #24
259// 0x1428 + 4 + 0x3e8 = 0x1814 = PLT(arm_callee1)
260// CHECK-PI-THUMB-PLT-NEXT: 1420: 40 f2 e8 3c movw r12, #1000
261// CHECK-PI-THUMB-PLT-NEXT: 1424: c0 f2 00 0c movt r12, #0
262// CHECK-PI-THUMB-PLT-NEXT: 1428: fc 44 add r12, pc
263// CHECK-PI-THUMB-PLT-NEXT: 142a: 60 47 bx r12
264// 0x1434 + 4 + 0x3ec = 0x1824 = PLT(arm_callee2)
265// CHECK-PI-THUMB-PLT-NEXT: 142c: 40 f2 ec 3c movw r12, #1004
266// CHECK-PI-THUMB-PLT-NEXT: 1430: c0 f2 00 0c movt r12, #0
267// CHECK-PI-THUMB-PLT-NEXT: 1434: fc 44 add r12, pc
268// CHECK-PI-THUMB-PLT-NEXT: 1436: 60 47 bx r12
269// 0x1440 + 4 + 0x3f0 = 0x1834 = PLT(arm_callee3)
270// CHECK-PI-THUMB-PLT-NEXT: 1438: 40 f2 f0 3c movw r12, #1008
271// CHECK-PI-THUMB-PLT-NEXT: 143c: c0 f2 00 0c movt r12, #0
272// CHECK-PI-THUMB-PLT-NEXT: 1440: fc 44 add r12, pc
273// CHECK-PI-THUMB-PLT-NEXT: 1442: 60 47 bx r12
274
275// Target Sections for thunks at a higher address than the callers.
276.section .R_ARM_JUMP24_callee_high, "ax", %progbits
277 .thumb
278 .balign 0x100
279 .globl thumb_callee2
280 .type thumb_callee2, %function
281thumb_callee2:
282 bx lr
283
284 .globl thumb_callee3
285 .type thumb_callee3, %function
286thumb_callee3:
287 bx lr
288// CHECK-THUMB: Disassembly of section .R_ARM_JUMP24_callee_2:
289// CHECK-THUMB-NEXT: thumb_callee2:
290// CHECK-THUMB-NEXT: 1500: 70 47 bx lr
291// CHECK-THUMB: thumb_callee3:
292// CHECK-THUMB-NEXT: 1502: 70 47 bx lr
293
294 .section .R_ARM_THM_JUMP_callee_high, "ax", %progbits
295 .arm
296 .balign 0x100
297 .globl arm_callee2
298 .type arm_callee2, %function
299arm_callee2:
300 bx lr
301 .globl arm_callee3
302 .type arm_callee3, %function
303arm_callee3:
304 bx lr
305// CHECK-ARM: Disassembly of section .R_ARM_THM_JUMP_callee_2:
306// CHECK-ARM-NEXT: arm_callee2:
307// CHECK-ARM-NEXT: 1600: 1e ff 2f e1 bx lr
308// CHECK-ARM: arm_callee3:
309// CHECK-ARM-NEXT: 1604: 1e ff 2f e1 bx lr
310
311// _start section just calls the arm and thumb calling sections
312 .text
313 .arm
314 .globl _start
315 .balign 0x100
316 .type _start, %function
317_start:
318 bl arm_caller
319 bl thumb_caller
320 bx lr
321
322
323// CHECK-PI-ARM-PLT: Disassembly of section .plt:
324// CHECK-PI-ARM-PLT-NEXT: .plt:
325// CHECK-PI-ARM-PLT-NEXT: 17b0: 04 e0 2d e5 str lr, [sp, #-4]!
326// CHECK-PI-ARM-PLT-NEXT: 17b4: 04 e0 9f e5 ldr lr, [pc, #4]
327// CHECK-PI-ARM-PLT-NEXT: 17b8: 0e e0 8f e0 add lr, pc, lr
328// CHECK-PI-ARM-PLT-NEXT: 17bc: 08 f0 be e5 ldr pc, [lr, #8]!
329// CHECK-PI-ARM-PLT-NEXT: 17c0: d4 00 00 00
330// 0x17c8 + 8 + 0xd0 = 0x18a0 arm_caller
331// CHECK-PI-ARM-PLT-NEXT: 17c4: 04 c0 9f e5 ldr r12, [pc, #4]
332// CHECK-PI-ARM-PLT-NEXT: 17c8: 0f c0 8c e0 add r12, r12, pc
333// CHECK-PI-ARM-PLT-NEXT: 17cc: 00 f0 9c e5 ldr pc, [r12]
334// CHECK-PI-ARM-PLT-NEXT: 17d0: d0 00 00 00
335// 0x17d8 + 8 + 0xc4 = 0x18a4 thumb_caller
336// CHECK-PI-ARM-PLT-NEXT: 17d4: 04 c0 9f e5 ldr r12, [pc, #4]
337// CHECK-PI-ARM-PLT-NEXT: 17d8: 0f c0 8c e0 add r12, r12, pc
338// CHECK-PI-ARM-PLT-NEXT: 17dc: 00 f0 9c e5 ldr pc, [r12]
339// CHECK-PI-ARM-PLT-NEXT: 17e0: c4 00 00 00
340// 0x17e8 + 8 + 0xb8 = 0x18a8 thumb_callee1
341// CHECK-PI-ARM-PLT-NEXT: 17e4: 04 c0 9f e5 ldr r12, [pc, #4]
342// CHECK-PI-ARM-PLT-NEXT: 17e8: 0f c0 8c e0 add r12, r12, pc
343// CHECK-PI-ARM-PLT-NEXT: 17ec: 00 f0 9c e5 ldr pc, [r12]
344// CHECK-PI-ARM-PLT-NEXT: 17f0: b8 00 00 00
345// 0x17f8 + 8 + 0xac = 0x18ac thumb_callee2
346// CHECK-PI-ARM-PLT-NEXT: 17f4: 04 c0 9f e5 ldr r12, [pc, #4]
347// CHECK-PI-ARM-PLT-NEXT: 17f8: 0f c0 8c e0 add r12, r12, pc
348// CHECK-PI-ARM-PLT-NEXT: 17fc: 00 f0 9c e5 ldr pc, [r12]
349// CHECK-PI-ARM-PLT-NEXT: 1800: ac 00 00 00
350// 0x1808 + 8 + 0xa0 = 0x18b0 thumb_callee3
351// CHECK-PI-ARM-PLT-NEXT: 1804: 04 c0 9f e5 ldr r12, [pc, #4]
352// CHECK-PI-ARM-PLT-NEXT: 1808: 0f c0 8c e0 add r12, r12, pc
353// CHECK-PI-ARM-PLT-NEXT: 180c: 00 f0 9c e5 ldr pc, [r12]
354// CHECK-PI-ARM-PLT-NEXT: 1810: a0 00 00 00
355// 0x1818 + 8 + 0x94 = 0x18b4 arm_callee1
356// CHECK-PI-ARM-PLT-NEXT: 1814: 04 c0 9f e5 ldr r12, [pc, #4]
357// CHECK-PI-ARM-PLT-NEXT: 1818: 0f c0 8c e0 add r12, r12, pc
358// CHECK-PI-ARM-PLT-NEXT: 181c: 00 f0 9c e5 ldr pc, [r12]
359// CHECK-PI-ARM-PLT-NEXT: 1820: 94 00 00 00
360// 0x1828 + 8 + 0x88 = 0x18b8 arm_callee2
361// CHECK-PI-ARM-PLT-NEXT: 1824: 04 c0 9f e5 ldr r12, [pc, #4]
362// CHECK-PI-ARM-PLT-NEXT: 1828: 0f c0 8c e0 add r12, r12, pc
363// CHECK-PI-ARM-PLT-NEXT: 182c: 00 f0 9c e5 ldr pc, [r12]
364// CHECK-PI-ARM-PLT-NEXT: 1830: 88 00 00 00
365// 0x1838 + 8 + 0x7c = 0x18bc arm_callee3
366// CHECK-PI-ARM-PLT-NEXT: 1834: 04 c0 9f e5 ldr r12, [pc, #4]
367// CHECK-PI-ARM-PLT-NEXT: 1838: 0f c0 8c e0 add r12, r12, pc
368// CHECK-PI-ARM-PLT-NEXT: 183c: 00 f0 9c e5 ldr pc, [r12]
369// CHECK-PI-ARM-PLT-NEXT: 1840: 7c 00 00 00
370
371// CHECK-DSO-REL: 0x18A0 R_ARM_JUMP_SLOT arm_caller
372// CHECK-DSO-REL-NEXT: 0x18A4 R_ARM_JUMP_SLOT thumb_caller
373// CHECK-DSO-REL-NEXT: 0x18A8 R_ARM_JUMP_SLOT thumb_callee1
374// CHECK-DSO-REL-NEXT: 0x18AC R_ARM_JUMP_SLOT thumb_callee2
375// CHECK-DSO-REL-NEXT: 0x18B0 R_ARM_JUMP_SLOT thumb_callee3
376// CHECK-DSO-REL-NEXT: 0x18B4 R_ARM_JUMP_SLOT arm_callee1
377// CHECK-DSO-REL-NEXT: 0x18B8 R_ARM_JUMP_SLOT arm_callee2
378// CHECK-DSO-REL-NEXT: 0x18BC R_ARM_JUMP_SLOT arm_callee3
deps/lld/test/ELF/arm-thumb-narrow-branch-check.s created+73
......@@ -0,0 +1,73 @@
1// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
2// RUN: echo "SECTIONS { \
3// RUN: . = SIZEOF_HEADERS; \
4// RUN: .R_ARM_PC11_1 : { *(.R_ARM_PC11_1) } \
5// RUN: .caller : { *(.caller) } \
6// RUN: .R_ARM_PC11_2 : { *(.R_ARM_PC11_2) } \
7// RUN: .text : { *(.text) } } " > %t.script
8// RUN: ld.lld --script %t.script %t %S/Inputs/arm-thumb-narrow-branch.o -o %t2 2>&1
9// RUN: llvm-objdump -d -triple=thumbv7a-none-linux-gnueabi %t2 | FileCheck %s
10// REQUIRES: arm
11
12// Test the R_ARM_PC11 relocation which is used with the narrow encoding of B.N
13// the source of these relocations is a binary file arm-thumb-narrow-branch.o
14// which has been assembled with the GNU assembler as llvm-mc doesn't emit it
15// as the range of +-2048 bytes is too small to be practically useful for out
16// of section branches.
17 .syntax unified
18
19.global callee_low_far
20.type callee_low_far,%function
21callee_low_far = 0x809
22
23 .section .R_ARM_PC11_1,"ax",%progbits
24 .thumb
25 .balign 0x1000
26 .type callee_low,%function
27 .globl callee_low
28callee_low:
29 bx lr
30
31 .text
32 .align 2
33 .thumb
34 .globl _start
35 .type _start, %function
36_start:
37 bl callers
38 bx lr
39
40 .section .R_ARM_PC11_2,"ax",%progbits
41 .thumb
42 .align 2
43 .type callee_high,%function
44 .globl callee_high
45callee_high:
46 bx lr
47
48.global callee_high_far
49.type callee_high_far,%function
50callee_high_far = 0x180d
51
52// CHECK: Disassembly of section .R_ARM_PC11_1:
53// CHECK-NEXT: callee_low:
54// CHECK-NEXT: 1000: 70 47 bx lr
55// CHECK-NEXT: Disassembly of section .caller:
56// CHECK-NEXT: callers:
57// 1004 - 0x800 (2048) + 4 = 0x808 = callee_low_far
58// CHECK-NEXT: 1004: 00 e4 b #-2048
59// 1006 - 0xa (10) + 4 = 0x1000 = callee_low
60// CHECK-NEXT: 1006: fb e7 b #-10
61// 1008 + 4 + 4 = 0x1010 = callee_high
62// CHECK-NEXT: 1008: 02 e0 b #4
63// 100a + 0x7fe (2046) + 4 = 0x180c = callee_high_far
64// CHECK-NEXT: 100a: ff e3 b #2046
65// CHECK-NEXT: 100c: 70 47 bx lr
66// CHECK-NEXT: 100e: 00 bf nop
67// CHECK-NEXT: Disassembly of section .R_ARM_PC11_2:
68// CHECK-NEXT: callee_high:
69// CHECK-NEXT: 1010: 70 47 bx lr
70// CHECK-NEXT: Disassembly of section .text:
71// CHECK-NEXT: _start:
72// CHECK-NEXT: 1014: ff f7 f6 ff bl #-20
73// CHECK-NEXT: 1018: 70 47 bx lr
deps/lld/test/ELF/arm-thumb-no-undefined-thunk.s created+24
......@@ -0,0 +1,24 @@
1// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
2// RUN: ld.lld %t -o %t2 2>&1
3// RUN: llvm-objdump -triple=thumbv7a-none-linux-gnueabi -d %t2 | FileCheck %s
4// REQUIRES: arm
5
6// Check that no thunks are created for an undefined weak symbol
7 .syntax unified
8
9.weak target
10
11.section .text.thumb, "ax", %progbits
12 .thumb
13 .global
14_start:
15 bl target
16 b target
17 b.w target
18
19// CHECK: Disassembly of section .text:
20// CHECK-NEXT: _start:
21// 69636 = 0x11004 = next instruction
22// CHECK: 11000: {{.*}} bl #0
23// CHECK-NEXT: 11004: {{.*}} b.w #0 <_start+0x8>
24// CHECK-NEXT: 11008: {{.*}} b.w #0 <_start+0xC>
deps/lld/test/ELF/arm-thumb-plt-reloc.s created+108
......@@ -0,0 +1,108 @@
1// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %p/Inputs/arm-plt-reloc.s -o %t1
2// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t2
3// RUN: ld.lld %t1 %t2 -o %t
4// RUN: llvm-objdump -triple=thumbv7a-none-linux-gnueabi -d %t | FileCheck %s
5// RUN: ld.lld -shared %t1 %t2 -o %t3
6// RUN: llvm-objdump -triple=thumbv7a-none-linux-gnueabi -d %t3 | FileCheck -check-prefix=DSOTHUMB %s
7// RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t3 | FileCheck -check-prefix=DSOARM %s
8// RUN: llvm-readobj -s -r %t3 | FileCheck -check-prefix=DSOREL %s
9// REQUIRES: arm
10//
11// Test PLT entry generation
12 .syntax unified
13 .text
14 .align 2
15 .globl _start
16 .type _start,%function
17_start:
18// FIXME, interworking is only supported for BL via BLX at the moment, when
19// interworking thunks are available for b.w and b<cond>.w this can be altered
20// to test the different forms of interworking.
21 bl func1
22 bl func2
23 bl func3
24
25// Executable, expect no PLT
26// CHECK: Disassembly of section .text:
27// CHECK-NEXT: func1:
28// CHECK-NEXT: 11000: 70 47 bx lr
29// CHECK: func2:
30// CHECK-NEXT: 11002: 70 47 bx lr
31// CHECK: func3:
32// CHECK-NEXT: 11004: 70 47 bx lr
33// CHECK-NEXT: 11006: d4 d4
34// CHECK: _start:
35// 11008 + 4 -12 = 0x11000 = func1
36// CHECK-NEXT: 11008: ff f7 fa ff bl #-12
37// 1100c + 4 -14 = 0x11002 = func2
38// CHECK-NEXT: 1100c: ff f7 f9 ff bl #-14
39// 11010 + 4 -16 = 0x11004 = func3
40// CHECK-NEXT: 11010: ff f7 f8 ff bl #-16
41
42// Expect PLT entries as symbols can be preempted
43// .text is Thumb and .plt is ARM, llvm-objdump can currently only disassemble
44// as ARM or Thumb. Work around by disassembling twice.
45// DSOTHUMB: Disassembly of section .text:
46// DSOTHUMB: func1:
47// DSOTHUMB-NEXT: 1000: 70 47 bx lr
48// DSOTHUMB: func2:
49// DSOTHUMB-NEXT: 1002: 70 47 bx lr
50// DSOTHUMB: func3:
51// DSOTHUMB-NEXT: 1004: 70 47 bx lr
52// DSOTHUMB-NEXT: 1006: d4 d4
53// DSOTHUMB: _start:
54// 0x1008 + 0x28 + 4 = 0x1034 = PLT func1
55// DSOTHUMB-NEXT: 1008: 00 f0 14 e8 blx #40
56// 0x100c + 0x34 + 4 = 0x1044 = PLT func2
57// DSOTHUMB-NEXT: 100c: 00 f0 1a e8 blx #52
58// 0x1010 + 0x40 + 4 = 0x1054 = PLT func3
59// DSOTHUMB-NEXT: 1010: 00 f0 20 e8 blx #64
60// DSOARM: Disassembly of section .plt:
61// DSOARM-NEXT: $a:
62// DSOARM-NEXT: 1020: 04 e0 2d e5 str lr, [sp, #-4]!
63// DSOARM-NEXT: 1024: 04 e0 9f e5 ldr lr, [pc, #4]
64// DSOARM-NEXT: 1028: 0e e0 8f e0 add lr, pc, lr
65// DSOARM-NEXT: 102c: 08 f0 be e5 ldr pc, [lr, #8]!
66// DSOARM: $d:
67// DSOARM-NEXT: 1030: d0 0f 00 00 .word 0x00000fd0
68// 0x1028 + 8 + 0fd0 = 0x2000
69// DSOARM: $a:
70// DSOARM-NEXT: 1034: 04 c0 9f e5 ldr r12, [pc, #4]
71// DSOARM-NEXT: 1038: 0f c0 8c e0 add r12, r12, pc
72// DSOARM-NEXT: 103c: 00 f0 9c e5 ldr pc, [r12]
73// DSOARM: $d:
74// DSOARM-NEXT: 1040: cc 0f 00 00 .word 0x00000fcc
75// 0x1038 + 8 + 0fcc = 0x200c
76// DSOARM: $a:
77// DSOARM-NEXT: 1044: 04 c0 9f e5 ldr r12, [pc, #4]
78// DSOARM-NEXT: 1048: 0f c0 8c e0 add r12, r12, pc
79// DSOARM-NEXT: 104c: 00 f0 9c e5 ldr pc, [r12]
80// DSOARM: $d:
81// DSOARM-NEXT: 1050: c0 0f 00 00 .word 0x00000fc0
82// 0x1048 + 8 + 0fc0 = 0x2010
83// DSOARM: $a:
84// DSOARM-NEXT: 1054: 04 c0 9f e5 ldr r12, [pc, #4]
85// DSOARM-NEXT: 1058: 0f c0 8c e0 add r12, r12, pc
86// DSOARM-NEXT: 105c: 00 f0 9c e5 ldr pc, [r12]
87// DSOARM: $d:
88// DSOARM-NEXT: 1060: b4 0f 00 00 .word 0x00000fb4
89// 0x1058 + 8 + 0fb4 = 0x2014
90
91// DSOREL: Name: .got.plt
92// DSOREL-NEXT: Type: SHT_PROGBITS
93// DSOREL-NEXT: Flags [
94// DSOREL-NEXT: SHF_ALLOC
95// DSOREL-NEXT: SHF_WRITE
96// DSOREL-NEXT: ]
97// DSOREL-NEXT: Address: 0x2000
98// DSOREL-NEXT: Offset:
99// DSOREL-NEXT: Size: 24
100// DSOREL-NEXT: Link:
101// DSOREL-NEXT: Info:
102// DSOREL-NEXT: AddressAlignment: 4
103// DSOREL-NEXT: EntrySize:
104// DSOREL: Relocations [
105// DSOREL-NEXT: Section (4) .rel.plt {
106// DSOREL-NEXT: 0x200C R_ARM_JUMP_SLOT func1 0x0
107// DSOREL-NEXT: 0x2010 R_ARM_JUMP_SLOT func2 0x0
108// DSOREL-NEXT: 0x2014 R_ARM_JUMP_SLOT func3 0x0
deps/lld/test/ELF/arm-thumb-thunk-symbols.s created+42
......@@ -0,0 +1,42 @@
1// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
2// RUN: ld.lld %t -o %t2 2>&1
3// RUN: llvm-readobj --symbols %t2 | FileCheck %s
4// RUN: ld.lld --shared %t -o %t3 2>&1
5// RUN: llvm-readobj --symbols %t3 | FileCheck -check-prefix=CHECK-PI %s
6// REQUIRES: arm
7
8// Check that the symbols generated for Thunks have the correct symbol type
9// of STT_FUNC and the correct value of bit 0 (0 for ARM 1 for Thumb)
10 .syntax unified
11 .section .text.thumb, "ax", %progbits
12 .thumb
13 .balign 0x1000
14 .globl thumb_fn
15 .type thumb_fn, %function
16thumb_fn:
17 b.w arm_fn
18
19 .section .text.arm, "ax", %progbits
20 .arm
21 .balign 0x1000
22 .globl arm_fn
23 .type arm_fn, %function
24arm_fn:
25 b thumb_fn
26
27// CHECK: Name: __Thumbv7ABSLongThunk_arm_fn
28// CHECK-NEXT: Value: 0x11005
29// CHECK-NEXT: Size: 10
30// CHECK-NEXT: Binding: Local (0x0)
31// CHECK-NEXT: Type: Function (0x2)
32// CHECK: Name: __ARMv7ABSLongThunk_thumb_fn
33// CHECK-NEXT: Value: 0x11010
34// CHECK-NEXT: Size: 12
35// CHECK-NEXT: Binding: Local (0x0)
36// CHECK-NEXT: Type: Function (0x2)
37
38// CHECK-PI: Name: __ThumbV7PILongThunk_arm_fn
39// CHECK-PI-NEXT: Value: 0x1005
40// CHECK-PI-NEXT: Size: 12
41// CHECK-PI-NEXT: Binding: Local (0x0)
42// CHECK-PI-NEXT: Type: Function (0x2)
deps/lld/test/ELF/arm-thumb-undefined-weak.s created+38
......@@ -0,0 +1,38 @@
1// RUN: llvm-mc -filetype=obj -triple=thumbv7a-none-linux-gnueabi %s -o %t
2// RUN: ld.lld %t -o %t2 2>&1
3// RUN: llvm-objdump -triple=thumbv7a-none-linux-gnueabi -d %t2 | FileCheck %s
4// REQUIRES: arm
5
6// Check that the ARM ABI rules for undefined weak symbols are applied.
7// Branch instructions are resolved to the next instruction. Relative
8// relocations are resolved to the place.
9
10 .syntax unified
11
12 .weak target
13
14 .text
15 .global _start
16_start:
17// R_ARM_THM_JUMP19
18 beq.w target
19// R_ARM_THM_JUMP24
20 b.w target
21// R_ARM_THM_CALL
22 bl target
23// R_ARM_THM_CALL with exchange
24 blx target
25// R_ARM_THM_MOVT_PREL
26 movt r0, :upper16:target - .
27// R_ARM_THM_MOVW_PREL_NC
28 movw r0, :lower16:target - .
29
30// CHECK: Disassembly of section .text:
31// 69636 = 0x11004
32// CHECK: 11000: {{.*}} beq.w #0 <_start+0x4>
33// CHECK-NEXT: 11004: {{.*}} b.w #0 <_start+0x8>
34// CHECK-NEXT: 11008: {{.*}} bl #0
35// blx is transformed into bl so we don't change state
36// CHECK-NEXT: 1100c: {{.*}} bl #0
37// CHECK-NEXT: 11010: {{.*}} movt r0, #0
38// CHECK-NEXT: 11014: {{.*}} movw r0, #0
deps/lld/test/ELF/arm-tls-gd-nonpreemptible.s created+72
......@@ -0,0 +1,72 @@
1// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
2// RUN: ld.lld %t -o %t2
3// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi
4// RUN: llvm-objdump -s %t2 | FileCheck %s
5// RUN: ld.lld %t --shared -o %t3.so
6// RUN: llvm-objdump -s %t3.so | FileCheck -check-prefix=CHECK-SHARED %s
7// REQUIRES: arm
8
9// For an executable, we write the module index 1 and the offset into the TLS
10// directly into the GOT. For a shared library we can only write the offset
11// into the TLS directly if the symbol is non-preemptible
12
13 .text
14 .syntax unified
15 .globl __tls_get_addr
16 .type __tls_get_addr,%function
17__tls_get_addr:
18 bx lr
19
20 .globl _start
21 .p2align 2
22 .type _start,%function
23func:
24.L0:
25 nop
26.L1:
27 nop
28.L2:
29 nop
30.L3:
31 nop
32 .p2align 2
33// Generate R_ARM_TLS_GD32 relocations
34// These can be resolved at static link time for executables as 1 is always the
35// module index and the offset into tls is known at static link time
36.Lt0: .word x1(TLSGD) + (. - .L0 - 8)
37.Lt1: .word x2(TLSGD) + (. - .L1 - 8)
38.Lt2: .word x3(TLSGD) + (. - .L2 - 8)
39.Lt3: .word x4(TLSGD) + (. - .L3 - 8)
40 .hidden x1
41 .globl x1
42 .hidden x2
43 .globl x2
44 .globl x3
45 .globl x4
46
47 .section .tdata,"awT",%progbits
48 .p2align 2
49.TLSSTART:
50 .type x1, %object
51x1:
52 .word 10
53 .type x2, %object
54x2:
55 .word 20
56
57 .section .tbss,"awT",%nobits
58 .p2align 2
59 .type x3, %object
60x3:
61 .space 4
62 .type x4, %object
63x4:
64 .space 4
65
66// CHECK: Contents of section .got:
67// CHECK-NEXT: 12008 01000000 00000000 01000000 04000000
68// CHECK-NEXT: 12018 01000000 08000000 01000000 0c000000
69
70// CHECK-SHARED: Contents of section .got:
71// CHECK-SHARED-NEXT: 2050 00000000 00000000 00000000 04000000
72// CHECK-SHARED-NEXT: 2060 00000000 00000000 00000000 00000000
deps/lld/test/ELF/arm-tls-gd32.s created+106
......@@ -0,0 +1,106 @@
1// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi
2// RUN: ld.lld %t.o -o %t.so -shared
3// RUN: llvm-readobj -s -dyn-relocations %t.so | FileCheck --check-prefix=SEC %s
4// RUN: llvm-objdump -d -triple=armv7a-linux-gnueabi %t.so | FileCheck %s
5// REQUIRES: arm
6
7// Test the handling of the global-dynamic TLS model. Dynamic Loader finds
8// module index R_ARM_TLS_DTPMOD32 and the offset within the module
9// R_ARM_TLS_DTPOFF32. One of the variables is hidden which permits relaxation
10// to local dynamic
11
12 .text
13 .syntax unified
14 .globl func
15 .p2align 2
16 .type func,%function
17func:
18.L0:
19 nop
20.L1:
21 nop
22.L2:
23 nop
24
25 .p2align 2
26// Generate R_ARM_TLS_GD32 relocations
27// Allocates a pair of GOT entries dynamically relocated by R_ARM_TLS_DTPMOD32
28// and R_ARM_TLS_DTPOFF32 respectively. The literal contains the offset of the
29// first GOT entry from the place
30.Lt0: .word x(TLSGD) + (. - .L0 - 8)
31.Lt1: .word y(TLSGD) + (. - .L1 - 8)
32.Lt2: .word z(TLSGD) + (. - .L2 - 8)
33
34// __thread int x = 10
35// __thread int y;
36// __thread int z __attribute((visibility("hidden")))
37
38 .hidden z
39 .globl z
40 .globl y
41 .globl x
42
43 .section .tbss,"awT",%nobits
44 .p2align 2
45.TLSSTART:
46 .type z, %object
47z:
48 .space 4
49 .type y, %object
50y:
51 .space 4
52 .section .tdata,"awT",%progbits
53 .p2align 2
54 .type x, %object
55x:
56 .word 10
57
58// SEC: Name: .tdata
59// SEC-NEXT: Type: SHT_PROGBITS
60// SEC-NEXT: Flags [
61// SEC-NEXT: SHF_ALLOC
62// SEC-NEXT: SHF_TLS
63// SEC-NEXT: SHF_WRITE
64// SEC-NEXT: ]
65// SEC-NEXT: Address: 0x2000
66// SEC: Size: 4
67// SEC: Name: .tbss
68// SEC-NEXT: Type: SHT_NOBITS
69// SEC-NEXT: Flags [
70// SEC-NEXT: SHF_ALLOC
71// SEC-NEXT: SHF_TLS
72// SEC-NEXT: SHF_WRITE
73// SEC-NEXT: ]
74// SEC-NEXT: Address: 0x2004
75// SEC: Size: 8
76
77// SEC: Name: .got
78// SEC-NEXT: Type: SHT_PROGBITS
79// SEC-NEXT: Flags [
80// SEC-NEXT: SHF_ALLOC
81// SEC-NEXT: SHF_WRITE
82// SEC-NEXT: ]
83// SEC-NEXT: Address: 0x204C
84// SEC: Size: 24
85
86// SEC: Dynamic Relocations {
87// SEC-NEXT: 0x205C R_ARM_TLS_DTPMOD32 -
88// SEC-NEXT: 0x204C R_ARM_TLS_DTPMOD32 x
89// SEC-NEXT: 0x2050 R_ARM_TLS_DTPOFF32 x
90// SEC-NEXT: 0x2054 R_ARM_TLS_DTPMOD32 y
91// SEC-NEXT: 0x2058 R_ARM_TLS_DTPOFF32 y
92
93
94// CHECK: Disassembly
95// CHECK-NEXT: func:
96// CHECK-NEXT: 1000: 00 f0 20 e3 nop
97// CHECK-NEXT: 1004: 00 f0 20 e3 nop
98// CHECK-NEXT: 1008: 00 f0 20 e3 nop
99
100// (0x204c - 0x100c) + (0x100c - 0x1000 - 8) = 0x1044
101// CHECK: 100c: 44 10 00 00
102// (0x2054 - 0x1010) + (0x1010 - 0x1004 - 8) = 0x1048
103// CHECK-NEXT: 1010: 48 10 00 00
104// (0x205c - 0x1014) + (0x1014 - 0x1008 - 8) = 0x104c
105// CHECK-NEXT: 1014: 4c 10 00 00
106
deps/lld/test/ELF/arm-tls-ie32.s created+96
......@@ -0,0 +1,96 @@
1// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi
2// RUN: ld.lld %t.o -o %t.so -shared
3// RUN: llvm-readobj -s -dyn-relocations %t.so | FileCheck --check-prefix=SEC %s
4// RUN: llvm-objdump -d -triple=armv7a-linux-gnueabi %t.so | FileCheck %s
5// REQUIRES: arm
6
7// Test the handling of the initial-exec TLS model. Relative location within
8// static TLS is a run-time constant computed by dynamic loader as a result
9// of the R_ARM_TLS_TPOFF32 relocation.
10
11 .syntax unified
12 .arm
13 .globl func
14 .type func,%function
15 .p2align 2
16func:
17.L0:
18 nop
19.L1:
20 nop
21.L2:
22 nop
23
24 .p2align 2
25// Generate R_ARM_TLS_IE32 static relocations
26// Allocates a GOT entry dynamically relocated by R_ARM_TLS_TPOFF32
27// literal contains the offset of the GOT entry from the place
28.Lt0: .word x(gottpoff) + (. - .L0 - 8)
29.Lt1: .word y(gottpoff) + (. - .L1 - 8)
30.Lt2: .word .TLSSTART(gottpoff) + (. - .L2 - 8)
31
32// __thread int x = 10
33// __thread int y;
34// __thread int z __attribute((visibility("hidden")))
35 .hidden z
36 .globl z
37 .globl y
38 .globl x
39
40 .section .tbss,"awT",%nobits
41 .p2align 2
42.TLSSTART:
43 .type z, %object
44z:
45 .space 4
46 .type y, %object
47y:
48 .space 4
49 .section .tdata,"awT",%progbits
50 .p2align 2
51 .type x, %object
52x:
53 .word 10
54
55// SEC: Name: .tdata
56// SEC-NEXT: Type: SHT_PROGBITS
57// SEC-NEXT: Flags [
58// SEC-NEXT: SHF_ALLOC
59// SEC-NEXT: SHF_TLS
60// SEC-NEXT: SHF_WRITE
61// SEC: Size: 4
62// SEC: Name: .tbss
63// SEC-NEXT: Type: SHT_NOBITS
64// SEC-NEXT: Flags [
65// SEC-NEXT: SHF_ALLOC
66// SEC-NEXT: SHF_TLS
67// SEC-NEXT: SHF_WRITE
68// SEC: Size: 8
69
70// SEC: Name: .got
71// SEC-NEXT: Type: SHT_PROGBITS
72// SEC-NEXT: Flags [
73// SEC-NEXT: SHF_ALLOC
74// SEC-NEXT: SHF_WRITE
75// SEC-NEXT: ]
76// SEC-NEXT: Address: 0x204C
77// SEC: Size: 12
78
79
80// SEC: Dynamic Relocations {
81// SEC: 0x2054 R_ARM_TLS_TPOFF32
82// SEC: 0x204C R_ARM_TLS_TPOFF32 x
83// SEC: 0x2050 R_ARM_TLS_TPOFF32 y
84
85// CHECK: Disassembly of section .text:
86// CHECK-NEXT: func:
87// CHECK-NEXT: 1000: 00 f0 20 e3 nop
88// CHECK-NEXT: 1004: 00 f0 20 e3 nop
89// CHECK-NEXT: 1008: 00 f0 20 e3 nop
90
91// (0x204c - 0x100c) + (0x100c - 0x1000 - 8) = 0x1044
92// CHECK: 100c: 44 10 00 00
93// (0x2050 - 0x1010) + (0x1010 - 0x1004 - 8) = 0x1044
94// CHECK-NEXT: 1010: 44 10 00 00
95// (0x2054 - 0x1014) + (0x1014 - 0x1008 - 8) = 0x1044
96// CHECK-NEXT: 1014: 44 10 00 00
deps/lld/test/ELF/arm-tls-ldm32.s created+73
......@@ -0,0 +1,73 @@
1// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi
2// RUN: ld.lld %t.o -o %t.so -shared
3// RUN: llvm-readobj -s -dyn-relocations %t.so | FileCheck --check-prefix=SEC %s
4// RUN: llvm-objdump -d -triple=armv7a-linux-gnueabi %t.so | FileCheck %s
5// REQUIRES: arm
6
7// Test the handling of the local-dynamic TLS model. Dynamic loader finds
8// module index R_ARM_TLS_DTPMOD32. The offset in the next GOT slot is 0
9// The R_ARM_TLS_LDO is the offset of the variable within the TLS block.
10 .global __tls_get_addr
11 .text
12 .p2align 2
13 .global _start
14 .syntax unified
15 .arm
16 .type _start, %function
17_start:
18.L0:
19 nop
20
21 .word x(tlsldm) + (. - .L0 - 8)
22 .word x(tlsldo)
23 .word y(tlsldo)
24
25 .section .tbss,"awT",%nobits
26 .p2align 2
27 .type y, %object
28y:
29 .space 4
30 .section .tdata,"awT",%progbits
31 .p2align 2
32 .type x, %object
33x:
34 .word 10
35
36// SEC: Name: .tdata
37// SEC-NEXT: Type: SHT_PROGBITS
38// SEC-NEXT: Flags [
39// SEC-NEXT: SHF_ALLOC
40// SEC-NEXT: SHF_TLS
41// SEC-NEXT: SHF_WRITE
42// SEC-NEXT: ]
43// SEC-NEXT: Address: 0x2000
44// SEC: Size: 4
45// SEC: Name: .tbss
46// SEC-NEXT: Type: SHT_NOBITS (0x8)
47// SEC-NEXT: Flags [
48// SEC-NEXT: SHF_ALLOC
49// SEC-NEXT: SHF_TLS
50// SEC-NEXT: SHF_WRITE
51// SEC-NEXT: ]
52// SEC-NEXT: Address: 0x2004
53// SEC: Size: 4
54
55// SEC: Dynamic Relocations {
56// SEC-NEXT: 0x204C R_ARM_TLS_DTPMOD32 - 0x0
57
58// CHECK: Disassembly of section .text:
59// CHECK-NEXT: _start:
60// CHECK-NEXT: 1000: 00 f0 20 e3 nop
61
62// (0x204c - 0x1004) + (0x1004 - 0x1000 - 8) = 0x1044
63// CHECK: 1004: 44 10 00 00
64// CHECK-NEXT: 1008: 00 00 00 00
65// CHECK-NEXT: 100c: 04 00 00 00
66
67// CHECK-EXE: Disassembly of section .text:
68// CHECK-NEXT-EXE: _start:
69// CHECK-NEXT-EXE: 11000: 00 f0 20 e3 nop
70
71// CHECK-EXE: 11004: fc 0f 00 00
72// CHECK-EXE: 11008: 00 00 00 00
73// CHECK-EXE: 1100c: 04 00 00 00
deps/lld/test/ELF/arm-tls-le32.s created+77
......@@ -0,0 +1,77 @@
1// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi
2// RUN: ld.lld %t.o -o %t
3// RUN: llvm-readobj -s -dyn-relocations %t | FileCheck --check-prefix=SEC %s
4// RUN: llvm-objdump -d -triple=armv7a-linux-gnueabi %t | FileCheck %s
5// REQUIRES: arm
6
7// Test the handling of the local exec TLS model. TLS can be resolved
8// statically for an application. The code sequences assume a thread pointer
9// in r9
10
11 .text
12 .syntax unified
13 .globl _start
14 .p2align 2
15 .type _start,%function
16_start:
17 .p2align 2
18// Generate R_ARM_TLS_LE32 relocations. These resolve statically to the offset
19// of the variable from the thread pointer
20.Lt0: .word x(TPOFF)
21.Lt1: .word y(TPOFF)
22.Lt2: .word z(TPOFF)
23
24// __thread int x = 10
25// __thread int y;
26// __thread int z __attribute((visibility("hidden")))
27
28 .hidden z
29 .globl z
30 .globl y
31 .globl x
32
33 .section .tbss,"awT",%nobits
34 .p2align 2
35.TLSSTART:
36 .type z, %object
37z:
38 .space 4
39 .type y, %object
40y:
41 .space 4
42 .section .tdata,"awT",%progbits
43 .p2align 2
44 .type x, %object
45x:
46 .word 10
47
48// SEC: Name: .tdata
49// SEC-NEXT: Type: SHT_PROGBITS
50// SEC-NEXT: Flags [
51// SEC-NEXT: SHF_ALLOC
52// SEC-NEXT: SHF_TLS
53// SEC-NEXT: SHF_WRITE
54// SEC-NEXT: ]
55// SEC-NEXT: Address: 0x12000
56// SEC: Size: 4
57// SEC: Name: .tbss
58// SEC-NEXT: Type: SHT_NOBITS
59// SEC-NEXT: Flags [
60// SEC-NEXT: SHF_ALLOC
61// SEC-NEXT: SHF_TLS
62// SEC-NEXT: SHF_WRITE
63// SEC-NEXT: ]
64// SEC-NEXT: Address: 0x12004
65// SEC: Size: 8
66
67// SEC: Dynamic Relocations {
68// SEC-NEXT: }
69
70// CHECK: Disassembly of section .text:
71// CHECK-NEXT: _start:
72// offset of x from Thread pointer = (TcbSize + 0x0 = 0x8)
73// CHECK-NEXT: 11000: 08 00 00 00
74// offset of z from Thread pointer = (TcbSize + 0x8 = 0x10)
75// CHECK-NEXT: 11004: 10 00 00 00
76// offset of y from Thread pointer = (TcbSize + 0x4 = 0xc)
77// CHECK-NEXT: 11008: 0c 00 00 00
deps/lld/test/ELF/arm-tls-norelax-gd-ie.s created+30
......@@ -0,0 +1,30 @@
1// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-tls-get-addr.s -o %t1
2// RUN: ld.lld %t1 --shared -o %t1.so
3// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi
4// RUN: ld.lld %t1.so %t.o -o %t
5// RUN: llvm-readobj -s -dyn-relocations %t | FileCheck %s
6// REQUIRES: arm
7
8// This tls global-dynamic sequence is with respect to a preemptible symbol but
9// is in an application so a relaxation to Initial Exec would normally be
10// possible. This would result in an assertion failure on ARM as the
11// relaxation functions can't be implemented on ARM. Check that the sequence
12// is handled as global dynamic
13
14 .text
15 .syntax unified
16 .globl func
17 .p2align 2
18 .type func,%function
19func:
20.L0:
21 .globl __tls_get_addr
22 bl __tls_get_addr
23 bx lr
24 .p2align 2
25 .Lt0: .word y(TLSGD) + (. - .L0 - 8)
26
27// CHECK: Dynamic Relocations {
28// CHECK-NEXT: 0x13078 R_ARM_TLS_DTPMOD32 y
29// CHECK-NEXT: 0x1307C R_ARM_TLS_DTPOFF32 y
30// CHECK-NEXT: 0x1200C R_ARM_JUMP_SLOT __tls_get_addr
deps/lld/test/ELF/arm-tls-norelax-gd-le.s created+37
......@@ -0,0 +1,37 @@
1// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-tls-get-addr.s -o %t1
2// RUN: ld.lld %t1 --shared -o %t1.so
3// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi
4// RUN: ld.lld %t1.so %t.o -o %t
5// RUN: llvm-objdump -s %t | FileCheck %s
6// REQUIRES: arm
7
8// This tls global-dynamic sequence is with respect to a non-preemptible
9// symbol in an application so a relaxation to Local Exec would normally be
10// possible. This would result in an assertion failure on ARM as the
11// relaxation functions can't be implemented on ARM. Check that the sequence
12// is handled as global dynamic
13
14 .text
15 .syntax unified
16 .globl func
17 .p2align 2
18 .type func,%function
19func:
20.L0:
21 .globl __tls_get_addr
22 bl __tls_get_addr
23 bx lr
24 .p2align 2
25 .Lt0: .word x(TLSGD) + (. - .L0 - 8)
26
27 .globl x
28.section .tbss,"awT",%nobits
29 .p2align 2
30x:
31 .space 4
32 .type x, %object
33
34// CHECK: Contents of section .got:
35// Module index is always 1 for executable
36// CHECK-NEXT: 13060 01000000 00000000
37
deps/lld/test/ELF/arm-tls-norelax-ie-le.s created+41
......@@ -0,0 +1,41 @@
1// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-tls-get-addr.s -o %t1
2// RUN: ld.lld %t1 --shared -o %t1.so
3// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi
4// RUN: ld.lld %t1.so %t.o -o %t
5// RUN: llvm-objdump -s -triple=armv7a-linux-gnueabi %t | FileCheck %s
6// REQUIRES: arm
7
8// This tls Initial Exec sequence is with respect to a non-preemptible symbol
9// so a relaxation would normally be possible. This would result in an assertion
10// failure on ARM as the relaxation functions can't be implemented on ARM.
11// Check that the sequence is handled as initial exec
12 .text
13 .syntax unified
14 .globl func
15 .p2align 2
16 .type func,%function
17func:
18.L0:
19 .globl __tls_get_addr
20 bl __tls_get_addr
21.L1:
22 bx lr
23 .p2align 2
24 .Lt0: .word x1(gottpoff) + (. - .L0 - 8)
25 .Lt1: .word x2(gottpoff) + (. - .L1 - 8)
26
27 .globl x1
28 .section .trw,"awT",%progbits
29 .p2align 2
30x1:
31 .word 0x1
32 .globl x2
33 .section .tbss,"awT",%nobits
34 .type x1, %object
35x2:
36 .space 4
37 .type x2, %object
38
39// CHECK: Contents of section .got:
40// x1 at offset 8 from TP, x2 at offset c from TP. Offsets include TCB size of 8
41// CHECK-NEXT: 13064 08000000 0c000000
deps/lld/test/ELF/arm-tls-norelax-ld-le.s created+35
......@@ -0,0 +1,35 @@
1// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %p/Inputs/arm-tls-get-addr.s -o %t1
2// RUN: ld.lld %t1 --shared -o %t1.so
3// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=armv7a-linux-gnueabi
4// RUN: ld.lld %t1.so %t.o -o %t
5// RUN: llvm-objdump -s %t | FileCheck %s
6// REQUIRES: arm
7
8 .global __tls_get_addr
9 .text
10 .p2align 2
11 .global _start
12 .syntax unified
13 .arm
14 .type _start, %function
15_start:
16.L0:
17 bl __tls_get_addr
18
19 .word x(tlsldm) + (. - .L0 - 8)
20 .word x(tlsldo)
21 .word y(tlsldo)
22
23 .section .tbss,"awT",%nobits
24 .p2align 2
25 .type y, %object
26y:
27 .space 4
28 .section .tdata,"awT",%progbits
29 .p2align 2
30 .type x, %object
31x:
32 .word 10
33
34// CHECK: Contents of section .got:
35// CHECK-NEXT: 13064 01000000 00000000
deps/lld/test/ELF/arm-undefined-weak.s created+39
......@@ -0,0 +1,39 @@
1// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t
2// RUN: ld.lld %t -o %t2 2>&1
3// RUN: llvm-objdump -triple=armv7a-none-linux-gnueabi -d %t2 | FileCheck %s
4// REQUIRES: arm
5
6// Check that the ARM ABI rules for undefined weak symbols are applied.
7// Branch instructions are resolved to the next instruction. Undefined
8// Symbols in relative are resolved to the place so S - P + A = A.
9
10 .syntax unified
11
12 .weak target
13
14 .text
15 .global _start
16_start:
17// R_ARM_JUMP24
18 b target
19// R_ARM_CALL
20 bl target
21// R_ARM_CALL with exchange
22 blx target
23// R_ARM_MOVT_PREL
24 movt r0, :upper16:target - .
25// R_ARM_MOVW_PREL_NC
26 movw r0, :lower16:target - .
27// R_ARM_REL32
28 .word target - .
29
30// CHECK: Disassembly of section .text:
31// 69636 = 0x11004
32// CHECK: 11000: {{.*}} b #-4 <_start+0x4>
33// CHECK-NEXT: 11004: {{.*}} bl #-4 <_start+0x8>
34// blx is transformed into bl so we don't change state
35// CHECK-NEXT: 11008: {{.*}} bl #-4 <_start+0xC>
36// CHECK-NEXT: 1100c: {{.*}} movt r0, #0
37// CHECK-NEXT: 11010: {{.*}} movw r0, #0
38// CHECK: 11014: {{.*}} .word 0x00000000
39
deps/lld/test/ELF/arm-use-r-output.s created+13
......@@ -0,0 +1,13 @@
1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
3// RUN: ld.lld -r %t.o -o %t2.o
4// RUN: ld.lld -shared %t2.o -o %t.so
5
6// We used to crash using the output of -r because of the relative order of
7// SHF_LINK_ORDER sections.
8
9// That can be fixed by changing -r or making the regular link more flexible,
10// so this is an end to end test.
11
12 .fnstart
13 .fnend
deps/lld/test/ELF/as-needed-no-reloc.s created+23
......@@ -0,0 +1,23 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/shared.s -o %t2.o
3# RUN: ld.lld -shared %t2.o -o %t2.so
4# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
5# RUN: ld.lld -o %t %t.o --as-needed %t2.so
6# RUN: llvm-readobj --dynamic-table --dyn-symbols %t | FileCheck %s
7
8
9# There must be a NEEDED entry for each undefined
10
11# CHECK: Name: bar
12# CHECK-NEXT: Value: 0x0
13# CHECK-NEXT: Size: 0
14# CHECK-NEXT: Binding: Global
15# CHECK-NEXT: Type: Function
16# CHECK-NEXT: Other: 0
17# CHECK-NEXT: Section: Undefined
18
19# CHECK: NEEDED Shared library: [{{.*}}as-needed-no-reloc{{.*}}2.so]
20
21 .globl _start
22_start:
23 .global bar
deps/lld/test/ELF/as-needed.s created+45
......@@ -0,0 +1,45 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o
3// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/shared.s -o %t2.o
4// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/shared2.s -o %t3.o
5// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/shared3.s -o %t4.o
6// RUN: ld.lld -shared %t2.o -soname shared1 -o %t2.so
7// RUN: ld.lld -shared %t3.o -soname shared2 -o %t3.so
8// RUN: ld.lld -shared %t4.o -soname shared3 -o %t4.so
9
10/// Check if --as-needed actually works.
11
12// RUN: ld.lld %t.o %t2.so %t3.so %t4.so -o %t2
13// RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s
14
15// RUN: ld.lld --as-needed %t.o %t2.so %t3.so %t4.so -o %t2
16// RUN: llvm-readobj -dynamic-table %t2 | FileCheck -check-prefix=CHECK2 %s
17
18// RUN: ld.lld --as-needed %t.o %t2.so --no-as-needed %t3.so %t4.so -o %t2
19// RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s
20
21/// GROUP directive is the same as --as-needed.
22
23// RUN: echo "GROUP(\"%t2.so\" \"%t3.so\" \"%t4.so\")" > %t.script
24// RUN: ld.lld %t.o %t.script -o %t2
25// RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s
26
27// RUN: echo "GROUP(AS_NEEDED(\"%t2.so\" \"%t3.so\" \"%t4.so\"))" > %t.script
28// RUN: ld.lld %t.o %t.script -o %t2
29// RUN: llvm-readobj -dynamic-table %t2 | FileCheck -check-prefix=CHECK2 %s
30
31// CHECK: NEEDED Shared library: [shared1]
32// CHECK: NEEDED Shared library: [shared2]
33// CHECK: NEEDED Shared library: [shared3]
34
35// CHECK2: NEEDED Shared library: [shared1]
36// CHECK2-NOT: NEEDED Shared library: [shared2]
37// CHECK2-NOT: NEEDED Shared library: [shared3]
38
39.global _start
40_start:
41.data
42.long bar
43.long zed
44.weak baz
45 call baz
deps/lld/test/ELF/auxiliary.s created+13
......@@ -0,0 +1,13 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: ld.lld %t.o -shared -f aaa --auxiliary bbb -o %t
4# RUN: llvm-readobj --dynamic-table %t | FileCheck %s
5
6# CHECK: DynamicSection [
7# CHECK-NEXT: Tag Type Name/Value
8# CHECK-NEXT: 0x000000007FFFFFFD AUXILIARY Auxiliary library: [aaa]
9# CHECK-NEXT: 0x000000007FFFFFFD AUXILIARY Auxiliary library: [bbb]
10
11# RUN: not ld.lld %t.o -f aaa --auxiliary bbb -o %t 2>&1 \
12# RUN: | FileCheck -check-prefix=ERR %s
13# ERR: -f may not be used without -shared
deps/lld/test/ELF/avoid-empty-program-headers.s created+78
......@@ -0,0 +1,78 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3// RUN: ld.lld %t -o %tout
4// RUN: llvm-readobj -program-headers %tout | FileCheck %s
5
6.global _start
7_start:
8 retq
9
10.section .tbss,"awT",@nobits
11 .zero 4
12// FIXME: Test that we don't create unecessary empty PT_LOAD and PT_GNU_RELRO
13// for the .tbss section.
14
15// CHECK: ProgramHeaders [
16// CHECK-NEXT: ProgramHeader {
17// CHECK-NEXT: Type: PT_PHDR (0x6)
18// CHECK-NEXT: Offset: 0x40
19// CHECK-NEXT: VirtualAddress: 0x200040
20// CHECK-NEXT: PhysicalAddress: 0x200040
21// CHECK-NEXT: FileSize: 280
22// CHECK-NEXT: MemSize: 280
23// CHECK-NEXT: Flags [ (0x4)
24// CHECK-NEXT: PF_R (0x4)
25// CHECK-NEXT: ]
26// CHECK-NEXT: Alignment: 8
27// CHECK-NEXT: }
28// CHECK-NEXT: ProgramHeader {
29// CHECK-NEXT: Type: PT_LOAD (0x1)
30// CHECK-NEXT: Offset: 0x0
31// CHECK-NEXT: VirtualAddress: 0x200000
32// CHECK-NEXT: PhysicalAddress: 0x200000
33// CHECK-NEXT: FileSize: 344
34// CHECK-NEXT: MemSize: 344
35// CHECK-NEXT: Flags [ (0x4)
36// CHECK-NEXT: PF_R (0x4)
37// CHECK-NEXT: ]
38// CHECK-NEXT: Alignment: 4096
39// CHECK-NEXT: }
40// CHECK-NEXT: ProgramHeader {
41// CHECK-NEXT: Type: PT_LOAD (0x1)
42// CHECK-NEXT: Offset: 0x1000
43// CHECK-NEXT: VirtualAddress: 0x201000
44// CHECK-NEXT: PhysicalAddress: 0x201000
45// CHECK-NEXT: FileSize: 1
46// CHECK-NEXT: MemSize: 1
47// CHECK-NEXT: Flags [ (0x5)
48// CHECK-NEXT: PF_R (0x4)
49// CHECK-NEXT: PF_X (0x1)
50// CHECK-NEXT: ]
51// CHECK-NEXT: Alignment: 4096
52// CHECK-NEXT: }
53// CHECK-NEXT: ProgramHeader {
54// CHECK-NEXT: Type: PT_TLS (0x7)
55// CHECK-NEXT: Offset: 0x1001
56// CHECK-NEXT: VirtualAddress: 0x201001
57// CHECK-NEXT: PhysicalAddress: 0x201001
58// CHECK-NEXT: FileSize: 0
59// CHECK-NEXT: MemSize: 4
60// CHECK-NEXT: Flags [ (0x4)
61// CHECK-NEXT: PF_R (0x4)
62// CHECK-NEXT: ]
63// CHECK-NEXT: Alignment: 1
64// CHECK-NEXT: }
65// CHECK-NEXT: ProgramHeader {
66// CHECK-NEXT: Type: PT_GNU_STACK (0x6474E551)
67// CHECK-NEXT: Offset: 0x0
68// CHECK-NEXT: VirtualAddress: 0x0
69// CHECK-NEXT: PhysicalAddress: 0x0
70// CHECK-NEXT: FileSize: 0
71// CHECK-NEXT: MemSize: 0
72// CHECK-NEXT: Flags [ (0x6)
73// CHECK-NEXT: PF_R (0x4)
74// CHECK-NEXT: PF_W (0x2)
75// CHECK-NEXT: ]
76// CHECK-NEXT: Alignment: 0
77// CHECK-NEXT: }
78// CHECK-NEXT: ]
deps/lld/test/ELF/bad-archive.s created+11
......@@ -0,0 +1,11 @@
1// REQUIRES: x86
2
3// Check bad archive error reporting with --whole-archive
4// and without it.
5// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
6// RUN: not ld.lld %t.o %p/Inputs/bad-archive.a -o %t 2>&1 | FileCheck %s
7// RUN: not ld.lld %t.o --whole-archive %p/Inputs/bad-archive.a -o %t 2>&1 | FileCheck %s
8// CHECK: bad-archive.a: failed to parse archive
9
10.globl _start
11_start:
deps/lld/test/ELF/basic-aarch64.s created+209
......@@ -0,0 +1,209 @@
1# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-freebsd %s -o %t
2# RUN: ld.lld %t -o %t2
3# RUN: llvm-readobj -file-headers -sections -program-headers -symbols %t2 \
4# RUN: | FileCheck %s
5# REQUIRES: aarch64
6
7# exits with return code 42 on FreeBSD/AArch64
8.globl _start
9_start:
10 mov x0, 42
11 mov x8, 1
12 svc 0
13
14# CHECK: ElfHeader {
15# CHECK-NEXT: Ident {
16# CHECK-NEXT: Magic: (7F 45 4C 46)
17# CHECK-NEXT: Class: 64-bit (0x2)
18# CHECK-NEXT: DataEncoding: LittleEndian (0x1)
19# CHECK-NEXT: FileVersion: 1
20# CHECK-NEXT: OS/ABI: FreeBSD (0x9)
21# CHECK-NEXT: ABIVersion: 0
22# CHECK-NEXT: Unused: (00 00 00 00 00 00 00)
23# CHECK-NEXT: }
24# CHECK-NEXT: Type: Executable (0x2)
25# CHECK-NEXT: Machine: EM_AARCH64 (0xB7)
26# CHECK-NEXT: Version: 1
27# CHECK-NEXT: Entry: [[ENTRY:0x[0-9A-F]+]]
28# CHECK-NEXT: ProgramHeaderOffset: 0x40
29# CHECK-NEXT: SectionHeaderOffset: 0x10098
30# CHECK-NEXT: Flags [ (0x0)
31# CHECK-NEXT: ]
32# CHECK-NEXT: HeaderSize: 64
33# CHECK-NEXT: ProgramHeaderEntrySize: 56
34# CHECK-NEXT: ProgramHeaderCount: 4
35# CHECK-NEXT: SectionHeaderEntrySize: 64
36# CHECK-NEXT: SectionHeaderCount: 6
37# CHECK-NEXT: StringTableSectionIndex: 4
38# CHECK-NEXT: }
39# CHECK-NEXT: Sections [
40# CHECK-NEXT: Section {
41# CHECK-NEXT: Index: 0
42# CHECK-NEXT: Name: (0)
43# CHECK-NEXT: Type: SHT_NULL (0x0)
44# CHECK-NEXT: Flags [ (0x0)
45# CHECK-NEXT: ]
46# CHECK-NEXT: Address: 0x0
47# CHECK-NEXT: Offset: 0x0
48# CHECK-NEXT: Size: 0
49# CHECK-NEXT: Link: 0
50# CHECK-NEXT: Info: 0
51# CHECK-NEXT: AddressAlignment: 0
52# CHECK-NEXT: EntrySize: 0
53# CHECK-NEXT: }
54# CHECK-NEXT: Section {
55# CHECK-NEXT: Index: 1
56# CHECK-NEXT: Name: .text
57# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
58# CHECK-NEXT: Flags [ (0x6)
59# CHECK-NEXT: SHF_ALLOC (0x2)
60# CHECK-NEXT: SHF_EXECINSTR (0x4)
61# CHECK-NEXT: ]
62# CHECK-NEXT: Address: 0x20000
63# CHECK-NEXT: Offset: 0x10000
64# CHECK-NEXT: Size: 12
65# CHECK-NEXT: Link: 0
66# CHECK-NEXT: Info: 0
67# CHECK-NEXT: AddressAlignment: 4
68# CHECK-NEXT: EntrySize: 0
69# CHECK-NEXT: }
70# CHECK-NEXT: Section {
71# CHECK-NEXT: Index: 2
72# CHECK-NEXT: Name: .comment
73# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
74# CHECK-NEXT: Flags [ (0x30)
75# CHECK-NEXT: SHF_MERGE (0x10)
76# CHECK-NEXT: SHF_STRINGS (0x20)
77# CHECK-NEXT: ]
78# CHECK-NEXT: Address: 0x0
79# CHECK-NEXT: Offset: 0x1000C
80# CHECK-NEXT: Size: 8
81# CHECK-NEXT: Link: 0
82# CHECK-NEXT: Info: 0
83# CHECK-NEXT: AddressAlignment: 1
84# CHECK-NEXT: EntrySize: 0
85# CHECK-NEXT: }
86# CHECK-NEXT: Section {
87# CHECK-NEXT: Index: 3
88# CHECK-NEXT: Name: .symtab
89# CHECK-NEXT: Type: SHT_SYMTAB (0x2)
90# CHECK-NEXT: Flags [ (0x0)
91# CHECK-NEXT: ]
92# CHECK-NEXT: Address: 0x0
93# CHECK-NEXT: Offset: 0x10018
94# CHECK-NEXT: Size: 72
95# CHECK-NEXT: Link: 5
96# CHECK-NEXT: Info: 2
97# CHECK-NEXT: AddressAlignment: 8
98# CHECK-NEXT: EntrySize: 24
99# CHECK-NEXT: }
100# CHECK-NEXT: Section {
101# CHECK-NEXT: Index: 4
102# CHECK-NEXT: Name: .shstrtab
103# CHECK-NEXT: Type: SHT_STRTAB (0x3)
104# CHECK-NEXT: Flags [ (0x0)
105# CHECK-NEXT: ]
106# CHECK-NEXT: Address: 0x0
107# CHECK-NEXT: Offset: 0x10060
108# CHECK-NEXT: Size: 42
109# CHECK-NEXT: Link: 0
110# CHECK-NEXT: Info: 0
111# CHECK-NEXT: AddressAlignment: 1
112# CHECK-NEXT: EntrySize: 0
113# CHECK-NEXT: }
114# CHECK-NEXT: Section {
115# CHECK-NEXT: Index: 5
116# CHECK-NEXT: Name: .strtab
117# CHECK-NEXT: Type: SHT_STRTAB (0x3)
118# CHECK-NEXT: Flags [ (0x0)
119# CHECK-NEXT: ]
120# CHECK-NEXT: Address: 0x0
121# CHECK-NEXT: Offset: 0x1008A
122# CHECK-NEXT: Size: 13
123# CHECK-NEXT: Link: 0
124# CHECK-NEXT: Info: 0
125# CHECK-NEXT: AddressAlignment: 1
126# CHECK-NEXT: EntrySize: 0
127# CHECK-NEXT: }
128# CHECK-NEXT: ]
129# CHECK-NEXT: Symbols [
130# CHECK-NEXT: Symbol {
131# CHECK-NEXT: Name: (0)
132# CHECK-NEXT: Value: 0x0
133# CHECK-NEXT: Size: 0
134# CHECK-NEXT: Binding: Local (0x0)
135# CHECK-NEXT: Type: None (0x0)
136# CHECK-NEXT: Other: 0
137# CHECK-NEXT: Section: Undefined (0x0)
138# CHECK-NEXT: }
139# CHECK-NEXT: Symbol {
140# CHECK-NEXT: Name: $x.0
141# CHECK-NEXT: Value: 0x20000
142# CHECK-NEXT: Size: 0
143# CHECK-NEXT: Binding: Local (0x0)
144# CHECK-NEXT: Type: None (0x0)
145# CHECK-NEXT: Other: 0
146# CHECK-NEXT: Section: .text
147# CHECK-NEXT: }
148# CHECK-NEXT: Symbol {
149# CHECK-NEXT: Name: _start
150# CHECK-NEXT: Value: [[ENTRY]]
151# CHECK-NEXT: Size: 0
152# CHECK-NEXT: Binding: Global (0x1)
153# CHECK-NEXT: Type: None (0x0)
154# CHECK-NEXT: Other: 0
155# CHECK-NEXT: Section: .text
156# CHECK-NEXT: }
157# CHECK-NEXT: ]
158# CHECK-NEXT: ProgramHeaders [
159# CHECK-NEXT: ProgramHeader {
160# CHECK-NEXT: Type: PT_PHDR (0x6)
161# CHECK-NEXT: Offset: 0x40
162# CHECK-NEXT: VirtualAddress: 0x10040
163# CHECK-NEXT: PhysicalAddress: 0x10040
164# CHECK-NEXT: FileSize: 224
165# CHECK-NEXT: MemSize: 224
166# CHECK-NEXT: Flags [ (0x4)
167# CHECK-NEXT: PF_R (0x4)
168# CHECK-NEXT: ]
169# CHECK-NEXT: Alignment: 8
170# CHECK-NEXT: }
171# CHECK-NEXT: ProgramHeader {
172# CHECK-NEXT: Type: PT_LOAD (0x1)
173# CHECK-NEXT: Offset: 0x0
174# CHECK-NEXT: VirtualAddress: 0x10000
175# CHECK-NEXT: PhysicalAddress: 0x10000
176# CHECK-NEXT: FileSize: 288
177# CHECK-NEXT: MemSize: 288
178# CHECK-NEXT: Flags [
179# CHECK-NEXT: PF_R
180# CHECK-NEXT: ]
181# CHECK-NEXT: Alignment: 65536
182# CHECK-NEXT: }
183# CHECK-NEXT: ProgramHeader {
184# CHECK-NEXT: Type: PT_LOAD (0x1)
185# CHECK-NEXT: Offset: 0x1000
186# CHECK-NEXT: VirtualAddress: 0x20000
187# CHECK-NEXT: PhysicalAddress: 0x20000
188# CHECK-NEXT: FileSize: 12
189# CHECK-NEXT: MemSize: 12
190# CHECK-NEXT: Flags [ (0x5)
191# CHECK-NEXT: PF_R (0x4)
192# CHECK-NEXT: PF_X (0x1)
193# CHECK-NEXT: ]
194# CHECK-NEXT: Alignment: 65536
195# CHECK-NEXT: }
196# CHECK-NEXT: ProgramHeader {
197# CHECK-NEXT: Type: PT_GNU_STACK
198# CHECK-NEXT: Offset: 0x0
199# CHECK-NEXT: VirtualAddress: 0x0
200# CHECK-NEXT: PhysicalAddress: 0x0
201# CHECK-NEXT: FileSize: 0
202# CHECK-NEXT: MemSize: 0
203# CHECK-NEXT: Flags [
204# CHECK-NEXT: PF_R
205# CHECK-NEXT: PF_W
206# CHECK-NEXT: ]
207# CHECK-NEXT: Alignment: 0
208# CHECK-NEXT: }
209# CHECK-NEXT: ]
deps/lld/test/ELF/basic-avr.s created+14
......@@ -0,0 +1,14 @@
1# REQUIRES: avr
2# RUN: llvm-mc -filetype=obj -triple=avr-unknown-linux -mcpu=atmega328p %s -o %t.o
3# RUN: ld.lld %t.o -o %t.exe -Ttext=0
4# RUN: llvm-objdump -d %t.exe | FileCheck %s
5
6main:
7 call foo
8foo:
9 jmp foo
10
11# CHECK: main:
12# CHECK-NEXT: 0: 0e 94 02 00 <unknown>
13# CHECK: foo:
14# CHECK-NEXT: 4: 0c 94 02 00 <unknown>
deps/lld/test/ELF/basic-freebsd.s created+25
......@@ -0,0 +1,25 @@
1# Verify that OSABI is set to the correct value.
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %t
4# RUN: ld.lld %t -o %t2
5# RUN: llvm-readobj -file-headers %t2 | FileCheck %s
6# REQUIRES: x86
7
8.globl _start
9_start:
10 mov $1, %rax
11 mov $42, %rdi
12 syscall
13
14# CHECK: ElfHeader {
15# CHECK-NEXT: Ident {
16# CHECK-NEXT: Magic: (7F 45 4C 46)
17# CHECK-NEXT: Class: 64-bit (0x2)
18# CHECK-NEXT: DataEncoding: LittleEndian (0x1)
19# CHECK-NEXT: FileVersion: 1
20# CHECK-NEXT: OS/ABI: FreeBSD (0x9)
21# CHECK-NEXT: ABIVersion: 0
22# CHECK-NEXT: Unused: (00 00 00 00 00 00 00)
23# CHECK-NEXT: }
24# CHECK-NEXT: Type: Executable (0x2)
25# CHECK-NEXT: Machine: EM_X86_64 (0x3E)
deps/lld/test/ELF/basic-mips.s created+307
......@@ -0,0 +1,307 @@
1# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %t.o
2# RUN: ld.lld %t.o -o %t.exe
3# RUN: llvm-readobj -file-headers -sections -program-headers -symbols %t.exe \
4# RUN: | FileCheck %s
5
6# REQUIRES: mips
7
8# Exits with return code 1 on Linux.
9 .globl __start
10__start:
11 li $a0,1
12 li $v0,4001
13 syscall
14
15# CHECK: ElfHeader {
16# CHECK-NEXT: Ident {
17# CHECK-NEXT: Magic: (7F 45 4C 46)
18# CHECK-NEXT: Class: 32-bit (0x1)
19# CHECK-NEXT: DataEncoding: LittleEndian (0x1)
20# CHECK-NEXT: FileVersion: 1
21# CHECK-NEXT: OS/ABI: SystemV (0x0)
22# CHECK-NEXT: ABIVersion: 0
23# CHECK-NEXT: Unused: (00 00 00 00 00 00 00)
24# CHECK-NEXT: }
25# CHECK-NEXT: Type: Executable (0x2)
26# CHECK-NEXT: Machine: EM_MIPS (0x8)
27# CHECK-NEXT: Version: 1
28# CHECK-NEXT: Entry: 0x20000
29# CHECK-NEXT: ProgramHeaderOffset: 0x34
30# CHECK-NEXT: SectionHeaderOffset: 0x200A0
31# CHECK-NEXT: Flags [
32# CHECK-NEXT: EF_MIPS_ABI_O32
33# CHECK-NEXT: EF_MIPS_ARCH_32
34# CHECK-NEXT: EF_MIPS_CPIC
35# CHECK-NEXT: ]
36# CHECK-NEXT: HeaderSize: 52
37# CHECK-NEXT: ProgramHeaderEntrySize: 32
38# CHECK-NEXT: ProgramHeaderCount: 5
39# CHECK-NEXT: SectionHeaderEntrySize: 40
40# CHECK-NEXT: SectionHeaderCount: 11
41# CHECK-NEXT: StringTableSectionIndex: 9
42# CHECK-NEXT: }
43# CHECK-NEXT: Sections [
44# CHECK-NEXT: Section {
45# CHECK-NEXT: Index: 0
46# CHECK-NEXT: Name: (0)
47# CHECK-NEXT: Type: SHT_NULL (0x0)
48# CHECK-NEXT: Flags [ (0x0)
49# CHECK-NEXT: ]
50# CHECK-NEXT: Address: 0x0
51# CHECK-NEXT: Offset: 0x0
52# CHECK-NEXT: Size: 0
53# CHECK-NEXT: Link: 0
54# CHECK-NEXT: Info: 0
55# CHECK-NEXT: AddressAlignment: 0
56# CHECK-NEXT: EntrySize: 0
57# CHECK-NEXT: }
58# CHECK-NEXT: Section {
59# CHECK-NEXT: Index: 1
60# CHECK-NEXT: Name: .MIPS.abiflags
61# CHECK-NEXT: Type: SHT_MIPS_ABIFLAGS (0x7000002A)
62# CHECK-NEXT: Flags [ (0x2)
63# CHECK-NEXT: SHF_ALLOC (0x2)
64# CHECK-NEXT: ]
65# CHECK-NEXT: Address: 0x100D8
66# CHECK-NEXT: Offset: 0xD8
67# CHECK-NEXT: Size: 24
68# CHECK-NEXT: Link: 0
69# CHECK-NEXT: Info: 0
70# CHECK-NEXT: AddressAlignment: 8
71# CHECK-NEXT: EntrySize: 24
72# CHECK-NEXT: }
73# CHECK-NEXT: Section {
74# CHECK-NEXT: Index: 2
75# CHECK-NEXT: Name: .reginfo
76# CHECK-NEXT: Type: SHT_MIPS_REGINFO (0x70000006)
77# CHECK-NEXT: Flags [ (0x2)
78# CHECK-NEXT: SHF_ALLOC (0x2)
79# CHECK-NEXT: ]
80# CHECK-NEXT: Address: 0x100F0
81# CHECK-NEXT: Offset: 0xF0
82# CHECK-NEXT: Size: 24
83# CHECK-NEXT: Link: 0
84# CHECK-NEXT: Info: 0
85# CHECK-NEXT: AddressAlignment: 4
86# CHECK-NEXT: EntrySize: 24
87# CHECK-NEXT: }
88# CHECK-NEXT: Section {
89# CHECK-NEXT: Index: 3
90# CHECK-NEXT: Name: .text
91# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
92# CHECK-NEXT: Flags [ (0x6)
93# CHECK-NEXT: SHF_ALLOC (0x2)
94# CHECK-NEXT: SHF_EXECINSTR (0x4)
95# CHECK-NEXT: ]
96# CHECK-NEXT: Address: 0x20000
97# CHECK-NEXT: Offset: 0x10000
98# CHECK-NEXT: Size: 12
99# CHECK-NEXT: Link: 0
100# CHECK-NEXT: Info: 0
101# CHECK-NEXT: AddressAlignment: 16
102# CHECK-NEXT: EntrySize: 0
103# CHECK-NEXT: }
104# CHECK-NEXT: Section {
105# CHECK-NEXT: Index: 4
106# CHECK-NEXT: Name: .data
107# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
108# CHECK-NEXT: Flags [ (0x3)
109# CHECK-NEXT: SHF_ALLOC (0x2)
110# CHECK-NEXT: SHF_WRITE (0x1)
111# CHECK-NEXT: ]
112# CHECK-NEXT: Address: 0x30000
113# CHECK-NEXT: Offset: 0x20000
114# CHECK-NEXT: Size: 0
115# CHECK-NEXT: Link: 0
116# CHECK-NEXT: Info: 0
117# CHECK-NEXT: AddressAlignment: 16
118# CHECK-NEXT: EntrySize: 0
119# CHECK-NEXT: }
120# CHECK-NEXT: Section {
121# CHECK-NEXT: Index: 5
122# CHECK-NEXT: Name: .got
123# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
124# CHECK-NEXT: Flags [ (0x10000003)
125# CHECK-NEXT: SHF_ALLOC (0x2)
126# CHECK-NEXT: SHF_MIPS_GPREL (0x10000000)
127# CHECK-NEXT: SHF_WRITE (0x1)
128# CHECK-NEXT: ]
129# CHECK-NEXT: Address: 0x30000
130# CHECK-NEXT: Offset: 0x20000
131# CHECK-NEXT: Size: 8
132# CHECK-NEXT: Link: 0
133# CHECK-NEXT: Info: 0
134# CHECK-NEXT: AddressAlignment: 16
135# CHECK-NEXT: EntrySize: 0
136# CHECK-NEXT: }
137# CHECK-NEXT: Section {
138# CHECK-NEXT: Index: 6
139# CHECK-NEXT: Name: .bss
140# CHECK-NEXT: Type: SHT_NOBITS (0x8)
141# CHECK-NEXT: Flags [ (0x3)
142# CHECK-NEXT: SHF_ALLOC (0x2)
143# CHECK-NEXT: SHF_WRITE (0x1)
144# CHECK-NEXT: ]
145# CHECK-NEXT: Address: 0x30010
146# CHECK-NEXT: Offset: 0x20008
147# CHECK-NEXT: Size: 0
148# CHECK-NEXT: Link: 0
149# CHECK-NEXT: Info: 0
150# CHECK-NEXT: AddressAlignment: 16
151# CHECK-NEXT: EntrySize: 0
152# CHECK-NEXT: }
153# CHECK-NEXT: Section {
154# CHECK-NEXT: Index: 7
155# CHECK-NEXT: Name: .comment
156# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
157# CHECK-NEXT: Flags [ (0x30)
158# CHECK-NEXT: SHF_MERGE (0x10)
159# CHECK-NEXT: SHF_STRINGS (0x20)
160# CHECK-NEXT: ]
161# CHECK-NEXT: Address: 0x0
162# CHECK-NEXT: Offset: 0x20008
163# CHECK-NEXT: Size: 8
164# CHECK-NEXT: Link: 0
165# CHECK-NEXT: Info: 0
166# CHECK-NEXT: AddressAlignment: 1
167# CHECK-NEXT: EntrySize: 0
168# CHECK-NEXT: }
169# CHECK-NEXT: Section {
170# CHECK-NEXT: Index: 8
171# CHECK-NEXT: Name: .symtab
172# CHECK-NEXT: Type: SHT_SYMTAB (0x2)
173# CHECK-NEXT: Flags [ (0x0)
174# CHECK-NEXT: ]
175# CHECK-NEXT: Address: 0x0
176# CHECK-NEXT: Offset: 0x20010
177# CHECK-NEXT: Size: 48
178# CHECK-NEXT: Link: 10
179# CHECK-NEXT: Info: 2
180# CHECK-NEXT: AddressAlignment: 4
181# CHECK-NEXT: EntrySize: 16
182# CHECK-NEXT: }
183# CHECK-NEXT: Section {
184# CHECK-NEXT: Index: 9
185# CHECK-NEXT: Name: .shstrtab
186# CHECK-NEXT: Type: SHT_STRTAB (0x3)
187# CHECK-NEXT: Flags [ (0x0)
188# CHECK-NEXT: ]
189# CHECK-NEXT: Address: 0x0
190# CHECK-NEXT: Offset: 0x20040
191# CHECK-NEXT: Size: 82
192# CHECK-NEXT: Link: 0
193# CHECK-NEXT: Info: 0
194# CHECK-NEXT: AddressAlignment: 1
195# CHECK-NEXT: EntrySize: 0
196# CHECK-NEXT: }
197# CHECK-NEXT: Section {
198# CHECK-NEXT: Index: 10
199# CHECK-NEXT: Name: .strtab
200# CHECK-NEXT: Type: SHT_STRTAB (0x3)
201# CHECK-NEXT: Flags [ (0x0)
202# CHECK-NEXT: ]
203# CHECK-NEXT: Address: 0x0
204# CHECK-NEXT: Offset: 0x20092
205# CHECK-NEXT: Size: 13
206# CHECK-NEXT: Link: 0
207# CHECK-NEXT: Info: 0
208# CHECK-NEXT: AddressAlignment: 1
209# CHECK-NEXT: EntrySize: 0
210# CHECK-NEXT: }
211# CHECK-NEXT: ]
212# CHECK-NEXT: Symbols [
213# CHECK-NEXT: Symbol {
214# CHECK-NEXT: Name: (0)
215# CHECK-NEXT: Value: 0x0
216# CHECK-NEXT: Size: 0
217# CHECK-NEXT: Binding: Local (0x0)
218# CHECK-NEXT: Type: None (0x0)
219# CHECK-NEXT: Other: 0
220# CHECK-NEXT: Section: Undefined (0x0)
221# CHECK-NEXT: }
222# CHECK-NEXT: Symbol {
223# CHECK-NEXT: Name: _gp
224# CHECK-NEXT: Value: 0x37FF0
225# CHECK-NEXT: Size: 0
226# CHECK-NEXT: Binding: Local
227# CHECK-NEXT: Type: None (0x0)
228# CHECK-NEXT: Other [ (0x2)
229# CHECK-NEXT: STV_HIDDEN (0x2)
230# CHECK-NEXT: ]
231# CHECK-NEXT: Section: Absolute
232# CHECK-NEXT: }
233# CHECK-NEXT: Symbol {
234# CHECK-NEXT: Name: __start
235# CHECK-NEXT: Value: 0x20000
236# CHECK-NEXT: Size: 0
237# CHECK-NEXT: Binding: Global (0x1)
238# CHECK-NEXT: Type: None (0x0)
239# CHECK-NEXT: Other: 0
240# CHECK-NEXT: Section: .text
241# CHECK-NEXT: }
242# CHECK-NEXT: ]
243# CHECK-NEXT: ProgramHeaders [
244# CHECK-NEXT: ProgramHeader {
245# CHECK-NEXT: Type: PT_PHDR (0x6)
246# CHECK-NEXT: Offset: 0x34
247# CHECK-NEXT: VirtualAddress: 0x10034
248# CHECK-NEXT: PhysicalAddress: 0x10034
249# CHECK-NEXT: FileSize: 160
250# CHECK-NEXT: MemSize: 160
251# CHECK-NEXT: Flags [ (0x4)
252# CHECK-NEXT: PF_R (0x4)
253# CHECK-NEXT: ]
254# CHECK-NEXT: Alignment: 4
255# CHECK-NEXT: }
256# CHECK-NEXT: ProgramHeader {
257# CHECK-NEXT: Type: PT_LOAD (0x1)
258# CHECK-NEXT: Offset: 0x0
259# CHECK-NEXT: VirtualAddress: 0x10000
260# CHECK-NEXT: PhysicalAddress: 0x10000
261# CHECK-NEXT: FileSize: 264
262# CHECK-NEXT: MemSize: 264
263# CHECK-NEXT: Flags [ (0x4)
264# CHECK-NEXT: PF_R (0x4)
265# CHECK-NEXT: ]
266# CHECK-NEXT: Alignment: 65536
267# CHECK-NEXT: }
268# CHECK-NEXT: ProgramHeader {
269# CHECK-NEXT: Type: PT_LOAD (0x1)
270# CHECK-NEXT: Offset: 0x10000
271# CHECK-NEXT: VirtualAddress: 0x20000
272# CHECK-NEXT: PhysicalAddress: 0x20000
273# CHECK-NEXT: FileSize: 12
274# CHECK-NEXT: MemSize: 12
275# CHECK-NEXT: Flags [ (0x5)
276# CHECK-NEXT: PF_R (0x4)
277# CHECK-NEXT: PF_X (0x1)
278# CHECK-NEXT: ]
279# CHECK-NEXT: Alignment: 65536
280# CHECK-NEXT: }
281# CHECK-NEXT: ProgramHeader {
282# CHECK-NEXT: Type: PT_LOAD (0x1)
283# CHECK-NEXT: Offset: 0x20000
284# CHECK-NEXT: VirtualAddress: 0x30000
285# CHECK-NEXT: PhysicalAddress: 0x30000
286# CHECK-NEXT: FileSize: 8
287# CHECK-NEXT: MemSize: 16
288# CHECK-NEXT: Flags [
289# CHECK-NEXT: PF_R
290# CHECK-NEXT: PF_W
291# CHECK-NEXT: ]
292# CHECK-NEXT: Alignment: 65536
293# CHECK-NEXT: }
294# CHECK-NEXT: ProgramHeader {
295# CHECK-NEXT: Type: PT_GNU_STACK
296# CHECK-NEXT: Offset: 0x0
297# CHECK-NEXT: VirtualAddress: 0x0
298# CHECK-NEXT: PhysicalAddress: 0x0
299# CHECK-NEXT: FileSize: 0
300# CHECK-NEXT: MemSize: 0
301# CHECK-NEXT: Flags [
302# CHECK-NEXT: PF_R
303# CHECK-NEXT: PF_W
304# CHECK-NEXT: ]
305# CHECK-NEXT: Alignment: 0
306# CHECK-NEXT: }
307# CHECK-NEXT:]
deps/lld/test/ELF/basic-ppc.s created+317
......@@ -0,0 +1,317 @@
1# RUN: llvm-mc -filetype=obj -triple=powerpc-unknown-freebsd %s -o %t
2# RUN: ld.lld -discard-all -shared %t -o %t2
3# RUN: llvm-readobj -file-headers -sections -section-data -program-headers %t2 | FileCheck %s
4# REQUIRES: ppc
5
6# exits with return code 42 on FreeBSD
7.text
8 li 0,1
9 li 3,1
10 sc
11
12// CHECK: Format: ELF32-ppc
13// CHECK-NEXT: Arch: powerpc
14// CHECK-NEXT: AddressSize: 32bit
15// CHECK-NEXT: LoadName:
16// CHECK-NEXT: ElfHeader {
17// CHECK-NEXT: Ident {
18// CHECK-NEXT: Magic: (7F 45 4C 46)
19// CHECK-NEXT: Class: 32-bit (0x1)
20// CHECK-NEXT: DataEncoding: BigEndian (0x2)
21// CHECK-NEXT: FileVersion: 1
22// CHECK-NEXT: OS/ABI: FreeBSD (0x9)
23// CHECK-NEXT: ABIVersion: 0
24// CHECK-NEXT: Unused: (00 00 00 00 00 00 00)
25// CHECK-NEXT: }
26// CHECK-NEXT: Type: SharedObject (0x3)
27// CHECK-NEXT: Machine: EM_PPC (0x14)
28// CHECK-NEXT: Version: 1
29// CHECK-NEXT: Entry: 0x1000
30// CHECK-NEXT: ProgramHeaderOffset: 0x34
31// CHECK-NEXT: SectionHeaderOffset: 0x20AC
32// CHECK-NEXT: Flags [ (0x0)
33// CHECK-NEXT: ]
34// CHECK-NEXT: HeaderSize: 52
35// CHECK-NEXT: ProgramHeaderEntrySize: 32
36// CHECK-NEXT: ProgramHeaderCount: 7
37// CHECK-NEXT: SectionHeaderEntrySize: 40
38// CHECK-NEXT: SectionHeaderCount: 10
39// CHECK-NEXT: StringTableSectionIndex: 8
40// CHECK-NEXT: }
41// CHECK-NEXT: Sections [
42// CHECK-NEXT: Section {
43// CHECK-NEXT: Index: 0
44// CHECK-NEXT: Name: (0)
45// CHECK-NEXT: Type: SHT_NULL (0x0)
46// CHECK-NEXT: Flags [ (0x0)
47// CHECK-NEXT: ]
48// CHECK-NEXT: Address: 0x0
49// CHECK-NEXT: Offset: 0x0
50// CHECK-NEXT: Size: 0
51// CHECK-NEXT: Link: 0
52// CHECK-NEXT: Info: 0
53// CHECK-NEXT: AddressAlignment: 0
54// CHECK-NEXT: EntrySize: 0
55// CHECK-NEXT: SectionData (
56// CHECK-NEXT: )
57// CHECK-NEXT: }
58// CHECK-NEXT: Section {
59// CHECK-NEXT: Index: 1
60// CHECK-NEXT: Name: .dynsym
61// CHECK-NEXT: Type: SHT_DYNSYM (0xB)
62// CHECK-NEXT: Flags [ (0x2)
63// CHECK-NEXT: SHF_ALLOC (0x2)
64// CHECK-NEXT: ]
65// CHECK-NEXT: Address: 0x114
66// CHECK-NEXT: Offset: 0x114
67// CHECK-NEXT: Size: 16
68// CHECK-NEXT: Link: 3
69// CHECK-NEXT: Info: 1
70// CHECK-NEXT: AddressAlignment: 4
71// CHECK-NEXT: EntrySize: 16
72// CHECK-NEXT: SectionData (
73// CHECK-NEXT: 0000: 00000000 00000000 00000000 00000000 |................|
74// CHECK-NEXT: )
75// CHECK-NEXT: }
76// CHECK-NEXT: Section {
77// CHECK-NEXT: Index: 2
78// CHECK-NEXT: Name: .hash
79// CHECK-NEXT: Type: SHT_HASH (0x5)
80// CHECK-NEXT: Flags [ (0x2)
81// CHECK-NEXT: SHF_ALLOC (0x2)
82// CHECK-NEXT: ]
83// CHECK-NEXT: Address: 0x124
84// CHECK-NEXT: Offset: 0x124
85// CHECK-NEXT: Size: 16
86// CHECK-NEXT: Link: 1
87// CHECK-NEXT: Info: 0
88// CHECK-NEXT: AddressAlignment: 4
89// CHECK-NEXT: EntrySize: 4
90// CHECK-NEXT: SectionData (
91// CHECK-NEXT: 0000: 00000001 00000001 00000000 00000000 |................|
92// CHECK-NEXT: )
93// CHECK-NEXT: }
94// CHECK-NEXT: Section {
95// CHECK-NEXT: Index: 3
96// CHECK-NEXT: Name: .dynstr
97// CHECK-NEXT: Type: SHT_STRTAB (0x3)
98// CHECK-NEXT: Flags [ (0x2)
99// CHECK-NEXT: SHF_ALLOC (0x2)
100// CHECK-NEXT: ]
101// CHECK-NEXT: Address: 0x134
102// CHECK-NEXT: Offset: 0x134
103// CHECK-NEXT: Size: 1
104// CHECK-NEXT: Link: 0
105// CHECK-NEXT: Info: 0
106// CHECK-NEXT: AddressAlignment: 1
107// CHECK-NEXT: EntrySize: 0
108// CHECK-NEXT: SectionData (
109// CHECK-NEXT: 0000: 00 |.|
110// CHECK-NEXT: )
111// CHECK-NEXT: }
112// CHECK-NEXT: Section {
113// CHECK-NEXT: Index: 4
114// CHECK-NEXT: Name: .text
115// CHECK-NEXT: Type: SHT_PROGBITS (0x1)
116// CHECK-NEXT: Flags [ (0x6)
117// CHECK-NEXT: SHF_ALLOC (0x2)
118// CHECK-NEXT: SHF_EXECINSTR (0x4)
119// CHECK-NEXT: ]
120// CHECK-NEXT: Address: 0x1000
121// CHECK-NEXT: Offset: 0x1000
122// CHECK-NEXT: Size: 12
123// CHECK-NEXT: Link: 0
124// CHECK-NEXT: Info: 0
125// CHECK-NEXT: AddressAlignment: 4
126// CHECK-NEXT: EntrySize: 0
127// CHECK-NEXT: SectionData (
128// CHECK-NEXT: 0000: 38000001 38600001 44000002 |8...8`..D...|
129// CHECK-NEXT: )
130// CHECK-NEXT: }
131// CHECK-NEXT: Section {
132// CHECK-NEXT: Index: 5
133// CHECK-NEXT: Name: .dynamic
134// CHECK-NEXT: Type: SHT_DYNAMIC (0x6)
135// CHECK-NEXT: Flags [ (0x3)
136// CHECK-NEXT: SHF_ALLOC (0x2)
137// CHECK-NEXT: SHF_WRITE (0x1)
138// CHECK-NEXT: ]
139// CHECK-NEXT: Address: 0x2000
140// CHECK-NEXT: Offset: 0x2000
141// CHECK-NEXT: Size: 48
142// CHECK-NEXT: Link: 3
143// CHECK-NEXT: Info: 0
144// CHECK-NEXT: AddressAlignment: 4
145// CHECK-NEXT: EntrySize: 8
146// CHECK-NEXT: SectionData (
147// CHECK-NEXT: 0000: 00000006 00000114 0000000B 00000010 |................|
148// CHECK-NEXT: 0010: 00000005 00000134 0000000A 00000001 |.......4........|
149// CHECK-NEXT: 0020: 00000004 00000124 00000000 00000000 |.......$........|
150// CHECK-NEXT: )
151// CHECK-NEXT: }
152// CHECK-NEXT: Section {
153// CHECK-NEXT: Index: 6
154// CHECK-NEXT: Name: .comment
155// CHECK-NEXT: Type: SHT_PROGBITS (0x1)
156// CHECK-NEXT: Flags [ (0x30)
157// CHECK-NEXT: SHF_MERGE (0x10)
158// CHECK-NEXT: SHF_STRINGS (0x20)
159// CHECK-NEXT: ]
160// CHECK-NEXT: Address: 0x0
161// CHECK-NEXT: Offset: 0x2030
162// CHECK-NEXT: Size: 8
163// CHECK-NEXT: Link: 0
164// CHECK-NEXT: Info: 0
165// CHECK-NEXT: AddressAlignment: 1
166// CHECK-NEXT: EntrySize: 0
167// CHECK-NEXT: SectionData (
168// CHECK-NEXT: 0000: 4C4C4420 312E3000 |LLD 1.0.|
169// CHECK-NEXT: )
170// CHECK-NEXT: }
171// CHECK-NEXT: Section {
172// CHECK-NEXT: Index: 7
173// CHECK-NEXT: Name: .symtab
174// CHECK-NEXT: Type: SHT_SYMTAB (0x2)
175// CHECK-NEXT: Flags [ (0x0)
176// CHECK-NEXT: ]
177// CHECK-NEXT: Address: 0x0
178// CHECK-NEXT: Offset: 0x2038
179// CHECK-NEXT: Size: 32
180// CHECK-NEXT: Link: 9
181// CHECK-NEXT: Info: 2
182// CHECK-NEXT: AddressAlignment: 4
183// CHECK-NEXT: EntrySize: 16
184// CHECK-NEXT: SectionData (
185// CHECK-NEXT: 0000: 00000000 00000000 00000000 00000000 |................|
186// CHECK-NEXT: 0010: 00000001 00002000 00000000 00020005 |...... .........|
187// CHECK-NEXT: )
188// CHECK-NEXT: }
189// CHECK-NEXT: Section {
190// CHECK-NEXT: Index: 8
191// CHECK-NEXT: Name: .shstrtab
192// CHECK-NEXT: Type: SHT_STRTAB (0x3)
193// CHECK-NEXT: Flags [ (0x0)
194// CHECK-NEXT: ]
195// CHECK-NEXT: Address: 0x0
196// CHECK-NEXT: Offset: 0x2058
197// CHECK-NEXT: Size: 73
198// CHECK-NEXT: Link: 0
199// CHECK-NEXT: Info: 0
200// CHECK-NEXT: AddressAlignment: 1
201// CHECK-NEXT: EntrySize: 0
202// CHECK-NEXT: SectionData (
203// CHECK-NEXT: 0000: 002E6479 6E73796D 002E6861 7368002E |..dynsym..hash..|
204// CHECK-NEXT: 0010: 64796E73 7472002E 74657874 002E6479 |dynstr..text..dy|
205// CHECK-NEXT: 0020: 6E616D69 63002E63 6F6D6D65 6E74002E |namic..comment..|
206// CHECK-NEXT: 0030: 73796D74 6162002E 73687374 72746162 |symtab..shstrtab|
207// CHECK-NEXT: 0040: 002E7374 72746162 00 |..strtab.|
208// CHECK-NEXT: )
209// CHECK-NEXT: }
210// CHECK-NEXT: Section {
211// CHECK-NEXT: Index: 9
212// CHECK-NEXT: Name: .strtab
213// CHECK-NEXT: Type: SHT_STRTAB (0x3)
214// CHECK-NEXT: Flags [ (0x0)
215// CHECK-NEXT: ]
216// CHECK-NEXT: Address: 0x0
217// CHECK-NEXT: Offset: 0x20A1
218// CHECK-NEXT: Size: 1
219// CHECK-NEXT: Link: 0
220// CHECK-NEXT: Info: 0
221// CHECK-NEXT: AddressAlignment: 1
222// CHECK-NEXT: EntrySize: 0
223// CHECK-NEXT: SectionData (
224// CHECK-NEXT: 0000: 005F4459 4E414D49 4300 |._DYNAMIC.|
225// CHECK-NEXT: )
226// CHECK-NEXT: }
227// CHECK-NEXT: ]
228// CHECK-NEXT: ProgramHeaders [
229// CHECK-NEXT: ProgramHeader {
230// CHECK-NEXT: Type: PT_PHDR (0x6)
231// CHECK-NEXT: Offset: 0x34
232// CHECK-NEXT: VirtualAddress: 0x34
233// CHECK-NEXT: PhysicalAddress: 0x34
234// CHECK-NEXT: FileSize: 224
235// CHECK-NEXT: MemSize: 224
236// CHECK-NEXT: Flags [ (0x4)
237// CHECK-NEXT: PF_R (0x4)
238// CHECK-NEXT: ]
239// CHECK-NEXT: Alignment: 4
240// CHECK-NEXT: }
241// CHECK-NEXT: ProgramHeader {
242// CHECK-NEXT: Type: PT_LOAD (0x1)
243// CHECK-NEXT: Offset: 0x0
244// CHECK-NEXT: VirtualAddress: 0x0
245// CHECK-NEXT: PhysicalAddress: 0x0
246// CHECK-NEXT: FileSize: 309
247// CHECK-NEXT: MemSize: 309
248// CHECK-NEXT: Flags [ (0x4)
249// CHECK-NEXT: PF_R (0x4)
250// CHECK-NEXT: ]
251// CHECK-NEXT: Alignment: 4096
252// CHECK-NEXT: }
253// CHECK-NEXT: ProgramHeader {
254// CHECK-NEXT: Type: PT_LOAD (0x1)
255// CHECK-NEXT: Offset: 0x1000
256// CHECK-NEXT: VirtualAddress: 0x1000
257// CHECK-NEXT: PhysicalAddress: 0x1000
258// CHECK-NEXT: FileSize: 12
259// CHECK-NEXT: MemSize: 12
260// CHECK-NEXT: Flags [ (0x5)
261// CHECK-NEXT: PF_R (0x4)
262// CHECK-NEXT: PF_X (0x1)
263// CHECK-NEXT: ]
264// CHECK-NEXT: Alignment: 4096
265// CHECK-NEXT: }
266// CHECK-NEXT: ProgramHeader {
267// CHECK-NEXT: Type: PT_LOAD (0x1)
268// CHECK-NEXT: Offset: 0x2000
269// CHECK-NEXT: VirtualAddress: 0x2000
270// CHECK-NEXT: PhysicalAddress: 0x2000
271// CHECK-NEXT: FileSize: 48
272// CHECK-NEXT: MemSize: 48
273// CHECK-NEXT: Flags [ (0x6)
274// CHECK-NEXT: PF_R (0x4)
275// CHECK-NEXT: PF_W (0x2)
276// CHECK-NEXT: ]
277// CHECK-NEXT: Alignment: 4096
278// CHECK-NEXT: }
279// CHECK-NEXT: ProgramHeader {
280// CHECK-NEXT: Type: PT_DYNAMIC (0x2)
281// CHECK-NEXT: Offset: 0x2000
282// CHECK-NEXT: VirtualAddress: 0x2000
283// CHECK-NEXT: PhysicalAddress: 0x2000
284// CHECK-NEXT: FileSize: 48
285// CHECK-NEXT: MemSize: 48
286// CHECK-NEXT: Flags [ (0x6)
287// CHECK-NEXT: PF_R (0x4)
288// CHECK-NEXT: PF_W (0x2)
289// CHECK-NEXT: ]
290// CHECK-NEXT: Alignment: 4
291// CHECK-NEXT: }
292// CHECK-NEXT: ProgramHeader {
293// CHECK-NEXT: Type: PT_GNU_RELRO (0x6474E552)
294// CHECK-NEXT: Offset: 0x2000
295// CHECK-NEXT: VirtualAddress: 0x2000
296// CHECK-NEXT: PhysicalAddress: 0x2000
297// CHECK-NEXT: FileSize: 48
298// CHECK-NEXT: MemSize: 4096
299// CHECK-NEXT: Flags [ (0x4)
300// CHECK-NEXT: PF_R (0x4)
301// CHECK-NEXT: ]
302// CHECK-NEXT: Alignment: 1
303// CHECK-NEXT: }
304// CHECK-NEXT: ProgramHeader {
305// CHECK-NEXT: Type: PT_GNU_STACK (0x6474E551)
306// CHECK-NEXT: Offset: 0x0
307// CHECK-NEXT: VirtualAddress: 0x0
308// CHECK-NEXT: PhysicalAddress: 0x0
309// CHECK-NEXT: FileSize: 0
310// CHECK-NEXT: MemSize: 0
311// CHECK-NEXT: Flags [ (0x6)
312// CHECK-NEXT: PF_R (0x4)
313// CHECK-NEXT: PF_W (0x2)
314// CHECK-NEXT: ]
315// CHECK-NEXT: Alignment: 0
316// CHECK-NEXT: }
317// CHECK-NEXT: ]
deps/lld/test/ELF/basic-sparcv9.s created+200
......@@ -0,0 +1,200 @@
1# RUN: llvm-mc -filetype=obj -triple=sparc64-unknown-openbsd %s -o %t
2# RUN: ld.lld %t -o %t2
3# RUN: llvm-readobj -file-headers -sections -program-headers -symbols %t2 \
4# RUN: | FileCheck %s
5# REQUIRES: sparc
6
7# exits with return code 42 on OpenBSD/sparc64
8.global _start
9_start:
10 mov 42, %o0
11 mov 1, %g1
12 ta 0
13
14# CHECK: ElfHeader {
15# CHECK-NEXT: Ident {
16# CHECK-NEXT: Magic: (7F 45 4C 46)
17# CHECK-NEXT: Class: 64-bit (0x2)
18# CHECK-NEXT: DataEncoding: BigEndian (0x2)
19# CHECK-NEXT: FileVersion: 1
20# CHECK-NEXT: OS/ABI: SystemV (0x0)
21# CHECK-NEXT: ABIVersion: 0
22# CHECK-NEXT: Unused: (00 00 00 00 00 00 00)
23# CHECK-NEXT: }
24# CHECK-NEXT: Type: Executable (0x2)
25# CHECK-NEXT: Machine: EM_SPARCV9 (0x2B)
26# CHECK-NEXT: Version: 1
27# CHECK-NEXT: Entry: [[ENTRY:0x[0-9A-F]+]]
28# CHECK-NEXT: ProgramHeaderOffset: 0x40
29# CHECK-NEXT: SectionHeaderOffset: 0x100080
30# CHECK-NEXT: Flags [ (0x0)
31# CHECK-NEXT: ]
32# CHECK-NEXT: HeaderSize: 64
33# CHECK-NEXT: ProgramHeaderEntrySize: 56
34# CHECK-NEXT: ProgramHeaderCount: 4
35# CHECK-NEXT: SectionHeaderEntrySize: 64
36# CHECK-NEXT: SectionHeaderCount: 6
37# CHECK-NEXT: StringTableSectionIndex: 4
38# CHECK-NEXT: }
39# CHECK-NEXT: Sections [
40# CHECK-NEXT: Section {
41# CHECK-NEXT: Index: 0
42# CHECK-NEXT: Name: (0)
43# CHECK-NEXT: Type: SHT_NULL (0x0)
44# CHECK-NEXT: Flags [ (0x0)
45# CHECK-NEXT: ]
46# CHECK-NEXT: Address: 0x0
47# CHECK-NEXT: Offset: 0x0
48# CHECK-NEXT: Size: 0
49# CHECK-NEXT: Link: 0
50# CHECK-NEXT: Info: 0
51# CHECK-NEXT: AddressAlignment: 0
52# CHECK-NEXT: EntrySize: 0
53# CHECK-NEXT: }
54# CHECK-NEXT: Section {
55# CHECK-NEXT: Index: 1
56# CHECK-NEXT: Name: .text
57# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
58# CHECK-NEXT: Flags [ (0x6)
59# CHECK-NEXT: SHF_ALLOC (0x2)
60# CHECK-NEXT: SHF_EXECINSTR (0x4)
61# CHECK-NEXT: ]
62# CHECK-NEXT: Address: 0x200000
63# CHECK-NEXT: Offset: 0x100000
64# CHECK-NEXT: Size: 12
65# CHECK-NEXT: Link: 0
66# CHECK-NEXT: Info: 0
67# CHECK-NEXT: AddressAlignment: 4
68# CHECK-NEXT: EntrySize: 0
69# CHECK-NEXT: }
70# CHECK-NEXT: Section {
71# CHECK-NEXT: Index: 2
72# CHECK-NEXT: Name: .comment
73# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
74# CHECK-NEXT: Flags [ (0x30)
75# CHECK-NEXT: SHF_MERGE (0x10)
76# CHECK-NEXT: SHF_STRINGS (0x20)
77# CHECK-NEXT: ]
78# CHECK-NEXT: Address: 0x0
79# CHECK-NEXT: Offset: 0x10000C
80# CHECK-NEXT: Size: 8
81# CHECK-NEXT: Link: 0
82# CHECK-NEXT: Info: 0
83# CHECK-NEXT: AddressAlignment: 1
84# CHECK-NEXT: EntrySize: 0
85# CHECK-NEXT: }
86# CHECK-NEXT: Section {
87# CHECK-NEXT: Index: 3
88# CHECK-NEXT: Name: .symtab
89# CHECK-NEXT: Type: SHT_SYMTAB (0x2)
90# CHECK-NEXT: Flags [ (0x0)
91# CHECK-NEXT: ]
92# CHECK-NEXT: Address: 0x0
93# CHECK-NEXT: Offset: 0x100018
94# CHECK-NEXT: Size: 48
95# CHECK-NEXT: Link: 5
96# CHECK-NEXT: Info: 1
97# CHECK-NEXT: AddressAlignment: 8
98# CHECK-NEXT: EntrySize: 24
99# CHECK-NEXT: }
100# CHECK-NEXT: Section {
101# CHECK-NEXT: Index: 4
102# CHECK-NEXT: Name: .shstrtab
103# CHECK-NEXT: Type: SHT_STRTAB (0x3)
104# CHECK-NEXT: Flags [ (0x0)
105# CHECK-NEXT: ]
106# CHECK-NEXT: Address: 0x0
107# CHECK-NEXT: Offset: 0x100048
108# CHECK-NEXT: Size: 42
109# CHECK-NEXT: Link: 0
110# CHECK-NEXT: Info: 0
111# CHECK-NEXT: AddressAlignment: 1
112# CHECK-NEXT: EntrySize: 0
113# CHECK-NEXT: }
114# CHECK-NEXT: Section {
115# CHECK-NEXT: Index: 5
116# CHECK-NEXT: Name: .strtab
117# CHECK-NEXT: Type: SHT_STRTAB (0x3)
118# CHECK-NEXT: Flags [ (0x0)
119# CHECK-NEXT: ]
120# CHECK-NEXT: Address: 0x0
121# CHECK-NEXT: Offset: 0x100072
122# CHECK-NEXT: Size: 8
123# CHECK-NEXT: Link: 0
124# CHECK-NEXT: Info: 0
125# CHECK-NEXT: AddressAlignment: 1
126# CHECK-NEXT: EntrySize: 0
127# CHECK-NEXT: }
128# CHECK-NEXT: ]
129# CHECK-NEXT: Symbols [
130# CHECK-NEXT: Symbol {
131# CHECK-NEXT: Name: (0)
132# CHECK-NEXT: Value: 0x0
133# CHECK-NEXT: Size: 0
134# CHECK-NEXT: Binding: Local (0x0)
135# CHECK-NEXT: Type: None (0x0)
136# CHECK-NEXT: Other: 0
137# CHECK-NEXT: Section: Undefined (0x0)
138# CHECK-NEXT: }
139# CHECK-NEXT: Symbol {
140# CHECK-NEXT: Name: _start
141# CHECK-NEXT: Value: [[ENTRY]]
142# CHECK-NEXT: Size: 0
143# CHECK-NEXT: Binding: Global (0x1)
144# CHECK-NEXT: Type: None (0x0)
145# CHECK-NEXT: Other: 0
146# CHECK-NEXT: Section: .text
147# CHECK-NEXT: }
148# CHECK-NEXT: ]
149# CHECK-NEXT: ProgramHeaders [
150# CHECK-NEXT: ProgramHeader {
151# CHECK-NEXT: Type: PT_PHDR (0x6)
152# CHECK-NEXT: Offset: 0x40
153# CHECK-NEXT: VirtualAddress: 0x100040
154# CHECK-NEXT: PhysicalAddress: 0x100040
155# CHECK-NEXT: FileSize: 224
156# CHECK-NEXT: MemSize: 224
157# CHECK-NEXT: Flags [ (0x4)
158# CHECK-NEXT: PF_R (0x4)
159# CHECK-NEXT: ]
160# CHECK-NEXT: Alignment: 8
161# CHECK-NEXT: }
162# CHECK-NEXT: ProgramHeader {
163# CHECK-NEXT: Type: PT_LOAD (0x1)
164# CHECK-NEXT: Offset: 0x0
165# CHECK-NEXT: VirtualAddress: 0x100000
166# CHECK-NEXT: PhysicalAddress: 0x100000
167# CHECK-NEXT: FileSize: 288
168# CHECK-NEXT: MemSize: 288
169# CHECK-NEXT: Flags [
170# CHECK-NEXT: PF_R
171# CHECK-NEXT: ]
172# CHECK-NEXT: Alignment: 1048576
173# CHECK-NEXT: }
174# CHECK-NEXT: ProgramHeader {
175# CHECK-NEXT: Type: PT_LOAD (0x1)
176# CHECK-NEXT: Offset: 0x100000
177# CHECK-NEXT: VirtualAddress: 0x200000
178# CHECK-NEXT: PhysicalAddress: 0x200000
179# CHECK-NEXT: FileSize: 12
180# CHECK-NEXT: MemSize: 12
181# CHECK-NEXT: Flags [ (0x5)
182# CHECK-NEXT: PF_R (0x4)
183# CHECK-NEXT: PF_X (0x1)
184# CHECK-NEXT: ]
185# CHECK-NEXT: Alignment: 1048576
186# CHECK-NEXT: }
187# CHECK-NEXT: ProgramHeader {
188# CHECK-NEXT: Type: PT_GNU_STACK
189# CHECK-NEXT: Offset: 0x0
190# CHECK-NEXT: VirtualAddress: 0x0
191# CHECK-NEXT: PhysicalAddress: 0x0
192# CHECK-NEXT: FileSize: 0
193# CHECK-NEXT: MemSize: 0
194# CHECK-NEXT: Flags [
195# CHECK-NEXT: PF_R
196# CHECK-NEXT: PF_W
197# CHECK-NEXT: ]
198# CHECK-NEXT: Alignment: 0
199# CHECK-NEXT: }
200# CHECK-NEXT: ]
deps/lld/test/ELF/basic.s created+252
......@@ -0,0 +1,252 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
4# RUN: ld.lld %t -o %t2
5# RUN: llvm-readobj -file-headers -sections -program-headers -symbols %t2 \
6# RUN: | FileCheck %s
7# RUN: ld.lld %t -o /dev/null
8
9# exits with return code 42 on linux
10.globl _start
11_start:
12 mov $60, %rax
13 mov $42, %rdi
14 syscall
15
16# CHECK: ElfHeader {
17# CHECK-NEXT: Ident {
18# CHECK-NEXT: Magic: (7F 45 4C 46)
19# CHECK-NEXT: Class: 64-bit (0x2)
20# CHECK-NEXT: DataEncoding: LittleEndian (0x1)
21# CHECK-NEXT: FileVersion: 1
22# CHECK-NEXT: OS/ABI: SystemV (0x0)
23# CHECK-NEXT: ABIVersion: 0
24# CHECK-NEXT: Unused: (00 00 00 00 00 00 00)
25# CHECK-NEXT: }
26# CHECK-NEXT: Type: Executable (0x2)
27# CHECK-NEXT: Machine: EM_X86_64 (0x3E)
28# CHECK-NEXT: Version: 1
29# CHECK-NEXT: Entry: [[ENTRY:0x[0-9A-F]+]]
30# CHECK-NEXT: ProgramHeaderOffset: 0x40
31# CHECK-NEXT: SectionHeaderOffset: 0x1080
32# CHECK-NEXT: Flags [ (0x0)
33# CHECK-NEXT: ]
34# CHECK-NEXT: HeaderSize: 64
35# CHECK-NEXT: ProgramHeaderEntrySize: 56
36# CHECK-NEXT: ProgramHeaderCount: 4
37# CHECK-NEXT: SectionHeaderEntrySize: 64
38# CHECK-NEXT: SectionHeaderCount: 6
39# CHECK-NEXT: StringTableSectionIndex: 4
40# CHECK-NEXT: }
41# CHECK-NEXT: Sections [
42# CHECK-NEXT: Section {
43# CHECK-NEXT: Index: 0
44# CHECK-NEXT: Name: (0)
45# CHECK-NEXT: Type: SHT_NULL (0x0)
46# CHECK-NEXT: Flags [ (0x0)
47# CHECK-NEXT: ]
48# CHECK-NEXT: Address: 0x0
49# CHECK-NEXT: Offset: 0x0
50# CHECK-NEXT: Size: 0
51# CHECK-NEXT: Link: 0
52# CHECK-NEXT: Info: 0
53# CHECK-NEXT: AddressAlignment: 0
54# CHECK-NEXT: EntrySize: 0
55# CHECK-NEXT: }
56# CHECK-NEXT: Section {
57# CHECK-NEXT: Index: 1
58# CHECK-NEXT: Name: .text
59# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
60# CHECK-NEXT: Flags [ (0x6)
61# CHECK-NEXT: SHF_ALLOC (0x2)
62# CHECK-NEXT: SHF_EXECINSTR (0x4)
63# CHECK-NEXT: ]
64# CHECK-NEXT: Address: 0x201000
65# CHECK-NEXT: Offset: 0x1000
66# CHECK-NEXT: Size: 16
67# CHECK-NEXT: Link: 0
68# CHECK-NEXT: Info: 0
69# CHECK-NEXT: AddressAlignment: 4
70# CHECK-NEXT: EntrySize: 0
71# CHECK-NEXT: }
72# CHECK-NEXT: Section {
73# CHECK-NEXT: Index: 2
74# CHECK-NEXT: Name: .comment
75# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
76# CHECK-NEXT: Flags [ (0x30)
77# CHECK-NEXT: SHF_MERGE (0x10)
78# CHECK-NEXT: SHF_STRINGS (0x20)
79# CHECK-NEXT: ]
80# CHECK-NEXT: Address: 0x0
81# CHECK-NEXT: Offset: 0x1010
82# CHECK-NEXT: Size: 8
83# CHECK-NEXT: Link: 0
84# CHECK-NEXT: Info: 0
85# CHECK-NEXT: AddressAlignment: 1
86# CHECK-NEXT: EntrySize: 0
87# CHECK-NEXT: }
88# CHECK-NEXT: Section {
89# CHECK-NEXT: Index: 3
90# CHECK-NEXT: Name: .symtab
91# CHECK-NEXT: Type: SHT_SYMTAB (0x2)
92# CHECK-NEXT: Flags [ (0x0)
93# CHECK-NEXT: ]
94# CHECK-NEXT: Address: 0x0
95# CHECK-NEXT: Offset: 0x1018
96# CHECK-NEXT: Size: 48
97# CHECK-NEXT: Link: 5
98# CHECK-NEXT: Info: 1
99# CHECK-NEXT: AddressAlignment: 8
100# CHECK-NEXT: EntrySize: 24
101# CHECK-NEXT: }
102# CHECK-NEXT: Section {
103# CHECK-NEXT: Index: 4
104# CHECK-NEXT: Name: .shstrtab
105# CHECK-NEXT: Type: SHT_STRTAB (0x3)
106# CHECK-NEXT: Flags [ (0x0)
107# CHECK-NEXT: ]
108# CHECK-NEXT: Address: 0x0
109# CHECK-NEXT: Offset: 0x1048
110# CHECK-NEXT: Size: 42
111# CHECK-NEXT: Link: 0
112# CHECK-NEXT: Info: 0
113# CHECK-NEXT: AddressAlignment: 1
114# CHECK-NEXT: EntrySize: 0
115# CHECK-NEXT: }
116# CHECK-NEXT: Section {
117# CHECK-NEXT: Index: 5
118# CHECK-NEXT: Name: .strtab
119# CHECK-NEXT: Type: SHT_STRTAB (0x3)
120# CHECK-NEXT: Flags [ (0x0)
121# CHECK-NEXT: ]
122# CHECK-NEXT: Address: 0x0
123# CHECK-NEXT: Offset: 0x1072
124# CHECK-NEXT: Size: 8
125# CHECK-NEXT: Link: 0
126# CHECK-NEXT: Info: 0
127# CHECK-NEXT: AddressAlignment: 1
128# CHECK-NEXT: EntrySize: 0
129# CHECK-NEXT: }
130# CHECK-NEXT: ]
131# CHECK-NEXT: Symbols [
132# CHECK-NEXT: Symbol {
133# CHECK-NEXT: Name: (0)
134# CHECK-NEXT: Value: 0x0
135# CHECK-NEXT: Size: 0
136# CHECK-NEXT: Binding: Local (0x0)
137# CHECK-NEXT: Type: None (0x0)
138# CHECK-NEXT: Other: 0
139# CHECK-NEXT: Section: Undefined (0x0)
140# CHECK-NEXT: }
141# CHECK-NEXT: Symbol {
142# CHECK-NEXT: Name: _start
143# CHECK-NEXT: Value: [[ENTRY]]
144# CHECK-NEXT: Size: 0
145# CHECK-NEXT: Binding: Global (0x1)
146# CHECK-NEXT: Type: None (0x0)
147# CHECK-NEXT: Other: 0
148# CHECK-NEXT: Section: .text
149# CHECK-NEXT: }
150# CHECK-NEXT: ]
151# CHECK-NEXT: ProgramHeaders [
152# CHECK-NEXT: ProgramHeader {
153# CHECK-NEXT: Type: PT_PHDR (0x6)
154# CHECK-NEXT: Offset: 0x40
155# CHECK-NEXT: VirtualAddress: 0x200040
156# CHECK-NEXT: PhysicalAddress: 0x200040
157# CHECK-NEXT: FileSize: 224
158# CHECK-NEXT: MemSize: 224
159# CHECK-NEXT: Flags [ (0x4)
160# CHECK-NEXT: PF_R (0x4)
161# CHECK-NEXT: ]
162# CHECK-NEXT: Alignment: 8
163# CHECK-NEXT: }
164# CHECK-NEXT: ProgramHeader {
165# CHECK-NEXT: Type: PT_LOAD (0x1)
166# CHECK-NEXT: Offset: 0x0
167# CHECK-NEXT: VirtualAddress: 0x200000
168# CHECK-NEXT: PhysicalAddress: 0x200000
169# CHECK-NEXT: FileSize: 288
170# CHECK-NEXT: MemSize: 288
171# CHECK-NEXT: Flags [
172# CHECK-NEXT: PF_R
173# CHECK-NEXT: ]
174# CHECK-NEXT: Alignment: 4096
175# CHECK-NEXT: }
176# CHECK-NEXT: ProgramHeader {
177# CHECK-NEXT: Type: PT_LOAD (0x1)
178# CHECK-NEXT: Offset: 0x1000
179# CHECK-NEXT: VirtualAddress: 0x201000
180# CHECK-NEXT: PhysicalAddress: 0x201000
181# CHECK-NEXT: FileSize: 16
182# CHECK-NEXT: MemSize: 16
183# CHECK-NEXT: Flags [ (0x5)
184# CHECK-NEXT: PF_R (0x4)
185# CHECK-NEXT: PF_X (0x1)
186# CHECK-NEXT: ]
187# CHECK-NEXT: Alignment: 4096
188# CHECK-NEXT: }
189# CHECK-NEXT: ProgramHeader {
190# CHECK-NEXT: Type: PT_GNU_STACK
191# CHECK-NEXT: Offset: 0x0
192# CHECK-NEXT: VirtualAddress: 0x0
193# CHECK-NEXT: PhysicalAddress: 0x0
194# CHECK-NEXT: FileSize: 0
195# CHECK-NEXT: MemSize: 0
196# CHECK-NEXT: Flags [
197# CHECK-NEXT: PF_R
198# CHECK-NEXT: PF_W
199# CHECK-NEXT: ]
200# CHECK-NEXT: Alignment: 0
201# CHECK-NEXT: }
202# CHECK-NEXT: ]
203
204# Test for the response file (POSIX quoting style)
205# RUN: echo " -o %t2" > %t.responsefile
206# RUN: ld.lld %t --rsp-quoting=posix @%t.responsefile
207# RUN: llvm-readobj -file-headers -sections -program-headers -symbols %t2 \
208# RUN: | FileCheck %s
209
210# Test for the response file (Windows quoting style)
211# RUN: echo " c:\blah\foo" > %t.responsefile
212# RUN: not ld.lld --rsp-quoting=windows %t @%t.responsefile 2>&1 | FileCheck \
213# RUN: %s --check-prefix=WINRSP
214# WINRSP: cannot open c:\blah\foo
215
216# Test for the response file (invalid quoting style)
217# RUN: not ld.lld --rsp-quoting=patatino %t 2>&1 | FileCheck %s \
218# RUN: --check-prefix=INVRSP
219# INVRSP: invalid response file quoting: patatino
220
221# RUN: not ld.lld %t.foo -o %t2 2>&1 | \
222# RUN: FileCheck --check-prefix=MISSING %s
223# MISSING: cannot open {{.*}}.foo: {{[Nn]}}o such file or directory
224
225# RUN: not ld.lld -o %t2 2>&1 | \
226# RUN: FileCheck --check-prefix=NO_INPUT %s
227# NO_INPUT: ld.lld{{.*}}: no input files
228
229# RUN: not ld.lld %t.no.such.file -o %t2 2>&1 | \
230# RUN: FileCheck --check-prefix=CANNOT_OPEN %s
231# CANNOT_OPEN: cannot open {{.*}}.no.such.file: {{[Nn]}}o such file or directory
232
233# RUN: not ld.lld %t -o 2>&1 | FileCheck --check-prefix=NO_O_VAL %s
234# NO_O_VAL: -o: missing argument
235
236# RUN: not ld.lld --foo 2>&1 | FileCheck --check-prefix=UNKNOWN %s
237# UNKNOWN: unknown argument: --foo
238
239# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
240# RUN: not ld.lld %t %t -o %t2 2>&1 | FileCheck --check-prefix=DUP %s
241# DUP: duplicate symbol: _start
242# DUP-NEXT: >>> defined at {{.*}}:(.text+0x0)
243# DUP-NEXT: >>> defined at {{.*}}:(.text+0x0)
244
245# RUN: not ld.lld %t -o %t -m wrong_emul_fbsd 2>&1 | FileCheck --check-prefix=UNKNOWN_EMUL %s
246# UNKNOWN_EMUL: unknown emulation: wrong_emul_fbsd
247
248# RUN: not ld.lld %t --lto-partitions=0 2>&1 | FileCheck --check-prefix=NOTHREADS %s
249# NOTHREADS: --lto-partitions: number of threads must be > 0
250
251# RUN: not ld.lld %t --thinlto-jobs=0 2>&1 | FileCheck --check-prefix=NOTHREADSTHIN %s
252# NOTHREADSTHIN: --thinlto-jobs: number of threads must be > 0
deps/lld/test/ELF/basic32.s created+179
......@@ -0,0 +1,179 @@
1# RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t
2# RUN: ld.lld %t -o %t2
3# RUN: llvm-readobj -file-headers -sections -program-headers %t2 | FileCheck %s
4# REQUIRES: x86
5
6# exits with return code 42 on linux
7.globl _start
8_start:
9 mov $1, %eax
10 mov $42, %ebx
11 int $0x80
12
13# CHECK: ElfHeader {
14# CHECK-NEXT: Ident {
15# CHECK-NEXT: Magic: (7F 45 4C 46)
16# CHECK-NEXT: Class: 32-bit (0x1)
17# CHECK-NEXT: DataEncoding: LittleEndian (0x1)
18# CHECK-NEXT: FileVersion: 1
19# CHECK-NEXT: OS/ABI: SystemV (0x0)
20# CHECK-NEXT: ABIVersion: 0
21# CHECK-NEXT: Unused: (00 00 00 00 00 00 00)
22# CHECK-NEXT: }
23# CHECK-NEXT: Type: Executable (0x2)
24# CHECK-NEXT: Machine: EM_386 (0x3)
25# CHECK-NEXT: Version: 1
26# CHECK-NEXT: Entry: 0x11000
27# CHECK-NEXT: ProgramHeaderOffset: 0x34
28# CHECK-NEXT: SectionHeaderOffset: 0x1068
29# CHECK-NEXT: Flags [ (0x0)
30# CHECK-NEXT: ]
31# CHECK-NEXT: HeaderSize: 52
32# CHECK-NEXT: ProgramHeaderEntrySize: 32
33# CHECK-NEXT: ProgramHeaderCount: 4
34# CHECK-NEXT: SectionHeaderEntrySize: 40
35# CHECK-NEXT: SectionHeaderCount: 6
36# CHECK-NEXT: StringTableSectionIndex: 4
37# CHECK-NEXT: }
38# CHECK-NEXT: Sections [
39# CHECK-NEXT: Section {
40# CHECK-NEXT: Index: 0
41# CHECK-NEXT: Name: (0)
42# CHECK-NEXT: Type: SHT_NULL (0x0)
43# CHECK-NEXT: Flags [ (0x0)
44# CHECK-NEXT: ]
45# CHECK-NEXT: Address: 0x0
46# CHECK-NEXT: Offset: 0x0
47# CHECK-NEXT: Size: 0
48# CHECK-NEXT: Link: 0
49# CHECK-NEXT: Info: 0
50# CHECK-NEXT: AddressAlignment: 0
51# CHECK-NEXT: EntrySize: 0
52# CHECK-NEXT: }
53# CHECK-NEXT: Section {
54# CHECK-NEXT: Index: 1
55# CHECK-NEXT: Name: .text
56# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
57# CHECK-NEXT: Flags [ (0x6)
58# CHECK-NEXT: SHF_ALLOC (0x2)
59# CHECK-NEXT: SHF_EXECINSTR (0x4)
60# CHECK-NEXT: ]
61# CHECK-NEXT: Address: 0x11000
62# CHECK-NEXT: Offset: 0x1000
63# CHECK-NEXT: Size: 12
64# CHECK-NEXT: Link: 0
65# CHECK-NEXT: Info: 0
66# CHECK-NEXT: AddressAlignment: 4
67# CHECK-NEXT: EntrySize: 0
68# CHECK-NEXT: }
69# CHECK-NEXT: Section {
70# CHECK-NEXT: Index: 2
71# CHECK-NEXT: Name: .comment
72# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
73# CHECK-NEXT: Flags [ (0x30)
74# CHECK-NEXT: SHF_MERGE (0x10)
75# CHECK-NEXT: SHF_STRINGS (0x20)
76# CHECK-NEXT: ]
77# CHECK-NEXT: Address: 0x0
78# CHECK-NEXT: Offset: 0x100C
79# CHECK-NEXT: Size: 8
80# CHECK-NEXT: Link: 0
81# CHECK-NEXT: Info: 0
82# CHECK-NEXT: AddressAlignment: 1
83# CHECK-NEXT: EntrySize: 0
84# CHECK-NEXT: }
85# CHECK-NEXT: Section {
86# CHECK-NEXT: Index: 3
87# CHECK-NEXT: Name: .symtab
88# CHECK-NEXT: Type: SHT_SYMTAB
89# CHECK-NEXT: Flags [
90# CHECK-NEXT: ]
91# CHECK-NEXT: Address: 0x0
92# CHECK-NEXT: Offset: 0x1014
93# CHECK-NEXT: Size: 32
94# CHECK-NEXT: Link: 5
95# CHECK-NEXT: Info: 1
96# CHECK-NEXT: AddressAlignment: 4
97# CHECK-NEXT: EntrySize: 16
98# CHECK-NEXT: }
99# CHECK-NEXT: Section {
100# CHECK-NEXT: Index: 4
101# CHECK-NEXT: Name: .shstrtab
102# CHECK-NEXT: Type: SHT_STRTAB (0x3)
103# CHECK-NEXT: Flags [ (0x0)
104# CHECK-NEXT: ]
105# CHECK-NEXT: Address: 0x0
106# CHECK-NEXT: Offset: 0x1034
107# CHECK-NEXT: Size: 42
108# CHECK-NEXT: Link: 0
109# CHECK-NEXT: Info: 0
110# CHECK-NEXT: AddressAlignment: 1
111# CHECK-NEXT: EntrySize: 0
112# CHECK-NEXT: }
113# CHECK-NEXT: Section {
114# CHECK-NEXT: Index: 5
115# CHECK-NEXT: Name: .strtab
116# CHECK-NEXT: Type: SHT_STRTAB (0x3)
117# CHECK-NEXT: Flags [ (0x0)
118# CHECK-NEXT: ]
119# CHECK-NEXT: Address: 0x0
120# CHECK-NEXT: Offset: 0x105E
121# CHECK-NEXT: Size: 8
122# CHECK-NEXT: Link: 0
123# CHECK-NEXT: Info: 0
124# CHECK-NEXT: AddressAlignment: 1
125# CHECK-NEXT: EntrySize: 0
126# CHECK-NEXT: }
127# CHECK-NEXT: ]
128# CHECK-NEXT: ProgramHeaders [
129# CHECK-NEXT: ProgramHeader {
130# CHECK-NEXT: Type: PT_PHDR (0x6)
131# CHECK-NEXT: Offset: 0x34
132# CHECK-NEXT: VirtualAddress: 0x10034
133# CHECK-NEXT: PhysicalAddress: 0x10034
134# CHECK-NEXT: FileSize: 128
135# CHECK-NEXT: MemSize: 128
136# CHECK-NEXT: Flags [ (0x4)
137# CHECK-NEXT: PF_R (0x4)
138# CHECK-NEXT: ]
139# CHECK-NEXT: Alignment: 4
140# CHECK-NEXT: }
141# CHECK-NEXT: ProgramHeader {
142# CHECK-NEXT: Type: PT_LOAD (0x1)
143# CHECK-NEXT: Offset: 0x0
144# CHECK-NEXT: VirtualAddress: 0x10000
145# CHECK-NEXT: PhysicalAddress: 0x10000
146# CHECK-NEXT: FileSize: 180
147# CHECK-NEXT: MemSize: 180
148# CHECK-NEXT: Flags [
149# CHECK-NEXT: PF_R
150# CHECK-NEXT: ]
151# CHECK-NEXT: Alignment: 4096
152# CHECK-NEXT: }
153# CHECK-NEXT: ProgramHeader {
154# CHECK-NEXT: Type: PT_LOAD (0x1)
155# CHECK-NEXT: Offset: 0x1000
156# CHECK-NEXT: VirtualAddress: 0x11000
157# CHECK-NEXT: PhysicalAddress: 0x11000
158# CHECK-NEXT: FileSize: 12
159# CHECK-NEXT: MemSize: 12
160# CHECK-NEXT: Flags [ (0x5)
161# CHECK-NEXT: PF_R (0x4)
162# CHECK-NEXT: PF_X (0x1)
163# CHECK-NEXT: ]
164# CHECK-NEXT: Alignment: 4096
165# CHECK-NEXT: }
166# CHECK-NEXT: ProgramHeader {
167# CHECK-NEXT: Type: PT_GNU_STACK
168# CHECK-NEXT: Offset: 0x0
169# CHECK-NEXT: VirtualAddress: 0x0
170# CHECK-NEXT: PhysicalAddress: 0x0
171# CHECK-NEXT: FileSize: 0
172# CHECK-NEXT: MemSize: 0
173# CHECK-NEXT: Flags [
174# CHECK-NEXT: PF_R
175# CHECK-NEXT: PF_W
176# CHECK-NEXT: ]
177# CHECK-NEXT: Alignment: 0
178# CHECK-NEXT: }
179# CHECK-NEXT: ]
deps/lld/test/ELF/basic64be.s created+309
......@@ -0,0 +1,309 @@
1# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t
2# RUN: ld.lld -discard-all %t -o %t2
3# RUN: llvm-readobj -file-headers -sections -section-data -program-headers %t2 | FileCheck %s
4# REQUIRES: ppc
5
6# exits with return code 42 on linux
7.section ".opd","aw"
8.global _start
9_start:
10.quad .Lfoo,.TOC.@tocbase,0
11
12# generate .toc and .toc1 sections to make sure that the ordering is as
13# intended (.toc before .toc1, and both before .opd).
14.section ".toc1","aw"
15.quad 22, 37, 89, 47
16
17.section ".toc","aw"
18.quad 45, 86, 72, 24
19
20.text
21.Lfoo:
22 li 0,1
23 li 3,42
24 sc
25
26# CHECK: ElfHeader {
27# CHECK-NEXT: Ident {
28# CHECK-NEXT: Magic: (7F 45 4C 46)
29# CHECK-NEXT: Class: 64-bit (0x2)
30# CHECK-NEXT: DataEncoding: BigEndian (0x2)
31# CHECK-NEXT: FileVersion: 1
32# CHECK-NEXT: OS/ABI: SystemV (0x0)
33# CHECK-NEXT: ABIVersion: 0
34# CHECK-NEXT: Unused: (00 00 00 00 00 00 00)
35# CHECK-NEXT: }
36# CHECK-NEXT: Type: Executable (0x2)
37# CHECK-NEXT: Machine: EM_PPC64 (0x15)
38# CHECK-NEXT: Version: 1
39# CHECK-NEXT: Entry: 0x10020040
40# CHECK-NEXT: ProgramHeaderOffset: 0x40
41# CHECK-NEXT: SectionHeaderOffset: 0x30080
42# CHECK-NEXT: Flags [ (0x0)
43# CHECK-NEXT: ]
44# CHECK-NEXT: HeaderSize: 64
45# CHECK-NEXT: ProgramHeaderEntrySize: 56
46# CHECK-NEXT: ProgramHeaderCount: 6
47# CHECK-NEXT: SectionHeaderEntrySize: 64
48# CHECK-NEXT: SectionHeaderCount: 10
49# CHECK-NEXT: StringTableSectionIndex: 8
50# CHECK-NEXT: }
51# CHECK-NEXT: Sections [
52# CHECK-NEXT: Section {
53# CHECK-NEXT: Index: 0
54# CHECK-NEXT: Name: (0)
55# CHECK-NEXT: Type: SHT_NULL (0x0)
56# CHECK-NEXT: Flags [ (0x0)
57# CHECK-NEXT: ]
58# CHECK-NEXT: Address: 0x0
59# CHECK-NEXT: Offset: 0x0
60# CHECK-NEXT: Size: 0
61# CHECK-NEXT: Link: 0
62# CHECK-NEXT: Info: 0
63# CHECK-NEXT: AddressAlignment: 0
64# CHECK-NEXT: EntrySize: 0
65# CHECK-NEXT: SectionData (
66# CHECK-NEXT: )
67# CHECK-NEXT: }
68# CHECK-NEXT: Section {
69# CHECK-NEXT: Index: 1
70# CHECK-NEXT: Name: .text
71# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
72# CHECK-NEXT: Flags [ (0x6)
73# CHECK-NEXT: SHF_ALLOC (0x2)
74# CHECK-NEXT: SHF_EXECINSTR (0x4)
75# CHECK-NEXT: ]
76# CHECK-NEXT: Address: 0x10010000
77# CHECK-NEXT: Offset: 0x10000
78# CHECK-NEXT: Size: 12
79# CHECK-NEXT: Link: 0
80# CHECK-NEXT: Info: 0
81# CHECK-NEXT: AddressAlignment: 4
82# CHECK-NEXT: EntrySize: 0
83# CHECK-NEXT: SectionData (
84# CHECK: )
85# CHECK-NEXT: }
86# CHECK-NEXT: Section {
87# CHECK-NEXT: Index: 2
88# CHECK-NEXT: Name: .toc
89# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
90# CHECK-NEXT: Flags [ (0x3)
91# CHECK-NEXT: SHF_ALLOC (0x2)
92# CHECK-NEXT: SHF_WRITE (0x1)
93# CHECK-NEXT: ]
94# CHECK-NEXT: Address: 0x10020000
95# CHECK-NEXT: Offset: 0x20000
96# CHECK-NEXT: Size: 32
97# CHECK-NEXT: Link: 0
98# CHECK-NEXT: Info: 0
99# CHECK-NEXT: AddressAlignment: 1
100# CHECK-NEXT: EntrySize: 0
101# CHECK-NEXT: SectionData (
102# CHECK-NEXT: 0000: 00000000 0000002D 00000000 00000056 |.......-.......V|
103# CHECK-NEXT: 0010: 00000000 00000048 00000000 00000018 |.......H........|
104# CHECK-NEXT: )
105# CHECK-NEXT: }
106# CHECK-NEXT: Section {
107# CHECK-NEXT: Index: 3
108# CHECK-NEXT: Name: .toc1
109# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
110# CHECK-NEXT: Flags [ (0x3)
111# CHECK-NEXT: SHF_ALLOC (0x2)
112# CHECK-NEXT: SHF_WRITE (0x1)
113# CHECK-NEXT: ]
114# CHECK-NEXT: Address: 0x10020020
115# CHECK-NEXT: Offset: 0x20020
116# CHECK-NEXT: Size: 32
117# CHECK-NEXT: Link: 0
118# CHECK-NEXT: Info: 0
119# CHECK-NEXT: AddressAlignment: 1
120# CHECK-NEXT: EntrySize: 0
121# CHECK-NEXT: SectionData (
122# CHECK-NEXT: 0000: 00000000 00000016 00000000 00000025 |...............%|
123# CHECK-NEXT: 0010: 00000000 00000059 00000000 0000002F |.......Y......./|
124# CHECK-NEXT: )
125# CHECK-NEXT: }
126# CHECK-NEXT: Section {
127# CHECK-NEXT: Index: 4
128# CHECK-NEXT: Name: .opd
129# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
130# CHECK-NEXT: Flags [ (0x3)
131# CHECK-NEXT: SHF_ALLOC (0x2)
132# CHECK-NEXT: SHF_WRITE (0x1)
133# CHECK-NEXT: ]
134# CHECK-NEXT: Address: 0x10020040
135# CHECK-NEXT: Offset: 0x20040
136# CHECK-NEXT: Size: 24
137# CHECK-NEXT: Link: 0
138# CHECK-NEXT: Info: 0
139# CHECK-NEXT: AddressAlignment: 1
140# CHECK-NEXT: EntrySize: 0
141# CHECK-NEXT: SectionData (
142# CHECK-NEXT: 0000: 00000000 10010000 00000000 10038000 |................|
143# CHECK-NEXT: 0010: 00000000 00000000 |........|
144# CHECK-NEXT: )
145# CHECK-NEXT: }
146# CHECK-NEXT: Section {
147# CHECK-NEXT: Index: 5
148# CHECK-NEXT: Name: .got
149# CHECK-NEXT: Type: SHT_PROGBITS
150# CHECK-NEXT: Flags [
151# CHECK-NEXT: SHF_ALLOC
152# CHECK-NEXT: SHF_WRITE
153# CHECK-NEXT: ]
154# CHECK-NEXT: Address: 0x10030000
155# CHECK-NEXT: Offset: 0x30000
156# CHECK-NEXT: Size: 0
157# CHECK-NEXT: Link: 0
158# CHECK-NEXT: Info: 0
159# CHECK-NEXT: AddressAlignment: 8
160# CHECK-NEXT: EntrySize: 0
161# CHECK-NEXT: SectionData (
162# CHECK-NEXT: )
163# CHECK-NEXT: }
164# CHECK-NEXT: Section {
165# CHECK-NEXT: Index: 6
166# CHECK-NEXT: Name: .comment
167# CHECK-NEXT: Type: SHT_PROGBITS (0x1)
168# CHECK-NEXT: Flags [ (0x30)
169# CHECK-NEXT: SHF_MERGE (0x10)
170# CHECK-NEXT: SHF_STRINGS (0x20)
171# CHECK-NEXT: ]
172# CHECK-NEXT: Address: 0x0
173# CHECK-NEXT: Offset: 0x30000
174# CHECK-NEXT: Size: 8
175# CHECK-NEXT: Link: 0
176# CHECK-NEXT: Info: 0
177# CHECK-NEXT: AddressAlignment: 1
178# CHECK-NEXT: EntrySize: 0
179# CHECK-NEXT: SectionData (
180# CHECK-NEXT: 0000: 4C4C4420 312E3000 |LLD 1.0.|
181# CHECK-NEXT: )
182# CHECK-NEXT: }
183# CHECK-NEXT: Section {
184# CHECK-NEXT: Index: 7
185# CHECK-NEXT: Name: .symtab
186# CHECK-NEXT: Type: SHT_SYMTAB (0x2)
187# CHECK-NEXT: Flags [ (0x0)
188# CHECK-NEXT: ]
189# CHECK-NEXT: Address: 0x0
190# CHECK-NEXT: Offset: 0x30008
191# CHECK-NEXT: Size: 48
192# CHECK-NEXT: Link: 9
193# CHECK-NEXT: Info: 1
194# CHECK-NEXT: AddressAlignment: 8
195# CHECK-NEXT: EntrySize: 24
196# CHECK-NEXT: SectionData (
197# CHECK: )
198# CHECK-NEXT: }
199# CHECK-NEXT: Section {
200# CHECK-NEXT: Index: 8
201# CHECK-NEXT: Name: .shstrtab
202# CHECK-NEXT: Type: SHT_STRTAB
203# CHECK-NEXT: Flags [
204# CHECK-NEXT: ]
205# CHECK-NEXT: Address: 0x0
206# CHECK-NEXT: Offset: 0x30038
207# CHECK-NEXT: Size: 63
208# CHECK-NEXT: Link: 0
209# CHECK-NEXT: Info: 0
210# CHECK-NEXT: AddressAlignment: 1
211# CHECK-NEXT: EntrySize: 0
212# CHECK-NEXT: SectionData (
213# CHECK: )
214# CHECK-NEXT: }
215# CHECK-NEXT: Section {
216# CHECK-NEXT: Index: 9
217# CHECK-NEXT: Name: .strtab
218# CHECK-NEXT: Type: SHT_STRTAB
219# CHECK-NEXT: Flags [ (0x0)
220# CHECK-NEXT: ]
221# CHECK-NEXT: Address: 0x0
222# CHECK-NEXT: Offset: 0x30077
223# CHECK-NEXT: Size: 8
224# CHECK-NEXT: Link: 0
225# CHECK-NEXT: Info: 0
226# CHECK-NEXT: AddressAlignment: 1
227# CHECK-NEXT: EntrySize: 0
228# CHECK-NEXT: SectionData (
229# CHECK-NEXT: 0000: 005F7374 61727400 |._start.|
230# CHECK-NEXT: )
231# CHECK-NEXT: }
232# CHECK-NEXT: ]
233# CHECK-NEXT: ProgramHeaders [
234# CHECK-NEXT: ProgramHeader {
235# CHECK-NEXT: Type: PT_PHDR (0x6)
236# CHECK-NEXT: Offset: 0x40
237# CHECK-NEXT: VirtualAddress: 0x10000040
238# CHECK-NEXT: PhysicalAddress: 0x10000040
239# CHECK-NEXT: FileSize: 336
240# CHECK-NEXT: MemSize: 336
241# CHECK-NEXT: Flags [
242# CHECK-NEXT: PF_R
243# CHECK-NEXT: ]
244# CHECK-NEXT: Alignment: 8
245# CHECK-NEXT: }
246# CHECK-NEXT: ProgramHeader {
247# CHECK-NEXT: Type: PT_LOAD (0x1)
248# CHECK-NEXT: Offset: 0x0
249# CHECK-NEXT: VirtualAddress: 0x10000000
250# CHECK-NEXT: PhysicalAddress: 0x10000000
251# CHECK-NEXT: FileSize: 400
252# CHECK-NEXT: MemSize: 400
253# CHECK-NEXT: Flags [
254# CHECK-NEXT: PF_R
255# CHECK-NEXT: ]
256# CHECK-NEXT: Alignment: 65536
257# CHECK-NEXT: }
258# CHECK-NEXT: ProgramHeader {
259# CHECK-NEXT: Type: PT_LOAD (0x1)
260# CHECK-NEXT: Offset: 0x10000
261# CHECK-NEXT: VirtualAddress: 0x10010000
262# CHECK-NEXT: PhysicalAddress: 0x10010000
263# CHECK-NEXT: FileSize: 12
264# CHECK-NEXT: MemSize: 12
265# CHECK-NEXT: Flags [ (0x5)
266# CHECK-NEXT: PF_R (0x4)
267# CHECK-NEXT: PF_X (0x1)
268# CHECK-NEXT: ]
269# CHECK-NEXT: Alignment: 65536
270# CHECK-NEXT: }
271# CHECK-NEXT: ProgramHeader {
272# CHECK-NEXT: Type: PT_LOAD (0x1)
273# CHECK-NEXT: Offset: 0x20000
274# CHECK-NEXT: VirtualAddress: 0x10020000
275# CHECK-NEXT: PhysicalAddress: 0x10020000
276# CHECK-NEXT: FileSize: 65536
277# CHECK-NEXT: MemSize: 65536
278# CHECK-NEXT: Flags [ (0x6)
279# CHECK-NEXT: PF_R (0x4)
280# CHECK-NEXT: PF_W (0x2)
281# CHECK-NEXT: ]
282# CHECK-NEXT: Alignment: 65536
283# CHECK-NEXT: }
284# CHECK-NEXT: ProgramHeader {
285# CHECK-NEXT: Type: PT_GNU_RELRO
286# CHECK-NEXT: Offset: 0x30000
287# CHECK-NEXT: VirtualAddress: 0x10030000
288# CHECK-NEXT: PhysicalAddress: 0x10030000
289# CHECK-NEXT: FileSize: 0
290# CHECK-NEXT: MemSize: 0
291# CHECK-NEXT: Flags [ (0x4)
292# CHECK-NEXT: PF_R (0x4)
293# CHECK-NEXT: ]
294# CHECK-NEXT: Alignment: 1
295# CHECK-NEXT: }
296# CHECK-NEXT: ProgramHeader {
297# CHECK-NEXT: Type: PT_GNU_STACK (0x6474E551)
298# CHECK-NEXT: Offset: 0x0
299# CHECK-NEXT: VirtualAddress: 0x0
300# CHECK-NEXT: PhysicalAddress: 0x0
301# CHECK-NEXT: FileSize: 0
302# CHECK-NEXT: MemSize: 0
303# CHECK-NEXT: Flags [ (0x6)
304# CHECK-NEXT: PF_R (0x4)
305# CHECK-NEXT: PF_W (0x2)
306# CHECK-NEXT: ]
307# CHECK-NEXT: Alignment: 0
308# CHECK-NEXT: }
309# CHECK-NEXT: ]
deps/lld/test/ELF/bss-start-common.s created+15
......@@ -0,0 +1,15 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: ld.lld %t -o %t2
4# RUN: llvm-objdump -t -section-headers %t2 | FileCheck %s
5
6# CHECK: Sections:
7# CHECK: Idx Name Size Address Type
8# CHECK: 2 .bss 00000004 0000000000201000 BSS
9# CHECK: SYMBOL TABLE:
10# CHECK: 0000000000201000 .bss 00000000 __bss_start
11
12.global __bss_start
13.text
14_start:
15.comm sym1,4,4
deps/lld/test/ELF/bss.s created+37
......@@ -0,0 +1,37 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
2// RUN: ld.lld %t -o %t2
3// RUN: llvm-readobj -sections %t2 | FileCheck %s
4// REQUIRES: x86
5
6// Test that bss takes no space on disk.
7
8// CHECK: Name: .bss
9// CHECK-NEXT: Type: SHT_NOBITS
10// CHECK-NEXT: Flags [
11// CHECK-NEXT: SHF_ALLOC
12// CHECK-NEXT: SHF_WRITE
13// CHECK-NEXT: ]
14// CHECK-NEXT: Address:
15// CHECK-NEXT: Offset: 0x[[OFFSET:.*]]
16// CHECK-NEXT: Size: 4
17// CHECK-NEXT: Link: 0
18// CHECK-NEXT: Info: 0
19// CHECK-NEXT: AddressAlignment:
20// CHECK-NEXT: EntrySize: 0
21// CHECK-NEXT: }
22// CHECK-NEXT: Section {
23// CHECK-NEXT: Index:
24// CHECK-NEXT: Name:
25// CHECK-NEXT: Type:
26// CHECK-NEXT: Flags [
27// CHECK-NEXT: SHF_MERGE
28// CHECK-NEXT: SHF_STRINGS
29// CHECK-NEXT: ]
30// CHECK-NEXT: Address:
31// CHECK-NEXT: Offset: 0x[[OFFSET]]
32
33 .global _start
34_start:
35
36 .bss
37 .zero 4
deps/lld/test/ELF/bsymbolic-undef.s created+26
......@@ -0,0 +1,26 @@
1# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
2# RUN: ld.lld -shared -Bsymbolic %t.o -o %t.so
3# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s
4
5# CHECK: DynamicSymbols [
6# CHECK-NEXT: Symbol {
7# CHECK-NEXT: Name: @
8# CHECK-NEXT: Value: 0x0
9# CHECK-NEXT: Size: 0
10# CHECK-NEXT: Binding: Local (0x0)
11# CHECK-NEXT: Type: None (0x0)
12# CHECK-NEXT: Other: 0
13# CHECK-NEXT: Section: Undefined (0x0)
14# CHECK-NEXT: }
15# CHECK-NEXT: Symbol {
16# CHECK-NEXT: Name: undef@
17# CHECK-NEXT: Value: 0x0
18# CHECK-NEXT: Size: 0
19# CHECK-NEXT: Binding: Global (0x1)
20# CHECK-NEXT: Type: None (0x0)
21# CHECK-NEXT: Other: 0
22# CHECK-NEXT: Section: Undefined (0x0)
23# CHECK-NEXT: }
24# CHECK-NEXT: ]
25
26call undef@PLT
deps/lld/test/ELF/bsymbolic.s created+34
......@@ -0,0 +1,34 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
2// RUN: ld.lld -shared %t.o -o %t0.so
3// RUN: ld.lld -shared -Bsymbolic %t.o -o %t1.so
4// RUN: ld.lld -shared -Bsymbolic-functions %t.o -o %t2.so
5// RUN: llvm-readobj -s %t0.so | FileCheck -check-prefix=NOOPTION %s
6// RUN: llvm-readobj -s %t1.so | FileCheck -check-prefix=SYMBOLIC %s
7// RUN: llvm-readobj -s %t2.so | FileCheck -check-prefix=SYMBOLIC %s
8
9// NOOPTION: Section {
10// NOOPTION: Name: .plt
11
12// SYMBOLIC: Section {
13// SYMBOLIC-NOT: Name: .plt
14
15.text
16.globl foo
17.type foo,@function
18foo:
19nop
20
21.globl bar
22.type bar,@function
23bar:
24nop
25
26.globl do
27.type do,@function
28do:
29callq foo@PLT
30callq bar@PLT
31
32.weak zed
33.protected zed
34.quad zed
deps/lld/test/ELF/build-id.s created+68
......@@ -0,0 +1,68 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
4
5# RUN: ld.lld --build-id %t -o %t2 -threads
6# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=DEFAULT %s
7# RUN: ld.lld --build-id %t -o %t2 -no-threads
8# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=DEFAULT %s
9
10# RUN: ld.lld --build-id=md5 %t -o %t2 -threads
11# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=MD5 %s
12# RUN: ld.lld --build-id=md5 %t -o %t2 -no-threads
13# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=MD5 %s
14
15# RUN: ld.lld --build-id=sha1 %t -o %t2 -threads
16# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=SHA1 %s
17# RUN: ld.lld --build-id=sha1 %t -o %t2 -no-threads
18# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=SHA1 %s
19
20# RUN: ld.lld --build-id=tree %t -o %t2 -threads
21# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=SHA1 %s
22# RUN: ld.lld --build-id=tree %t -o %t2 -no-threads
23# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=SHA1 %s
24
25# RUN: ld.lld --build-id=uuid %t -o %t2
26# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=UUID %s
27
28# RUN: ld.lld --build-id=0x12345678 %t -o %t2
29# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=HEX %s
30
31# RUN: ld.lld %t -o %t2
32# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=NONE %s
33
34# RUN: ld.lld --build-id=md5 --build-id=none %t -o %t2
35# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=NONE %s
36# RUN: ld.lld --build-id --build-id=none %t -o %t2
37# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=NONE %s
38# RUN: ld.lld --build-id=none --build-id %t -o %t2
39# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=DEFAULT %s
40
41.globl _start
42_start:
43 nop
44
45.section .note.test, "a", @note
46 .quad 42
47
48# DEFAULT: Contents of section .note.test:
49# DEFAULT: Contents of section .note.gnu.build-id:
50# DEFAULT-NEXT: 04000000 08000000 03000000 474e5500 ............GNU.
51# DEFAULT-NEXT: fd36edb1 f6ff02af
52
53# MD5: Contents of section .note.gnu.build-id:
54# MD5-NEXT: 04000000 10000000 03000000 474e5500 ............GNU.
55# MD5-NEXT: fc
56
57# SHA1: Contents of section .note.gnu.build-id:
58# SHA1-NEXT: 04000000 14000000 03000000 474e5500 ............GNU.
59# SHA1-NEXT: 55b1eedb 03b588e1 09987d1d e9a79be7
60
61# UUID: Contents of section .note.gnu.build-id:
62# UUID-NEXT: 04000000 10000000 03000000 474e5500 ............GNU.
63
64# HEX: Contents of section .note.gnu.build-id:
65# HEX-NEXT: 04000000 04000000 03000000 474e5500 ............GNU.
66# HEX-NEXT: 12345678
67
68# NONE-NOT: Contents of section .note.gnu.build-id:
deps/lld/test/ELF/color-diagnostics.test created+18
......@@ -0,0 +1,18 @@
1# Windows command prompt doesn't support ANSI escape sequences.
2# REQUIRES: shell
3
4# RUN: not ld.lld -xyz -color-diagnostics /nosuchfile 2>&1 \
5# RUN: | FileCheck -check-prefix=COLOR %s
6# RUN: not ld.lld -xyz -color-diagnostics=always /nosuchfile 2>&1 \
7# RUN: | FileCheck -check-prefix=COLOR %s
8
9# COLOR: {{ld.lld: .\[0;1;31merror: .\[0munknown argument: -xyz}}
10# COLOR: {{ld.lld: .\[0;1;31merror: .\[0mcannot open /nosuchfile}}
11
12# RUN: not ld.lld /nosuchfile 2>&1 | FileCheck -check-prefix=NOCOLOR %s
13# RUN: not ld.lld -color-diagnostics=never /nosuchfile 2>&1 \
14# RUN: | FileCheck -check-prefix=NOCOLOR %s
15# RUN: not ld.lld -color-diagnostics=always -no-color-diagnostics \
16# RUN: /nosuchfile 2>&1 | FileCheck -check-prefix=NOCOLOR %s
17
18# NOCOLOR: ld.lld: error: cannot open /nosuchfile
deps/lld/test/ELF/combrelocs.s created+92
......@@ -0,0 +1,92 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
4# RUN: ld.lld -shared %t.o -o %t.out
5# RUN: llvm-readobj -r --expand-relocs --dynamic-table %t.out | FileCheck %s
6
7# CHECK: Relocations [
8# CHECK-NEXT: Section ({{.*}}) .rela.dyn {
9# CHECK-NEXT: Relocation {
10# CHECK-NEXT: Offset: 0x1000
11# CHECK-NEXT: Type: R_X86_64_64
12# CHECK-NEXT: Symbol: aaa (1)
13# CHECK-NEXT: Addend: 0x0
14# CHECK-NEXT: }
15# CHECK-NEXT: Relocation {
16# CHECK-NEXT: Offset: 0x1018
17# CHECK-NEXT: Type: R_X86_64_64
18# CHECK-NEXT: Symbol: aaa (1)
19# CHECK-NEXT: Addend: 0x0
20# CHECK-NEXT: }
21# CHECK-NEXT: Relocation {
22# CHECK-NEXT: Offset: 0x1010
23# CHECK-NEXT: Type: R_X86_64_64
24# CHECK-NEXT: Symbol: bbb (2)
25# CHECK-NEXT: Addend: 0x0
26# CHECK-NEXT: }
27# CHECK-NEXT: Relocation {
28# CHECK-NEXT: Offset: 0x1008
29# CHECK-NEXT: Type: R_X86_64_64
30# CHECK-NEXT: Symbol: ccc (3)
31# CHECK-NEXT: Addend: 0x0
32# CHECK-NEXT: }
33# CHECK-NEXT: Relocation {
34# CHECK-NEXT: Offset: 0x1020
35# CHECK-NEXT: Type: R_X86_64_64
36# CHECK-NEXT: Symbol: ddd (4)
37# CHECK-NEXT: Addend: 0x0
38# CHECK-NEXT: }
39# CHECK-NEXT: }
40# CHECK-NEXT: ]
41# CHECK: DynamicSection [
42# CHECK-NEXT: Tag
43# CHECK-NOT: RELACOUNT
44
45# RUN: ld.lld -z nocombreloc -shared %t.o -o %t.out
46# RUN: llvm-readobj -r --expand-relocs --dynamic-table %t.out | \
47# RUN: FileCheck --check-prefix=NOCOMB %s
48
49# NOCOMB: Relocations [
50# NOCOMB-NEXT: Section ({{.*}}) .rela.dyn {
51# NOCOMB-NEXT: Relocation {
52# NOCOMB-NEXT: Offset: 0x1000
53# NOCOMB-NEXT: Type: R_X86_64_64
54# NOCOMB-NEXT: Symbol: aaa (1)
55# NOCOMB-NEXT: Addend: 0x0
56# NOCOMB-NEXT: }
57# NOCOMB-NEXT: Relocation {
58# NOCOMB-NEXT: Offset: 0x1008
59# NOCOMB-NEXT: Type: R_X86_64_64
60# NOCOMB-NEXT: Symbol: ccc (3)
61# NOCOMB-NEXT: Addend: 0x0
62# NOCOMB-NEXT: }
63# NOCOMB-NEXT: Relocation {
64# NOCOMB-NEXT: Offset: 0x1010
65# NOCOMB-NEXT: Type: R_X86_64_64
66# NOCOMB-NEXT: Symbol: bbb (2)
67# NOCOMB-NEXT: Addend: 0x0
68# NOCOMB-NEXT: }
69# NOCOMB-NEXT: Relocation {
70# NOCOMB-NEXT: Offset: 0x1018
71# NOCOMB-NEXT: Type: R_X86_64_64
72# NOCOMB-NEXT: Symbol: aaa (1)
73# NOCOMB-NEXT: Addend: 0x0
74# NOCOMB-NEXT: }
75# NOCOMB-NEXT: Relocation {
76# NOCOMB-NEXT: Offset: 0x1020
77# NOCOMB-NEXT: Type: R_X86_64_64
78# NOCOMB-NEXT: Symbol: ddd (4)
79# NOCOMB-NEXT: Addend: 0x0
80# NOCOMB-NEXT: }
81# NOCOMB-NEXT: }
82# NOCOMB-NEXT: ]
83# NOCOMB: DynamicSection [
84# NOCOMB-NEXT: Tag
85# NOCOMB-NOT: RELACOUNT
86
87.data
88 .quad aaa
89 .quad ccc
90 .quad bbb
91 .quad aaa
92 .quad ddd
deps/lld/test/ELF/comdat-linkonce.s created+9
......@@ -0,0 +1,9 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/comdat.s -o %t2.o
3// RUN: ld.lld -shared %t.o %t2.o -o %t
4// RUN: ld.lld -shared %t2.o %t.o -o %t
5
6.section .gnu.linkonce.t.zed
7.globl abc
8abc:
9nop
deps/lld/test/ELF/comdat.s created+92
......@@ -0,0 +1,92 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/comdat.s -o %t2.o
3// RUN: ld.lld -shared %t.o %t.o %t2.o -o %t
4// RUN: llvm-objdump -d %t | FileCheck %s
5// RUN: llvm-readobj -s -t %t | FileCheck --check-prefix=READ %s
6// REQUIRES: x86
7
8// Check that we don't crash with --gc-section and that we print a list of
9// reclaimed sections on stderr.
10// RUN: ld.lld --gc-sections --print-gc-sections -shared %t.o %t.o %t2.o -o %t \
11// RUN: 2>&1 | FileCheck --check-prefix=GC %s
12// GC: removing unused section from '.text' in file
13// GC: removing unused section from '.text3' in file
14// GC: removing unused section from '.text' in file
15// GC: removing unused section from '.text' in file
16
17 .section .text2,"axG",@progbits,foo,comdat,unique,0
18foo:
19 nop
20
21// CHECK: Disassembly of section .text2:
22// CHECK-NEXT: foo:
23// CHECK-NEXT: 1000: {{.*}} nop
24// CHECK-NOT: nop
25
26 .section bar, "ax"
27 call foo
28
29// CHECK: Disassembly of section bar:
30// CHECK-NEXT: bar:
31// 0x1000 - 0x1001 - 5 = -6
32// 0 - 0x1006 - 5 = -4107
33// CHECK-NEXT: 1001: {{.*}} callq -6
34// CHECK-NEXT: 1006: {{.*}} callq -4107
35
36 .section .text3,"axG",@progbits,zed,comdat,unique,0
37
38
39// READ: Name: .text2
40// READ-NEXT: Type: SHT_PROGBITS
41// READ-NEXT: Flags [
42// READ-NEXT: SHF_ALLOC
43// READ-NEXT: SHF_EXECINSTR
44// READ-NEXT: ]
45
46// READ: Name: .text3
47// READ-NEXT: Type: SHT_PROGBITS
48// READ-NEXT: Flags [
49// READ-NEXT: SHF_ALLOC
50// READ-NEXT: SHF_EXECINSTR
51// READ-NEXT: ]
52
53// READ: Symbols [
54// READ-NEXT: Symbol {
55// READ-NEXT: Name: (0)
56// READ-NEXT: Value: 0x0
57// READ-NEXT: Size: 0
58// READ-NEXT: Binding: Local
59// READ-NEXT: Type: None
60// READ-NEXT: Other: 0
61// READ-NEXT: Section: Undefined
62// READ-NEXT: }
63// READ-NEXT: Symbol {
64// READ-NEXT: Name: foo
65// READ-NEXT: Value
66// READ-NEXT: Size: 0
67// READ-NEXT: Binding: Local
68// READ-NEXT: Type: None
69// READ-NEXT: Other: 0
70// READ-NEXT: Section: .text
71// READ-NEXT: }
72// READ-NEXT: Symbol {
73// READ-NEXT: Name: _DYNAMIC
74// READ-NEXT: Value: 0x2000
75// READ-NEXT: Size: 0
76// READ-NEXT: Binding: Local
77// READ-NEXT: Type: None
78// READ-NEXT: Other [ (0x2)
79// READ-NEXT: STV_HIDDEN
80// READ-NEXT: ]
81// READ-NEXT: Section: .dynamic
82// READ-NEXT: }
83// READ-NEXT: Symbol {
84// READ-NEXT: Name: abc
85// READ-NEXT: Value: 0x0
86// READ-NEXT: Size: 0
87// READ-NEXT: Binding: Global
88// READ-NEXT: Type: None
89// READ-NEXT: Other: 0
90// READ-NEXT: Section: Undefined
91// READ-NEXT: }
92// READ-NEXT: ]
deps/lld/test/ELF/comment-gc.s created+15
......@@ -0,0 +1,15 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/comment-gc.s -o %t2.o
4# RUN: ld.lld %t.o %t2.o -o %t1 --gc-sections -shared
5# RUN: llvm-objdump -s %t1 | FileCheck %s
6
7# CHECK: Contents of section .comment:
8# CHECK-NEXT: 0000 00666f6f 00626172 004c4c44 20312e30 .foo.bar.LLD 1.0
9# CHECK-NEXT: 0010 00 .
10
11.ident "foo"
12
13.globl _start
14_start:
15 nop
deps/lld/test/ELF/common.s created+59
......@@ -0,0 +1,59 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/common.s -o %t2
3// RUN: ld.lld %t %t2 -o %t3
4// RUN: llvm-readobj -t -s %t3 | FileCheck %s
5// REQUIRES: x86
6
7// CHECK: Name: .bss
8// CHECK-NEXT: Type: SHT_NOBITS
9// CHECK-NEXT: Flags [
10// CHECK-NEXT: SHF_ALLOC
11// CHECK-NEXT: SHF_WRITE
12// CHECK-NEXT: ]
13// CHECK-NEXT: Address: 0x201000
14// CHECK-NEXT: Offset:
15// CHECK-NEXT: Size: 22
16// CHECK-NEXT: Link: 0
17// CHECK-NEXT: Info: 0
18// CHECK-NEXT: AddressAlignment: 16
19
20// CHECK: Name: sym1
21// CHECK-NEXT: Value: 0x201004
22// CHECK-NEXT: Size: 8
23// CHECK-NEXT: Binding: Global
24// CHECK-NEXT: Type: Object
25// CHECK-NEXT: Other: 0
26// CHECK-NEXT: Section: .bss
27
28// CHECK: Name: sym2
29// CHECK-NEXT: Value: 0x20100C
30// CHECK-NEXT: Size: 8
31// CHECK-NEXT: Binding: Global
32// CHECK-NEXT: Type: Object
33// CHECK-NEXT: Other: 0
34// CHECK-NEXT: Section: .bss
35
36// CHECK: Name: sym3
37// CHECK-NEXT: Value: 0x201014
38// CHECK-NEXT: Size: 2
39// CHECK-NEXT: Binding: Global
40// CHECK-NEXT: Type: Object
41// CHECK-NEXT: Other: 0
42// CHECK-NEXT: Section: .bss
43
44// CHECK: Name: sym4
45// CHECK-NEXT: Value: 0x201000
46// CHECK-NEXT: Size: 4
47// CHECK-NEXT: Binding: Global
48// CHECK-NEXT: Type: Object
49// CHECK-NEXT: Other: 0
50// CHECK-NEXT: Section: .bss
51
52
53.globl _start
54_start:
55
56.comm sym1,4,4
57.comm sym2,8,4
58.comm sym3,2,2
59.comm sym4,4,2
deps/lld/test/ELF/compatible-section-types.s created+20
......@@ -0,0 +1,20 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
2// RUN: ld.lld -shared %t.o -o %t
3// RUN: llvm-objdump -section-headers %t | FileCheck %s
4
5// CHECK: .foo {{0*}}28
6
7.section .foo, "aw", @progbits, unique, 1
8.quad 0
9
10.section .foo, "aw", @init_array, unique, 2
11.quad 0
12
13.section .foo, "aw", @preinit_array, unique, 3
14.quad 0
15
16.section .foo, "aw", @fini_array, unique, 4
17.quad 0
18
19.section .foo, "aw", @note, unique, 5
20.quad 0
deps/lld/test/ELF/compress-debug-sections.s created+32
......@@ -0,0 +1,32 @@
1# REQUIRES: x86, zlib
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
4# RUN: ld.lld %t.o -o %t1 --compress-debug-sections=zlib
5
6# RUN: llvm-objdump -s %t1 | FileCheck %s --check-prefix=ZLIBCONTENT
7# ZLIBCONTENT: Contents of section .debug_str:
8# ZLIBCONTENT-NOT: AAAAAAAAA
9
10# RUN: llvm-readobj -s %t1 | FileCheck %s --check-prefix=ZLIBFLAGS
11# ZLIBFLAGS: Section {
12# ZLIBFLAGS: Index:
13# ZLIBFLAGS: Name: .debug_str
14# ZLIBFLAGS-NEXT: Type: SHT_PROGBITS
15# ZLIBFLAGS-NEXT: Flags [
16# ZLIBFLAGS-NEXT: SHF_COMPRESSED
17
18# RUN: llvm-dwarfdump %t1 -debug-dump=str | \
19# RUN: FileCheck %s --check-prefix=DEBUGSTR
20# DEBUGSTR: .debug_str contents:
21# DEBUGSTR-NEXT: AAAAAAAAAAAAAAAAAAAAAAAAAAA
22# DEBUGSTR-NEXT: BBBBBBBBBBBBBBBBBBBBBBBBBBB
23
24# RUN: not ld.lld %t.o -o %t1 --compress-debug-sections=zlib-gabi 2>&1 | \
25# RUN: FileCheck -check-prefix=ERR %s
26# ERR: unknown --compress-debug-sections value: zlib-gabi
27
28.section .debug_str,"MS",@progbits,1
29.Linfo_string0:
30 .asciz "AAAAAAAAAAAAAAAAAAAAAAAAAAA"
31.Linfo_string1:
32 .asciz "BBBBBBBBBBBBBBBBBBBBBBBBBBB"
deps/lld/test/ELF/compressed-debug-input.s created+82
......@@ -0,0 +1,82 @@
1# REQUIRES: zlib, x86
2
3# RUN: llvm-mc -compress-debug-sections=zlib -filetype=obj -triple=x86_64-unknown-linux %s -o %t
4# RUN: llvm-readobj -sections %t | FileCheck -check-prefix=ZLIB %s
5# ZLIB: Section {
6# ZLIB: Index: 2
7# ZLIB: Name: .debug_str
8# ZLIB-NEXT: Type: SHT_PROGBITS
9# ZLIB-NEXT: Flags [
10# ZLIB-NEXT: SHF_COMPRESSED (0x800)
11# ZLIB-NEXT: SHF_MERGE (0x10)
12# ZLIB-NEXT: SHF_STRINGS (0x20)
13# ZLIB-NEXT: ]
14# ZLIB-NEXT: Address:
15# ZLIB-NEXT: Offset:
16# ZLIB-NEXT: Size:
17# ZLIB-NEXT: Link:
18# ZLIB-NEXT: Info:
19# ZLIB-NEXT: AddressAlignment: 1
20# ZLIB-NEXT: EntrySize: 1
21# ZLIB-NEXT: }
22
23# RUN: llvm-mc -compress-debug-sections=zlib-gnu -filetype=obj -triple=x86_64-unknown-linux %s -o %t2
24# RUN: llvm-readobj -sections %t2 | FileCheck -check-prefix=GNU %s
25# GNU: Section {
26# GNU: Index: 2
27# GNU: Name: .zdebug_str
28# GNU-NEXT: Type: SHT_PROGBITS
29# GNU-NEXT: Flags [
30# GNU-NEXT: SHF_MERGE (0x10)
31# GNU-NEXT: SHF_STRINGS (0x20)
32# GNU-NEXT: ]
33# GNU-NEXT: Address:
34# GNU-NEXT: Offset:
35# GNU-NEXT: Size:
36# GNU-NEXT: Link:
37# GNU-NEXT: Info:
38# GNU-NEXT: AddressAlignment: 1
39# GNU-NEXT: EntrySize: 1
40# GNU-NEXT: }
41
42# RUN: ld.lld %t -o %t.so -shared
43# RUN: llvm-readobj -sections -section-data %t.so | FileCheck -check-prefix=DATA %s
44
45# RUN: ld.lld %t2 -o %t2.so -shared
46# RUN: llvm-readobj -sections -section-data %t2.so | FileCheck -check-prefix=DATA %s
47
48# DATA: Section {
49# DATA: Index: 6
50# DATA: Name: .debug_str
51# DATA-NEXT: Type: SHT_PROGBITS
52# DATA-NEXT: Flags [
53# DATA-NEXT: SHF_MERGE (0x10)
54# DATA-NEXT: SHF_STRINGS (0x20)
55# DATA-NEXT: ]
56# DATA-NEXT: Address: 0x0
57# DATA-NEXT: Offset: 0x1060
58# DATA-NEXT: Size: 69
59# DATA-NEXT: Link: 0
60# DATA-NEXT: Info: 0
61# DATA-NEXT: AddressAlignment: 1
62# DATA-NEXT: EntrySize: 0
63# DATA-NEXT: SectionData (
64# DATA-NEXT: 0000: 73686F72 7420756E 7369676E 65642069 |short unsigned i|
65# DATA-NEXT: 0010: 6E740075 6E736967 6E656420 696E7400 |nt.unsigned int.|
66# DATA-NEXT: 0020: 6C6F6E67 20756E73 69676E65 6420696E |long unsigned in|
67# DATA-NEXT: 0030: 74006368 61720075 6E736967 6E656420 |t.char.unsigned |
68# DATA-NEXT: 0040: 63686172 00 |char.|
69# DATA-NEXT: )
70# DATA-NEXT: }
71
72.section .debug_str,"MS",@progbits,1
73.LASF2:
74 .string "short unsigned int"
75.LASF3:
76 .string "unsigned int"
77.LASF0:
78 .string "long unsigned int"
79.LASF8:
80 .string "char"
81.LASF1:
82 .string "unsigned char"
deps/lld/test/ELF/conflict.s created+50
......@@ -0,0 +1,50 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
4# RUN: not ld.lld %t1.o %t1.o -o %t2 2>&1 | FileCheck -check-prefix=DEMANGLE %s
5
6# DEMANGLE: duplicate symbol: mul(double, double)
7# DEMANGLE-NEXT: >>> defined at {{.*}}:(.text+0x0)
8# DEMANGLE-NEXT: >>> defined at {{.*}}:(.text+0x0)
9# DEMANGLE: duplicate symbol: foo
10# DEMANGLE-NEXT: >>> defined at {{.*}}:(.text+0x0)
11# DEMANGLE-NEXT: >>> defined at {{.*}}:(.text+0x0)
12
13# RUN: not ld.lld %t1.o %t1.o -o %t2 --no-demangle 2>&1 | \
14# RUN: FileCheck -check-prefix=NO_DEMANGLE %s
15
16# NO_DEMANGLE: duplicate symbol: _Z3muldd
17# NO_DEMANGLE-NEXT: >>> defined at {{.*}}:(.text+0x0)
18# NO_DEMANGLE-NEXT: >>> defined at {{.*}}:(.text+0x0)
19# NO_DEMANGLE: duplicate symbol: foo
20# NO_DEMANGLE-NEXT: >>> defined at {{.*}}:(.text+0x0)
21# NO_DEMANGLE-NEXT: >>> defined at {{.*}}:(.text+0x0)
22
23# RUN: not ld.lld %t1.o %t1.o -o %t2 --demangle --no-demangle 2>&1 | \
24# RUN: FileCheck -check-prefix=NO_DEMANGLE %s
25# RUN: not ld.lld %t1.o %t1.o -o %t2 --no-demangle --demangle 2>&1 | \
26# RUN: FileCheck -check-prefix=DEMANGLE %s
27
28# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/conflict.s -o %t2.o
29# RUN: llvm-ar rcs %t3.a %t2.o
30# RUN: not ld.lld %t1.o %t3.a -u baz -o %t2 2>&1 | FileCheck -check-prefix=ARCHIVE %s
31
32# ARCHIVE: duplicate symbol: foo
33# ARCHIVE-NEXT: >>> defined at {{.*}}:(.text+0x0)
34# ARCHIVE-NEXT: >>> defined at {{.*}}:(.text+0x0) in archive {{.*}}.a
35
36# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/conflict-debug.s -o %t-dbg.o
37# RUN: not ld.lld %t-dbg.o %t-dbg.o -o %t-dbg 2>&1 | FileCheck -check-prefix=DBGINFO %s
38
39# DBGINFO: duplicate symbol: zed
40# DBGINFO-NEXT: >>> defined at conflict-debug.s:4
41# DBGINFO-NEXT: >>> {{.*}}:(.text+0x0)
42# DBGINFO-NEXT: >>> defined at conflict-debug.s:4
43# DBGINFO-NEXT: >>> {{.*}}:(.text+0x0)
44
45.globl _Z3muldd, foo
46_Z3muldd:
47foo:
48 mov $60, %rax
49 mov $42, %rdi
50 syscall
deps/lld/test/ELF/copy-errors.s created+15
......@@ -0,0 +1,15 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/protected-shared.s -o %t2.o
4// RUN: ld.lld %t2.o -o %t2.so -shared
5// RUN: not ld.lld %t.o %t2.so -o %t 2>&1 | FileCheck %s
6
7// CHECK: cannot preempt symbol: bar
8// CHECK: >>> defined in {{.*}}.so
9// CHECK: >>> referenced by {{.*}}.o:(.text+0x1)
10// CHECK: symbol 'zed' defined in {{.*}}.so has no type
11
12.global _start
13_start:
14call bar
15call zed
deps/lld/test/ELF/copy-in-shared.s created+11
......@@ -0,0 +1,11 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/copy-in-shared.s -o %t1.o
3// RUN: ld.lld -shared %t1.o -o %t1.so
4// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t2.o
5// RUN: not ld.lld %t2.o %t1.so -o %t2.so -shared 2>&1 | FileCheck %s
6
7// CHECK: can't create dynamic relocation R_X86_64_64 against symbol: foo in readonly segment
8// CHECK: >>> defined in {{.*}}.so
9// CHECK: >>> referenced by {{.*}}.o:(.text+0x0)
10
11.quad foo
deps/lld/test/ELF/copy-rel-corrupted.s created+10
......@@ -0,0 +1,10 @@
1// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
2// RUN: llvm-mc %p/Inputs/copy-rel-corrupted.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux
3// RUN: ld.lld %t2.o -o %t2.so -shared
4// RUN: not ld.lld %t.o %t2.so -o %t.exe 2>&1 | FileCheck %s
5
6// CHECK: error: cannot create a copy relocation for symbol x
7
8.global _start
9_start:
10 call x
deps/lld/test/ELF/copy-rel-pie-error.s created+17
......@@ -0,0 +1,17 @@
1// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
2// RUN: llvm-mc %p/Inputs/copy-rel-pie.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux
3// RUN: ld.lld %t2.o -o %t2.so -shared
4// RUN: not ld.lld %t.o %t2.so -o %t.exe -pie 2>&1 | FileCheck %s
5
6// CHECK: can't create dynamic relocation R_X86_64_64 against symbol: bar
7// CHECK: >>> defined in {{.*}}.so
8// CHECK: >>> referenced by {{.*}}.o:(.text+0x0)
9
10// CHECK: can't create dynamic relocation R_X86_64_64 against symbol: foo
11// CHECK: >>> defined in {{.*}}.so
12// CHECK: >>> referenced by {{.*}}.o:(.text+0x8)
13
14.global _start
15_start:
16 .quad bar
17 .quad foo
deps/lld/test/ELF/copy-rel-pie.s created+44
......@@ -0,0 +1,44 @@
1// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
2// RUN: llvm-mc %p/Inputs/copy-rel-pie.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux
3// RUN: ld.lld %t2.o -o %t2.so -shared
4// RUN: ld.lld %t.o %t2.so -o %t.exe -pie
5// RUN: llvm-readobj -s -r %t.exe | FileCheck %s
6// RUN: llvm-objdump -d %t.exe | FileCheck --check-prefix=DISASM %s
7
8.global _start
9_start:
10 call bar
11 call foo
12
13// CHECK: Name: .plt
14// CHECK-NEXT: Type: SHT_PROGBITS
15// CHECK-NEXT: Flags [
16// CHECK-NEXT: SHF_ALLOC
17// CHECK-NEXT: SHF_EXECINSTR
18// CHECK-NEXT: ]
19// CHECK-NEXT: Address: 0x1010
20
21// CHECK: Name: .bss
22// CHECK-NEXT: Type: SHT_NOBITS
23// CHECK-NEXT: Flags [
24// CHECK-NEXT: SHF_ALLOC
25// CHECK-NEXT: SHF_WRITE
26// CHECK-NEXT: ]
27// CHECK-NEXT: Address: 0x4000
28
29// CHECK: Relocations [
30// CHECK-NEXT: Section (4) .rela.dyn {
31// CHECK-NEXT: 0x4000 R_X86_64_COPY foo 0x0
32// CHECK-NEXT: }
33// CHECK-NEXT: Section (5) .rela.plt {
34// CHECK-NEXT: 0x2018 R_X86_64_JUMP_SLOT bar 0x0
35// CHECK-NEXT: }
36// CHECK-NEXT: ]
37
38// (0x1010 + 0x10) - 0x1005 = 27
39// 0x4000 - 0x100a = 12278
40
41// DISASM: Disassembly of section .text:
42// DISASM-NEXT: _start:
43// DISASM-NEXT: 1000: e8 1b 00 00 00 callq 27
44// DISASM-NEXT: 1005: e8 f6 2f 00 00 callq 12278 <foo>
deps/lld/test/ELF/ctors_dtors_priority.s created+48
......@@ -0,0 +1,48 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
3// RUN: %p/Inputs/ctors_dtors_priority1.s -o %t-crtbegin.o
4// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
5// RUN: %p/Inputs/ctors_dtors_priority2.s -o %t2
6// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
7// RUN: %p/Inputs/ctors_dtors_priority3.s -o %t-crtend.o
8// RUN: ld.lld %t1 %t2 %t-crtend.o %t-crtbegin.o -o %t.exe
9// RUN: llvm-objdump -s %t.exe | FileCheck %s
10// REQUIRES: x86
11
12.globl _start
13_start:
14 nop
15
16.section .ctors, "aw", @progbits
17 .quad 1
18.section .ctors.100, "aw", @progbits
19 .quad 2
20.section .ctors.005, "aw", @progbits
21 .quad 3
22.section .ctors, "aw", @progbits
23 .quad 4
24.section .ctors, "aw", @progbits
25 .quad 5
26
27.section .dtors, "aw", @progbits
28 .quad 0x11
29.section .dtors.100, "aw", @progbits
30 .quad 0x12
31.section .dtors.005, "aw", @progbits
32 .quad 0x13
33.section .dtors, "aw", @progbits
34 .quad 0x14
35.section .dtors, "aw", @progbits
36 .quad 0x15
37
38// CHECK: Contents of section .ctors:
39// CHECK-NEXT: 202000 a1000000 00000000 01000000 00000000
40// CHECK-NEXT: 202010 04000000 00000000 05000000 00000000
41// CHECK-NEXT: 202020 b1000000 00000000 03000000 00000000
42// CHECK-NEXT: 202030 02000000 00000000 c1000000 00000000
43
44// CHECK: Contents of section .dtors:
45// CHECK-NEXT: 202040 a2000000 00000000 11000000 00000000
46// CHECK-NEXT: 202050 14000000 00000000 15000000 00000000
47// CHECK-NEXT: 202060 b2000000 00000000 13000000 00000000
48// CHECK-NEXT: 202070 12000000 00000000 c2000000 00000000
deps/lld/test/ELF/debug-gc.s created+30
......@@ -0,0 +1,30 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: ld.lld %t.o -o %t1 --gc-sections
4# RUN: llvm-objdump -s %t1 | FileCheck %s
5
6# CHECK: Contents of section .debug_str:
7# CHECK-NEXT: 0000 41414100 42424200 43434300 AAA.BBB.CCC.
8# CHECK: Contents of section .foo:
9# CHECK-NEXT: 0000 2a000000
10# CHECK: Contents of section .debug_info:
11# CHECK-NEXT: 0000 00000000 04000000
12
13.globl _start
14_start:
15
16.section .debug_str,"MS",@progbits,1
17.Linfo_string0:
18 .asciz "AAA"
19.Linfo_string1:
20 .asciz "BBB"
21.Linfo_string2:
22 .asciz "CCC"
23
24.section .foo,"M",@progbits,4
25.p2align 2
26 .long 42
27
28.section .debug_info,"",@progbits
29 .long .Linfo_string0
30 .long .Linfo_string1
deps/lld/test/ELF/debug-gnu-pubnames.s created+18
......@@ -0,0 +1,18 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3
4# RUN: ld.lld %t.o -o %t1.exe
5# RUN: llvm-readobj -sections %t1.exe | FileCheck %s
6# CHECK: .debug_gnu_pubnames
7# CHECK: .debug_gnu_pubtypes
8
9# RUN: ld.lld -gdb-index %t.o -o %t2.exe
10# RUN: llvm-readobj -sections %t2.exe | FileCheck %s --check-prefix=GDB
11# GDB-NOT: .debug_gnu_pubnames
12# GDB-NOT: .debug_gnu_pubtypes
13
14.section .debug_gnu_pubnames,"",@progbits
15.long 0
16
17.section .debug_gnu_pubtypes,"",@progbits
18.long 0
deps/lld/test/ELF/default-fill.s created+38
......@@ -0,0 +1,38 @@
1# REQUIRES: x86
2# Verify that the fill between sections has a default of interrupt instructions
3# (0xcc on x86/x86_64) for executable sections and zero for other sections.
4
5# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
6# RUN: ld.lld %t1.o -o %t1.elf
7# RUN: llvm-objdump -s %t1.elf > %t1.sections
8# RUN: FileCheck %s --input-file %t1.sections --check-prefix=TEXT
9# RUN: FileCheck %s --input-file %t1.sections --check-prefix=DATA
10
11# RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t2.o
12# RUN: ld.lld %t2.o -o %t2.elf
13# RUN: llvm-objdump -s %t2.elf > %t2.sections
14# RUN: FileCheck %s --input-file %t2.sections --check-prefix=TEXT
15# RUN: FileCheck %s --input-file %t2.sections --check-prefix=DATA
16
17# TEXT: Contents of section .text:
18# TEXT-NEXT: 11cccccc cccccccc cccccccc cccccccc
19# TEXT-NEXT: 22
20# DATA: Contents of section .data:
21# DATA-NEXT: 33000000 00000000 00000000 00000000
22# DATA-NEXT: 44
23
24.section .text.1,"ax",@progbits
25.align 16
26.byte 0x11
27
28.section .text.2,"ax",@progbits
29.align 16
30.byte 0x22
31
32.section .data.1,"a",@progbits
33.align 16
34.byte 0x33
35
36.section .data.2,"a",@progbits
37.align 16
38.byte 0x44
deps/lld/test/ELF/default-output.s created+16
......@@ -0,0 +1,16 @@
1# REQUIRES: x86
2# Verify that default output filename is a.out.
3
4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
5# RUN: mkdir -p %t.dir
6# RUN: cd %t.dir
7# RUN: rm -f a.out
8# RUN: not llvm-readobj a.out > /dev/null 2>&1
9# RUN: ld.lld %t
10# RUN: llvm-readobj a.out > /dev/null 2>&1
11
12.globl _start
13_start:
14 mov $60, %rax
15 mov $42, %rdi
16 syscall
deps/lld/test/ELF/defined-tls_get_addr.s created+10
......@@ -0,0 +1,10 @@
1// RUN: llvm-mc %s -o %t.o -triple x86_64-pc-linux -filetype=obj
2// RUN: ld.lld %t.o -o %t
3
4// Don't error if __tls_get_addr is defined.
5
6.global _start
7.global __tls_get_addr
8_start:
9__tls_get_addr:
10nop
deps/lld/test/ELF/defsym.s created+47
......@@ -0,0 +1,47 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: ld.lld -o %t %t.o --defsym=foo2=foo1
4# RUN: llvm-readobj -t -s %t | FileCheck %s
5# RUN: llvm-objdump -d -print-imm-hex %t | FileCheck %s --check-prefix=USE
6
7## Check that we accept --defsym foo2=foo1 form.
8# RUN: ld.lld -o %t2 %t.o --defsym foo2=foo1
9# RUN: llvm-readobj -t -s %t2 | FileCheck %s
10# RUN: llvm-objdump -d -print-imm-hex %t2 | FileCheck %s --check-prefix=USE
11
12# CHECK: Symbol {
13# CHECK: Name: foo1
14# CHECK-NEXT: Value: 0x123
15# CHECK-NEXT: Size:
16# CHECK-NEXT: Binding: Global
17# CHECK-NEXT: Type:
18# CHECK-NEXT: Other:
19# CHECK-NEXT: Section: Absolute
20# CHECK-NEXT: }
21# CHECK-NEXT: Symbol {
22# CHECK-NEXT: Name: foo1
23# CHECK-NEXT: Value: 0x123
24# CHECK-NEXT: Size:
25# CHECK-NEXT: Binding: Global
26# CHECK-NEXT: Type:
27# CHECK-NEXT: Other:
28# CHECK-NEXT: Section: Absolute
29# CHECK-NEXT: }
30
31## Check we can use foo2 and it that it is an alias for foo1.
32# USE: Disassembly of section .text:
33# USE-NEXT: _start:
34# USE-NEXT: movl $0x123, %edx
35
36# RUN: not ld.lld -o %t %t.o --defsym=foo2=1 2>&1 | FileCheck %s -check-prefix=ERR1
37# ERR1: error: --defsym: symbol name expected, but got 1
38
39# RUN: not ld.lld -o %t %t.o --defsym=foo2=und 2>&1 | FileCheck %s -check-prefix=ERR2
40# ERR2: error: -defsym: undefined symbol: und
41
42.globl foo1
43 foo1 = 0x123
44
45.global _start
46_start:
47 movl $foo2, %edx
deps/lld/test/ELF/discard-locals.s created+50
......@@ -0,0 +1,50 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux -save-temp-labels %s -o %t
2// RUN: ld.lld -discard-locals %t -o %t2
3// RUN: llvm-readobj -s -sd -t %t2 | FileCheck %s
4// REQUIRES: x86
5
6.global _start
7_start:
8
9.text
10.Lmyvar:
11.Lmyothervar:
12
13// CHECK: Section {
14// CHECK: Name: .strtab
15// CHECK-NEXT: Type: SHT_STRTAB
16// CHECK-NEXT: Flags [
17// CHECK-NEXT: ]
18// CHECK-NEXT: Address:
19// CHECK-NEXT: Offset:
20// CHECK-NEXT: Size:
21// CHECK-NEXT: Link:
22// CHECK-NEXT: Info:
23// CHECK-NEXT: AddressAlignment:
24// CHECK-NEXT: EntrySize:
25// CHECK-NEXT: SectionData (
26// CHECK-NEXT: 0000: 005F7374 61727400 |._start.|
27// CHECK-NEXT: )
28// CHECK-NEXT: }
29// CHECK-NEXT: ]
30
31// CHECK: Symbols [
32// CHECK-NEXT: Symbol {
33// CHECK-NEXT: Name:
34// CHECK-NEXT: Value: 0x0
35// CHECK-NEXT: Size: 0
36// CHECK-NEXT: Binding: Local
37// CHECK-NEXT: Type: None
38// CHECK-NEXT: Other: 0
39// CHECK-NEXT: Section: Undefined
40// CHECK-NEXT: }
41// CHECK-NEXT: Symbol {
42// CHECK-NEXT: Name: _start
43// CHECK-NEXT: Value:
44// CHECK-NEXT: Size: 0
45// CHECK-NEXT: Binding: Global
46// CHECK-NEXT: Type: None
47// CHECK-NEXT: Other: 0
48// CHECK-NEXT: Section: .text
49// CHECK-NEXT: }
50// CHECk-NEXT: ]
deps/lld/test/ELF/discard-merge-locals.s created+35
......@@ -0,0 +1,35 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
2// RUN: ld.lld %t -o %t2 -shared
3// RUN: llvm-readobj -t %t2 | FileCheck %s
4// REQUIRES: x86
5
6 leaq .L.str(%rip), %rdi
7
8 .section .rodata.str1.1,"aMS",@progbits,1
9.L.str:
10 .asciz "foobar"
11
12// Test that the .L symbol is omitted
13
14// CHECK: Symbols [
15// CHECK-NEXT: Symbol {
16// CHECK-NEXT: Name: (0)
17// CHECK-NEXT: Value: 0x0
18// CHECK-NEXT: Size: 0
19// CHECK-NEXT: Binding: Local
20// CHECK-NEXT: Type: None
21// CHECK-NEXT: Other: 0
22// CHECK-NEXT: Section: Undefined
23// CHECK-NEXT: }
24// CHECK-NEXT: Symbol {
25// CHECK-NEXT: Name: _DYNAMIC
26// CHECK-NEXT: Value: 0x2000
27// CHECK-NEXT: Size: 0
28// CHECK-NEXT: Binding: Local
29// CHECK-NEXT: Type: None
30// CHECK-NEXT: Other [ (0x2)
31// CHECK-NEXT: STV_HIDDEN
32// CHECK-NEXT: ]
33// CHECK-NEXT: Section: .dynamic
34// CHECK-NEXT: }
35// CHECK-NEXT: ]
deps/lld/test/ELF/discard-merge-unnamed.s created+27
......@@ -0,0 +1,27 @@
1// RUN: ld.lld %p/Inputs/discard-merge-unnamed.o -o %t2 -shared
2// RUN: llvm-readobj -t %t2 | FileCheck %s
3
4// Test that the unnamed symbol is SHF_MERGE is omitted.
5
6// CHECK: Symbols [
7// CHECK-NEXT: Symbol {
8// CHECK-NEXT: Name: (0)
9// CHECK-NEXT: Value: 0x0
10// CHECK-NEXT: Size: 0
11// CHECK-NEXT: Binding: Local
12// CHECK-NEXT: Type: None
13// CHECK-NEXT: Other: 0
14// CHECK-NEXT: Section: Undefined
15// CHECK-NEXT: }
16// CHECK-NEXT: Symbol {
17// CHECK-NEXT: Name: _DYNAMIC
18// CHECK-NEXT: Value: 0x2000
19// CHECK-NEXT: Size: 0
20// CHECK-NEXT: Binding: Local
21// CHECK-NEXT: Type: None
22// CHECK-NEXT: Other [ (0x2)
23// CHECK-NEXT: STV_HIDDEN
24// CHECK-NEXT: ]
25// CHECK-NEXT: Section: .dynamic
26// CHECK-NEXT: }
27// CHECK-NEXT: ]
deps/lld/test/ELF/discard-none.s created+54
......@@ -0,0 +1,54 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux -save-temp-labels %s -o %t
2// RUN: ld.lld -discard-none -shared %t -o %t2
3// RUN: llvm-readobj -s -sd -t %t2 | FileCheck %s
4// REQUIRES: x86
5
6.text
7.Lmyvar:
8.Lmyothervar:
9
10// CHECK: Section {
11// CHECK: Name: .strtab
12// CHECK-NEXT: Type: SHT_STRTAB
13// CHECK-NEXT: Flags [
14// CHECK-NEXT: ]
15// CHECK-NEXT: Address:
16// CHECK-NEXT: Offset:
17// CHECK-NEXT: Size:
18// CHECK-NEXT: Link:
19// CHECK-NEXT: Info:
20// CHECK-NEXT: AddressAlignment:
21// CHECK-NEXT: EntrySize:
22// CHECK-NEXT: SectionData (
23// CHECK-NEXT: 0000: 002E4C6D 796F7468 65727661 72002E4C |..Lmyothervar..L|
24// CHECK-NEXT: 0010: 6D797661 72005F44 594E414D 494300 |myvar._DYNAMIC.|
25// CHECK-NEXT: )
26// CHECK-NEXT: }
27
28// CHECK: Symbol {
29// CHECK-NEXT: Name:
30// CHECK-NEXT: Value: 0x0
31// CHECK-NEXT: Size: 0
32// CHECK-NEXT: Binding: Local
33// CHECK-NEXT: Type: None
34// CHECK-NEXT: Other: 0
35// CHECK-NEXT: Section: Undefined
36// CHECK-NEXT: }
37// CHECK-NEXT: Symbol {
38// CHECK-NEXT: Name: .Lmyothervar
39// CHECK-NEXT: Value:
40// CHECK-NEXT: Size: 0
41// CHECK-NEXT: Binding: Local
42// CHECK-NEXT: Type: None
43// CHECK-NEXT: Other: 0
44// CHECK-NEXT: Section: .text
45// CHECK-NEXT: }
46// CHECK-NEXT: Symbol {
47// CHECK-NEXT: Name: .Lmyvar
48// CHECK-NEXT: Value:
49// CHECK-NEXT: Size: 0
50// CHECK-NEXT: Binding: Local
51// CHECK-NEXT: Type: None
52// CHECK-NEXT: Other: 0
53// CHECK-NEXT: Section: .text
54// CHECK-NEXT: }
deps/lld/test/ELF/dont-export-hidden.s created+39
......@@ -0,0 +1,39 @@
1// RUN: llvm-mc %p/Inputs/shared.s -o %t.o -filetype=obj -triple=x86_64-pc-linux
2// RUN: llvm-mc %s -o %t2.o -filetype=obj -triple=x86_64-pc-linux
3// RUN: ld.lld %t.o -o %t.so -shared
4// RUN: ld.lld %t2.o %t.so -o %t.exe
5// RUN: llvm-readobj --dyn-symbols %t.exe | FileCheck %s
6
7 .global _start
8_start:
9 .global bar
10 .hidden bar
11bar:
12
13 .global bar2
14bar2:
15
16 .global foo
17foo:
18
19// CHECK: DynamicSymbols [
20// CHECK-NEXT: Symbol {
21// CHECK-NEXT: Name: @
22// CHECK-NEXT: Value: 0x0
23// CHECK-NEXT: Size: 0
24// CHECK-NEXT: Binding: Local
25// CHECK-NEXT: Type: None
26// CHECK-NEXT: Other: 0
27// CHECK-NEXT: Section: Undefined
28// CHECK-NEXT: }
29// CHECK-NEXT: Symbol {
30// CHECK-NEXT: Name: bar2
31// CHECK-NEXT: Value:
32// CHECK-NEXT: Size: 0
33// CHECK-NEXT: Binding: Global
34// CHECK-NEXT: Type: None
35// CHECK-NEXT: Other: 0
36// CHECK-NEXT: Section: .text
37// CHECK-NEXT: }
38// CHECK-NEXT: ]
39
deps/lld/test/ELF/driver-access.test created+15
......@@ -0,0 +1,15 @@
1# REQUIRES: x86, shell
2# Make sure that LLD works even if the current directory is not writable.
3
4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
5# RUN: ld.lld %t.o -o %t.exe
6
7# RUN: mkdir -p %t.dir
8# RUN: chmod 100 %t.dir
9# RUN: cd %t.dir
10# RUN: ld.lld %t.o -o %t.exe
11# RUN: chmod 755 %t.dir
12
13.globl _start
14_start:
15 nop
deps/lld/test/ELF/driver.test created+60
......@@ -0,0 +1,60 @@
1# REQUIRES: x86
2
3# RUN: not ld.lld --unknown1 --unknown2 -m foo /no/such/file -lnosuchlib \
4# RUN: 2>&1 | FileCheck -check-prefix=UNKNOWN %s
5
6# UNKNOWN: unknown argument: --unknown1
7# UNKNOWN: unknown argument: --unknown2
8# UNKNOWN: unknown emulation: foo
9# UNKNOWN: cannot open /no/such/file
10# UNKNOWN: unable to find library -lnosuchlib
11
12# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
13# RUN: not ld.lld %t -o /no/such/file 2>&1 | FileCheck -check-prefix=MISSING %s
14# MISSING: cannot open output file /no/such/file
15
16# RUN: ld.lld --help 2>&1 | FileCheck -check-prefix=HELP %s
17# HELP: USAGE:
18# HELP: : supported targets:{{.*}} elf
19
20# RUN: ld.lld --version 2>&1 | FileCheck -check-prefix=VERSION %s
21# VERSION: LLD {{.*}} (compatible with GNU linkers)
22
23# RUN: not ld.lld -v 2>&1 | FileCheck -check-prefix=VERSION %s
24
25## Attempt to link DSO with -r
26# RUN: ld.lld -shared %t -o %t.so
27# RUN: not ld.lld -r %t.so %t -o %tfail 2>&1 | FileCheck -check-prefix=ERR %s
28# ERR: attempted static link of dynamic object
29
30## Attempt to use -r and -shared together
31# RUN: not ld.lld -r -shared %t -o %tfail 2>&1 | FileCheck -check-prefix=ERR2 %s
32# ERR2: -r and -shared may not be used together
33
34## Attempt to use -r and --gc-sections together
35# RUN: not ld.lld -r --gc-sections %t -o %tfail 2>&1 | FileCheck -check-prefix=ERR3 %s
36# ERR3: -r and --gc-sections may not be used together
37
38## Attempt to use -r and --icf together
39# RUN: not ld.lld -r --icf=all %t -o %tfail 2>&1 | FileCheck -check-prefix=ERR4 %s
40# ERR4: -r and --icf may not be used together
41
42## Attempt to use -r and -pie together
43# RUN: not ld.lld -r -pie %t -o %tfail 2>&1 | FileCheck -check-prefix=ERR5 %s
44# ERR5: -r and -pie may not be used together
45
46## Attempt to use -shared and -pie together
47# RUN: not ld.lld -shared -pie %t -o %tfail 2>&1 | FileCheck -check-prefix=ERR6 %s
48# ERR6: -shared and -pie may not be used together
49
50## "--output=foo" is equivalent to "-o foo".
51# RUN: not ld.lld %t --output=/no/such/file 2>&1 | FileCheck -check-prefix=ERR7 %s
52# ERR7: cannot open output file /no/such/file
53
54## "-output=foo" is equivalent to "-o utput=foo".
55# RUN: not ld.lld %t -output=/no/such/file 2>&1 | FileCheck -check-prefix=ERR8 %s
56# ERR8: cannot open output file utput=/no/such/file
57
58.globl _start
59_start:
60 nop
deps/lld/test/ELF/dso-undef-size.s created+32
......@@ -0,0 +1,32 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/dso-undef-size.s -o %t1.o
3# RUN: ld.lld -shared %t1.o -o %t1.so
4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2.o
5# RUN: ld.lld -shared %t2.o %t1.so -o %t2.so
6# RUN: llvm-readobj -symbols -dyn-symbols %t2.so
7
8# CHECK: Symbols [
9# CHECK-NEXT: Symbol {
10# CHECK-NEXT: Name: foo
11# CHECK-NEXT: Value:
12# CHECK-NEXT: Size: 0
13# CHECK-NEXT: Binding:
14# CHECK-NEXT: Type:
15# CHECK-NEXT: Other:
16# CHECK-NEXT: Section: Undefined
17# CHECK-NEXT: }
18# CHECK-NEXT: ]
19# CHECK: DynamicSymbols [
20# CHECK-NEXT: Symbol {
21# CHECK-NEXT: Name: foo
22# CHECK-NEXT: Value:
23# CHECK-NEXT: Size: 0
24# CHECK-NEXT: Binding:
25# CHECK-NEXT: Type:
26# CHECK-NEXT: Other:
27# CHECK-NEXT: Section: Undefined
28# CHECK-NEXT: }
29# CHECK-NEXT: ]
30
31.text
32.global foo
deps/lld/test/ELF/dso_handle.s created+19
......@@ -0,0 +1,19 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
4# RUN: ld.lld -shared %t.o -o %t
5# RUN: llvm-readobj -symbols %t | FileCheck %s
6# CHECK: Name: __dso_handle
7# CHECK-NEXT: Value: 0x0
8# CHECK-NEXT: Size: 0
9# CHECK-NEXT: Binding: Local
10# CHECK-NEXT: Type: None
11# CHECK-NEXT: Other [
12# CHECK-NEXT: STV_HIDDEN
13# CHECK-NEXT: ]
14# CHECK-NEXT: Section: .dynsym
15
16.text
17.global foo, __dso_handle
18foo:
19 lea __dso_handle(%rip),%rax
deps/lld/test/ELF/dt_flags.s created+21
......@@ -0,0 +1,21 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
4# RUN: ld.lld -shared %t -o %t.so
5# RUN: ld.lld -z now -z nodelete -z nodlopen -z origin -Bsymbolic %t %t.so -o %t1
6# RUN: ld.lld %t %t.so -o %t2
7# RUN: llvm-readobj -dynamic-table %t1 | FileCheck -check-prefix=FLAGS %s
8# RUN: llvm-readobj -dynamic-table %t2 | FileCheck %s
9
10# FLAGS: DynamicSection [
11# FLAGS: 0x000000000000001E FLAGS ORIGIN SYMBOLIC BIND_NOW
12# FLAGS: 0x000000006FFFFFFB FLAGS_1 NOW NODELETE NOOPEN ORIGIN
13# FLAGS: ]
14
15# CHECK: DynamicSection [
16# CHECK-NOT: 0x000000000000001E FLAGS ORIGIN SYMBOLIC BIND_NOW
17# CHECK-NOT: 0x000000006FFFFFFB FLAGS_1 NOW NODELETE NOOPEN ORIGIN
18# CHECK: ]
19
20.globl _start
21_start:
deps/lld/test/ELF/dt_tags.s created+18
......@@ -0,0 +1,18 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %t
4# RUN: ld.lld -shared %t -o %t.so
5# RUN: ld.lld %t %t.so -o %t.exe
6# RUN: llvm-readobj -dynamic-table %t.so | FileCheck -check-prefix=DSO %s
7# RUN: llvm-readobj -dynamic-table %t.exe | FileCheck -check-prefix=EXE %s
8
9# EXE: DynamicSection [
10# EXE: 0x0000000000000015 DEBUG 0x0
11# EXE: ]
12
13# DSO: DynamicSection [
14# DSO-NOT: 0x0000000000000015 DEBUG 0x0
15# DSO: ]
16
17.globl _start
18_start:
deps/lld/test/ELF/dtrace-r.test created+8
......@@ -0,0 +1,8 @@
1RUN: ld.lld -r -o %t.o %p/Inputs/dtrace-r.o
2RUN: llvm-readobj -r %t.o | FileCheck %s
3
4CHECK: Relocations [
5CHECK-NEXT: Section ({{.*}}) .rela.text {
6CHECK-NEXT: 0x0 R_X86_64_NONE - 0x0
7CHECK-NEXT: }
8CHECK-NEXT: ]
deps/lld/test/ELF/duplicated-plt-entry.s created+17
......@@ -0,0 +1,17 @@
1// REQUIRES: x86
2
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/duplicated-plt-entry.s -o %t.o
4// RUN: ld.lld -shared %t.o -o %t.so
5
6// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2.o
7// RUN: ld.lld %t2.o %t.so -o %t2.so -shared
8
9// RUN: llvm-readobj -r %t2.so | FileCheck %s
10// CHECK: Relocations [
11// CHECK-NEXT: Section ({{.*}}) .rela.plt {
12// CHECK-NEXT: R_X86_64_JUMP_SLOT bar 0x0
13// CHECK-NEXT: }
14// CHECK-NEXT: ]
15
16callq bar@PLT
17callq bar@PLT
deps/lld/test/ELF/duplicated-synthetic-sym.s created+10
......@@ -0,0 +1,10 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
2// RUN: cd %S
3// RUN: not ld.lld %t.o --format=binary duplicated-synthetic-sym.s -o %t.elf 2>&1 | FileCheck %s
4
5// CHECK: duplicate symbol: _binary_duplicated_synthetic_sym_s_start
6// CHECK: defined at (internal):(.data+0x0)
7
8 .globl _binary_duplicated_synthetic_sym_s_start
9_binary_duplicated_synthetic_sym_s_start:
10 .long 0
deps/lld/test/ELF/dynamic-got-rela.s created+34
......@@ -0,0 +1,34 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: ld.lld %t.o -o %t.so -shared
4// RUN: llvm-readobj -r -s -l -section-data %t.so | FileCheck %s
5
6// CHECK: Name: .got
7// CHECK-NEXT: Type: SHT_PROGBITS
8// CHECK-NEXT: Flags [
9// CHECK-NEXT: SHF_ALLOC
10// CHECK-NEXT: SHF_WRITE
11// CHECK-NEXT: ]
12// CHECK-NEXT: Address: 0x[[GOT:.*]]
13// CHECK-NEXT: Offset:
14// CHECK-NEXT: Size:
15// CHECK-NEXT: Link:
16// CHECK-NEXT: Info:
17// CHECK-NEXT: AddressAlignment:
18// CHECK-NEXT: EntrySize:
19// CHECK-NEXT: SectionData (
20// CHECK-NEXT: 0000: 00000000 00000000 |
21// CHECK-NEXT: )
22
23// CHECK: Relocations [
24// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
25// CHECK-NEXT: 0x[[GOT]] R_X86_64_RELATIVE - 0x[[ADDEND:.*]]
26// CHECK-NEXT: }
27// CHECK-NEXT: ]
28
29// CHECK: Type: PT_DYNAMIC
30// CHECK-NEXT: Offset: 0x[[ADDEND]]
31// CHECK-NEXT: VirtualAddress: 0x[[ADDEND]]
32// CHECK-NEXT: PhysicalAddress: 0x[[ADDEND]]
33
34cmpq $0, _DYNAMIC@GOTPCREL(%rip)
deps/lld/test/ELF/dynamic-got.s created+39
......@@ -0,0 +1,39 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t.o
3// RUN: ld.lld %t.o -o %t.so -shared
4// RUN: llvm-readobj -s -l -section-data -r %t.so | FileCheck %s
5
6// CHECK: Name: .got
7// CHECK-NEXT: Type: SHT_PROGBITS
8// CHECK-NEXT: Flags [
9// CHECK-NEXT: SHF_ALLOC
10// CHECK-NEXT: SHF_WRITE
11// CHECK-NEXT: ]
12// CHECK-NEXT: Address:
13// CHECK-NEXT: Offset:
14// CHECK-NEXT: Size:
15// CHECK-NEXT: Link:
16// CHECK-NEXT: Info:
17// CHECK-NEXT: AddressAlignment:
18// CHECK-NEXT: EntrySize:
19// CHECK-NEXT: SectionData (
20// CHECK-NEXT: 0000: 00200000 |
21// CHECK-NEXT: )
22
23// CHECK: Relocations [
24// CHECK-NEXT: Section ({{.*}}) .rel.dyn {
25// CHECK-NEXT: 0x2050 R_386_RELATIVE - 0x0
26// CHECK-NEXT: }
27// CHECK-NEXT: ]
28
29// CHECK: Type: PT_DYNAMIC
30// CHECK-NEXT: Offset: 0x2000
31// CHECK-NEXT: VirtualAddress: 0x2000
32// CHECK-NEXT: PhysicalAddress: 0x2000
33
34 calll .L0$pb
35.L0$pb:
36 popl %eax
37.Ltmp0:
38 addl $_GLOBAL_OFFSET_TABLE_+(.Ltmp0-.L0$pb), %eax
39 movl _DYNAMIC@GOT(%eax), %eax
deps/lld/test/ELF/dynamic-list-extern.s created+15
......@@ -0,0 +1,15 @@
1# REQUIRES: x86
2
3# Test that we can parse multiple externs.
4
5# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
6
7# RUN: echo '{ \
8# RUN: extern "C" { \
9# RUN: foo; \
10# RUN: }; \
11# RUN: extern "C++" { \
12# RUN: bar; \
13# RUN: }; \
14# RUN: };' > %t.list
15# RUN: ld.lld --dynamic-list %t.list %t.o -shared -o %t.so
deps/lld/test/ELF/dynamic-list.s created+171
......@@ -0,0 +1,171 @@
1## There is some bad quoting interaction between lit's internal shell, which is
2## implemented in Python, and the Cygwin implementations of the Unix utilities.
3## Avoid running these tests on Windows for now by requiring a real shell.
4
5# REQUIRES: x86
6
7# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o
8# RUN: ld.lld -shared %t2.o -soname shared -o %t2.so
9# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
10
11## Check exporting only one symbol.
12# RUN: echo "{ foo1; };" > %t.list
13# RUN: ld.lld --dynamic-list %t.list %t %t2.so -o %t.exe
14# RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck %s
15
16## And now using quoted strings (the output is the same since it does
17## use any wildcard character).
18# RUN: echo "{ \"foo1\"; };" > %t.list
19# RUN: ld.lld --dynamic-list %t.list %t %t2.so -o %t.exe
20# RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck %s
21
22## And now using --export-dynamic-symbol.
23# RUN: ld.lld --export-dynamic-symbol foo1 %t %t2.so -o %t.exe
24# RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck %s
25# RUN: ld.lld --export-dynamic-symbol=foo1 %t %t2.so -o %t.exe
26# RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck %s
27
28# CHECK: DynamicSymbols [
29# CHECK-NEXT: Symbol {
30# CHECK-NEXT: Name: @
31# CHECK-NEXT: Value: 0x0
32# CHECK-NEXT: Size: 0
33# CHECK-NEXT: Binding: Local
34# CHECK-NEXT: Type: None
35# CHECK-NEXT: Other: 0
36# CHECK-NEXT: Section: Undefined
37# CHECK-NEXT: }
38# CHECK-NEXT: Symbol {
39# CHECK-NEXT: Name: foo1@
40# CHECK-NEXT: Value: 0x201000
41# CHECK-NEXT: Size: 0
42# CHECK-NEXT: Binding: Global (0x1)
43# CHECK-NEXT: Type: None (0x0)
44# CHECK-NEXT: Other: 0
45# CHECK-NEXT: Section: .text (0x4)
46# CHECK-NEXT: }
47# CHECK-NEXT: ]
48
49
50## Now export all the foo1, foo2, and foo31 symbols
51# RUN: echo "{ foo1; foo2; foo31; };" > %t.list
52# RUN: ld.lld --dynamic-list %t.list %t %t2.so -o %t.exe
53# RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck -check-prefix=CHECK2 %s
54# RUN: echo "{ foo1; foo2; };" > %t1.list
55# RUN: echo "{ foo31; };" > %t2.list
56# RUN: ld.lld --dynamic-list %t1.list --dynamic-list %t2.list %t %t2.so -o %t.exe
57# RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck -check-prefix=CHECK2 %s
58
59# CHECK2: DynamicSymbols [
60# CHECK2-NEXT: Symbol {
61# CHECK2-NEXT: Name: @
62# CHECK2-NEXT: Value: 0x0
63# CHECK2-NEXT: Size: 0
64# CHECK2-NEXT: Binding: Local
65# CHECK2-NEXT: Type: None
66# CHECK2-NEXT: Other: 0
67# CHECK2-NEXT: Section: Undefined
68# CHECK2-NEXT: }
69# CHECK2-NEXT: Symbol {
70# CHECK2-NEXT: Name: foo1@
71# CHECK2-NEXT: Value: 0x201000
72# CHECK2-NEXT: Size: 0
73# CHECK2-NEXT: Binding: Global (0x1)
74# CHECK2-NEXT: Type: None (0x0)
75# CHECK2-NEXT: Other: 0
76# CHECK2-NEXT: Section: .text (0x4)
77# CHECK2-NEXT: }
78# CHECK2-NEXT: Symbol {
79# CHECK2-NEXT: Name: foo2@
80# CHECK2-NEXT: Value: 0x201001
81# CHECK2-NEXT: Size: 0
82# CHECK2-NEXT: Binding: Global (0x1)
83# CHECK2-NEXT: Type: None (0x0)
84# CHECK2-NEXT: Other: 0
85# CHECK2-NEXT: Section: .text (0x4)
86# CHECK2-NEXT: }
87# CHECK2-NEXT: Symbol {
88# CHECK2-NEXT: Name: foo31@
89# CHECK2-NEXT: Value: 0x201002
90# CHECK2-NEXT: Size: 0
91# CHECK2-NEXT: Binding: Global (0x1)
92# CHECK2-NEXT: Type: None (0x0)
93# CHECK2-NEXT: Other: 0
94# CHECK2-NEXT: Section: .text (0x4)
95# CHECK2-NEXT: }
96# CHECK2-NEXT: ]
97
98
99## --export-dynamic overrides --dynamic-list, i.e. --export-dynamic with an
100## incomplete dynamic-list still exports everything.
101# RUN: echo "{ foo2; };" > %t.list
102# RUN: ld.lld --dynamic-list %t.list --export-dynamic %t %t2.so -o %t.exe
103# RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck -check-prefix=CHECK3 %s
104
105## The same with --export-dynamic-symbol.
106# RUN: ld.lld --export-dynamic-symbol=foo2 --export-dynamic %t %t2.so -o %t.exe
107# RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck -check-prefix=CHECK3 %s
108
109# CHECK3: DynamicSymbols [
110# CHECK3-NEXT: Symbol {
111# CHECK3-NEXT: Name: @
112# CHECK3-NEXT: Value: 0x0
113# CHECK3-NEXT: Size: 0
114# CHECK3-NEXT: Binding: Local
115# CHECK3-NEXT: Type: None
116# CHECK3-NEXT: Other: 0
117# CHECK3-NEXT: Section: Undefined
118# CHECK3-NEXT: }
119# CHECK3-NEXT: Symbol {
120# CHECK3-NEXT: Name: _start@
121# CHECK3-NEXT: Value: 0x201003
122# CHECK3-NEXT: Size: 0
123# CHECK3-NEXT: Binding: Global (0x1)
124# CHECK3-NEXT: Type: None (0x0)
125# CHECK3-NEXT: Other: 0
126# CHECK3-NEXT: Section: .text (0x4)
127# CHECK3-NEXT: }
128# CHECK3-NEXT: Symbol {
129# CHECK3-NEXT: Name: foo1@
130# CHECK3-NEXT: Value: 0x201000
131# CHECK3-NEXT: Size: 0
132# CHECK3-NEXT: Binding: Global (0x1)
133# CHECK3-NEXT: Type: None (0x0)
134# CHECK3-NEXT: Other: 0
135# CHECK3-NEXT: Section: .text (0x4)
136# CHECK3-NEXT: }
137# CHECK3-NEXT: Symbol {
138# CHECK3-NEXT: Name: foo2@
139# CHECK3-NEXT: Value: 0x201001
140# CHECK3-NEXT: Size: 0
141# CHECK3-NEXT: Binding: Global (0x1)
142# CHECK3-NEXT: Type: None (0x0)
143# CHECK3-NEXT: Other: 0
144# CHECK3-NEXT: Section: .text (0x4)
145# CHECK3-NEXT: }
146# CHECK3-NEXT: Symbol {
147# CHECK3-NEXT: Name: foo31@
148# CHECK3-NEXT: Value: 0x201002
149# CHECK3-NEXT: Size: 0
150# CHECK3-NEXT: Binding: Global (0x1)
151# CHECK3-NEXT: Type: None (0x0)
152# CHECK3-NEXT: Other: 0
153# CHECK3-NEXT: Section: .text (0x4)
154# CHECK3-NEXT: }
155# CHECK3-NEXT: ]
156
157.globl foo1
158foo1:
159 ret
160
161.globl foo2
162foo2:
163 ret
164
165.globl foo31
166foo31:
167 ret
168
169.globl _start
170_start:
171 retq
deps/lld/test/ELF/dynamic-reloc-in-ro.s created+10
......@@ -0,0 +1,10 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s
4
5// CHECK: can't create dynamic relocation R_X86_64_64 against local symbol in readonly segment
6// CHECK: >>> defined in {{.*}}.o
7// CHECK: >>> referenced by {{.*}}.o:(.text+0x0)
8
9foo:
10.quad foo
deps/lld/test/ELF/dynamic-reloc-index.s created+21
......@@ -0,0 +1,21 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o
3// RUN: ld.lld -shared %t2.o -o %t2.so
4// RUN: ld.lld %t.o %t2.so -o %t
5// RUN: llvm-readobj -r %t | FileCheck %s
6
7// We used to record the wrong symbol index for this test
8
9// CHECK: Relocations [
10// CHECK-NEXT: Section ({{.*}}) .rela.plt {
11// CHECK-NEXT: 0x202018 R_X86_64_JUMP_SLOT bar 0x0
12// CHECK-NEXT: }
13// CHECK-NEXT: ]
14
15 .global foobar
16foobar:
17 .global zedx
18zedx:
19 .global _start
20_start:
21.quad bar
deps/lld/test/ELF/dynamic-reloc-weak.s created+37
......@@ -0,0 +1,37 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/dynamic-reloc-weak.s -o %t2.o
3// RUN: ld.lld -shared %t2.o -o %t2.so
4// RUN: ld.lld %t.o %t2.so -o %t
5// RUN: llvm-readobj -r %t | FileCheck %s
6// REQUIRES: x86
7
8 .globl _start
9_start:
10 .type sym1,@function
11 .weak sym1
12 .long sym1@gotpcrel
13
14 .type sym2,@function
15 .weak sym2
16 .long sym2@plt
17
18 .type sym3,@function
19 .weak sym3
20 .quad sym3
21
22 .type sym4,@function
23 .weak sym4
24 .quad sym4
25
26// Test that we produce dynamic relocation for every weak undefined symbol
27// we found.
28
29// CHECK: Relocations [
30// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
31// CHECK-NEXT: 0x{{.*}} R_X86_64_GLOB_DAT sym1 0x0
32// CHECK-NEXT: }
33// CHECK-NEXT: Section ({{.*}}) .rela.plt {
34// CHECK-NEXT: 0x{{.*}} R_X86_64_JUMP_SLOT sym2 0x0
35// CHECK-NEXT: 0x{{.*}} R_X86_64_JUMP_SLOT sym3 0x0
36// CHECK-NEXT: }
37// CHECK-NEXT: ]
deps/lld/test/ELF/dynamic-reloc.s created+65
......@@ -0,0 +1,65 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o
3// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/dynamic-reloc.s -o %t3.o
4// RUN: ld.lld -shared %t2.o -o %t2.so
5// RUN: ld.lld %t.o %t3.o %t2.so -o %t
6// RUN: llvm-readobj -dynamic-table -r --expand-relocs -s %t | FileCheck %s
7// REQUIRES: x86
8
9// CHECK: Index: 1
10// CHECK-NEXT: Name: .dynsym
11
12// CHECK: Name: .rela.plt
13// CHECK-NEXT: Type: SHT_RELA
14// CHECK-NEXT: Flags [
15// CHECK-NEXT: SHF_ALLOC
16// CHECK-NEXT: ]
17// CHECK-NEXT: Address: [[RELAADDR:.*]]
18// CHECK-NEXT: Offset:
19// CHECK-NEXT: Size: [[RELASIZE:.*]]
20// CHECK-NEXT: Link: 1
21// CHECK-NEXT: Info: 0
22// CHECK-NEXT: AddressAlignment: 8
23// CHECK-NEXT: EntrySize: 24
24
25// CHECK: Name: .text
26// CHECK-NEXT: Type: SHT_PROGBITS
27// CHECK-NEXT: Flags [
28// CHECK-NEXT: SHF_ALLOC
29// CHECK-NEXT: SHF_EXECINSTR
30// CHECK-NEXT: ]
31// CHECK-NEXT: Address: 0x201000
32
33// CHECK: Relocations [
34// CHECK-NEXT: Section ({{.*}}) .rela.plt {
35// CHECK-NEXT: Relocation {
36// CHECK-NEXT: Offset: 0x202018
37// CHECK-NEXT: Type: R_X86_64_JUMP_SLOT
38// CHECK-NEXT: Symbol: bar
39// CHECK-NEXT: Addend: 0x0
40// CHECK-NEXT: }
41// CHECK-NEXT: }
42// CHECK-NEXT: ]
43
44// CHECK: DynamicSection [
45// CHECK-NEXT: Tag Type Name/Value
46// CHECK-NEXT: 0x0000000000000001 NEEDED Shared library: [{{.*}}2.so]
47// CHECK-NEXT: 0x0000000000000015 DEBUG 0x0
48// CHECK-NEXT: 0x0000000000000017 JMPREL
49// CHECK-NEXT: 0x0000000000000002 PLTRELSZ 24 (bytes)
50// CHECK-NEXT: 0x0000000000000003 PLTGOT
51// CHECK-NEXT: 0x0000000000000014 PLTREL RELA
52// CHECK-NEXT: 0x0000000000000006 SYMTAB
53// CHECK-NEXT: 0x000000000000000B SYMENT 24 (bytes)
54// CHECK-NEXT: 0x0000000000000005 STRTAB
55// CHECK-NEXT: 0x000000000000000A STRSZ
56// CHECK-NEXT: 0x0000000000000004 HASH
57// CHECK-NEXT: 0x0000000000000000 NULL 0x0
58// CHECK-NEXT: ]
59
60.global _start
61_start:
62.quad bar + 0x42
63.weak foo
64.quad foo
65call main
deps/lld/test/ELF/dynamic.s created+44
......@@ -0,0 +1,44 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %t.o
3
4## Check that _DYNAMIC symbol is created when creating dynamic output,
5## and has hidden visibility and address equal to .dynamic section.
6# RUN: ld.lld -shared %t.o -o %t.so
7# RUN: llvm-readobj -sections -symbols %t.so | FileCheck %s
8# CHECK: Section {
9# CHECK: Index: 5
10# CHECK: Name: .dynamic
11# CHECK-NEXT: Type: SHT_DYNAMIC
12# CHECK-NEXT: Flags [
13# CHECK-NEXT: SHF_ALLOC
14# CHECK-NEXT: SHF_WRITE
15# CHECK-NEXT: ]
16# CHECK-NEXT: Address: 0x[[ADDR:.*]]
17# CHECK-NEXT: Offset: 0x1000
18# CHECK-NEXT: Size:
19# CHECK-NEXT: Link:
20# CHECK-NEXT: Info:
21# CHECK-NEXT: AddressAlignment:
22# CHECK-NEXT: EntrySize:
23# CHECK-NEXT: }
24# CHECK: Symbols [
25# CHECK: Symbol {
26# CHECK: Name: _DYNAMIC
27# CHECK-NEXT: Value: 0x[[ADDR]]
28# CHECK-NEXT: Size: 0
29# CHECK-NEXT: Binding: Local
30# CHECK-NEXT: Type: None
31# CHECK-NEXT: Other [ (0x2)
32# CHECK-NEXT: STV_HIDDEN
33# CHECK-NEXT: ]
34# CHECK-NEXT: Section: .dynamic
35# CHECK-NEXT: }
36
37# RUN: ld.lld %t.o -o %t2
38# RUN: llvm-readobj -sections -symbols %t2 | FileCheck -check-prefix=NODYN %s
39# NODYN: Symbols [
40# NODYN-NOT: Name: _DYNAMIC
41# NODYN: ]
42
43.globl _start
44_start:
deps/lld/test/ELF/dynsym-pie.s created+36
......@@ -0,0 +1,36 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
3# RUN: ld.lld -pie %t -o %t.out
4# RUN: llvm-readobj -t -dyn-symbols %t.out | FileCheck %s
5
6# CHECK: DynamicSymbols [
7# CHECK-NEXT: Symbol {
8# CHECK-NEXT: Name: @
9# CHECK-NEXT: Value: 0x0
10# CHECK-NEXT: Size: 0
11# CHECK-NEXT: Binding: Local
12# CHECK-NEXT: Type: None
13# CHECK-NEXT: Other: 0
14# CHECK-NEXT: Section: Undefined
15# CHECK-NEXT: }
16# CHECK-NEXT: ]
17
18.text
19.globl _start
20_start:
21
22.global default
23default:
24
25.global protected
26protected:
27
28.global hidden
29hidden:
30
31.global internal
32internal:
33
34.global protected_with_hidden
35.protected
36protected_with_hidden:
deps/lld/test/ELF/early-exit-for-bad-paths.s created+35
......@@ -0,0 +1,35 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3
4# RUN: not ld.lld %t.o -o does_not_exist/output 2>&1 | \
5# RUN: FileCheck %s -check-prefixes=NO-DIR-OUTPUT,CHECK
6# RUN: not ld.lld %t.o -o %s/dir_is_a_file 2>&1 | \
7# RUN: FileCheck %s -check-prefixes=DIR-IS-OUTPUT,CHECK
8
9# RUN: echo "OUTPUT(\"does_not_exist/output\")" > %t.script
10# RUN: not ld.lld %t.o %t.script 2>&1 | \
11# RUN: FileCheck %s -check-prefixes=NO-DIR-OUTPUT,CHECK
12# RUN: echo "OUTPUT(\"%s/dir_is_a_file\")" > %t.script
13# RUN: not ld.lld %t.o %t.script 2>&1 | \
14# RUN: FileCheck %s -check-prefixes=DIR-IS-OUTPUT,CHECK
15
16# RUN: not ld.lld %t.o -o %t -Map=does_not_exist/output 2>&1 | \
17# RUN: FileCheck %s -check-prefixes=NO-DIR-MAP,CHECK
18# RUN: not ld.lld %t.o -o %t -Map=%s/dir_is_a_file 2>&1 | \
19# RUN: FileCheck %s -check-prefixes=DIR-IS-MAP,CHECK
20
21# NO-DIR-OUTPUT: error: cannot open output file does_not_exist/output:
22# DIR-IS-OUTPUT: error: cannot open output file {{.*}}/dir_is_a_file:
23# NO-DIR-MAP: error: cannot open map file does_not_exist/output:
24# DIR-IS-MAP: error: cannot open map file {{.*}}/dir_is_a_file:
25
26# We should exit before doing the actual link. If an undefined symbol error is
27# discovered we haven't bailed out early as expected.
28# CHECK-NOT: undefined_symbol
29
30# RUN: not ld.lld %t.o -o / 2>&1 | FileCheck %s -check-prefixes=ROOT,CHECK
31# ROOT: error: cannot open output file /
32
33 .globl _start
34_start:
35 call undefined_symbol
deps/lld/test/ELF/edata-etext.s created+40
......@@ -0,0 +1,40 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: ld.lld %t.o -o %t
4# RUN: llvm-objdump -t -section-headers %t | FileCheck %s
5
6## This checks that:
7## 1) Address of _etext is the first location after the last read-only loadable segment.
8## 2) Address of _edata points to the end of the last non SHT_NOBITS section.
9## That is how gold/bfd do. At the same time specs says: "If the address of _edata is
10## greater than the address of _etext, the address of _end is same as the address
11## of _edata." (https://docs.oracle.com/cd/E53394_01/html/E54766/u-etext-3c.html).
12## 3) Address of _end is different from _edata because of 2.
13# CHECK: Sections:
14# CHECK-NEXT: Idx Name Size Address Type
15# CHECK-NEXT: 0 00000000 0000000000000000
16# CHECK-NEXT: 1 .text 00000001 0000000000201000 TEXT DATA
17# CHECK-NEXT: 2 .data 00000002 0000000000202000 DATA
18# CHECK-NEXT: 3 .bss 00000006 0000000000202004 BSS
19# CHECK: SYMBOL TABLE:
20# CHECK-NEXT: 0000000000000000 *UND* 00000000
21# CHECK-NEXT: 0000000000202002 .data 00000000 _edata
22# CHECK-NEXT: 000000000020200a .data 00000000 _end
23# CHECK-NEXT: 0000000000201001 .text 00000000 _etext
24# CHECK-NEXT: 0000000000201000 .text 00000000 _start
25
26# RUN: ld.lld -r %t.o -o %t2
27# RUN: llvm-objdump -t %t2 | FileCheck %s --check-prefix=RELOCATABLE
28# RELOCATABLE: 0000000000000000 *UND* 00000000 _edata
29# RELOCATABLE-NEXT: 0000000000000000 *UND* 00000000 _end
30# RELOCATABLE-NEXT: 0000000000000000 *UND* 00000000 _etext
31
32.global _start,_end,_etext,_edata
33.text
34_start:
35 nop
36.data
37 .word 1
38.bss
39 .align 4
40 .space 6
deps/lld/test/ELF/eh-align-cie.s created+57
......@@ -0,0 +1,57 @@
1// REQUIRES: x86
2
3 .cfi_startproc
4 .cfi_personality 0x1b, bar
5 .cfi_endproc
6
7.global bar
8.hidden bar
9bar:
10
11// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
12// RUN: llvm-readobj -s -section-data %t.o | FileCheck --check-prefix=OBJ %s
13
14// Check the size of the CIE (0x18 + 4) an FDE (0x10 + 4)
15// OBJ: Name: .eh_frame
16// OBJ-NEXT: Type:
17// OBJ-NEXT: Flags [
18// OBJ-NEXT: SHF_ALLOC
19// OBJ-NEXT: ]
20// OBJ-NEXT: Address:
21// OBJ-NEXT: Offset:
22// OBJ-NEXT: Size:
23// OBJ-NEXT: Link:
24// OBJ-NEXT: Info:
25// OBJ-NEXT: AddressAlignment:
26// OBJ-NEXT: EntrySize:
27// OBJ-NEXT: SectionData (
28// OBJ-NEXT: 0000: 18000000 00000000 017A5052 00017810
29// OBJ-NEXT: 0010: 061B0000 00001B0C 07089001 10000000
30// OBJ-NEXT: 0020: 20000000 00000000 00000000 00000000
31// OBJ-NEXT: )
32
33
34// RUN: ld.lld %t.o -o %t -shared
35// RUN: llvm-readobj -s -section-data %t | FileCheck %s
36
37// Check that the size of the CIE was changed to (0x1C + 4) and the FDE one was
38// changed to (0x14 + 4)
39
40// CHECK: Name: .eh_frame
41// CHECK-NEXT: Type:
42// CHECK-NEXT: Flags
43// CHECK-NEXT: SHF_ALLOC
44// CHECK-NEXT: ]
45// CHECK-NEXT: Address:
46// CHECK-NEXT: Offset:
47// CHECK-NEXT: Size:
48// CHECK-NEXT: Link:
49// CHECK-NEXT: Info:
50// CHECK-NEXT: AddressAlignment:
51// CHECK-NEXT: EntrySize:
52// CHECK-NEXT: SectionData (
53// CHECK-NEXT: 0000: 1C000000 00000000 017A5052 00017810
54// CHECK-NEXT: 0010: 061BF60D 00001B0C 07089001 00000000
55// CHECK-NEXT: 0020: 14000000 24000000 E00D0000 00000000
56// CHECK-NEXT: 0030: 00000000 00000000
57// CHECK-NEXT: )
deps/lld/test/ELF/eh-frame-begin-end.s created+17
......@@ -0,0 +1,17 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=amd64-unknown-openbsd %s -o %t.o
3// RUN: llvm-mc -filetype=obj -triple=amd64-unknown-openbsd %p/Inputs/eh-frame-end.s -o %t2.o
4// RUN: ld.lld %t.o %t2.o -o %t
5// RUN: llvm-readobj -sections %t | FileCheck %s
6
7// CHECK: Name: .eh_frame
8// CHECK-NEXT: Type: SHT_PROGBITS
9// CHECK-NEXT: Flags [
10// CHECK-NEXT: SHF_ALLOC
11// CHECK-NEXT: ]
12// CHECK-NEXT: Address: 0x200120
13// CHECK-NEXT: Offset: 0x120
14// CHECK-NEXT: Size: 4
15
16 .section ".eh_frame", "a", @progbits
17__EH_FRAME_BEGIN__:
deps/lld/test/ELF/eh-frame-dyn-rel.s created+12
......@@ -0,0 +1,12 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: not ld.lld %t.o %t.o -o %t -shared 2>&1 | FileCheck %s
4
5// CHECK: can't create dynamic relocation R_X86_64_64 against symbol: foo
6// CHECK: >>> defined in {{.*}}.o
7// CHECK: >>> referenced by {{.*}}.o:(.eh_frame+0x12)
8
9.section bar,"axG",@progbits,foo,comdat
10.cfi_startproc
11.cfi_personality 0x8c, foo
12.cfi_endproc
deps/lld/test/ELF/eh-frame-gc.s created+20
......@@ -0,0 +1,20 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
3# RUN: ld.lld -shared --gc-sections %t.o -o %t
4# RUN: llvm-readobj -s %t | FileCheck %s
5
6## Check that section containing personality is
7## not garbage collected.
8# CHECK: Sections [
9# CHECK: Name: .test_personality_section
10
11.text
12.globl foo
13.type foo,@function
14foo:
15 .cfi_startproc
16 .cfi_personality 155, DW.ref.__gxx_personality_v0
17 .cfi_endproc
18
19.section .test_personality_section
20DW.ref.__gxx_personality_v0:
deps/lld/test/ELF/eh-frame-gc2.s created+15
......@@ -0,0 +1,15 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
3// RUN: ld.lld --gc-sections %t.o -o %t
4// RUN: llvm-readobj -s %t | FileCheck %s
5
6// Test that the we don't gc the personality function.
7// CHECK: Name: .foobar
8
9 .globl _start
10_start:
11 .cfi_startproc
12 .cfi_personality 3, foobar
13 .cfi_endproc
14 .section .foobar,"ax"
15foobar:
deps/lld/test/ELF/eh-frame-hdr-abs-fde.s created+33
......@@ -0,0 +1,33 @@
1# Check reading PC values of FDEs and writing lookup table in the .eh_frame_hdr
2# if CIE augmentation string has 'L' token and PC values are encoded using
3# absolute (not relative) format.
4
5# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
6# RUN: ld.lld --eh-frame-hdr %t.o -o %t
7# RUN: llvm-objdump -s -dwarf=frames %t | FileCheck %s
8
9# REQUIRES: mips
10
11# CHECK: Contents of section .eh_frame_hdr:
12# CHECK-NEXT: 10128 011b033b 00000010 00000001 0000fed8
13# ^-- 0x20000 - 0x10138
14# .text - .eh_frame_hdr
15# CHECK-NEXT: 10138 0000002c
16# CHECK: Contents of section .text:
17# CHECK-NEXT: 20000 00000000
18
19# CHECK: Augmentation: "zLR"
20# CHECK: Augmentation data: 00 0B
21# ^-- DW_EH_PE_udata4 | DW_EH_PE_signed
22
23 .text
24 .globl __start
25__start:
26 .cfi_startproc
27 .cfi_lsda 0, _ex
28 nop
29 .cfi_endproc
30
31 .data
32_ex:
33 .word 0
deps/lld/test/ELF/eh-frame-hdr-augmentation.s created+38
......@@ -0,0 +1,38 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: ld.lld --eh-frame-hdr %t.o -o %t -shared
4// RUN: llvm-objdump --dwarf=frames %t | FileCheck %s
5
6// CHECK: .eh_frame contents:
7
8// CHECK: 00000000 0000001c ffffffff CIE
9// CHECK-NEXT: Version: 1
10// CHECK-NEXT: Augmentation: "zPLR"
11// CHECK-NEXT: Code alignment factor: 1
12// CHECK-NEXT: Data alignment factor: -8
13// CHECK-NEXT: Return address column: 16
14// CHECK-NEXT: Augmentation data:
15
16// CHECK: DW_CFA_def_cfa: reg7 +8
17// CHECK-NEXT: DW_CFA_offset: reg16 -8
18// CHECK-NEXT: DW_CFA_nop:
19// CHECK-NEXT: DW_CFA_nop:
20
21// CHECK: 00000020 00000014 00000024 FDE cie=00000024 pc=00000d98...00000d98
22// CHECK-NEXT: DW_CFA_nop:
23// CHECK-NEXT: DW_CFA_nop:
24// CHECK-NEXT: DW_CFA_nop:
25
26 .cfi_startproc
27 .cfi_personality 0x9b, g
28 .cfi_lsda 0x1b, h
29 .cfi_endproc
30
31 .global g
32 .hidden g
33g:
34
35 .global h
36 .hidden h
37h:
38
deps/lld/test/ELF/eh-frame-hdr-icf.s created+27
......@@ -0,0 +1,27 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
4# RUN: ld.lld %t -o %t2 --icf=all --eh-frame-hdr
5# RUN: llvm-objdump -s %t2 | FileCheck %s
6
7# CHECK: Contents of section .eh_frame_hdr:
8# CHECK-NEXT: 200158 011b033b 1c000000 01000000 a80e0000
9# ^ FDE count
10# CHECK-NEXT: 200168 38000000 00000000 00000000
11# ^ FDE for f2
12
13.globl _start, f1, f2
14_start:
15 ret
16
17.section .text.f1, "ax"
18f1:
19 .cfi_startproc
20 ret
21 .cfi_endproc
22
23.section .text.f2, "ax"
24f2:
25 .cfi_startproc
26 ret
27 .cfi_endproc
deps/lld/test/ELF/eh-frame-hdr-no-out2.s created+19
......@@ -0,0 +1,19 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: ld.lld --eh-frame-hdr %t.o -o %t
4// RUN: llvm-readobj -s -program-headers %t | FileCheck %s --check-prefix=NOHDR
5
6.section foo,"ax",@progbits
7 nop
8
9.text
10.globl _start
11_start:
12
13// There is no .eh_frame section,
14// therefore .eh_frame_hdr also not created.
15// NOHDR: Sections [
16// NOHDR-NOT: Name: .eh_frame
17// NOHDR-NOT: Name: .eh_frame_hdr
18// NOHDR: ProgramHeaders [
19// NOHDR-NOT: PT_GNU_EH_FRAME
deps/lld/test/ELF/eh-frame-hdr.s created+126
......@@ -0,0 +1,126 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: ld.lld %t.o -o %t
4// RUN: llvm-readobj -file-headers -s -section-data -program-headers -symbols %t | FileCheck %s --check-prefix=NOHDR
5// RUN: ld.lld --eh-frame-hdr %t.o -o %t
6// RUN: llvm-readobj -file-headers -s -section-data -program-headers -symbols %t | FileCheck %s --check-prefix=HDR
7// RUN: llvm-objdump -d %t | FileCheck %s --check-prefix=HDRDISASM
8
9.section foo,"ax",@progbits
10.cfi_startproc
11 nop
12.cfi_endproc
13
14.section bar,"ax",@progbits
15.cfi_startproc
16 nop
17.cfi_endproc
18
19.section dah,"ax",@progbits
20.cfi_startproc
21 nop
22.cfi_endproc
23
24.text
25.globl _start
26_start:
27
28// NOHDR: Sections [
29// NOHDR-NOT: Name: .eh_frame_hdr
30// NOHDR: ProgramHeaders [
31// NOHDR-NOT: PT_GNU_EH_FRAME
32
33//HDRDISASM: Disassembly of section foo:
34//HDRDISASM-NEXT: foo:
35//HDRDISASM-NEXT: 201000: 90 nop
36//HDRDISASM-NEXT: Disassembly of section bar:
37//HDRDISASM-NEXT: bar:
38//HDRDISASM-NEXT: 201001: 90 nop
39//HDRDISASM-NEXT: Disassembly of section dah:
40//HDRDISASM-NEXT: dah:
41//HDRDISASM-NEXT: 201002: 90 nop
42
43// HDR: Section {
44// HDR: Index:
45// HDR: Name: .eh_frame_hdr
46// HDR-NEXT: Type: SHT_PROGBITS
47// HDR-NEXT: Flags [
48// HDR-NEXT: SHF_ALLOC
49// HDR-NEXT: ]
50// HDR-NEXT: Address: 0x200158
51// HDR-NEXT: Offset: 0x158
52// HDR-NEXT: Size: 36
53// HDR-NEXT: Link: 0
54// HDR-NEXT: Info: 0
55// HDR-NEXT: AddressAlignment: 1
56// HDR-NEXT: EntrySize: 0
57// HDR-NEXT: SectionData (
58// HDR-NEXT: 0000: 011B033B 24000000 03000000 A80E0000
59// HDR-NEXT: 0010: 40000000 A90E0000 58000000 AA0E0000
60// HDR-NEXT: 0020: 70000000
61// HDR-NEXT: )
62// Header (always 4 bytes): 0x011B033B
63// 24000000 = .eh_frame(0x200180) - .eh_frame_hdr(0x200158) - 4
64// 03000000 = 3 = the number of FDE pointers in the table.
65// Entry(1): A80E0000 40000000
66// 480E0000 = 0x201000 - .eh_frame_hdr(0x200158) = 0xEA8
67// 40000000 = address of FDE(1) - .eh_frame_hdr(0x200158) =
68// = .eh_frame(0x200180) + 24 - 0x200158 = 0x40
69// Entry(2): A90E0000 58000000
70// A90E0000 = 0x201001 - .eh_frame_hdr(0x200158) = 0xEA9
71// 58000000 = address of FDE(2) - .eh_frame_hdr(0x200158) =
72// = .eh_frame(0x200180) + 24 + 24 - 0x200158 = 0x58
73// Entry(3): AA0E0000 70000000
74// AA0E0000 = 0x201002 - .eh_frame_hdr(0x200158) = 0xEAA
75// 70000000 = address of FDE(3) - .eh_frame_hdr(0x200158) =
76// = .eh_frame(0x200180) + 24 + 24 + 24 - 0x200158 = 0x70
77// HDR-NEXT: }
78// HDR-NEXT: Section {
79// HDR-NEXT: Index:
80// HDR-NEXT: Name: .eh_frame
81// HDR-NEXT: Type: SHT_PROGBITS
82// HDR-NEXT: Flags [
83// HDR-NEXT: SHF_ALLOC
84// HDR-NEXT: ]
85// HDR-NEXT: Address: 0x200180
86// HDR-NEXT: Offset: 0x180
87// HDR-NEXT: Size: 96
88// HDR-NEXT: Link: 0
89// HDR-NEXT: Info: 0
90// HDR-NEXT: AddressAlignment: 8
91// HDR-NEXT: EntrySize: 0
92// HDR-NEXT: SectionData (
93// HDR-NEXT: 0000: 14000000 00000000 017A5200 01781001
94// HDR-NEXT: 0010: 1B0C0708 90010000 14000000 1C000000
95// HDR-NEXT: 0020: 600E0000 01000000 00000000 00000000
96// HDR-NEXT: 0030: 14000000 34000000 490E0000 01000000
97// HDR-NEXT: 0040: 00000000 00000000 14000000 4C000000
98// HDR-NEXT: 0050: 320E0000 01000000 00000000 00000000
99// HDR-NEXT: )
100// CIE: 14000000 00000000 017A5200 01781001 1B0C0708 90010000
101// FDE(1): 14000000 1C000000 600E0000 01000000 00000000 00000000
102// address of data (starts with 0x600E0000) = 0x200180 + 0x0020 = 0x2001A0
103// The starting address to which this FDE applies = 0xE60 + 0x2001A0 = 0x201000
104// The number of bytes after the start address to which this FDE applies = 0x01000000 = 1
105// FDE(2): 14000000 34000000 490E0000 01000000 00000000 00000000
106// address of data (starts with 0x490E0000) = 0x200180 + 0x0038 = 0x2001B8
107// The starting address to which this FDE applies = 0xE49 + 0x2001B8 = 0x201001
108// The number of bytes after the start address to which this FDE applies = 0x01000000 = 1
109// FDE(3): 14000000 4C000000 320E0000 01000000 00000000 00000000
110// address of data (starts with 0x320E0000) = 0x200180 + 0x0050 = 0x2001D0
111// The starting address to which this FDE applies = 0xE5A + 0x2001D0 = 0x201002
112// The number of bytes after the start address to which this FDE applies = 0x01000000 = 1
113// HDR-NEXT: }
114// HDR: ProgramHeaders [
115// HDR: ProgramHeader {
116// HDR: Type: PT_GNU_EH_FRAME
117// HDR-NEXT: Offset: 0x158
118// HDR-NEXT: VirtualAddress: 0x200158
119// HDR-NEXT: PhysicalAddress: 0x200158
120// HDR-NEXT: FileSize: 36
121// HDR-NEXT: MemSize: 36
122// HDR-NEXT: Flags [
123// HDR-NEXT: PF_R
124// HDR-NEXT: ]
125// HDR-NEXT: Alignment: 1
126// HDR-NEXT: }
deps/lld/test/ELF/eh-frame-marker.s created+19
......@@ -0,0 +1,19 @@
1// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
2// RUN: ld.lld --eh-frame-hdr %t.o -o %t.so -shared
3// RUN: llvm-readobj -t -s %t.so | FileCheck %s
4// We used to crash on this.
5
6// CHECK: Name: .eh_frame_hdr
7// CHECK: Name: .eh_frame
8// CHECK-NEXT: Type: SHT_PROGBITS
9// CHECK-NEXT: Flags [
10// CHECK-NEXT: SHF_ALLOC
11// CHECK-NEXT: ]
12// CHECK-NEXT: Address: [[ADDR:.*]]
13
14// CHECK: Name: foo
15// CHECK-NEXT: Value: [[ADDR]]
16
17 .section .eh_frame
18foo:
19 .long 0
deps/lld/test/ELF/eh-frame-merge.s created+58
......@@ -0,0 +1,58 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: ld.lld %t.o %t.o -o %t -shared
4// RUN: llvm-readobj -s -section-data %t | FileCheck %s
5
6 .section foo,"ax",@progbits
7 .cfi_startproc
8 nop
9 .cfi_endproc
10
11 .section bar,"axG",@progbits,foo,comdat
12 .cfi_startproc
13 nop
14 nop
15 .cfi_endproc
16
17// FIXME: We could really use a .eh_frame parser.
18// The intention is to show that:
19// * There is only one copy of the CIE
20// * There are two copies of the first FDE
21// * There is only one copy of the second FDE
22
23// CHECK: Name: .eh_frame
24// CHECK-NEXT: Type: SHT_PROGBITS
25// CHECK-NEXT: Flags [
26// CHECK-NEXT: SHF_ALLOC
27// CHECK-NEXT: ]
28// CHECK-NEXT: Address:
29// CHECK-NEXT: Offset:
30// CHECK-NEXT: Size: 96
31// CHECK-NEXT: Link: 0
32// CHECK-NEXT: Info: 0
33// CHECK-NEXT: AddressAlignment: 8
34// CHECK-NEXT: EntrySize: 0
35// CHECK-NEXT: SectionData (
36// CHECK-NEXT: 0000: 14000000 00000000 017A5200 01781001 |
37// CHECK-NEXT: 0010: 1B0C0708 90010000 14000000 1C000000 |
38// CHECK-NEXT: 0020: E80D0000 01000000 00000000 00000000 |
39// CHECK-NEXT: 0030: 14000000 34000000 D20D0000 02000000 |
40// CHECK-NEXT: 0040: 00000000 00000000 14000000 4C000000 |
41// CHECK-NEXT: 0050: B90D0000 01000000 00000000 00000000 |
42// CHECK-NEXT: )
43
44// CHECK: Name: foo
45// CHECK-NEXT: Type: SHT_PROGBITS
46// CHECK-NEXT: Flags [
47// CHECK-NEXT: SHF_ALLOC
48// CHECK-NEXT: SHF_EXECINSTR
49// CHECK-NEXT: ]
50// CHECK-NEXT: Address: 0x1000
51
52// CHECK: Name: bar
53// CHECK-NEXT: Type: SHT_PROGBITS
54// CHECK-NEXT: Flags [
55// CHECK-NEXT: SHF_ALLOC
56// CHECK-NEXT: SHF_EXECINSTR
57// CHECK-NEXT: ]
58// CHECK-NEXT: Address: 0x1002
deps/lld/test/ELF/eh-frame-multilpe-cie.s created+12
......@@ -0,0 +1,12 @@
1// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
2// RUN: ld.lld --eh-frame-hdr %t.o -o %t.so -shared
3// We would fail to parse multiple cies in the same file.
4
5 .cfi_startproc
6 .cfi_personality 0x9b, foo
7 .cfi_endproc
8
9 .cfi_startproc
10 .cfi_endproc
11
12foo:
deps/lld/test/ELF/eh-frame-plt.s created+16
......@@ -0,0 +1,16 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/shared.s -o %t.o
3// RUN: ld.lld %t.o -o %t.so -shared
4// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t2.o
5// RUN: ld.lld %t2.o %t.so -o %t
6// RUN: llvm-readobj -r %t | FileCheck %s
7
8 .globl _start
9_start:
10 .cfi_startproc
11 .cfi_personality 3, bar
12 .cfi_endproc
13
14// CHECK: Section ({{.*}}) .rela.plt {
15// CHECK-NEXT: R_X86_64_JUMP_SLOT bar 0x0
16// CHECK-NEXT: }
deps/lld/test/ELF/eh-frame-rel.s created+7
......@@ -0,0 +1,7 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
3// RUN: ld.lld %t.o %t.o -o %t -shared
4// We used to try to read the relocations as RELA and error out
5
6 .cfi_startproc
7 .cfi_endproc
deps/lld/test/ELF/eh-frame-type.test created+17
......@@ -0,0 +1,17 @@
1# RUN: yaml2obj %s -o %t.o
2# RUN: ld.lld %t.o -o %t -shared
3# RUN: llvm-readobj -s %t | FileCheck %s
4
5# CHECK: Name: .eh_frame
6# CHECK-NEXT: Type: SHT_PROGBITS
7
8!ELF
9FileHeader:
10 Class: ELFCLASS64
11 Data: ELFDATA2LSB
12 Type: ET_REL
13 Machine: EM_X86_64
14Sections:
15 - Name: .eh_frame
16 Type: SHT_PROGBITS
17 Flags: [ SHF_ALLOC ]
deps/lld/test/ELF/ehdr_start.s created+41
......@@ -0,0 +1,41 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
4# RUN: ld.lld %t.o -o %t
5# RUN: llvm-readobj -symbols %t | FileCheck %s
6# CHECK: Name: __ehdr_start (1)
7# CHECK-NEXT: Value: 0x200000
8# CHECK-NEXT: Size: 0
9# CHECK-NEXT: Binding: Local (0x0)
10# CHECK-NEXT: Type: None (0x0)
11# CHECK-NEXT: Other [ (0x2)
12# CHECK-NEXT: STV_HIDDEN (0x2)
13# CHECK-NEXT: ]
14# CHECK-NEXT: Section: .text (0x1)
15
16# CHECK: Name: __executable_start
17# CHECK-NEXT: Value: 0x200000
18# CHECK-NEXT: Size: 0
19# CHECK-NEXT: Binding: Local
20# CHECK-NEXT: Type: None
21# CHECK-NEXT: Other [
22# CHECK-NEXT: STV_HIDDEN
23# CHECK-NEXT: ]
24# CHECK-NEXT: Section: .text
25
26.text
27.global _start, __ehdr_start
28_start:
29 .quad __ehdr_start
30 .quad __executable_start
31
32# RUN: ld.lld -r %t.o -o %t.r
33# RUN: llvm-readobj -symbols %t.r | FileCheck %s --check-prefix=RELOCATABLE
34
35# RELOCATABLE: Name: __ehdr_start (1)
36# RELOCATABLE-NEXT: Value: 0x0
37# RELOCATABLE-NEXT: Size: 0
38# RELOCATABLE-NEXT: Binding: Global (0x1)
39# RELOCATABLE-NEXT: Type: None (0x0)
40# RELOCATABLE-NEXT: Other: 0
41# RELOCATABLE-NEXT: Section: Undefined (0x0)
deps/lld/test/ELF/ehframe-relocation.s created+31
......@@ -0,0 +1,31 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/ehframe-relocation.s -o %t2.o
4// RUN: ld.lld %t.o %t2.o -o %t
5// RUN: llvm-readobj -s %t | FileCheck %s
6// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
7
8// CHECK: Name: .eh_frame
9// CHECK-NEXT: Type: SHT_PROGBITS
10// CHECK-NEXT: Flags [
11// CHECK-NEXT: SHF_ALLOC
12// CHECK-NEXT: ]
13// CHECK-NEXT: Address: 0x200120
14// CHECK-NEXT: Offset:
15// CHECK-NEXT: Size: 48
16// CHECK-NOT: .eh_frame
17
18// 0x200120 = 2097440
19// 0x200120 + 5 = 2097445
20// DISASM: Disassembly of section .text:
21// DISASM-NEXT: _start:
22// DISASM-NEXT: 201000: {{.*}} movq 2097440, %rax
23// DISASM-NEXT: 201008: {{.*}} movq 2097445, %rax
24
25.section .eh_frame,"ax",@unwind
26
27.section .text
28.globl _start
29_start:
30 movq .eh_frame, %rax
31 movq .eh_frame + 5, %rax
deps/lld/test/ELF/emit-relocs-merge.s created+20
......@@ -0,0 +1,20 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: ld.lld --emit-relocs %t.o -o %t.so -shared
4# RUN: llvm-readobj -r %t.so | FileCheck %s
5
6# CHECK: Relocations [
7# CHECK-NEXT: Section ({{.*}}) .rela.dyn {
8# CHECK-NEXT: 0x1000 R_X86_64_64 zed 0x0
9# CHECK-NEXT: 0x1008 R_X86_64_64 zed 0x0
10# CHECK-NEXT: }
11# CHECK-NEXT: Section ({{.*}}) .rela.data.foo {
12# CHECK-NEXT: 0x1000 R_X86_64_64 zed 0x0
13# CHECK-NEXT: 0x1008 R_X86_64_64 zed 0x0
14# CHECK-NEXT: }
15# CHECK-NEXT: ]
16
17.section .data.foo,"aw",%progbits
18.quad zed
19.section .data.bar,"aw",%progbits
20.quad zed
deps/lld/test/ELF/emit-relocs-shared.s created+16
......@@ -0,0 +1,16 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: ld.lld --emit-relocs %t.o -o %t.so -shared
4# RUN: llvm-readobj -r %t.so | FileCheck %s
5
6.data
7.quad foo
8
9# CHECK: Relocations [
10# CHECK-NEXT: Section (4) .rela.dyn {
11# CHECK-NEXT: 0x1000 R_X86_64_64 foo 0x0
12# CHECK-NEXT: }
13# CHECK-NEXT: Section (8) .rela.data {
14# CHECK-NEXT: 0x1000 R_X86_64_64 foo 0x0
15# CHECK-NEXT: }
16# CHECK-NEXT: ]
deps/lld/test/ELF/emit-relocs.s created+106
......@@ -0,0 +1,106 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
3# RUN: ld.lld --emit-relocs %t1.o -o %t
4# RUN: llvm-readobj -t -r -s %t | FileCheck %s
5
6## Check single dash form.
7# RUN: ld.lld -emit-relocs %t1.o -o %t1
8# RUN: llvm-readobj -t -r -s %t1 | FileCheck %s
9
10## Check alias.
11# RUN: ld.lld -q %t1.o -o %t2
12# RUN: llvm-readobj -t -r -s %t2 | FileCheck %s
13
14# CHECK: Section {
15# CHECK: Index: 2
16# CHECK-NEXT: Name: .rela.text
17# CHECK-NEXT: Type: SHT_RELA
18# CHECK-NEXT: Flags [
19# CHECK-NEXT: SHF_INFO_LINK
20# CHECK-NEXT: ]
21# CHECK: Relocations [
22# CHECK-NEXT: Section ({{.*}}) .rela.text {
23# CHECK-NEXT: 0x201002 R_X86_64_32 .text 0x1
24# CHECK-NEXT: 0x201007 R_X86_64_PLT32 fn 0xFFFFFFFFFFFFFFFC
25# CHECK-NEXT: 0x20100E R_X86_64_32 .text 0xD
26# CHECK-NEXT: 0x201013 R_X86_64_PLT32 fn2 0xFFFFFFFFFFFFFFFC
27# CHECK-NEXT: }
28# CHECK-NEXT: ]
29# CHECK-NEXT: Symbols [
30# CHECK-NEXT: Symbol {
31# CHECK-NEXT: Name:
32# CHECK-NEXT: Value: 0x0
33# CHECK-NEXT: Size: 0
34# CHECK-NEXT: Binding: Local
35# CHECK-NEXT: Type: None
36# CHECK-NEXT: Other: 0
37# CHECK-NEXT: Section: Undefined
38# CHECK-NEXT: }
39# CHECK-NEXT: Symbol {
40# CHECK-NEXT: Name: bar
41# CHECK-NEXT: Value: 0x201001
42# CHECK-NEXT: Size: 0
43# CHECK-NEXT: Binding: Local
44# CHECK-NEXT: Type: None
45# CHECK-NEXT: Other: 0
46# CHECK-NEXT: Section: .text
47# CHECK-NEXT: }
48# CHECK-NEXT: Symbol {
49# CHECK-NEXT: Name: foo
50# CHECK-NEXT: Value: 0x20100D
51# CHECK-NEXT: Size: 0
52# CHECK-NEXT: Binding: Local
53# CHECK-NEXT: Type: None
54# CHECK-NEXT: Other: 0
55# CHECK-NEXT: Section: .text
56# CHECK-NEXT: }
57# CHECK-NEXT: Symbol {
58# CHECK-NEXT: Name:
59# CHECK-NEXT: Value: 0x201000
60# CHECK-NEXT: Size: 0
61# CHECK-NEXT: Binding: Local
62# CHECK-NEXT: Type: Section
63# CHECK-NEXT: Other: 0
64# CHECK-NEXT: Section: .text
65# CHECK-NEXT: }
66# CHECK-NEXT: Symbol {
67# CHECK-NEXT: Name: fn
68# CHECK-NEXT: Value: 0x201000
69# CHECK-NEXT: Size: 0
70# CHECK-NEXT: Binding: Global
71# CHECK-NEXT: Type: Function
72# CHECK-NEXT: Other: 0
73# CHECK-NEXT: Section: .text
74# CHECK-NEXT: }
75# CHECK-NEXT: Symbol {
76# CHECK-NEXT: Name: fn2
77# CHECK-NEXT: Value: 0x20100C
78# CHECK-NEXT: Size: 0
79# CHECK-NEXT: Binding: Global
80# CHECK-NEXT: Type: Function
81# CHECK-NEXT: Other: 0
82# CHECK-NEXT: Section: .text
83# CHECK-NEXT: }
84# CHECK-NEXT: ]
85
86.section .text,"ax",@progbits,unique,0
87.globl fn
88.type fn,@function
89fn:
90 nop
91
92bar:
93 movl $bar, %edx
94 callq fn@PLT
95 nop
96
97.section .text,"ax",@progbits,unique,1
98.globl fn2
99.type fn2,@function
100fn2:
101 nop
102
103foo:
104 movl $foo, %edx
105 callq fn2@PLT
106 nop
deps/lld/test/ELF/empty-archive.s created+3
......@@ -0,0 +1,3 @@
1// RUN: llvm-ar rc %t.a
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: ld.lld -shared %t.o %t.a -o t
deps/lld/test/ELF/empty-pt-load.s created+11
......@@ -0,0 +1,11 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: ld.lld %t.o -o %t.so -shared
4// RUN: llvm-readobj -l --elf-output-style=GNU %t.so | FileCheck %s
5
6// Test that we don't create an empty executable PT_LOAD.
7
8// CHECK: PHDR {{.*}} R 0x8
9// CHECK-NEXT: LOAD {{.*}} R 0x1000
10// CHECK-NEXT: LOAD {{.*}} RW 0x1000
11// CHECK-NEXT: DYNAMIC {{.*}} RW 0x8
deps/lld/test/ELF/empty-ver.s created+43
......@@ -0,0 +1,43 @@
1// REQUIRES: x86
2// RUN: mkdir -p %t.dir
3// RUN: cd %t.dir
4// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
5// RUN: ld.lld %t.o -o t.so -shared -version-script %p/Inputs/empty-ver.ver
6// RUN: llvm-readobj -s -section-data -version-info t.so | FileCheck %s
7
8// CHECK: Name: .dynstr
9// CHECK-NEXT: Type: SHT_STRTAB
10// CHECK-NEXT: Flags [
11// CHECK-NEXT: SHF_ALLOC
12// CHECK-NEXT: ]
13// CHECK-NEXT: Address:
14// CHECK-NEXT: Offset:
15// CHECK-NEXT: Size: 14
16// CHECK-NEXT: Link: 0
17// CHECK-NEXT: Info: 0
18// CHECK-NEXT: AddressAlignment: 1
19// CHECK-NEXT: EntrySize: 0
20// CHECK-NEXT: SectionData (
21// CHECK-NEXT: 0000: 00666F6F 00742E73 6F007665 7200 |.foo.t.so.ver.|
22// CHECK-NEXT: )
23
24// CHECK: Version symbols {
25// CHECK-NEXT: Section Name:
26// CHECK-NEXT: Address:
27// CHECK-NEXT: Offset:
28// CHECK-NEXT: Link:
29// CHECK-NEXT: Symbols [
30// CHECK-NEXT: Symbol {
31// CHECK-NEXT: Version: 0
32// CHECK-NEXT: Name: @
33// CHECK-NEXT: }
34// CHECK-NEXT: Symbol {
35// CHECK-NEXT: Version: 2
36// CHECK-NEXT: Name: foo@ver
37// CHECK-NEXT: }
38// CHECK-NEXT: ]
39// CHECK-NEXT: }
40
41
42.global foo@ver
43foo@ver:
deps/lld/test/ELF/emulation.s created+360
......@@ -0,0 +1,360 @@
1# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %tx64
2# RUN: ld.lld -m elf_amd64_fbsd %tx64 -o %t2x64
3# RUN: llvm-readobj -file-headers %t2x64 | FileCheck --check-prefix=AMD64 %s
4# RUN: ld.lld %tx64 -o %t3x64
5# RUN: llvm-readobj -file-headers %t3x64 | FileCheck --check-prefix=AMD64 %s
6# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.sysv
7# RUN: ld.lld -m elf_amd64_fbsd %t.sysv -o %t.freebsd
8# RUN: llvm-readobj -file-headers %t.freebsd | FileCheck --check-prefix=AMD64 %s
9# AMD64: ElfHeader {
10# AMD64-NEXT: Ident {
11# AMD64-NEXT: Magic: (7F 45 4C 46)
12# AMD64-NEXT: Class: 64-bit (0x2)
13# AMD64-NEXT: DataEncoding: LittleEndian (0x1)
14# AMD64-NEXT: FileVersion: 1
15# AMD64-NEXT: OS/ABI: FreeBSD (0x9)
16# AMD64-NEXT: ABIVersion: 0
17# AMD64-NEXT: Unused: (00 00 00 00 00 00 00)
18# AMD64-NEXT: }
19# AMD64-NEXT: Type: Executable (0x2)
20# AMD64-NEXT: Machine: EM_X86_64 (0x3E)
21# AMD64-NEXT: Version: 1
22# AMD64-NEXT: Entry:
23# AMD64-NEXT: ProgramHeaderOffset: 0x40
24# AMD64-NEXT: SectionHeaderOffset:
25# AMD64-NEXT: Flags [ (0x0)
26# AMD64-NEXT: ]
27# AMD64-NEXT: HeaderSize: 64
28# AMD64-NEXT: ProgramHeaderEntrySize: 56
29# AMD64-NEXT: ProgramHeaderCount:
30# AMD64-NEXT: SectionHeaderEntrySize: 64
31# AMD64-NEXT: SectionHeaderCount:
32# AMD64-NEXT: StringTableSectionIndex:
33# AMD64-NEXT: }
34
35# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %tx64
36# RUN: ld.lld -m elf_x86_64 %tx64 -o %t2x64
37# RUN: llvm-readobj -file-headers %t2x64 | FileCheck --check-prefix=X86-64 %s
38# RUN: ld.lld %tx64 -o %t3x64
39# RUN: llvm-readobj -file-headers %t3x64 | FileCheck --check-prefix=X86-64 %s
40# X86-64: ElfHeader {
41# X86-64-NEXT: Ident {
42# X86-64-NEXT: Magic: (7F 45 4C 46)
43# X86-64-NEXT: Class: 64-bit (0x2)
44# X86-64-NEXT: DataEncoding: LittleEndian (0x1)
45# X86-64-NEXT: FileVersion: 1
46# X86-64-NEXT: OS/ABI: SystemV (0x0)
47# X86-64-NEXT: ABIVersion: 0
48# X86-64-NEXT: Unused: (00 00 00 00 00 00 00)
49# X86-64-NEXT: }
50# X86-64-NEXT: Type: Executable (0x2)
51# X86-64-NEXT: Machine: EM_X86_64 (0x3E)
52# X86-64-NEXT: Version: 1
53# X86-64-NEXT: Entry:
54# X86-64-NEXT: ProgramHeaderOffset: 0x40
55# X86-64-NEXT: SectionHeaderOffset:
56# X86-64-NEXT: Flags [ (0x0)
57# X86-64-NEXT: ]
58# X86-64-NEXT: HeaderSize: 64
59# X86-64-NEXT: ProgramHeaderEntrySize: 56
60# X86-64-NEXT: ProgramHeaderCount:
61# X86-64-NEXT: SectionHeaderEntrySize: 64
62# X86-64-NEXT: SectionHeaderCount:
63# X86-64-NEXT: StringTableSectionIndex:
64# X86-64-NEXT: }
65
66# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux-gnux32 %s -o %tx32
67# RUN: ld.lld -m elf32_x86_64 %tx32 -o %t2x32
68# RUN: llvm-readobj -file-headers %t2x32 | FileCheck --check-prefix=X32 %s
69# RUN: ld.lld %tx32 -o %t3x32
70# RUN: llvm-readobj -file-headers %t3x32 | FileCheck --check-prefix=X32 %s
71# X32: ElfHeader {
72# X32-NEXT: Ident {
73# X32-NEXT: Magic: (7F 45 4C 46)
74# X32-NEXT: Class: 32-bit (0x1)
75# X32-NEXT: DataEncoding: LittleEndian (0x1)
76# X32-NEXT: FileVersion: 1
77# X32-NEXT: OS/ABI: SystemV (0x0)
78# X32-NEXT: ABIVersion: 0
79# X32-NEXT: Unused: (00 00 00 00 00 00 00)
80# X32-NEXT: }
81# X32-NEXT: Type: Executable (0x2)
82# X32-NEXT: Machine: EM_X86_64 (0x3E)
83# X32-NEXT: Version: 1
84# X32-NEXT: Entry:
85# X32-NEXT: ProgramHeaderOffset: 0x34
86# X32-NEXT: SectionHeaderOffset:
87# X32-NEXT: Flags [ (0x0)
88# X32-NEXT: ]
89# X32-NEXT: HeaderSize: 52
90# X32-NEXT: ProgramHeaderEntrySize: 32
91# X32-NEXT: ProgramHeaderCount:
92# X32-NEXT: SectionHeaderEntrySize: 40
93# X32-NEXT: SectionHeaderCount:
94# X32-NEXT: StringTableSectionIndex:
95# X32-NEXT: }
96
97# RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %tx86
98# RUN: ld.lld -m elf_i386 %tx86 -o %t2x86
99# RUN: llvm-readobj -file-headers %t2x86 | FileCheck --check-prefix=X86 %s
100# RUN: ld.lld %tx86 -o %t3x86
101# RUN: llvm-readobj -file-headers %t3x86 | FileCheck --check-prefix=X86 %s
102# X86: ElfHeader {
103# X86-NEXT: Ident {
104# X86-NEXT: Magic: (7F 45 4C 46)
105# X86-NEXT: Class: 32-bit (0x1)
106# X86-NEXT: DataEncoding: LittleEndian (0x1)
107# X86-NEXT: FileVersion: 1
108# X86-NEXT: OS/ABI: SystemV (0x0)
109# X86-NEXT: ABIVersion: 0
110# X86-NEXT: Unused: (00 00 00 00 00 00 00)
111# X86-NEXT: }
112# X86-NEXT: Type: Executable (0x2)
113# X86-NEXT: Machine: EM_386 (0x3)
114# X86-NEXT: Version: 1
115# X86-NEXT: Entry:
116# X86-NEXT: ProgramHeaderOffset: 0x34
117# X86-NEXT: SectionHeaderOffset:
118# X86-NEXT: Flags [ (0x0)
119# X86-NEXT: ]
120# X86-NEXT: HeaderSize: 52
121# X86-NEXT: ProgramHeaderEntrySize: 32
122# X86-NEXT: ProgramHeaderCount:
123# X86-NEXT: SectionHeaderEntrySize: 40
124# X86-NEXT: SectionHeaderCount:
125# X86-NEXT: StringTableSectionIndex:
126# X86-NEXT: }
127
128# RUN: llvm-mc -filetype=obj -triple=i686-unknown-freebsd %s -o %tx86fbsd
129# RUN: ld.lld -m elf_i386_fbsd %tx86fbsd -o %t2x86_fbsd
130# RUN: llvm-readobj -file-headers %t2x86_fbsd | FileCheck --check-prefix=X86FBSD %s
131# RUN: ld.lld %tx86fbsd -o %t3x86fbsd
132# RUN: llvm-readobj -file-headers %t3x86fbsd | FileCheck --check-prefix=X86FBSD %s
133# X86FBSD: ElfHeader {
134# X86FBSD-NEXT: Ident {
135# X86FBSD-NEXT: Magic: (7F 45 4C 46)
136# X86FBSD-NEXT: Class: 32-bit (0x1)
137# X86FBSD-NEXT: DataEncoding: LittleEndian (0x1)
138# X86FBSD-NEXT: FileVersion: 1
139# X86FBSD-NEXT: OS/ABI: FreeBSD (0x9)
140# X86FBSD-NEXT: ABIVersion: 0
141# X86FBSD-NEXT: Unused: (00 00 00 00 00 00 00)
142# X86FBSD-NEXT: }
143# X86FBSD-NEXT: Type: Executable (0x2)
144# X86FBSD-NEXT: Machine: EM_386 (0x3)
145# X86FBSD-NEXT: Version: 1
146# X86FBSD-NEXT: Entry:
147# X86FBSD-NEXT: ProgramHeaderOffset: 0x34
148# X86FBSD-NEXT: SectionHeaderOffset:
149# X86FBSD-NEXT: Flags [ (0x0)
150# X86FBSD-NEXT: ]
151# X86FBSD-NEXT: HeaderSize: 52
152# X86FBSD-NEXT: ProgramHeaderEntrySize: 32
153# X86FBSD-NEXT: ProgramHeaderCount:
154# X86FBSD-NEXT: SectionHeaderEntrySize: 40
155# X86FBSD-NEXT: SectionHeaderCount:
156# X86FBSD-NEXT: StringTableSectionIndex:
157# X86FBSD-NEXT: }
158
159# RUN: llvm-mc -filetype=obj -triple=i586-intel-elfiamcu %s -o %tiamcu
160# RUN: ld.lld -m elf_iamcu %tiamcu -o %t2iamcu
161# RUN: llvm-readobj -file-headers %t2iamcu | FileCheck --check-prefix=IAMCU %s
162# RUN: ld.lld %tiamcu -o %t3iamcu
163# RUN: llvm-readobj -file-headers %t3iamcu | FileCheck --check-prefix=IAMCU %s
164# IAMCU: ElfHeader {
165# IAMCU-NEXT: Ident {
166# IAMCU-NEXT: Magic: (7F 45 4C 46)
167# IAMCU-NEXT: Class: 32-bit (0x1)
168# IAMCU-NEXT: DataEncoding: LittleEndian (0x1)
169# IAMCU-NEXT: FileVersion: 1
170# IAMCU-NEXT: OS/ABI: SystemV (0x0)
171# IAMCU-NEXT: ABIVersion: 0
172# IAMCU-NEXT: Unused: (00 00 00 00 00 00 00)
173# IAMCU-NEXT: }
174# IAMCU-NEXT: Type: Executable (0x2)
175# IAMCU-NEXT: Machine: EM_IAMCU (0x6)
176# IAMCU-NEXT: Version: 1
177# IAMCU-NEXT: Entry:
178# IAMCU-NEXT: ProgramHeaderOffset: 0x34
179# IAMCU-NEXT: SectionHeaderOffset:
180# IAMCU-NEXT: Flags [ (0x0)
181# IAMCU-NEXT: ]
182# IAMCU-NEXT: HeaderSize: 52
183# IAMCU-NEXT: ProgramHeaderEntrySize: 32
184# IAMCU-NEXT: ProgramHeaderCount:
185# IAMCU-NEXT: SectionHeaderEntrySize: 40
186# IAMCU-NEXT: SectionHeaderCount:
187# IAMCU-NEXT: StringTableSectionIndex:
188# IAMCU-NEXT: }
189
190# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %tppc64
191# RUN: ld.lld -m elf64ppc %tppc64 -o %t2ppc64
192# RUN: llvm-readobj -file-headers %t2ppc64 | FileCheck --check-prefix=PPC64 %s
193# RUN: ld.lld %tppc64 -o %t3ppc64
194# RUN: llvm-readobj -file-headers %t3ppc64 | FileCheck --check-prefix=PPC64 %s
195# PPC64: ElfHeader {
196# PPC64-NEXT: Ident {
197# PPC64-NEXT: Magic: (7F 45 4C 46)
198# PPC64-NEXT: Class: 64-bit (0x2)
199# PPC64-NEXT: DataEncoding: BigEndian (0x2)
200# PPC64-NEXT: FileVersion: 1
201# PPC64-NEXT: OS/ABI: SystemV (0x0)
202# PPC64-NEXT: ABIVersion: 0
203# PPC64-NEXT: Unused: (00 00 00 00 00 00 00)
204# PPC64-NEXT: }
205# PPC64-NEXT: Type: Executable (0x2)
206# PPC64-NEXT: Machine: EM_PPC64 (0x15)
207# PPC64-NEXT: Version: 1
208# PPC64-NEXT: Entry:
209# PPC64-NEXT: ProgramHeaderOffset: 0x40
210# PPC64-NEXT: SectionHeaderOffset:
211# PPC64-NEXT: Flags [ (0x0)
212# PPC64-NEXT: ]
213# PPC64-NEXT: HeaderSize: 64
214# PPC64-NEXT: ProgramHeaderEntrySize: 56
215# PPC64-NEXT: ProgramHeaderCount:
216# PPC64-NEXT: SectionHeaderEntrySize: 64
217# PPC64-NEXT: SectionHeaderCount:
218# PPC64-NEXT: StringTableSectionIndex:
219# PPC64-NEXT: }
220
221# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %tmips
222# RUN: ld.lld -m elf32btsmip -e _start %tmips -o %t2mips
223# RUN: llvm-readobj -file-headers %t2mips | FileCheck --check-prefix=MIPS %s
224# RUN: ld.lld %tmips -e _start -o %t3mips
225# RUN: llvm-readobj -file-headers %t3mips | FileCheck --check-prefix=MIPS %s
226# MIPS: ElfHeader {
227# MIPS-NEXT: Ident {
228# MIPS-NEXT: Magic: (7F 45 4C 46)
229# MIPS-NEXT: Class: 32-bit (0x1)
230# MIPS-NEXT: DataEncoding: BigEndian (0x2)
231# MIPS-NEXT: FileVersion: 1
232# MIPS-NEXT: OS/ABI: SystemV (0x0)
233# MIPS-NEXT: ABIVersion: 0
234# MIPS-NEXT: Unused: (00 00 00 00 00 00 00)
235# MIPS-NEXT: }
236# MIPS-NEXT: Type: Executable (0x2)
237# MIPS-NEXT: Machine: EM_MIPS (0x8)
238# MIPS-NEXT: Version: 1
239# MIPS-NEXT: Entry:
240# MIPS-NEXT: ProgramHeaderOffset: 0x34
241# MIPS-NEXT: SectionHeaderOffset:
242# MIPS-NEXT: Flags [
243# MIPS-NEXT: EF_MIPS_ABI_O32
244# MIPS-NEXT: EF_MIPS_ARCH_32
245# MIPS-NEXT: EF_MIPS_CPIC
246# MIPS-NEXT: ]
247
248# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %tmipsel
249# RUN: ld.lld -m elf32ltsmip -e _start %tmipsel -o %t2mipsel
250# RUN: llvm-readobj -file-headers %t2mipsel | FileCheck --check-prefix=MIPSEL %s
251# RUN: ld.lld -melf32ltsmip -e _start %tmipsel -o %t2mipsel
252# RUN: llvm-readobj -file-headers %t2mipsel | FileCheck --check-prefix=MIPSEL %s
253# RUN: ld.lld %tmipsel -e _start -o %t3mipsel
254# RUN: llvm-readobj -file-headers %t3mipsel | FileCheck --check-prefix=MIPSEL %s
255# MIPSEL: ElfHeader {
256# MIPSEL-NEXT: Ident {
257# MIPSEL-NEXT: Magic: (7F 45 4C 46)
258# MIPSEL-NEXT: Class: 32-bit (0x1)
259# MIPSEL-NEXT: DataEncoding: LittleEndian (0x1)
260# MIPSEL-NEXT: FileVersion: 1
261# MIPSEL-NEXT: OS/ABI: SystemV (0x0)
262# MIPSEL-NEXT: ABIVersion: 0
263# MIPSEL-NEXT: Unused: (00 00 00 00 00 00 00)
264# MIPSEL-NEXT: }
265# MIPSEL-NEXT: Type: Executable (0x2)
266# MIPSEL-NEXT: Machine: EM_MIPS (0x8)
267# MIPSEL-NEXT: Version: 1
268# MIPSEL-NEXT: Entry:
269# MIPSEL-NEXT: ProgramHeaderOffset: 0x34
270# MIPSEL-NEXT: SectionHeaderOffset:
271# MIPSEL-NEXT: Flags [
272# MIPSEL-NEXT: EF_MIPS_ABI_O32
273# MIPSEL-NEXT: EF_MIPS_ARCH_32
274# MIPSEL-NEXT: EF_MIPS_CPIC
275# MIPSEL-NEXT: ]
276
277# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux -position-independent \
278# RUN: %s -o %tmips64
279# RUN: ld.lld -m elf64btsmip -e _start %tmips64 -o %t2mips64
280# RUN: llvm-readobj -file-headers %t2mips64 | FileCheck --check-prefix=MIPS64 %s
281# RUN: ld.lld %tmips64 -e _start -o %t3mips64
282# RUN: llvm-readobj -file-headers %t3mips64 | FileCheck --check-prefix=MIPS64 %s
283# MIPS64: ElfHeader {
284# MIPS64-NEXT: Ident {
285# MIPS64-NEXT: Magic: (7F 45 4C 46)
286# MIPS64-NEXT: Class: 64-bit (0x2)
287# MIPS64-NEXT: DataEncoding: BigEndian (0x2)
288# MIPS64-NEXT: FileVersion: 1
289# MIPS64-NEXT: OS/ABI: SystemV (0x0)
290# MIPS64-NEXT: ABIVersion: 0
291# MIPS64-NEXT: Unused: (00 00 00 00 00 00 00)
292# MIPS64-NEXT: }
293# MIPS64-NEXT: Type: Executable (0x2)
294# MIPS64-NEXT: Machine: EM_MIPS (0x8)
295# MIPS64-NEXT: Version: 1
296# MIPS64-NEXT: Entry:
297# MIPS64-NEXT: ProgramHeaderOffset: 0x40
298# MIPS64-NEXT: SectionHeaderOffset:
299# MIPS64-NEXT: Flags [
300# MIPS64-NEXT: EF_MIPS_ARCH_64
301# MIPS64-NEXT: EF_MIPS_CPIC
302# MIPS64-NEXT: EF_MIPS_PIC
303# MIPS64-NEXT: ]
304
305# RUN: llvm-mc -filetype=obj -triple=mips64el-unknown-linux \
306# RUN: -position-independent %s -o %tmips64el
307# RUN: ld.lld -m elf64ltsmip -e _start %tmips64el -o %t2mips64el
308# RUN: llvm-readobj -file-headers %t2mips64el | FileCheck --check-prefix=MIPS64EL %s
309# RUN: ld.lld %tmips64el -e _start -o %t3mips64el
310# RUN: llvm-readobj -file-headers %t3mips64el | FileCheck --check-prefix=MIPS64EL %s
311# MIPS64EL: ElfHeader {
312# MIPS64EL-NEXT: Ident {
313# MIPS64EL-NEXT: Magic: (7F 45 4C 46)
314# MIPS64EL-NEXT: Class: 64-bit (0x2)
315# MIPS64EL-NEXT: DataEncoding: LittleEndian (0x1)
316# MIPS64EL-NEXT: FileVersion: 1
317# MIPS64EL-NEXT: OS/ABI: SystemV (0x0)
318# MIPS64EL-NEXT: ABIVersion: 0
319# MIPS64EL-NEXT: Unused: (00 00 00 00 00 00 00)
320# MIPS64EL-NEXT: }
321# MIPS64EL-NEXT: Type: Executable (0x2)
322# MIPS64EL-NEXT: Machine: EM_MIPS (0x8)
323# MIPS64EL-NEXT: Version: 1
324# MIPS64EL-NEXT: Entry:
325# MIPS64EL-NEXT: ProgramHeaderOffset: 0x40
326# MIPS64EL-NEXT: SectionHeaderOffset:
327# MIPS64EL-NEXT: Flags [
328# MIPS64EL-NEXT: EF_MIPS_ARCH_64
329# MIPS64EL-NEXT: EF_MIPS_CPIC
330# MIPS64EL-NEXT: EF_MIPS_PIC
331# MIPS64EL-NEXT: ]
332
333# RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %taarch64
334# RUN: ld.lld -m aarch64linux %taarch64 -o %t2aarch64
335# RUN: llvm-readobj -file-headers %t2aarch64 | FileCheck --check-prefix=AARCH64 %s
336# RUN: ld.lld %taarch64 -o %t3aarch64
337# RUN: llvm-readobj -file-headers %t3aarch64 | FileCheck --check-prefix=AARCH64 %s
338# AARCH64: ElfHeader {
339# AARCH64-NEXT: Ident {
340# AARCH64-NEXT: Magic: (7F 45 4C 46)
341# AARCH64-NEXT: Class: 64-bit (0x2)
342# AARCH64-NEXT: DataEncoding: LittleEndian (0x1)
343# AARCH64-NEXT: FileVersion: 1
344# AARCH64-NEXT: OS/ABI: SystemV (0x0)
345# AARCH64-NEXT: ABIVersion: 0
346# AARCH64-NEXT: Unused: (00 00 00 00 00 00 00)
347# AARCH64-NEXT: }
348# AARCH64-NEXT: Type: Executable (0x2)
349# AARCH64-NEXT: Machine: EM_AARCH64 (0xB7)
350# AARCH64-NEXT: Version: 1
351# AARCH64-NEXT: Entry:
352# AARCH64-NEXT: ProgramHeaderOffset: 0x40
353# AARCH64-NEXT: SectionHeaderOffset:
354# AARCH64-NEXT: Flags [ (0x0)
355# AARCH64-NEXT: ]
356
357# REQUIRES: x86,ppc,mips,aarch64
358
359.globl _start
360_start:
deps/lld/test/ELF/end-abs.s created+11
......@@ -0,0 +1,11 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: ld.lld %t.o -o %t -pie
4# RUN: llvm-readobj -r %t | FileCheck %s
5
6# CHECK: Relocations [
7# CHECK-NEXT: ]
8
9.global _start
10_start:
11.long _end - .
deps/lld/test/ELF/end-preserve.s created+16
......@@ -0,0 +1,16 @@
1// Should preserve the value of the "end" symbol if it is defined.
2// REQUIRES: x86
3
4// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
5// RUN: ld.lld %t.o -o %t
6// RUN: llvm-nm %t | FileCheck %s
7
8// CHECK: 0000000000000005 A end
9
10.global _start,end
11end = 5
12.text
13_start:
14 nop
15.bss
16 .space 6
deps/lld/test/ELF/end-update.s created+29
......@@ -0,0 +1,29 @@
1// Should set the value of the "end" symbol if it is undefined.
2// REQUIRES: x86
3
4// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
5// RUN: ld.lld %t.o -o %t
6// RUN: llvm-readobj -sections -symbols %t | FileCheck %s
7
8// CHECK: Sections [
9// CHECK: Name: .bss
10// CHECK-NEXT: Type:
11// CHECK-NEXT: Flags [
12// CHECK-NEXT: SHF_ALLOC
13// CHECK-NEXT: SHF_WRITE
14// CHECK-NEXT: ]
15// CHECK-NEXT: Address: 0x202000
16// CHECK-NEXT: Offset:
17// CHECK-NEXT: Size: 6
18// CHECK: ]
19// CHECK: Symbols [
20// CHECK: Name: end
21// CHECK-NEXT: Value: 0x202006
22// CHECK: ]
23
24.global _start,end
25.text
26_start:
27 nop
28.bss
29 .space 6
deps/lld/test/ELF/end.s created+37
......@@ -0,0 +1,37 @@
1// Should set the value of the "_end" symbol to the end of the data segment.
2// REQUIRES: x86
3
4// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
5
6// By default, the .bss section is the latest section of the data segment.
7// RUN: ld.lld %t.o -o %t
8// RUN: llvm-readobj -sections -symbols %t | FileCheck %s --check-prefix=DEFAULT
9
10// DEFAULT: Sections [
11// DEFAULT: Name: .bss
12// DEFAULT-NEXT: Type:
13// DEFAULT-NEXT: Flags [
14// DEFAULT-NEXT: SHF_ALLOC
15// DEFAULT-NEXT: SHF_WRITE
16// DEFAULT-NEXT: ]
17// DEFAULT-NEXT: Address: 0x202002
18// DEFAULT-NEXT: Offset:
19// DEFAULT-NEXT: Size: 6
20// DEFAULT: ]
21// DEFAULT: Symbols [
22// DEFAULT: Name: _end
23// DEFAULT-NEXT: Value: 0x202008
24// DEFAULT: ]
25
26// RUN: ld.lld -r %t.o -o %t2
27// RUN: llvm-objdump -t %t2 | FileCheck %s --check-prefix=RELOCATABLE
28// RELOCATABLE: 0000000000000000 *UND* 00000000 _end
29
30.global _start,_end
31.text
32_start:
33 nop
34.data
35 .word 1
36.bss
37 .space 6
deps/lld/test/ELF/entry.s created+53
......@@ -0,0 +1,53 @@
1# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1
2
3# RUN: ld.lld -e foobar %t1 -o %t2 2>&1 | FileCheck -check-prefix=WARN1 %s
4# RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=TEXT %s
5
6# WARN1: warning: cannot find entry symbol foobar; defaulting to 0x201000
7# TEXT: Entry: 0x201000
8
9# RUN: ld.lld %t1 -o %t2 2>&1 | FileCheck -check-prefix=WARN2 %s
10# WARN2: warning: cannot find entry symbol _start; defaulting to 0x201000
11
12# RUN: ld.lld -shared -e foobar %t1 -o %t2 2>&1 | FileCheck -check-prefix=WARN3 %s
13# WARN3: warning: cannot find entry symbol foobar; defaulting to 0x1000
14
15# RUN: ld.lld -shared --fatal-warnings -e entry %t1 -o %t2
16# RUN: ld.lld -shared --fatal-warnings %t1 -o %t2
17
18# RUN: echo .data > %t.s
19# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux -n %t.s -o %t3
20# RUN: ld.lld %t3 -o %t4 2>&1 | FileCheck -check-prefix=WARN4 %s
21# RUN: llvm-readobj -file-headers %t4 | FileCheck -check-prefix=NOENTRY %s
22
23# WARN4: cannot find entry symbol _start; not setting start address
24# NOENTRY: Entry: 0x0
25
26# RUN: ld.lld -v -r %t1 -o %t2 2>&1 | FileCheck -check-prefix=WARN5 %s
27# WARN5-NOT: warning: cannot find entry symbol
28
29# RUN: ld.lld %t1 -o %t2 -e entry
30# RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=SYM %s
31# SYM: Entry: 0x201008
32
33# RUN: ld.lld %t1 --fatal-warnings -shared -o %t2 -e entry
34# RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=DSO %s
35# DSO: Entry: 0x1008
36
37# RUN: ld.lld %t1 -o %t2 --entry=4096
38# RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=DEC %s
39# DEC: Entry: 0x1000
40
41# RUN: ld.lld %t1 -o %t2 --entry 0xcafe
42# RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=HEX %s
43# HEX: Entry: 0xCAFE
44
45# RUN: ld.lld %t1 -o %t2 -e 0777
46# RUN: llvm-readobj -file-headers %t2 | FileCheck -check-prefix=OCT %s
47# OCT: Entry: 0x1FF
48
49.globl entry
50.text
51 .quad 0
52entry:
53 ret
deps/lld/test/ELF/error-limit.test created+26
......@@ -0,0 +1,26 @@
1RUN: not ld.lld 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 \
2RUN: 21 22 2>&1 | FileCheck -check-prefix=DEFAULT %s
3
4DEFAULT: cannot open 01
5DEFAULT: cannot open 20
6DEFAULT-NEXT: too many errors emitted, stopping now (use -error-limit=0 to see all errors)
7DEFAULT-NOT: cannot open 21
8
9RUN: not ld.lld -error-limit=5 01 02 03 04 05 06 07 08 09 10 2>&1 \
10RUN: | FileCheck -check-prefix=LIMIT5 %s
11RUN: not ld.lld -error-limit 5 01 02 03 04 05 06 07 08 09 10 2>&1 \
12RUN: | FileCheck -check-prefix=LIMIT5 %s
13
14LIMIT5: cannot open 01
15LIMIT5: cannot open 05
16LIMIT5-NEXT: too many errors emitted, stopping now (use -error-limit=0 to see all errors)
17LIMIT5-NOT: cannot open 06
18
19RUN: not ld.lld -error-limit=0 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 \
20RUN: 16 17 18 19 20 21 22 2>&1 | FileCheck -check-prefix=UNLIMITED %s
21
22UNLIMITED: cannot open 01
23UNLIMITED: cannot open 20
24UNLIMITED: cannot open 21
25UNLIMITED: cannot open 22
26UNLIMITED-NOT: too many errors emitted, stopping now (use -error-limit=0 to see all errors)
deps/lld/test/ELF/exclude-libs.s created+30
......@@ -0,0 +1,30 @@
1// REQUIRES: x86
2
3// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
4// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
5// RUN: %p/Inputs/exclude-libs.s -o %t2.o
6// RUN: mkdir -p %t.dir
7// RUN: rm -f %t.dir/exc.a
8// RUN: llvm-ar rcs %t.dir/exc.a %t2.o
9
10// RUN: ld.lld -shared %t.o %t.dir/exc.a -o %t.exe
11// RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=DEFAULT %s
12
13// RUN: ld.lld -shared %t.o %t.dir/exc.a -o %t.exe --exclude-libs=foo,bar
14// RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=DEFAULT %s
15
16// RUN: ld.lld -shared %t.o %t.dir/exc.a -o %t.exe --exclude-libs foo,bar,exc.a
17// RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=EXCLUDE %s
18
19// RUN: ld.lld -shared %t.o %t.dir/exc.a -o %t.exe --exclude-libs foo:bar:exc.a
20// RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=EXCLUDE %s
21
22// RUN: ld.lld -shared %t.o %t.dir/exc.a -o %t.exe --exclude-libs=ALL
23// RUN: llvm-readobj -dyn-symbols %t.exe | FileCheck --check-prefix=EXCLUDE %s
24
25// DEFAULT: Name: fn
26// EXCLUDE-NOT: Name: fn
27
28.globl fn
29foo:
30 call fn@PLT
deps/lld/test/ELF/exclude.s created+19
......@@ -0,0 +1,19 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: ld.lld -o %t1 %t
4# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
5# RUN: ld.lld -r -o %t1 %t
6# RUN: llvm-objdump -section-headers %t1 | FileCheck --check-prefix=RELOCATABLE %s
7
8# CHECK-NOT: .aaa
9# RELOCATABLE: .aaa
10
11.globl _start
12_start:
13 jmp _start
14
15.section .aaa,"ae"
16 .quad .bbb
17
18.section .bbb,"a"
19 .quad 0
deps/lld/test/ELF/fatal-warnings.s created+16
......@@ -0,0 +1,16 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
3# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/warn-common.s -o %t2.o
4
5# RUN: ld.lld --warn-common %t1.o %t2.o -o %t1.out 2>&1 | \
6# RUN: FileCheck -check-prefix=ERR %s
7# ERR: multiple common of
8
9# RUN: not ld.lld --warn-common --fatal-warnings %t1.o %t2.o -o %t2.out 2>&1 | \
10# RUN: FileCheck -check-prefix=ERR %s
11
12.globl _start
13_start:
14
15.type arr,@object
16.comm arr,4,4
deps/lld/test/ELF/file-sym.s created+12
......@@ -0,0 +1,12 @@
1# Check that we do not keep STT_FILE symbols in the symbol table
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
4# RUN: ld.lld %t.o -shared -o %t.so
5# RUN: llvm-readobj -symbols %t.so | FileCheck %s
6
7# REQUIRES: x86
8
9# CHECK-NOT: xxx
10
11.file "xxx"
12.file ""
deps/lld/test/ELF/filter.s created+15
......@@ -0,0 +1,15 @@
1# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
2# RUN: ld.lld %t.o -shared -F foo.so -F boo.so -o %t1
3# RUN: llvm-readobj --dynamic-table %t1 | FileCheck %s
4
5# Test alias.
6# RUN: ld.lld %t.o -shared --filter=foo.so --filter=boo.so -o %t2
7# RUN: llvm-readobj --dynamic-table %t2 | FileCheck %s
8
9# CHECK: DynamicSection [
10# CHECK-NEXT: Tag Type Name/Value
11# CHECK-NEXT: 0x000000007FFFFFFF FILTER Filter library: [foo.so]
12# CHECK-NEXT: 0x000000007FFFFFFF FILTER Filter library: [boo.so]
13
14# RUN: not ld.lld %t.o -F x -o %t 2>&1 | FileCheck -check-prefix=ERR %s
15# ERR: -F may not be used without -shared
deps/lld/test/ELF/format-binary.test created+57
......@@ -0,0 +1,57 @@
1# REQUIRES: x86
2
3# RUN: echo -n "Fluffle Puff" > %t.binary
4# RUN: ld.lld -m elf_x86_64 -r -b binary %t.binary -o %t.out
5# RUN: llvm-readobj %t.out -sections -section-data -symbols | FileCheck %s
6
7# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
8# RUN: ld.lld %t.o -b binary %t.binary -b default %t.o -shared -o %t.out
9
10# RUN: not ld.lld -b foo > %t.log 2>&1
11# RUN: FileCheck -check-prefix=ERR %s < %t.log
12# ERR: error: unknown -format value: foo (supported formats: elf, default, binary)
13
14# CHECK: Name: .data
15# CHECK-NEXT: Type: SHT_PROGBITS
16# CHECK-NEXT: Flags [
17# CHECK-NEXT: SHF_ALLOC
18# CHECK-NEXT: SHF_WRITE
19# CHECK-NEXT: ]
20# CHECK-NEXT: Address: 0x0
21# CHECK-NEXT: Offset:
22# CHECK-NEXT: Size: 12
23# CHECK-NEXT: Link: 0
24# CHECK-NEXT: Info: 0
25# CHECK-NEXT: AddressAlignment:
26# CHECK-NEXT: EntrySize: 0
27# CHECK-NEXT: SectionData (
28# CHECK-NEXT: 0000: 466C7566 666C6520 50756666 |Fluffle Puff|
29# CHECK-NEXT: )
30# CHECK-NEXT: }
31
32# CHECK: Name: _binary_{{[a-zA-Z0-9_]+}}test_ELF_Output_format_binary_test_tmp_binary_start
33# CHECK-NEXT: Value: 0x0
34# CHECK-NEXT: Size: 0
35# CHECK-NEXT: Binding: Global
36# CHECK-NEXT: Type: Object
37# CHECK-NEXT: Other: 0
38# CHECK-NEXT: Section: .data
39# CHECK-NEXT: }
40# CHECK-NEXT: Symbol {
41# CHECK-NEXT: Name: _binary_{{[a-zA-Z0-9_]+}}test_ELF_Output_format_binary_test_tmp_binary_end
42# CHECK-NEXT: Value: 0xC
43# CHECK-NEXT: Size: 0
44# CHECK-NEXT: Binding: Global
45# CHECK-NEXT: Type: Object
46# CHECK-NEXT: Other: 0
47# CHECK-NEXT: Section: .data
48# CHECK-NEXT: }
49# CHECK-NEXT: Symbol {
50# CHECK-NEXT: Name: _binary_{{[a-zA-Z0-9_]+}}test_ELF_Output_format_binary_test_tmp_binary_size
51# CHECK-NEXT: Value: 0xC
52# CHECK-NEXT: Size: 0
53# CHECK-NEXT: Binding: Global
54# CHECK-NEXT: Type: Object
55# CHECK-NEXT: Other: 0
56# CHECK-NEXT: Section: Absolute
57# CHECK-NEXT: }
deps/lld/test/ELF/gc-absolute.s created+7
......@@ -0,0 +1,7 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
4# RUN: ld.lld %t -o %t2 -shared --gc-sections
5
6.global foo
7foo = 0x123
deps/lld/test/ELF/gc-debuginfo-tls.s created+23
......@@ -0,0 +1,23 @@
1# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
2# RUN: ld.lld %t.o --gc-sections -shared -o %t1
3# RUN: ld.lld %t.o -shared -o %t2
4# RUN: llvm-readobj -symbols %t1 | FileCheck %s --check-prefix=GC
5# RUN: llvm-readobj -symbols %t2 | FileCheck %s --check-prefix=NOGC
6
7# NOGC: Symbol {
8# NOGC: Name: patatino
9# NOGC-NEXT: Value: 0x0
10# NOGC-NEXT: Size: 0
11# NOGC-NEXT: Binding: Local
12# NOGC-NEXT: Type: TLS
13# NOGC-NEXT: Other: 0
14# NOGC-NEXT: Section: .tbss
15# NOGC-NEXT: }
16
17# GC-NOT: tbss
18
19.section .tbss,"awT",@nobits
20patatino:
21 .long 0
22 .section .noalloc,""
23 .quad patatino
deps/lld/test/ELF/gc-merge-local-sym.s created+34
......@@ -0,0 +1,34 @@
1// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
2// RUN: ld.lld %t.o -o %t.so -shared -O3 --gc-sections
3// RUN: llvm-readobj -s -section-data -t %t.so | FileCheck %s
4
5// CHECK: Name: .rodata
6// CHECK-NEXT: Type: SHT_PROGBITS
7// CHECK-NEXT: Flags [
8// CHECK-NEXT: SHF_ALLOC
9// CHECK-NEXT: SHF_MERGE
10// CHECK-NEXT: SHF_STRINGS
11// CHECK-NEXT: ]
12// CHECK-NEXT: Address: 0x1C8
13// CHECK-NEXT: Offset:
14// CHECK-NEXT: Size: 4
15// CHECK-NEXT: Link: 0
16// CHECK-NEXT: Info: 0
17// CHECK-NEXT: AddressAlignment: 1
18// CHECK-NEXT: EntrySize: 0
19// CHECK-NEXT: SectionData (
20// CHECK-NEXT: 0000: 61626300 |abc.|
21// CHECK-NEXT: )
22
23// CHECK: Symbols [
24// CHECK: Symbol {
25// CHECK-NOT: Name: bar
26
27 .global foo
28foo:
29 leaq .L.str(%rip), %rsi
30 .section .rodata.str1.1,"aMS",@progbits,1
31.L.str:
32 .asciz "abc"
33bar:
34 .asciz "def"
deps/lld/test/ELF/gc-sections-alloc.s created+31
......@@ -0,0 +1,31 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
4# RUN: ld.lld %t -o %t2 --gc-sections -shared
5# RUN: llvm-readobj -sections -section-data %t2 | FileCheck %s
6
7# Non alloca section .bar should not keep section .foo alive.
8
9# CHECK-NOT: Name: .foo
10
11# CHECK: Name: .bar
12# CHECK-NEXT: Type: SHT_PROGBITS
13# CHECK-NEXT: Flags [
14# CHECK-NEXT: ]
15# CHECK-NEXT: Address:
16# CHECK-NEXT: Offset:
17# CHECK-NEXT: Size:
18# CHECK-NEXT: Link:
19# CHECK-NEXT: Info:
20# CHECK-NEXT: AddressAlignment:
21# CHECK-NEXT: EntrySize:
22# CHECK-NEXT: SectionData (
23# CHECK-NEXT: 0000: 00000000 00000000 |
24# CHECK-NEXT: )
25
26
27.section .foo,"a"
28.byte 0
29
30.section .bar
31.quad .foo
deps/lld/test/ELF/gc-sections-eh.s created+32
......@@ -0,0 +1,32 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
4
5# RUN: ld.lld %t -o %t2 --gc-sections
6# RUN: llvm-readobj -t %t2 | FileCheck %s
7# RUN: llvm-objdump --dwarf=frames %t2 | FileCheck --check-prefix=EH %s
8
9# RUN: ld.lld %t -o %t3
10# RUN: llvm-readobj -t %t3 | FileCheck --check-prefix=NOGC %s
11# RUN: llvm-objdump --dwarf=frames %t3 | FileCheck --check-prefix=EHNOGC %s
12
13# CHECK-NOT: foo
14# NOGC: foo
15
16# EH: FDE cie={{.*}} pc=
17# EH-NOT: FDE
18
19# EHNOGC: FDE cie={{.*}} pc=
20# EHNOGC: FDE cie={{.*}} pc=
21
22 .section .text,"ax",@progbits,unique,0
23 .globl foo
24foo:
25 .cfi_startproc
26 .cfi_endproc
27
28 .section .text,"ax",@progbits,unique,1
29 .globl _start
30_start:
31 .cfi_startproc
32 .cfi_endproc
deps/lld/test/ELF/gc-sections-implicit-addend.s created+26
......@@ -0,0 +1,26 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=i386-unknown-linux %s -o %t.o
4# RUN: ld.lld %t.o -o %t --gc-sections
5# RUN: llvm-readobj -s %t | FileCheck %s
6# RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
7
8# CHECK: Name: .foo
9# CHECK-NEXT: Type: SHT_PROGBITS
10# CHECK-NEXT: Flags [
11# CHECK-NEXT: SHF_ALLOC
12# CHECK-NEXT: SHF_MERGE
13# CHECK-NEXT: SHF_STRINGS
14# CHECK-NEXT: ]
15# CHECK-NEXT: Address: 0x100B4
16
17# 0x100B4 == 65716
18# DISASM: leal 65716, %eax
19
20 .section .foo,"aMS",@progbits,1
21 .byte 0
22
23 .text
24 .global _start
25_start:
26 leal .foo, %eax
deps/lld/test/ELF/gc-sections-keep-shared-start.s created+30
......@@ -0,0 +1,30 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
4# RUN: ld.lld -shared --gc-sections -o %t1 %t
5# RUN: llvm-readobj --elf-output-style=GNU --file-headers --symbols %t1
6# | FileCheck %s
7# CHECK: Entry point address: 0x1000
8# CHECK: 0000000000001000 0 FUNC LOCAL HIDDEN 4 _start
9# CHECK: 0000000000001006 0 FUNC LOCAL HIDDEN 4 internal
10# CHECK: 0000000000001005 0 FUNC GLOBAL DEFAULT 4 foobar
11
12.section .text.start,"ax"
13.globl _start
14.type _start,%function
15.hidden _start
16_start:
17 jmp internal
18
19.section .text.foobar,"ax"
20.globl foobar
21.type foobar,%function
22foobar:
23 ret
24
25.section .text.internal,"ax"
26.globl internal
27.hidden internal
28.type internal,%function
29internal:
30 ret
deps/lld/test/ELF/gc-sections-local-sym.s created+57
......@@ -0,0 +1,57 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
2// RUN: ld.lld %t -o %t2 -shared --gc-sections
3// RUN: llvm-readobj -t -s -section-data %t2 | FileCheck %s
4// REQUIRES: x86
5
6.global foo
7foo:
8
9.section .bar,"a"
10zed:
11
12// CHECK: Name: .strtab
13// CHECK-NEXT: Type: SHT_STRTAB
14// CHECK-NEXT: Flags [
15// CHECK-NEXT: ]
16// CHECK-NEXT: Address:
17// CHECK-NEXT: Offset:
18// CHECK-NEXT: Size:
19// CHECK-NEXT: Link:
20// CHECK-NEXT: Info:
21// CHECK-NEXT: AddressAlignment:
22// CHECK-NEXT: EntrySize:
23// CHECK-NEXT: SectionData (
24// CHECK-NEXT: 0000: 00666F6F 005F4459 4E414D49 4300 |.foo._DYNAMIC.|
25// CHECK-NEXT: )
26
27// CHECK: Symbols [
28// CHECK-NEXT: Symbol {
29// CHECK-NEXT: Name: (0)
30// CHECK-NEXT: Value: 0x0
31// CHECK-NEXT: Size: 0
32// CHECK-NEXT: Binding: Local
33// CHECK-NEXT: Type: None
34// CHECK-NEXT: Other: 0
35// CHECK-NEXT: Section: Undefined
36// CHECK-NEXT: }
37// CHECK-NEXT: Symbol {
38// CHECK-NEXT: Name: _DYNAMIC
39// CHECK-NEXT: Value: 0x1000
40// CHECK-NEXT: Size: 0
41// CHECK-NEXT: Binding: Local
42// CHECK-NEXT: Type: None
43// CHECK-NEXT: Other [ (0x2)
44// CHECK-NEXT: STV_HIDDEN
45// CHECK-NEXT: ]
46// CHECK-NEXT: Section: .dynamic
47// CHECK-NEXT: }
48// CHECK-NEXT: Symbol {
49// CHECK-NEXT: Name: foo
50// CHECK-NEXT: Value:
51// CHECK-NEXT: Size:
52// CHECK-NEXT: Binding: Global
53// CHECK-NEXT: Type: None
54// CHECK-NEXT: Other:
55// CHECK-NEXT: Section: .text
56// CHECK-NEXT: }
57// CHECK-NEXT: ]
deps/lld/test/ELF/gc-sections-lsda.s created+21
......@@ -0,0 +1,21 @@
1// REQUIRES: x86
2
3// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
4// RUN: ld.lld -shared --gc-sections %t.o -o %t
5
6// Test that we handle .eh_frame keeping sections alive. We could be more
7// precise and gc the entire contents of this file, but test that at least
8// we are consistent: if we keep .abc, we have to keep .foo
9
10// RUN: llvm-readobj -s %t | FileCheck %s
11// CHECK: Name: .abc
12// CHECK: Name: .foo
13
14 .cfi_startproc
15 .cfi_lsda 0x1b,zed
16 .cfi_endproc
17 .section .abc,"a"
18zed:
19 .long bar-.
20 .section .foo,"ax"
21bar:
deps/lld/test/ELF/gc-sections-merge-addend.s created+39
......@@ -0,0 +1,39 @@
1// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
2// RUN: ld.lld %t.o -o %t.so -shared --gc-sections
3// RUN: llvm-readobj -s -section-data %t.so | FileCheck %s
4
5
6// CHECK: Name: .rodata
7// CHECK-NEXT: Type: SHT_PROGBITS
8// CHECK-NEXT: Flags [
9// CHECK-NEXT: SHF_ALLOC
10// CHECK-NEXT: SHF_MERGE
11// CHECK-NEXT: SHF_STRINGS
12// CHECK-NEXT: ]
13// CHECK-NEXT: Address:
14// CHECK-NEXT: Offset:
15// CHECK-NEXT: Size: 4
16// CHECK-NEXT: Link: 0
17// CHECK-NEXT: Info: 0
18// CHECK-NEXT: AddressAlignment: 1
19// CHECK-NEXT: EntrySize: 0
20// CHECK-NEXT: SectionData (
21// CHECK-NEXT: 0000: 62617200 |bar.|
22// CHECK-NEXT: )
23
24 .section .data.f,"aw",@progbits
25 .globl f
26f:
27 .quad .rodata.str1.1 + 4
28
29 .section .data.g,"aw",@progbits
30 .hidden g
31 .globl g
32g:
33 .quad .rodata.str1.1
34
35 .section .rodata.str1.1,"aMS",@progbits,1
36.L.str:
37 .asciz "foo"
38.L.str.1:
39 .asciz "bar"
deps/lld/test/ELF/gc-sections-merge-implicit-addend.s created+39
......@@ -0,0 +1,39 @@
1// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=i386-pc-linux
2// RUN: ld.lld %t.o -o %t.so -shared --gc-sections
3// RUN: llvm-readobj -s -section-data %t.so | FileCheck %s
4
5
6// CHECK: Name: .rodata
7// CHECK-NEXT: Type: SHT_PROGBITS
8// CHECK-NEXT: Flags [
9// CHECK-NEXT: SHF_ALLOC
10// CHECK-NEXT: SHF_MERGE
11// CHECK-NEXT: SHF_STRINGS
12// CHECK-NEXT: ]
13// CHECK-NEXT: Address:
14// CHECK-NEXT: Offset:
15// CHECK-NEXT: Size: 4
16// CHECK-NEXT: Link: 0
17// CHECK-NEXT: Info: 0
18// CHECK-NEXT: AddressAlignment: 1
19// CHECK-NEXT: EntrySize: 0
20// CHECK-NEXT: SectionData (
21// CHECK-NEXT: 0000: 62617200 |bar.|
22// CHECK-NEXT: )
23
24 .section .data.f,"aw",@progbits
25 .globl f
26f:
27 .long .rodata.str1.1 + 4
28
29 .section .data.g,"aw",@progbits
30 .hidden g
31 .globl g
32g:
33 .long .rodata.str1.1
34
35 .section .rodata.str1.1,"aMS",@progbits,1
36.L.str:
37 .asciz "foo"
38.L.str.1:
39 .asciz "bar"
deps/lld/test/ELF/gc-sections-merge.s created+61
......@@ -0,0 +1,61 @@
1// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
2// RUN: ld.lld %t.o -o %t.so -shared
3// RUN: ld.lld %t.o -o %t.gc.so -shared --gc-sections
4// RUN: llvm-readobj -s -section-data %t.so | FileCheck %s
5// RUN: llvm-readobj -s -section-data %t.gc.so | FileCheck --check-prefix=GC %s
6
7
8// CHECK: Name: .rodata
9// CHECK-NEXT: Type: SHT_PROGBITS
10// CHECK-NEXT: Flags [
11// CHECK-NEXT: SHF_ALLOC
12// CHECK-NEXT: SHF_MERGE
13// CHECK-NEXT: SHF_STRINGS
14// CHECK-NEXT: ]
15// CHECK-NEXT: Address:
16// CHECK-NEXT: Offset:
17// CHECK-NEXT: Size: 8
18// CHECK-NEXT: Link: 0
19// CHECK-NEXT: Info: 0
20// CHECK-NEXT: AddressAlignment: 1
21// CHECK-NEXT: EntrySize: 0
22// CHECK-NEXT: SectionData (
23// CHECK-NEXT: 0000: 666F6F00 62617200 |foo.bar.|
24// CHECK-NEXT: )
25
26// GC: Name: .rodata
27// GC-NEXT: Type: SHT_PROGBITS
28// GC-NEXT: Flags [
29// GC-NEXT: SHF_ALLOC
30// GC-NEXT: SHF_MERGE
31// GC-NEXT: SHF_STRINGS
32// GC-NEXT: ]
33// GC-NEXT: Address:
34// GC-NEXT: Offset:
35// GC-NEXT: Size: 4
36// GC-NEXT: Link: 0
37// GC-NEXT: Info: 0
38// GC-NEXT: AddressAlignment: 1
39// GC-NEXT: EntrySize: 0
40// GC-NEXT: SectionData (
41// GC-NEXT: 0000: 666F6F00 |foo.|
42// GC-NEXT: )
43
44 .section .text.f,"ax",@progbits
45 .globl f
46f:
47 leaq .L.str(%rip), %rax
48 retq
49
50 .section .text.g,"ax",@progbits
51 .hidden g
52 .globl g
53g:
54 leaq .L.str.1(%rip), %rax
55 retq
56
57 .section .rodata.str1.1,"aMS",@progbits,1
58.L.str:
59 .asciz "foo"
60.L.str.1:
61 .asciz "bar"
deps/lld/test/ELF/gc-sections-metadata-startstop.s created+33
......@@ -0,0 +1,33 @@
1# LINK_ORDER cnamed sections are not kept alive by the __start_* reference.
2# REQUIRES: x86
3
4# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
5# RUN: ld.lld --gc-sections %t.o -o %t
6# RUN: llvm-objdump -section-headers -t %t | FileCheck %s
7
8# CHECK: Sections:
9# CHECK-NOT: yy
10# CHECK: xx {{.*}} DATA
11# CHECK-NOT: yy
12
13# CHECK: SYMBOL TABLE:
14# CHECK: xx 00000000 __start_xx
15# CHECK: w *UND* 00000000 __start_yy
16
17.weak __start_xx
18.weak __start_yy
19
20.global _start
21_start:
22.quad __start_xx
23.quad __start_yy
24
25.section xx,"a"
26.quad 0
27
28.section .foo,"a"
29.quad 0
30
31.section yy,"ao",@progbits,.foo
32.quad 0
33
deps/lld/test/ELF/gc-sections-metadata.s created+38
......@@ -0,0 +1,38 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
4# RUN: ld.lld --gc-sections %t.o -o %t
5# RUN: llvm-objdump -section-headers %t | FileCheck %s
6
7# CHECK: 1 .foo1
8# CHECK-NEXT: bar1
9# CHECK-NEXT: .zed1
10# CHECK-NEXT: .text
11# CHECK-NEXT: .comment
12# CHECK-NEXT: .symtab
13# CHECK-NEXT: .shstrtab
14# CHECK-NEXT: .strtab
15
16.global _start
17_start:
18.quad .foo1
19
20.section .foo1,"a"
21.quad 0
22
23.section .foo2,"a"
24.quad 0
25
26.section bar1,"ao",@progbits,.foo1
27.quad .zed1
28.quad .foo1
29
30.section bar2,"ao",@progbits,.foo2
31.quad .zed2
32.quad .foo2
33
34.section .zed1,"a"
35.quad 0
36
37.section .zed2,"a"
38.quad 0
deps/lld/test/ELF/gc-sections-metadata2.s created+19
......@@ -0,0 +1,19 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: ld.lld --gc-sections %t.o -o %t
4# RUN: llvm-objdump -section-headers %t | FileCheck %s
5
6# CHECK: .foo
7# CHECK: .bar
8# CHECK: .zed
9
10.globl _start
11_start:
12.quad .foo
13
14.section .foo,"a"
15.quad 0
16.section .bar,"ao",@progbits,.foo
17.quad 0
18.section .zed,"ao",@progbits,.foo
19.quad 0
deps/lld/test/ELF/gc-sections-non-alloc-to-merge.s created+27
......@@ -0,0 +1,27 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
4# RUN: ld.lld %t.o -o %t --gc-sections
5# RUN: llvm-readobj -s --elf-output-style=GNU %t | FileCheck %s
6
7# CHECK: .merge1 PROGBITS {{[0-9a-z]*}} {{[0-9a-z]*}} 000004
8
9 .global _start
10_start:
11 .quad .Lfoo
12
13 .section .merge1,"aM",@progbits,4
14 .p2align 2
15.Lfoo:
16 .long 1
17.Lbar:
18 .long 2
19
20 .section .merge2,"aM",@progbits,4
21 .p2align 2
22.Lzed:
23 .long 1
24
25 .section bar
26 .quad .Lbar
27 .quad .Lzed
deps/lld/test/ELF/gc-sections-print.s created+23
......@@ -0,0 +1,23 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: ld.lld %t --gc-sections --print-gc-sections -o %t2 2>&1 | FileCheck -check-prefix=PRINT %s
4
5# PRINT: removing unused section from '.text.x' in file
6# PRINT-NEXT: removing unused section from '.text.y' in file
7
8.globl _start
9.protected a, x, y
10_start:
11 call a
12
13.section .text.a,"ax",@progbits
14a:
15 nop
16
17.section .text.x,"ax",@progbits
18x:
19 nop
20
21.section .text.y,"ax",@progbits
22y:
23 nop
deps/lld/test/ELF/gc-sections-protected.s created+18
......@@ -0,0 +1,18 @@
1// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
2// RUN: ld.lld %t.o -o %t.so -shared --gc-sections
3// RUN: llvm-readobj -s %t.so | FileCheck %s
4
5// CHECK: Name: .text
6// CHECK-NEXT: Type: SHT_PROGBITS
7// CHECK-NEXT: Flags [
8// CHECK-NEXT: SHF_ALLOC
9// CHECK-NEXT: SHF_EXECINSTR
10// CHECK-NEXT: ]
11// CHECK-NEXT: Address:
12// CHECK-NEXT: Offset:
13// CHECK-NEXT: Size: 1
14
15.protected g
16.globl g
17g:
18retq
deps/lld/test/ELF/gc-sections-shared.s created+59
......@@ -0,0 +1,59 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o
3# RUN: ld.lld -shared %t2.o -o %t2.so
4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
5# RUN: ld.lld --gc-sections --export-dynamic-symbol foo -o %t %t.o --as-needed %t2.so
6# RUN: llvm-readobj --dynamic-table --dyn-symbols %t | FileCheck %s
7
8# This test the property that we have a needed line for every undefined.
9# It would also be OK to drop bar2 and the need for the .so
10
11# CHECK: DynamicSymbols [
12# CHECK-NEXT: Symbol {
13# CHECK-NEXT: Name:
14# CHECK-NEXT: Value:
15# CHECK-NEXT: Size:
16# CHECK-NEXT: Binding: Local
17# CHECK-NEXT: Type:
18# CHECK-NEXT: Other:
19# CHECK-NEXT: Section: Undefined (0x0)
20# CHECK-NEXT: }
21# CHECK-NEXT: Symbol {
22# CHECK-NEXT: Name: bar2
23# CHECK-NEXT: Value:
24# CHECK-NEXT: Size:
25# CHECK-NEXT: Binding: Global
26# CHECK-NEXT: Type:
27# CHECK-NEXT: Other:
28# CHECK-NEXT: Section: Undefined
29# CHECK-NEXT: }
30# CHECK-NEXT: Symbol {
31# CHECK-NEXT: Name: foo
32# CHECK-NEXT: Value:
33# CHECK-NEXT: Size:
34# CHECK-NEXT: Binding: Global
35# CHECK-NEXT: Type:
36# CHECK-NEXT: Other:
37# CHECK-NEXT: Section: .text
38# CHECK-NEXT: }
39# CHECK-NEXT: ]
40
41# CHECK: NEEDED Shared library: [{{.*}}.so]
42
43.section .text.foo, "ax"
44.globl foo
45foo:
46call bar
47
48.section .text.bar, "ax"
49.globl bar
50bar:
51ret
52
53.section .text._start, "ax"
54.globl _start
55_start:
56ret
57
58.section .text.unused, "ax"
59call bar2
deps/lld/test/ELF/gc-sections-synthetic.s created+16
......@@ -0,0 +1,16 @@
1# REQUIRES: x86
2
3# Linker-synthesized sections shouldn't be gc'ed.
4
5# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t1
6# RUN: ld.lld %t1 -shared -o %t.so
7# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2
8# RUN: ld.lld %t2 %t.so -build-id -dynamic-linker /foo/bar -o %t.out
9# RUN: llvm-readobj -sections %t.out | FileCheck %s
10
11# CHECK: Name: .interp
12# CHECK: Name: .note.gnu.build-id
13
14.globl _start
15_start:
16 ret
deps/lld/test/ELF/gc-sections-weak.s created+24
......@@ -0,0 +1,24 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/gc-sections-weak.s -o %t2.o
4// RUN: ld.lld %t.o %t2.o -o %t.so -shared --gc-sections
5// RUN: llvm-readobj -s %t.so | FileCheck %s
6
7.global foo
8foo:
9nop
10
11.data
12.global bar1
13bar1:
14.quad foo
15
16// CHECK: Name: .text
17// CHECK-NEXT: Type: SHT_PROGBITS
18// CHECK-NEXT: Flags [
19// CHECK-NEXT: SHF_ALLOC
20// CHECK-NEXT: SHF_EXECINSTR
21// CHECK-NEXT: ]
22// CHECK-NEXT: Address:
23// CHECK-NEXT: Offset:
24// CHECK-NEXT: Size: 1
deps/lld/test/ELF/gc-sections.s created+108
......@@ -0,0 +1,108 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
4# RUN: ld.lld %t -o %t2
5# RUN: llvm-readobj -sections -symbols %t2 | FileCheck -check-prefix=NOGC %s
6# RUN: ld.lld --gc-sections %t -o %t2
7# RUN: llvm-readobj -sections -symbols %t2 | FileCheck -check-prefix=GC1 %s
8# RUN: ld.lld --export-dynamic --gc-sections %t -o %t2
9# RUN: llvm-readobj -sections -symbols %t2 | FileCheck -check-prefix=GC2 %s
10
11# NOGC: Name: .eh_frame
12# NOGC: Name: .text
13# NOGC: Name: .init
14# NOGC: Name: .fini
15# NOGC: Name: .ctors
16# NOGC: Name: .dtors
17# NOGC: Name: .debug_pubtypes
18# NOGC: Name: .comment
19# NOGC: Name: a
20# NOGC: Name: b
21# NOGC: Name: c
22# NOGC: Name: x
23# NOGC: Name: y
24# NOGC: Name: d
25
26# GC1: Name: .eh_frame
27# GC1: Name: .text
28# GC1: Name: .init
29# GC1: Name: .fini
30# GC1: Name: .ctors
31# GC1: Name: .dtors
32# GC1: Name: .debug_pubtypes
33# GC1: Name: .comment
34# GC1: Name: a
35# GC1: Name: b
36# GC1: Name: c
37# GC1-NOT: Name: x
38# GC1-NOT: Name: y
39# GC1-NOT: Name: d
40
41# GC2: Name: .eh_frame
42# GC2: Name: .text
43# GC2: Name: .init
44# GC2: Name: .fini
45# GC2: Name: .ctors
46# GC2: Name: .dtors
47# GC2: Name: .debug_pubtypes
48# GC2: Name: .comment
49# GC2: Name: a
50# GC2: Name: b
51# GC2: Name: c
52# GC2-NOT: Name: x
53# GC2-NOT: Name: y
54# GC2: Name: d
55
56.globl _start, d
57.protected a, b, c, x, y
58_start:
59 call a
60
61.section .text.a,"ax",@progbits
62a:
63 call _start
64 call b
65
66.section .text.b,"ax",@progbits
67b:
68 call c
69
70.section .text.c,"ax",@progbits
71c:
72 nop
73
74.section .text.d,"ax",@progbits
75d:
76 nop
77
78.section .text.x,"ax",@progbits
79x:
80 call y
81
82.section .text.y,"ax",@progbits
83y:
84 call x
85
86.section .ctors,"aw",@progbits
87 .quad 0
88
89.section .dtors,"aw",@progbits
90 .quad 0
91
92.section .init,"aw",@init_array
93 .quad 0
94
95.section .fini,"aw",@fini_array
96 .quad 0
97
98.section .preinit_array,"aw",@preinit_array
99 .quad 0
100
101.section .eh_frame,"a",@unwind
102 .quad 0
103
104.section .debug_pubtypes,"",@progbits
105 .quad 0
106
107.section .comment,"MS",@progbits,8
108 .quad 0
deps/lld/test/ELF/gdb-index-dup-types.s created+60
......@@ -0,0 +1,60 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: ld.lld --gdb-index %t.o -o %t
4# RUN: llvm-dwarfdump -debug-dump=gdb_index %t | FileCheck %s
5
6## Testcase is based on output produced by gcc version 5.4.1 20160904
7## it has duplicate entries in .debug_gnu_pubtypes which seems to be
8## compiler bug. In that case it is useless to have them in .gdb_index
9## and we filter such entries out to reduce size of .gdb_index.
10
11## CHECK: Constant pool offset = {{.*}}, has 1 CU vectors:
12## CHECK-NOT: 0(0x0): 0x90000000 0x90000000
13
14.section .debug_abbrev,"",@progbits
15 .byte 1 # Abbreviation Code
16 .byte 17 # DW_TAG_compile_unit
17 .byte 0 # DW_CHILDREN_no
18 .byte 16 # DW_AT_stmt_list
19 .byte 23 # DW_FORM_sec_offset
20 .ascii "\260B" # DW_AT_GNU_dwo_name
21 .byte 14 # DW_FORM_strp
22 .byte 27 # DW_AT_comp_dir
23 .byte 14 # DW_FORM_strp
24 .ascii "\264B" # DW_AT_GNU_pubnames
25 .byte 25 # DW_FORM_flag_present
26 .ascii "\261B" # DW_AT_GNU_dwo_id
27 .byte 7 # DW_FORM_data8
28 .ascii "\263B" # DW_AT_GNU_addr_base
29 .byte 23 # DW_FORM_sec_offset
30 .byte 0 # EOM(1)
31 .byte 0 # EOM(2)
32 .byte 0 # EOM(3)
33
34.section .debug_info,"",@progbits
35.Lcu_begin0:
36 .long 32 # Length of Unit
37 .short 4 # DWARF version number
38 .long .debug_abbrev # Offset Into Abbrev. Section
39 .byte 8 # Address Size (in bytes)
40 .byte 1 # Abbrev [1] 0xb:0x19 DW_TAG_compile_unit
41 .long 0 # DW_AT_stmt_list
42 .long 0 # DW_AT_GNU_dwo_name
43 .long 0 # DW_AT_comp_dir
44 .quad 0 # DW_AT_GNU_dwo_id
45 .long 0 # DW_AT_GNU_addr_base
46
47.section .debug_gnu_pubtypes,"",@progbits
48.long .LpubTypes_end0-.LpubTypes_begin0 # Length of Public Types Info
49.LpubTypes_begin0:
50 .short 2 # DWARF Version
51 .long .Lcu_begin0 # Offset of Compilation Unit Info
52 .long 36 # Compilation Unit Length
53 .long 36 # DIE offset
54 .byte 144 # Kind: TYPE, STATIC
55 .asciz "int" # External Name
56 .long 36 # DIE offset
57 .byte 144 # Kind: TYPE, STATIC
58 .asciz "int" # External Name
59 .long 0 # End Mark
60.LpubTypes_end0:
deps/lld/test/ELF/gdb-index-empty.s created+81
......@@ -0,0 +1,81 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux -o %t %s
3# RUN: ld.lld --gdb-index --gc-sections -o %t2 %t
4# RUN: llvm-dwarfdump -debug-dump=gdb_index %t2 | FileCheck %s
5
6# CHECK: Address area offset = 0x28, has 0 entries:
7
8# Generated with: (clang r302976)
9# echo "void _start() { __builtin_unreachable(); }" | \
10# clang -Os -g -S -o gdb-index-empty.s -x c - -Xclang -fdebug-compilation-dir -Xclang .
11
12.text
13.globl _start
14.type _start,@function
15_start:
16.Lfunc_begin0:
17.Lfunc_end0:
18
19.section .debug_abbrev,"",@progbits
20 .byte 1 # Abbreviation Code
21 .byte 17 # DW_TAG_compile_unit
22 .byte 1 # DW_CHILDREN_yes
23 .byte 37 # DW_AT_producer
24 .byte 14 # DW_FORM_strp
25 .byte 19 # DW_AT_language
26 .byte 5 # DW_FORM_data2
27 .byte 3 # DW_AT_name
28 .byte 14 # DW_FORM_strp
29 .byte 16 # DW_AT_stmt_list
30 .byte 23 # DW_FORM_sec_offset
31 .byte 27 # DW_AT_comp_dir
32 .byte 14 # DW_FORM_strp
33 .byte 17 # DW_AT_low_pc
34 .byte 1 # DW_FORM_addr
35 .byte 18 # DW_AT_high_pc
36 .byte 6 # DW_FORM_data4
37 .byte 0 # EOM(1)
38 .byte 0 # EOM(2)
39 .byte 2 # Abbreviation Code
40 .byte 46 # DW_TAG_subprogram
41 .byte 0 # DW_CHILDREN_no
42 .byte 17 # DW_AT_low_pc
43 .byte 1 # DW_FORM_addr
44 .byte 18 # DW_AT_high_pc
45 .byte 6 # DW_FORM_data4
46 .byte 64 # DW_AT_frame_base
47 .byte 24 # DW_FORM_exprloc
48 .byte 3 # DW_AT_name
49 .byte 14 # DW_FORM_strp
50 .byte 58 # DW_AT_decl_file
51 .byte 11 # DW_FORM_data1
52 .byte 59 # DW_AT_decl_line
53 .byte 11 # DW_FORM_data1
54 .byte 63 # DW_AT_external
55 .byte 25 # DW_FORM_flag_present
56 .byte 0 # EOM(1)
57 .byte 0 # EOM(2)
58 .byte 0 # EOM(3)
59
60.section .debug_info,"",@progbits
61 .long 60 # Length of Unit
62 .short 4 # DWARF version number
63 .long .debug_abbrev # Offset Into Abbrev. Section
64 .byte 8 # Address Size (in bytes)
65 .byte 1 # Abbrev [1] 0xb:0x35 DW_TAG_compile_unit
66 .long 0 # DW_AT_producer
67 .short 12 # DW_AT_language
68 .long 0 # DW_AT_name
69 .long 0 # DW_AT_stmt_list
70 .long 0 # DW_AT_comp_dir
71 .quad .Lfunc_begin0 # DW_AT_low_pc
72 .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
73 .byte 2 # Abbrev [2] 0x2a:0x15 DW_TAG_subprogram
74 .quad .Lfunc_begin0 # DW_AT_low_pc
75 .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
76 .byte 1 # DW_AT_frame_base
77 .byte 87
78 .long 0 # DW_AT_name
79 .byte 1 # DW_AT_decl_file
80 .byte 1 # DW_AT_decl_line
81 .byte 0 # End Of Children Mark
deps/lld/test/ELF/gdb-index-gc-sections.s created+158
......@@ -0,0 +1,158 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux -o %t %s
3# RUN: ld.lld --gdb-index --gc-sections -o %t2 %t
4# RUN: llvm-dwarfdump -debug-dump=gdb_index %t2 | FileCheck %s
5
6# CHECK: Address area offset = 0x28, has 1 entries:
7# CHECK-NEXT: Low/High address = [0x201000, 0x201001) (Size: 0x1), CU id = 0
8
9# Generated with: (clang r302976)
10# echo "void _start() {} void dead() {}" | \
11# clang -Os -g -S -ffunction-sections -o gdb-index-gc-sections.s -x c - -Xclang -fdebug-compilation-dir -Xclang .
12
13 .text
14 .file "-"
15 .section .text._start,"ax",@progbits
16 .globl _start
17 .type _start,@function
18_start: # @_start
19.Lfunc_begin0:
20 .file 1 "<stdin>"
21 .loc 1 1 0 # <stdin>:1:0
22 .cfi_startproc
23# BB#0: # %entry
24 .loc 1 1 16 prologue_end # <stdin>:1:16
25 retq
26.Ltmp0:
27.Lfunc_end0:
28 .size _start, .Lfunc_end0-_start
29 .cfi_endproc
30
31 .section .text.dead,"ax",@progbits
32 .globl dead
33 .type dead,@function
34dead: # @dead
35.Lfunc_begin1:
36 .loc 1 1 0 # <stdin>:1:0
37 .cfi_startproc
38# BB#0: # %entry
39 .loc 1 1 31 prologue_end # <stdin>:1:31
40 retq
41.Ltmp1:
42.Lfunc_end1:
43 .size dead, .Lfunc_end1-dead
44 .cfi_endproc
45
46 .section .debug_str,"MS",@progbits,1
47.Linfo_string0:
48 .asciz "clang version 5.0.0 " # string offset=0
49.Linfo_string1:
50 .asciz "-" # string offset=21
51.Linfo_string2:
52 .asciz "." # string offset=23
53.Linfo_string3:
54 .asciz "_start" # string offset=25
55.Linfo_string4:
56 .asciz "dead" # string offset=32
57 .section .debug_loc,"",@progbits
58 .section .debug_abbrev,"",@progbits
59 .byte 1 # Abbreviation Code
60 .byte 17 # DW_TAG_compile_unit
61 .byte 1 # DW_CHILDREN_yes
62 .byte 37 # DW_AT_producer
63 .byte 14 # DW_FORM_strp
64 .byte 19 # DW_AT_language
65 .byte 5 # DW_FORM_data2
66 .byte 3 # DW_AT_name
67 .byte 14 # DW_FORM_strp
68 .byte 16 # DW_AT_stmt_list
69 .byte 23 # DW_FORM_sec_offset
70 .byte 27 # DW_AT_comp_dir
71 .byte 14 # DW_FORM_strp
72 .byte 17 # DW_AT_low_pc
73 .byte 1 # DW_FORM_addr
74 .byte 85 # DW_AT_ranges
75 .byte 23 # DW_FORM_sec_offset
76 .byte 0 # EOM(1)
77 .byte 0 # EOM(2)
78 .byte 2 # Abbreviation Code
79 .byte 46 # DW_TAG_subprogram
80 .byte 0 # DW_CHILDREN_no
81 .byte 17 # DW_AT_low_pc
82 .byte 1 # DW_FORM_addr
83 .byte 18 # DW_AT_high_pc
84 .byte 6 # DW_FORM_data4
85 .byte 64 # DW_AT_frame_base
86 .byte 24 # DW_FORM_exprloc
87 .byte 3 # DW_AT_name
88 .byte 14 # DW_FORM_strp
89 .byte 58 # DW_AT_decl_file
90 .byte 11 # DW_FORM_data1
91 .byte 59 # DW_AT_decl_line
92 .byte 11 # DW_FORM_data1
93 .byte 63 # DW_AT_external
94 .byte 25 # DW_FORM_flag_present
95 .byte 0 # EOM(1)
96 .byte 0 # EOM(2)
97 .byte 0 # EOM(3)
98 .section .debug_info,"",@progbits
99.Lcu_begin0:
100 .long 81 # Length of Unit
101 .short 4 # DWARF version number
102 .long .debug_abbrev # Offset Into Abbrev. Section
103 .byte 8 # Address Size (in bytes)
104 .byte 1 # Abbrev [1] 0xb:0x4a DW_TAG_compile_unit
105 .long .Linfo_string0 # DW_AT_producer
106 .short 12 # DW_AT_language
107 .long .Linfo_string1 # DW_AT_name
108 .long .Lline_table_start0 # DW_AT_stmt_list
109 .long .Linfo_string2 # DW_AT_comp_dir
110 .quad 0 # DW_AT_low_pc
111 .long .Ldebug_ranges0 # DW_AT_ranges
112 .byte 2 # Abbrev [2] 0x2a:0x15 DW_TAG_subprogram
113 .quad .Lfunc_begin0 # DW_AT_low_pc
114 .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc
115 .byte 1 # DW_AT_frame_base
116 .byte 87
117 .long .Linfo_string3 # DW_AT_name
118 .byte 1 # DW_AT_decl_file
119 .byte 1 # DW_AT_decl_line
120 # DW_AT_external
121 .byte 2 # Abbrev [2] 0x3f:0x15 DW_TAG_subprogram
122 .quad .Lfunc_begin1 # DW_AT_low_pc
123 .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc
124 .byte 1 # DW_AT_frame_base
125 .byte 87
126 .long .Linfo_string4 # DW_AT_name
127 .byte 1 # DW_AT_decl_file
128 .byte 1 # DW_AT_decl_line
129 # DW_AT_external
130 .byte 0 # End Of Children Mark
131 .section .debug_ranges,"",@progbits
132.Ldebug_ranges0:
133 .quad .Lfunc_begin0
134 .quad .Lfunc_end0
135 .quad .Lfunc_begin1
136 .quad .Lfunc_end1
137 .quad 0
138 .quad 0
139 .section .debug_macinfo,"",@progbits
140.Lcu_macro_begin0:
141 .byte 0 # End Of Macro List Mark
142 .section .debug_pubnames,"",@progbits
143 .long .LpubNames_end0-.LpubNames_begin0 # Length of Public Names Info
144.LpubNames_begin0:
145 .short 2 # DWARF Version
146 .long .Lcu_begin0 # Offset of Compilation Unit Info
147 .long 85 # Compilation Unit Length
148 .long 42 # DIE offset
149 .asciz "_start" # External Name
150 .long 63 # DIE offset
151 .asciz "dead" # External Name
152 .long 0 # End Mark
153.LpubNames_end0:
154
155 .ident "clang version 5.0.0 "
156 .section ".note.GNU-stack","",@progbits
157 .section .debug_line,"",@progbits
158.Lline_table_start0:
deps/lld/test/ELF/gdb-index-ranges.s created+66
......@@ -0,0 +1,66 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: ld.lld --gdb-index -e main %t.o -o %t
4# RUN: llvm-dwarfdump -debug-dump=gdb_index %t | FileCheck %s
5
6# CHECK: .gnu_index contents:
7# CHECK: Address area offset = 0x28, has 2 entries:
8# CHECK-NEXT: Low/High address = [0x201000, 0x201001) (Size: 0x1), CU id = 0
9# CHECK-NEXT: Low/High address = [0x201001, 0x201003) (Size: 0x2), CU id = 0
10
11.section .text.foo1,"ax",@progbits
12.Lfunc_begin0:
13 nop
14.Lfunc_end0:
15
16.section .text.foo2,"ax",@progbits
17.Lfunc_begin1:
18 nop
19 nop
20.Lfunc_end1:
21
22.section .debug_abbrev,"",@progbits
23.byte 1 # Abbreviation Code
24.byte 17 # DW_TAG_compile_unit
25.byte 0 # DW_CHILDREN_no
26.byte 37 # DW_AT_producer
27.byte 14 # DW_FORM_strp
28.byte 19 # DW_AT_language
29.byte 5 # DW_FORM_data2
30.byte 3 # DW_AT_name
31.byte 14 # DW_FORM_strp
32.byte 16 # DW_AT_stmt_list
33.byte 23 # DW_FORM_sec_offset
34.byte 27 # DW_AT_comp_dir
35.byte 14 # DW_FORM_strp
36.byte 17 # DW_AT_low_pc
37.byte 1 # DW_FORM_addr
38.byte 85 # DW_AT_ranges
39.byte 23 # DW_FORM_sec_offset
40.byte 0 # EOM(1)
41.byte 0 # EOM(2)
42.byte 0 # EOM(3)
43
44.section .debug_info,"",@progbits
45.Lcu_begin0:
46.long 38 # Length of Unit
47.short 4 # DWARF version number
48.long .debug_abbrev # Offset Into Abbrev. Section
49.byte 8 # Address Size (in bytes)
50.byte 1 # Abbrev [1] 0xb:0x1f DW_TAG_compile_unit
51.long 0 # DW_AT_producer
52.short 4 # DW_AT_language
53.long 0 # DW_AT_name
54.long 0 # DW_AT_stmt_list
55.long 0 # DW_AT_comp_dir
56.quad 0 # DW_AT_low_pc
57.long .Ldebug_ranges0 # DW_AT_ranges
58
59.section .debug_ranges,"",@progbits
60.Ldebug_ranges0:
61.quad .Lfunc_begin0
62.quad .Lfunc_end0
63.quad .Lfunc_begin1
64.quad .Lfunc_end1
65.quad 0
66.quad 0
deps/lld/test/ELF/gdb-index.s created+112
......@@ -0,0 +1,112 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
3# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/gdb-index.s -o %t2.o
4# RUN: ld.lld --gdb-index -e main %t1.o %t2.o -o %t
5# RUN: llvm-dwarfdump -debug-dump=gdb_index %t | FileCheck %s
6# RUN: llvm-objdump -d %t | FileCheck %s --check-prefix=DISASM
7
8# DISASM: Disassembly of section .text:
9# DISASM: main:
10# DISASM-CHECK: 201000: 90 nop
11# DISASM-CHECK: 201001: cc int3
12# DISASM-CHECK: 201002: cc int3
13# DISASM-CHECK: 201003: cc int3
14# DISASM: main2:
15# DISASM-CHECK: 201004: 90 nop
16# DISASM-CHECK: 201005: 90 nop
17
18# CHECK: .gnu_index contents:
19# CHECK-NEXT: Version = 7
20# CHECK: CU list offset = 0x18, has 2 entries:
21# CHECK-NEXT: 0: Offset = 0x0, Length = 0x34
22# CHECK-NEXT: 1: Offset = 0x34, Length = 0x34
23# CHECK: Address area offset = 0x38, has 2 entries:
24# CHECK-NEXT: Low/High address = [0x201000, 0x201001) (Size: 0x1), CU id = 0
25# CHECK-NEXT: Low/High address = [0x201004, 0x201006) (Size: 0x2), CU id = 1
26# CHECK: Symbol table offset = 0x60, size = 1024, filled slots:
27# CHECK-NEXT: 489: Name offset = 0x1d, CU vector offset = 0x0
28# CHECK-NEXT: String name: main, CU vector index: 0
29# CHECK-NEXT: 754: Name offset = 0x22, CU vector offset = 0x8
30# CHECK-NEXT: String name: int, CU vector index: 1
31# CHECK-NEXT: 956: Name offset = 0x26, CU vector offset = 0x14
32# CHECK-NEXT: String name: main2, CU vector index: 2
33# CHECK: Constant pool offset = 0x2060, has 3 CU vectors:
34# CHECK-NEXT: 0(0x0): 0x30000000
35# CHECK-NEXT: 1(0x8): 0x90000000 0x90000001
36# CHECK-NEXT: 2(0x14): 0x30000001
37
38## The following section contents are created by this using gcc 7.1.0:
39## echo 'int main() { return 0; }' | gcc -gsplit-dwarf -xc++ -S -o- -
40
41.text
42.Ltext0:
43.globl main
44.type main, @function
45main:
46 nop
47.Letext0:
48
49.section .debug_info,"",@progbits
50.long 0x30
51.value 0x4
52.long 0
53.byte 0x8
54.uleb128 0x1
55.quad .Ltext0
56.quad .Letext0-.Ltext0
57.long 0
58.long 0
59.long 0
60.long 0
61.byte 0x63
62.byte 0x88
63.byte 0xb4
64.byte 0x61
65.byte 0xaa
66.byte 0xb6
67.byte 0xb0
68.byte 0x67
69
70.section .debug_abbrev,"",@progbits
71.uleb128 0x1
72.uleb128 0x11
73.byte 0
74.uleb128 0x11
75.uleb128 0x1
76.uleb128 0x12
77.uleb128 0x7
78.uleb128 0x10
79.uleb128 0x17
80.uleb128 0x2130
81.uleb128 0xe
82.uleb128 0x1b
83.uleb128 0xe
84.uleb128 0x2134
85.uleb128 0x19
86.uleb128 0x2133
87.uleb128 0x17
88.uleb128 0x2131
89.uleb128 0x7
90.byte 0
91.byte 0
92.byte 0
93
94.section .debug_gnu_pubnames,"",@progbits
95.long 0x18
96.value 0x2
97.long 0
98.long 0x33
99.long 0x18
100.byte 0x30
101.string "main"
102.long 0
103
104.section .debug_gnu_pubtypes,"",@progbits
105.long 0x17
106.value 0x2
107.long 0
108.long 0x33
109.long 0x2b
110.byte 0x90
111.string "int"
112.long 0
deps/lld/test/ELF/global-offset-table-position-aarch64.s created+30
......@@ -0,0 +1,30 @@
1// RUN: llvm-mc -filetype=obj -triple=aarch64-linux-gnu %s -o %t
2// RUN: ld.lld -shared %t -o %t2
3// RUN: llvm-readobj -t %t2 | FileCheck %s
4// REQUIRES: aarch64
5.globl a
6.type a,@object
7.comm a,4,4
8
9.globl f
10.type f,@function
11f:
12 adrp x0, :got:a
13 ldr x0, [x0, #:got_lo12:a]
14
15.global _start
16.type _start,@function
17_start:
18 bl f
19.data
20.long _GLOBAL_OFFSET_TABLE_ - .
21
22// CHECK: Name: _GLOBAL_OFFSET_TABLE_ (11)
23// CHECK-NEXT: Value: 0x30090
24// CHECK-NEXT: Size: 0
25// CHECK-NEXT: Binding: Local (0x0)
26// CHECK-NEXT: Type: None (0x0)
27// CHECK-NEXT: Other [ (0x2)
28// CHECK-NEXT: STV_HIDDEN (0x2)
29// CHECK-NEXT: ]
30// CHECK-NEXT: Section: .got
deps/lld/test/ELF/global-offset-table-position-arm.s created+35
......@@ -0,0 +1,35 @@
1// RUN: llvm-mc -filetype=obj -triple=armv7a-linux-gnueabihf %s -o %t
2// RUN: ld.lld -shared %t -o %t2
3// RUN: llvm-readobj -t %t2 | FileCheck %s
4// REQUIRES: arm
5
6// The ARM _GLOBAL_OFFSET_TABLE_ should be defined at the start of the .got
7.globl a
8.type a,%object
9.comm a,4,4
10
11.globl f
12.type f,%function
13f:
14 ldr r2, .L1
15.L0:
16 add r2, pc
17.L1:
18.word _GLOBAL_OFFSET_TABLE_ - (.L0+4)
19.word a(GOT)
20
21.global _start
22.type _start,%function
23_start:
24 bl f
25.data
26
27// CHECK: Name: _GLOBAL_OFFSET_TABLE_
28// CHECK-NEXT: Value: 0x3068
29// CHECK-NEXT: Size: 0
30// CHECK-NEXT: Binding: Local
31// CHECK-NEXT: Type: None
32// CHECK-NEXT: Other [ (0x2)
33// CHECK-NEXT: STV_HIDDEN (0x2)
34// CHECK-NEXT: ]
35// CHECK-NEXT: Section: .got
deps/lld/test/ELF/global-offset-table-position-i386.s created+31
......@@ -0,0 +1,31 @@
1// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t
2// RUN: ld.lld -shared %t -o %t2
3// RUN: llvm-readobj -t %t2 | FileCheck %s
4// REQUIRES: x86
5
6// The X86 _GLOBAL_OFFSET_TABLE_ is defined at the end of the .got section.
7.globl a
8.type a,@object
9.comm a,4,4
10
11.globl f
12.type f,@function
13f:
14addl $_GLOBAL_OFFSET_TABLE_, %eax
15movl a@GOT(%eax), %eax
16
17.global _start
18.type _start,@function
19_start:
20addl $_GLOBAL_OFFSET_TABLE_, %eax
21calll f@PLT
22
23// CHECK: Name: _GLOBAL_OFFSET_TABLE_ (1)
24// CHECK-NEXT: Value: 0x306C
25// CHECK-NEXT: Size: 0
26// CHECK-NEXT: Binding: Local (0x0)
27// CHECK-NEXT: Type: None (0x0)
28// CHECK-NEXT: Other [ (0x2)
29// CHECK-NEXT: STV_HIDDEN (0x2)
30// CHECK-NEXT: ]
31// CHECK-NEXT: Section: .got (0xA)
deps/lld/test/ELF/global-offset-table-position-mips.s created+33
......@@ -0,0 +1,33 @@
1// RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t
2// RUN: ld.lld -shared %t -o %t2
3// RUN: llvm-readobj -t %t2 | FileCheck %s
4
5// REQUIRES: mips
6
7// The Mips _GLOBAL_OFFSET_TABLE_ should be defined at the start of the .got
8
9.globl a
10.hidden a
11.type a,@object
12.comm a,4,4
13
14.globl f
15.type f,@function
16f:
17 ld $v0,%got_page(a)($gp)
18 daddiu $v0,$v0,%got_ofst(a)
19
20.global _start
21.type _start,@function
22_start:
23 lw $t0,%call16(f)($gp)
24 .word _GLOBAL_OFFSET_TABLE_ - .
25// CHECK: Name: _GLOBAL_OFFSET_TABLE_ (1)
26// CHECK-NEXT: Value: 0x20000
27// CHECK-NEXT: Size: 0
28// CHECK-NEXT: Binding: Local (0x0)
29// CHECK-NEXT: Type: None (0x0)
30// CHECK-NEXT: Other [ (0x2)
31// CHECK-NEXT: STV_HIDDEN (0x2)
32// CHECK-NEXT: ]
33// CHECK-NEXT: Section: .got (0x9)
deps/lld/test/ELF/global-offset-table-position.s created+31
......@@ -0,0 +1,31 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
2// RUN: ld.lld -shared %t -o %t2
3// RUN: llvm-readobj -t %t2 | FileCheck %s
4// REQUIRES: x86
5
6// The X86_64 _GLOBAL_OFFSET_TABLE_ is defined at the end of the .got section.
7.globl a
8.type a,@object
9.comm a,4,4
10
11.globl f
12.type f,@function
13f:
14movq a@GOTPCREL(%rip), %rax
15
16.global _start
17.type _start,@function
18_start:
19callq f@PLT
20.data
21.long _GLOBAL_OFFSET_TABLE_ - .
22
23// CHECK: Name: _GLOBAL_OFFSET_TABLE_
24// CHECK-NEXT: Value: 0x30D8
25// CHECK-NEXT: Size: 0
26// CHECK-NEXT: Binding: Local
27// CHECK-NEXT: Type: None (0x0)
28// CHECK-NEXT: Other [
29// CHECK-NEXT: STV_HIDDEN
30// CHECK-NEXT: ]
31// CHECK-NEXT: Section: .got
deps/lld/test/ELF/global_offset_table.s created+5
......@@ -0,0 +1,5 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
2// RUN: ld.lld %t -o %t2
3.global _start
4_start:
5.long _GLOBAL_OFFSET_TABLE_
deps/lld/test/ELF/global_offset_table_shared.s created+14
......@@ -0,0 +1,14 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
2// RUN: ld.lld -shared %t -o %t2
3// RUN: llvm-readobj -t %t2 | FileCheck %s
4.long _GLOBAL_OFFSET_TABLE_ - .
5
6// CHECK: Name: _GLOBAL_OFFSET_TABLE_
7// CHECK-NEXT: Value: 0x2060
8// CHECK-NEXT: Size: 0
9// CHECK-NEXT: Binding: Local
10// CHECK-NEXT: Type: None
11// CHECK-NEXT: Other [ (0x2)
12// CHECK-NEXT: STV_HIDDEN (0x2)
13// CHECK-NEXT: ]
14// CHECK-NEXT: Section: .got
deps/lld/test/ELF/gnu-hash-table.s created+195
......@@ -0,0 +1,195 @@
1# REQUIRES: x86,ppc
2
3# RUN: echo ".globl foo" > %te.s
4# RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %te.s -o %te-i386.o
5# RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t-i386.o
6# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t-x86_64.o
7# RUN: llvm-mc -filetype=obj -triple=powerpc64-pc-linux %s -o %t-ppc64.o
8
9# RUN: ld.lld -shared --hash-style=gnu -o %te-i386.so %te-i386.o
10# RUN: ld.lld -shared -hash-style=gnu -o %t-i386.so %t-i386.o
11# RUN: ld.lld -shared -hash-style=gnu -o %t-x86_64.so %t-x86_64.o
12# RUN: ld.lld -shared --hash-style both -o %t-ppc64.so %t-ppc64.o
13
14# RUN: llvm-readobj -dyn-symbols -gnu-hash-table %te-i386.so \
15# RUN: | FileCheck %s -check-prefix=EMPTY
16# RUN: llvm-readobj -sections -dyn-symbols -gnu-hash-table %t-i386.so \
17# RUN: | FileCheck %s -check-prefix=I386
18# RUN: llvm-readobj -sections -dyn-symbols -gnu-hash-table %t-x86_64.so \
19# RUN: | FileCheck %s -check-prefix=X86_64
20# RUN: llvm-readobj -sections -dyn-symbols -gnu-hash-table %t-ppc64.so \
21# RUN: | FileCheck %s -check-prefix=PPC64
22
23# EMPTY: DynamicSymbols [
24# EMPTY: Symbol {
25# EMPTY: Name: foo@
26# EMPTY-NEXT: Value: 0x0
27# EMPTY-NEXT: Size: 0
28# EMPTY-NEXT: Binding: Global
29# EMPTY-NEXT: Type: None
30# EMPTY-NEXT: Other: 0
31# EMPTY-NEXT: Section: Undefined
32# EMPTY-NEXT: }
33# EMPTY-NEXT: ]
34# EMPTY: GnuHashTable {
35# EMPTY-NEXT: Num Buckets: 0
36# EMPTY-NEXT: First Hashed Symbol Index: 2
37# EMPTY-NEXT: Num Mask Words: 1
38# EMPTY-NEXT: Shift Count: 5
39# EMPTY-NEXT: Bloom Filter: [0x0]
40# EMPTY-NEXT: Buckets: []
41# EMPTY-NEXT: Values: []
42# EMPTY-NEXT: }
43
44# I386: Format: ELF32-i386
45# I386: Arch: i386
46# I386: AddressSize: 32bit
47# I386: Sections [
48# I386: Name: .gnu.hash
49# I386-NEXT: Type: SHT_GNU_HASH
50# I386-NEXT: Flags [
51# I386-NEXT: SHF_ALLOC
52# I386-NEXT: ]
53# I386-NEXT: Address:
54# I386-NEXT: Offset:
55# I386-NEXT: Size: 32
56# I386-NEXT: Link:
57# I386-NEXT: Info: 0
58# I386-NEXT: AddressAlignment: 4
59# I386-NEXT: EntrySize: 0
60# I386: ]
61# I386: DynamicSymbols [
62# I386: Symbol {
63# I386: Name: @
64# I386: Binding: Local
65# I386: Section: Undefined
66# I386: }
67# I386: Symbol {
68# I386: Name: baz@
69# I386: Binding: Global
70# I386: Section: Undefined
71# I386: }
72# I386: Symbol {
73# I386: Name: bar@
74# I386: Binding: Global
75# I386: Section: .text
76# I386: }
77# I386: Symbol {
78# I386: Name: foo@
79# I386: Binding: Global
80# I386: Section: .text
81# I386: }
82# I386: ]
83# I386: GnuHashTable {
84# I386-NEXT: Num Buckets: 1
85# I386-NEXT: First Hashed Symbol Index: 2
86# I386-NEXT: Num Mask Words: 1
87# I386-NEXT: Shift Count: 5
88# I386-NEXT: Bloom Filter: [0x14000220]
89# I386-NEXT: Buckets: [2]
90# I386-NEXT: Values: [0xB8860BA, 0xB887389]
91# I386-NEXT: }
92
93# X86_64: Format: ELF64-x86-64
94# X86_64: Arch: x86_64
95# X86_64: AddressSize: 64bit
96# X86_64: Sections [
97# X86_64: Name: .gnu.hash
98# X86_64-NEXT: Type: SHT_GNU_HASH
99# X86_64-NEXT: Flags [
100# X86_64-NEXT: SHF_ALLOC
101# X86_64-NEXT: ]
102# X86_64-NEXT: Address:
103# X86_64-NEXT: Offset:
104# X86_64-NEXT: Size: 36
105# X86_64-NEXT: Link:
106# X86_64-NEXT: Info: 0
107# X86_64-NEXT: AddressAlignment: 8
108# X86_64-NEXT: EntrySize: 0
109# X86_64-NEXT: }
110# X86_64: ]
111# X86_64: DynamicSymbols [
112# X86_64: Symbol {
113# X86_64: Name: @
114# X86_64: Binding: Local
115# X86_64: Section: Undefined
116# X86_64: }
117# X86_64: Symbol {
118# X86_64: Name: baz@
119# X86_64: Binding: Global
120# X86_64: Section: Undefined
121# X86_64: }
122# X86_64: Symbol {
123# X86_64: Name: bar@
124# X86_64: Binding: Global
125# X86_64: Section: .text
126# X86_64: }
127# X86_64: Symbol {
128# X86_64: Name: foo@
129# X86_64: Binding: Global
130# X86_64: Section: .text
131# X86_64: }
132# X86_64: ]
133# X86_64: GnuHashTable {
134# X86_64-NEXT: Num Buckets: 1
135# X86_64-NEXT: First Hashed Symbol Index: 2
136# X86_64-NEXT: Num Mask Words: 1
137# X86_64-NEXT: Shift Count: 6
138# X86_64-NEXT: Bloom Filter: [0x400000000004204]
139# X86_64-NEXT: Buckets: [2]
140# X86_64-NEXT: Values: [0xB8860BA, 0xB887389]
141# X86_64-NEXT: }
142
143# PPC64: Format: ELF64-ppc64
144# PPC64: Arch: powerpc64
145# PPC64: AddressSize: 64bit
146# PPC64: Sections [
147# PPC64: Name: .gnu.hash
148# PPC64-NEXT: Type: SHT_GNU_HASH
149# PPC64-NEXT: Flags [
150# PPC64-NEXT: SHF_ALLOC
151# PPC64-NEXT: ]
152# PPC64-NEXT: Address: 0x228
153# PPC64-NEXT: Offset: 0x228
154# PPC64-NEXT: Size: 36
155# PPC64-NEXT: Link: 1
156# PPC64-NEXT: Info: 0
157# PPC64-NEXT: AddressAlignment: 8
158# PPC64-NEXT: EntrySize: 0
159# PPC64-NEXT: }
160# PPC64: ]
161# PPC64: DynamicSymbols [
162# PPC64: Symbol {
163# PPC64: Name: @
164# PPC64: Binding: Local
165# PPC64: Section: Undefined
166# PPC64: }
167# PPC64: Symbol {
168# PPC64: Name: baz@
169# PPC64: Binding: Global
170# PPC64: Section: Undefined
171# PPC64: }
172# PPC64: Symbol {
173# PPC64: Name: bar@
174# PPC64: Binding: Global
175# PPC64: Section: .text
176# PPC64: }
177# PPC64: Symbol {
178# PPC64: Name: foo@
179# PPC64: Binding: Global
180# PPC64: Section: .text
181# PPC64: }
182# PPC64: ]
183# PPC64: GnuHashTable {
184# PPC64-NEXT: Num Buckets: 1
185# PPC64-NEXT: First Hashed Symbol Index: 2
186# PPC64-NEXT: Num Mask Words: 1
187# PPC64-NEXT: Shift Count: 6
188# PPC64-NEXT: Bloom Filter: [0x400000000004204]
189# PPC64-NEXT: Buckets: [2]
190# PPC64-NEXT: Values: [0xB8860BA, 0xB887389]
191# PPC64-NEXT: }
192
193.globl foo,bar,baz
194foo:
195bar:
deps/lld/test/ELF/gnu-ifunc-dso.s created+13
......@@ -0,0 +1,13 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/gnu-ifunc-dso.s -o %t1.o
3# RUN: ld.lld -shared %t1.o -o %t.so
4# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t2.o
5# RUN: ld.lld -shared %t2.o %t.so -o %t
6# RUN: llvm-readobj -dyn-relocations %t | FileCheck %s
7
8# CHECK: Dynamic Relocations {
9# CHECK-NEXT: 0x1000 R_X86_64_64 foo 0x0
10# CHECK-NEXT: }
11
12.data
13 .quad foo
deps/lld/test/ELF/gnu-ifunc-gotpcrel.s created+14
......@@ -0,0 +1,14 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/gnu-ifunc-gotpcrel.s -o %t2.o
3# RUN: ld.lld -shared %t2.o -o %t2.so
4# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
5# RUN: ld.lld %t.o %t2.so -o %t
6# RUN: llvm-readobj -dyn-relocations %t | FileCheck %s
7
8# CHECK: Dynamic Relocations {
9# CHECK-NEXT: 0x2020B0 R_X86_64_GLOB_DAT foo 0x0
10# CHECK-NEXT: }
11
12.globl _start
13_start:
14mov foo@gotpcrel(%rip), %rax
deps/lld/test/ELF/gnu-ifunc-i386.s created+126
......@@ -0,0 +1,126 @@
1// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
2// RUN: ld.lld -static %t.o -o %tout
3// RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM
4// RUN: llvm-readobj -r -symbols -sections %tout | FileCheck %s
5// REQUIRES: x86
6
7// CHECK: Sections [
8// CHECK: Section {
9// CHECK: Index: 1
10// CHECK-NEXT: Name: .rel.plt
11// CHECK-NEXT: Type: SHT_REL
12// CHECK-NEXT: Flags [
13// CHECK-NEXT: SHF_ALLOC
14// CHECK-NEXT: ]
15// CHECK-NEXT: Address: [[RELA:.*]]
16// CHECK-NEXT: Offset: 0xD4
17// CHECK-NEXT: Size: 16
18// CHECK-NEXT: Link: 6
19// CHECK-NEXT: Info: 0
20// CHECK-NEXT: AddressAlignment: 4
21// CHECK-NEXT: EntrySize: 8
22// CHECK-NEXT: }
23// CHECK: Relocations [
24// CHECK-NEXT: Section ({{.*}}) .rel.plt {
25// CHECK-NEXT: 0x12000 R_386_IRELATIVE
26// CHECK-NEXT: 0x12004 R_386_IRELATIVE
27// CHECK-NEXT: }
28// CHECK-NEXT: ]
29
30// CHECK: Symbols [
31// CHECK-NEXT: Symbol {
32// CHECK-NEXT: Name:
33// CHECK-NEXT: Value: 0x0
34// CHECK-NEXT: Size: 0
35// CHECK-NEXT: Binding: Local
36// CHECK-NEXT: Type: None
37// CHECK-NEXT: Other: 0
38// CHECK-NEXT: Section: Undefined
39// CHECK-NEXT: }
40// CHECK-NEXT: Symbol {
41// CHECK-NEXT: Name: __rel_iplt_end
42// CHECK-NEXT: Value: 0x100E4
43// CHECK-NEXT: Size: 0
44// CHECK-NEXT: Binding: Local
45// CHECK-NEXT: Type: None
46// CHECK-NEXT: Other [
47// CHECK-NEXT: STV_HIDDEN
48// CHECK-NEXT: ]
49// CHECK-NEXT: Section: .rel.plt
50// CHECK-NEXT: }
51// CHECK-NEXT: Symbol {
52// CHECK-NEXT: Name: __rel_iplt_start
53// CHECK-NEXT: Value: [[RELA]]
54// CHECK-NEXT: Size: 0
55// CHECK-NEXT: Binding: Local
56// CHECK-NEXT: Type: None
57// CHECK-NEXT: Other [
58// CHECK-NEXT: STV_HIDDEN
59// CHECK-NEXT: ]
60// CHECK-NEXT: Section: .rel.plt
61// CHECK-NEXT: }
62// CHECK-NEXT: Symbol {
63// CHECK-NEXT: Name: _start
64// CHECK-NEXT: Value: 0x11002
65// CHECK-NEXT: Size: 0
66// CHECK-NEXT: Binding: Global
67// CHECK-NEXT: Type: None
68// CHECK-NEXT: Other: 0
69// CHECK-NEXT: Section: .text
70// CHECK-NEXT: }
71// CHECK-NEXT: Symbol {
72// CHECK-NEXT: Name: bar
73// CHECK-NEXT: Value: 0x11001
74// CHECK-NEXT: Size: 0
75// CHECK-NEXT: Binding: Global
76// CHECK-NEXT: Type: GNU_IFunc
77// CHECK-NEXT: Other: 0
78// CHECK-NEXT: Section: .text
79// CHECK-NEXT: }
80// CHECK-NEXT: Symbol {
81// CHECK-NEXT: Name: foo
82// CHECK-NEXT: Value: 0x11000
83// CHECK-NEXT: Size: 0
84// CHECK-NEXT: Binding: Global
85// CHECK-NEXT: Type: GNU_IFunc
86// CHECK-NEXT: Other: 0
87// CHECK-NEXT: Section: .text
88// CHECK-NEXT: }
89// CHECK-NEXT:]
90
91// DISASM: Disassembly of section .text:
92// DISASM-NEXT: foo:
93// DISASM-NEXT: 11000: c3 retl
94// DISASM: bar:
95// DISASM-NEXT: 11001: c3 retl
96// DISASM: _start:
97// DISASM-NEXT: 11002: e8 19 00 00 00 calll 25
98// DISASM-NEXT: 11007: e8 24 00 00 00 calll 36
99// DISASM-NEXT: 1100c: ba d4 00 01 00 movl $65748, %edx
100// DISASM-NEXT: 11011: ba e4 00 01 00 movl $65764, %edx
101// DISASM-NEXT: Disassembly of section .plt:
102// DISASM-NEXT: .plt:
103// DISASM-NEXT: 11020: ff 25 00 20 01 00 jmpl *73728
104// DISASM-NEXT: 11026: 68 10 00 00 00 pushl $16
105// DISASM-NEXT: 1102b: e9 e0 ff ff ff jmp -32 <_start+0xE>
106// DISASM-NEXT: 11030: ff 25 04 20 01 00 jmpl *73732
107// DISASM-NEXT: 11036: 68 18 00 00 00 pushl $24
108// DISASM-NEXT: 1103b: e9 d0 ff ff ff jmp -48 <_start+0xE>
109
110.text
111.type foo STT_GNU_IFUNC
112.globl foo
113foo:
114 ret
115
116.type bar STT_GNU_IFUNC
117.globl bar
118bar:
119 ret
120
121.globl _start
122_start:
123 call foo
124 call bar
125 movl $__rel_iplt_start,%edx
126 movl $__rel_iplt_end,%edx
deps/lld/test/ELF/gnu-ifunc-nosym-i386.s created+27
......@@ -0,0 +1,27 @@
1// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
2// RUN: ld.lld -static %t.o -o %tout
3// RUN: llvm-readobj -symbols %tout | FileCheck %s
4// REQUIRES: x86
5
6// Check that no __rel_iplt_end/__rel_iplt_start
7// appear in symtab if there is no references to them.
8// CHECK: Symbols [
9// CHECK-NOT: __rel_iplt_end
10// CHECK-NOT: __rel_iplt_start
11// CHECK: ]
12
13.text
14.type foo STT_GNU_IFUNC
15.globl foo
16foo:
17 ret
18
19.type bar STT_GNU_IFUNC
20.globl bar
21bar:
22 ret
23
24.globl _start
25_start:
26 call foo
27 call bar
deps/lld/test/ELF/gnu-ifunc-nosym.s created+27
......@@ -0,0 +1,27 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
2// RUN: ld.lld -static %t.o -o %tout
3// RUN: llvm-readobj -symbols %tout | FileCheck %s
4// REQUIRES: x86
5
6// Check that no __rela_iplt_end/__rela_iplt_start
7// appear in symtab if there is no references to them.
8// CHECK: Symbols [
9// CHECK-NOT: __rela_iplt_end
10// CHECK-NOT: __rela_iplt_start
11// CHECK: ]
12
13.text
14.type foo STT_GNU_IFUNC
15.globl foo
16foo:
17 ret
18
19.type bar STT_GNU_IFUNC
20.globl bar
21bar:
22 ret
23
24.globl _start
25_start:
26 call foo
27 call bar
deps/lld/test/ELF/gnu-ifunc-plt-i386.s created+76
......@@ -0,0 +1,76 @@
1// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %S/Inputs/shared2-x86-64.s -o %t1.o
2// RUN: ld.lld %t1.o --shared -o %t.so
3// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
4// RUN: ld.lld %t.so %t.o -o %tout
5// RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM
6// RUN: llvm-objdump -s %tout | FileCheck %s --check-prefix=GOTPLT
7// RUN: llvm-readobj -r -dynamic-table %tout | FileCheck %s
8// REQUIRES: x86
9
10// Check that the IRELATIVE relocations are after the JUMP_SLOT in the plt
11// CHECK: Relocations [
12// CHECK-NEXT: Section (4) .rel.plt {
13// CHECK-NEXT: 0x1200C R_386_JUMP_SLOT bar2
14// CHECK-NEXT: 0x12010 R_386_JUMP_SLOT zed2
15// CHECK-NEXT: 0x12014 R_386_IRELATIVE
16// CHECK-NEXT: 0x12018 R_386_IRELATIVE
17
18// Check that IRELATIVE .got.plt entries point to ifunc resolver and not
19// back to the plt entry + 6.
20// GOTPLT: Contents of section .got.plt:
21// GOTPLT: 12000 00300100 00000000 00000000 36100100
22// GOTPLT-NEXT: 12010 46100100 00100100 01100100
23
24// Check that the PLTRELSZ tag includes the IRELATIVE relocations
25// CHECK: DynamicSection [
26// CHECK: 0x00000002 PLTRELSZ 32 (bytes)
27
28// Check that a PLT header is written and the ifunc entries appear last
29// DISASM: Disassembly of section .text:
30// DISASM-NEXT: foo:
31// DISASM-NEXT: 11000: c3 retl
32// DISASM: bar:
33// DISASM-NEXT: 11001: c3 retl
34// DISASM: _start:
35// DISASM-NEXT: 11002: e8 49 00 00 00 calll 73
36// DISASM-NEXT: 11007: e8 54 00 00 00 calll 84
37// DISASM-NEXT: 1100c: e8 1f 00 00 00 calll 31
38// DISASM-NEXT: 11011: e8 2a 00 00 00 calll 42
39// DISASM-NEXT: Disassembly of section .plt:
40// DISASM-NEXT: .plt:
41// DISASM-NEXT: 11020: ff 35 04 20 01 00 pushl 73732
42// DISASM-NEXT: 11026: ff 25 08 20 01 00 jmpl *73736
43// DISASM-NEXT: 1102c: 90 nop
44// DISASM-NEXT: 1102d: 90 nop
45// DISASM-NEXT: 1102e: 90 nop
46// DISASM-NEXT: 1102f: 90 nop
47// DISASM-NEXT: 11030: ff 25 0c 20 01 00 jmpl *73740
48// DISASM-NEXT: 11036: 68 00 00 00 00 pushl $0
49// DISASM-NEXT: 1103b: e9 e0 ff ff ff jmp -32 <.plt>
50// DISASM-NEXT: 11040: ff 25 10 20 01 00 jmpl *73744
51// DISASM-NEXT: 11046: 68 08 00 00 00 pushl $8
52// DISASM-NEXT: 1104b: e9 d0 ff ff ff jmp -48 <.plt>
53// DISASM-NEXT: 11050: ff 25 14 20 01 00 jmpl *73748
54// DISASM-NEXT: 11056: 68 30 00 00 00 pushl $48
55// DISASM-NEXT: 1105b: e9 e0 ff ff ff jmp -32 <.plt+0x20>
56// DISASM-NEXT: 11060: ff 25 18 20 01 00 jmpl *73752
57// DISASM-NEXT: 11066: 68 38 00 00 00 pushl $56
58// DISASM-NEXT: 1106b: e9 d0 ff ff ff jmp -48 <.plt+0x20>
59
60.text
61.type foo STT_GNU_IFUNC
62.globl foo
63foo:
64 ret
65
66.type bar STT_GNU_IFUNC
67.globl bar
68bar:
69 ret
70
71.globl _start
72_start:
73 call foo
74 call bar
75 call bar2
76 call zed2
deps/lld/test/ELF/gnu-ifunc-plt.s created+74
......@@ -0,0 +1,74 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/shared2-x86-64.s -o %t1.o
2// RUN: ld.lld %t1.o --shared -o %t.so
3// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
4// RUN: ld.lld %t.so %t.o -o %tout
5// RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM
6// RUN: llvm-objdump -s %tout | FileCheck %s --check-prefix=GOTPLT
7// RUN: llvm-readobj -r -dynamic-table %tout | FileCheck %s
8// REQUIRES: x86
9
10// Check that the IRELATIVE relocations are after the JUMP_SLOT in the plt
11// CHECK: Relocations [
12// CHECK-NEXT: Section (4) .rela.plt {
13// CHECK-NEXT: 0x202018 R_X86_64_JUMP_SLOT bar2 0x0
14// CHECK-NEXT: 0x202020 R_X86_64_JUMP_SLOT zed2 0x0
15// CHECK-NEXT: 0x202028 R_X86_64_IRELATIVE - 0x201000
16// CHECK-NEXT: 0x202030 R_X86_64_IRELATIVE - 0x201001
17
18// Check that .got.plt entries point back to PLT header
19// GOTPLT: Contents of section .got.plt:
20// GOTPLT-NEXT: 202000 00302000 00000000 00000000 00000000
21// GOTPLT-NEXT: 202010 00000000 00000000 36102000 00000000
22// GOTPLT-NEXT: 202020 46102000 00000000 56102000 00000000
23// GOTPLT-NEXT: 202030 66102000 00000000
24
25// Check that the PLTRELSZ tag includes the IRELATIVE relocations
26// CHECK: DynamicSection [
27// CHECK: 0x0000000000000002 PLTRELSZ 96 (bytes)
28
29// Check that a PLT header is written and the ifunc entries appear last
30// DISASM: Disassembly of section .text:
31// DISASM-NEXT: foo:
32// DISASM-NEXT: 201000: c3 retq
33// DISASM: bar:
34// DISASM-NEXT: 201001: c3 retq
35// DISASM: _start:
36// DISASM-NEXT: 201002: e8 49 00 00 00 callq 73
37// DISASM-NEXT: 201007: e8 54 00 00 00 callq 84
38// DISASM-NEXT: 20100c: e8 1f 00 00 00 callq 31
39// DISASM-NEXT: 201011: e8 2a 00 00 00 callq 42
40// DISASM-NEXT: Disassembly of section .plt:
41// DISASM-NEXT: .plt:
42// DISASM-NEXT: 201020: ff 35 e2 0f 00 00 pushq 4066(%rip)
43// DISASM-NEXT: 201026: ff 25 e4 0f 00 00 jmpq *4068(%rip)
44// DISASM-NEXT: 20102c: 0f 1f 40 00 nopl (%rax)
45// DISASM-NEXT: 201030: ff 25 e2 0f 00 00 jmpq *4066(%rip)
46// DISASM-NEXT: 201036: 68 00 00 00 00 pushq $0
47// DISASM-NEXT: 20103b: e9 e0 ff ff ff jmp -32 <.plt>
48// DISASM-NEXT: 201040: ff 25 da 0f 00 00 jmpq *4058(%rip)
49// DISASM-NEXT: 201046: 68 01 00 00 00 pushq $1
50// DISASM-NEXT: 20104b: e9 d0 ff ff ff jmp -48 <.plt>
51// DISASM-NEXT: 201050: ff 25 d2 0f 00 00 jmpq *4050(%rip)
52// DISASM-NEXT: 201056: 68 00 00 00 00 pushq $0
53// DISASM-NEXT: 20105b: e9 e0 ff ff ff jmp -32 <.plt+0x20>
54// DISASM-NEXT: 201060: ff 25 ca 0f 00 00 jmpq *4042(%rip)
55// DISASM-NEXT: 201066: 68 01 00 00 00 pushq $1
56// DISASM-NEXT: 20106b: e9 d0 ff ff ff jmp -48 <.plt+0x20>
57
58.text
59.type foo STT_GNU_IFUNC
60.globl foo
61foo:
62 ret
63
64.type bar STT_GNU_IFUNC
65.globl bar
66bar:
67 ret
68
69.globl _start
70_start:
71 call foo
72 call bar
73 call bar2
74 call zed2
deps/lld/test/ELF/gnu-ifunc-relative.s created+23
......@@ -0,0 +1,23 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
2// RUN: ld.lld -static %t.o -o %tout
3// RUN: llvm-readobj -r -t %tout | FileCheck %s
4// REQUIRES: x86
5
6.type foo STT_GNU_IFUNC
7.globl foo
8foo:
9 ret
10
11.globl _start
12_start:
13 call foo
14
15// CHECK: Section ({{.*}}) .rela.plt {
16// CHECK-NEXT: R_X86_64_IRELATIVE - 0x[[ADDR:.*]]
17// CHECK-NEXT: }
18
19// CHECK: Name: foo
20// CHECK-NEXT: Value: 0x[[ADDR]]
21// CHECK-NEXT: Size: 0
22// CHECK-NEXT: Binding: Global
23// CHECK-NEXT: Type: GNU_IFunc
deps/lld/test/ELF/gnu-ifunc-shared.s created+66
......@@ -0,0 +1,66 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3// RUN: ld.lld --shared -o %t.so %t.o
4// RUN: llvm-objdump -d %t.so | FileCheck %s --check-prefix=DISASM
5// RUN: llvm-readobj -r %t.so | FileCheck %s
6
7// Check that an IRELATIVE relocation is used for a non-preemptible ifunc
8// handler and a JUMP_SLOT is used for a preemptible ifunc
9// DISASM: Disassembly of section .text:
10// DISASM-NEXT: fct:
11// DISASM-NEXT: 1000: c3 retq
12// DISASM: fct2:
13// DISASM-NEXT: 1001: c3 retq
14// DISASM: f1:
15// DISASM-NEXT: 1002: e8 49 00 00 00 callq 73
16// DISASM-NEXT: 1007: e8 24 00 00 00 callq 36
17// DISASM-NEXT: 100c: e8 2f 00 00 00 callq 47
18// DISASM-NEXT: 1011: c3 retq
19// DISASM: f2:
20// DISASM-NEXT: 1012: c3 retq
21// DISASM-NEXT: Disassembly of section .plt:
22// DISASM-NEXT: .plt:
23// DISASM-NEXT: 1020: ff 35 e2 0f 00 00 pushq 4066(%rip)
24// DISASM-NEXT: 1026: ff 25 e4 0f 00 00 jmpq *4068(%rip)
25// DISASM-NEXT: 102c: 0f 1f 40 00 nopl (%rax)
26// DISASM-NEXT: 1030: ff 25 e2 0f 00 00 jmpq *4066(%rip)
27// DISASM-NEXT: 1036: 68 00 00 00 00 pushq $0
28// DISASM-NEXT: 103b: e9 e0 ff ff ff jmp -32 <.plt>
29// DISASM-NEXT: 1040: ff 25 da 0f 00 00 jmpq *4058(%rip)
30// DISASM-NEXT: 1046: 68 01 00 00 00 pushq $1
31// DISASM-NEXT: 104b: e9 d0 ff ff ff jmp -48 <.plt>
32// DISASM-NEXT: 1050: ff 25 d2 0f 00 00 jmpq *4050(%rip)
33// DISASM-NEXT: 1056: 68 00 00 00 00 pushq $0
34// DISASM-NEXT: 105b: e9 e0 ff ff ff jmp -32 <.plt+0x20>
35
36// CHECK: Relocations [
37// CHECK-NEXT: Section (4) .rela.plt {
38// CHECK-NEXT: 0x2018 R_X86_64_JUMP_SLOT fct2 0x0
39// CHECK-NEXT: 0x2020 R_X86_64_JUMP_SLOT f2 0x0
40// CHECK-NEXT: 0x2028 R_X86_64_IRELATIVE - 0x1000
41
42 // Hidden expect IRELATIVE
43 .globl fct
44 .hidden fct
45 .type fct, STT_GNU_IFUNC
46fct:
47 ret
48
49 // Not hidden expect JUMP_SLOT
50 .globl fct2
51 .type fct2, STT_GNU_IFUNC
52fct2:
53 ret
54
55 .globl f1
56 .type f1, @function
57f1:
58 call fct
59 call fct2
60 call f2@PLT
61 ret
62
63 .globl f2
64 .type f2, @function
65f2:
66 ret
deps/lld/test/ELF/gnu-ifunc.s created+127
......@@ -0,0 +1,127 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
2// RUN: ld.lld -static %t.o -o %tout
3// RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DISASM
4// RUN: llvm-readobj -r -symbols -sections %tout | FileCheck %s
5// REQUIRES: x86
6
7// CHECK: Sections [
8// CHECK: Section {
9// CHECK: Index: 1
10// CHECK-NEXT: Name: .rela.plt
11// CHECK-NEXT: Type: SHT_RELA
12// CHECK-NEXT: Flags [
13// CHECK-NEXT: SHF_ALLOC
14// CHECK-NEXT: ]
15// CHECK-NEXT: Address: [[RELA:.*]]
16// CHECK-NEXT: Offset: 0x158
17// CHECK-NEXT: Size: 48
18// CHECK-NEXT: Link: 6
19// CHECK-NEXT: Info: 0
20// CHECK-NEXT: AddressAlignment: 8
21// CHECK-NEXT: EntrySize: 24
22// CHECK-NEXT: }
23// CHECK: Relocations [
24// CHECK-NEXT: Section ({{.*}}) .rela.plt {
25// CHECK-NEXT: 0x202000 R_X86_64_IRELATIVE
26// CHECK-NEXT: 0x202008 R_X86_64_IRELATIVE
27// CHECK-NEXT: }
28// CHECK-NEXT: ]
29// CHECK: Symbols [
30// CHECK-NEXT: Symbol {
31// CHECK-NEXT: Name:
32// CHECK-NEXT: Value: 0x0
33// CHECK-NEXT: Size: 0
34// CHECK-NEXT: Binding: Local
35// CHECK-NEXT: Type: None
36// CHECK-NEXT: Other: 0
37// CHECK-NEXT: Section: Undefined
38// CHECK-NEXT: }
39// CHECK-NEXT: Symbol {
40// CHECK-NEXT: Name: __rela_iplt_end
41// CHECK-NEXT: Value: 0x200188
42// CHECK-NEXT: Size: 0
43// CHECK-NEXT: Binding: Local
44// CHECK-NEXT: Type: None
45// CHECK-NEXT: Other [
46// CHECK-NEXT: STV_HIDDEN
47// CHECK-NEXT: ]
48// CHECK-NEXT: Section: .rela.plt
49// CHECK-NEXT: }
50// CHECK-NEXT: Symbol {
51// CHECK-NEXT: Name: __rela_iplt_start
52// CHECK-NEXT: Value: [[RELA]]
53// CHECK-NEXT: Size: 0
54// CHECK-NEXT: Binding: Local
55// CHECK-NEXT: Type: None
56// CHECK-NEXT: Other [
57// CHECK-NEXT: STV_HIDDEN
58// CHECK-NEXT: ]
59// CHECK-NEXT: Section: .rela.plt
60// CHECK-NEXT: }
61// CHECK-NEXT: Symbol {
62// CHECK-NEXT: Name: _start
63// CHECK-NEXT: Value: 0x201002
64// CHECK-NEXT: Size: 0
65// CHECK-NEXT: Binding: Global
66// CHECK-NEXT: Type: None
67// CHECK-NEXT: Other: 0
68// CHECK-NEXT: Section: .text
69// CHECK-NEXT: }
70// CHECK-NEXT: Symbol {
71// CHECK-NEXT: Name: bar
72// CHECK-NEXT: Value: 0x201001
73// CHECK-NEXT: Size: 0
74// CHECK-NEXT: Binding: Global
75// CHECK-NEXT: Type: GNU_IFunc
76// CHECK-NEXT: Other: 0
77// CHECK-NEXT: Section: .text
78// CHECK-NEXT: }
79// CHECK-NEXT: Symbol {
80// CHECK-NEXT: Name: foo
81// CHECK-NEXT: Value: 0x201000
82// CHECK-NEXT: Size: 0
83// CHECK-NEXT: Binding: Global
84// CHECK-NEXT: Type: GNU_IFunc
85// CHECK-NEXT: Other: 0
86// CHECK-NEXT: Section: .text
87// CHECK-NEXT: }
88// CHECK-NEXT: ]
89
90// DISASM: Disassembly of section .text:
91// DISASM-NEXT: foo:
92// DISASM-NEXT: 201000: {{.*}} retq
93// DISASM: bar:
94// DISASM-NEXT: 201001: {{.*}} retq
95// DISASM: _start:
96// DISASM-NEXT: 201002: {{.*}} callq 25
97// DISASM-NEXT: 201007: {{.*}} callq 36
98// DISASM-NEXT: 20100c: {{.*}} movl $2097496, %edx
99// DISASM-NEXT: 201011: {{.*}} movl $2097544, %edx
100// DISASM-NEXT: 201016: {{.*}} movl $2097545, %edx
101// DISASM-NEXT: Disassembly of section .plt:
102// DISASM-NEXT: .plt:
103// DISASM-NEXT: 201020: {{.*}} jmpq *4058(%rip)
104// DISASM-NEXT: 201026: {{.*}} pushq $0
105// DISASM-NEXT: 20102b: {{.*}} jmp -32 <_start+0xE>
106// DISASM-NEXT: 201030: {{.*}} jmpq *4050(%rip)
107// DISASM-NEXT: 201036: {{.*}} pushq $1
108// DISASM-NEXT: 20103b: {{.*}} jmp -48 <_start+0xE>
109
110.text
111.type foo STT_GNU_IFUNC
112.globl foo
113foo:
114 ret
115
116.type bar STT_GNU_IFUNC
117.globl bar
118bar:
119 ret
120
121.globl _start
122_start:
123 call foo
124 call bar
125 movl $__rela_iplt_start,%edx
126 movl $__rela_iplt_end,%edx
127 movl $__rela_iplt_end + 1,%edx
deps/lld/test/ELF/gnu-unique.s created+37
......@@ -0,0 +1,37 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
3//
4// RUN: ld.lld %t -shared -o %tout.so
5// RUN: llvm-readobj -dyn-symbols %tout.so | FileCheck -check-prefix=GNU %s
6//
7// RUN: ld.lld %t -shared -o %tout.so --no-gnu-unique
8// RUN: llvm-readobj -dyn-symbols %tout.so | FileCheck -check-prefix=NO %s
9
10// Check that STB_GNU_UNIQUE is treated as a global and ends up in the dynamic
11// symbol table as STB_GNU_UNIQUE.
12
13.global _start
14.text
15_start:
16
17.data
18.type symb, @gnu_unique_object
19symb:
20
21# GNU: Name: symb@
22# GNU-NEXT: Value:
23# GNU-NEXT: Size: 0
24# GNU-NEXT: Binding: Unique
25# GNU-NEXT: Type: Object
26# GNU-NEXT: Other: 0
27# GNU-NEXT: Section: .data
28# GNU-NEXT: }
29
30# NO: Name: symb@
31# NO-NEXT: Value:
32# NO-NEXT: Size: 0
33# NO-NEXT: Binding: Global
34# NO-NEXT: Type: Object
35# NO-NEXT: Other: 0
36# NO-NEXT: Section: .data
37# NO-NEXT: }
deps/lld/test/ELF/gnustack.s created+34
......@@ -0,0 +1,34 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1
3# RUN: ld.lld %t1 -z execstack -o %t
4# RUN: llvm-readobj --program-headers -s %t | FileCheck --check-prefix=RWX %s
5# RUN: ld.lld %t1 -o %t
6# RUN: llvm-readobj --program-headers -s %t | FileCheck --check-prefix=RW %s
7
8# RW: Type: PT_GNU_STACK
9# RW-NEXT: Offset: 0x0
10# RW-NEXT: VirtualAddress: 0x0
11# RW-NEXT: PhysicalAddress: 0x0
12# RW-NEXT: FileSize: 0
13# RW-NEXT: MemSize: 0
14# RW-NEXT: Flags [
15# RW-NEXT: PF_R
16# RW-NEXT: PF_W
17# RW-NEXT: ]
18# RW-NEXT: Alignment: 0
19
20# RWX: Type: PT_GNU_STACK
21# RWX-NEXT: Offset: 0x0
22# RWX-NEXT: VirtualAddress: 0x0
23# RWX-NEXT: PhysicalAddress: 0x0
24# RWX-NEXT: FileSize: 0
25# RWX-NEXT: MemSize: 0
26# RWX-NEXT: Flags [
27# RWX-NEXT: PF_R
28# RWX-NEXT: PF_W
29# RWX-NEXT: PF_X
30# RWX-NEXT: ]
31# RWX-NEXT: Alignment: 0
32
33.globl _start
34_start:
deps/lld/test/ELF/got-aarch64.s created+40
......@@ -0,0 +1,40 @@
1// RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %t.o
2// RUN: ld.lld -shared %t.o -o %t.so
3// RUN: llvm-readobj -s -r %t.so | FileCheck %s
4// RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=DISASM %s
5// REQUIRES: aarch64
6
7// CHECK: Name: .got
8// CHECK-NEXT: Type: SHT_PROGBITS
9// CHECK-NEXT: Flags [
10// CHECK-NEXT: SHF_ALLOC
11// CHECK-NEXT: SHF_WRITE
12// CHECK-NEXT: ]
13// CHECK-NEXT: Address: 0x30090
14// CHECK-NEXT: Offset:
15// CHECK-NEXT: Size: 8
16// CHECK-NEXT: Link: 0
17// CHECK-NEXT: Info: 0
18// CHECK-NEXT: AddressAlignment: 8
19
20// CHECK: Relocations [
21// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
22// CHECK-NEXT: 0x30090 R_AARCH64_GLOB_DAT dat 0x0
23// CHECK-NEXT: }
24// CHECK-NEXT: ]
25
26// Page(0x20098) - Page(0x10000) = 0x10000 = 65536
27// 0x20098 & 0xff8 = 0x98 = 152
28
29// DISASM: main:
30// DISASM-NEXT: 10000: 00 01 00 90 adrp x0, #131072
31// DISASM-NEXT: 10004: 00 48 40 f9 ldr x0, [x0, #144]
32
33.global main,foo,dat
34.text
35main:
36 adrp x0, :got:dat
37 ldr x0, [x0, :got_lo12:dat]
38.data
39dat:
40 .word 42
deps/lld/test/ELF/got-i386.s created+56
......@@ -0,0 +1,56 @@
1// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o
2// RUN: ld.lld %t.o -o %t
3// RUN: llvm-readobj -s -r -t %t | FileCheck %s
4// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
5// REQUIRES: x86
6
7// CHECK: Name: .got
8// CHECK-NEXT: Type: SHT_PROGBITS
9// CHECK-NEXT: Flags [
10// CHECK-NEXT: SHF_ALLOC
11// CHECK-NEXT: SHF_WRITE
12// CHECK-NEXT: ]
13// CHECK-NEXT: Address: 0x12000
14// CHECK-NEXT: Offset:
15// CHECK-NEXT: Size: 0
16// CHECK-NEXT: Link:
17// CHECK-NEXT: Info:
18// CHECK-NEXT: AddressAlignment:
19
20// CHECK: Symbol {
21// CHECK: Name: bar
22// CHECK-NEXT: Value: 0x12000
23// CHECK-NEXT: Size: 10
24// CHECK-NEXT: Binding: Global
25// CHECK-NEXT: Type: Object
26// CHECK-NEXT: Other: 0
27// CHECK-NEXT: Section: .bss
28// CHECK-NEXT: }
29// CHECK-NEXT: Symbol {
30// CHECK-NEXT: Name: obj
31// CHECK-NEXT: Value: 0x1200A
32// CHECK-NEXT: Size: 10
33// CHECK-NEXT: Binding: Global
34// CHECK-NEXT: Type: Object
35// CHECK-NEXT: Other: 0
36// CHECK-NEXT: Section: .bss
37// CHECK-NEXT: }
38
39// 0x12000 - 0 = addr(.got) = 0x12000
40// 0x1200A - 10 = addr(.got) = 0x12000
41// 0x1200A + 5 - 15 = addr(.got) = 0x12000
42// DISASM: Disassembly of section .text:
43// DISASM-NEXT: _start:
44// DISASM-NEXT: 11000: c7 81 00 00 00 00 01 00 00 00 movl $1, (%ecx)
45// DISASM-NEXT: 1100a: c7 81 0a 00 00 00 02 00 00 00 movl $2, 10(%ecx)
46// DISASM-NEXT: 11014: c7 81 0f 00 00 00 03 00 00 00 movl $3, 15(%ecx)
47
48.global _start
49_start:
50 movl $1, bar@GOTOFF(%ecx)
51 movl $2, obj@GOTOFF(%ecx)
52 movl $3, obj+5@GOTOFF(%ecx)
53 .type bar, @object
54 .comm bar, 10
55 .type obj, @object
56 .comm obj, 10
deps/lld/test/ELF/got-plt-header.s created+30
......@@ -0,0 +1,30 @@
1// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
2// RUN: ld.lld %t.o -o %t.so -shared
3// RUN: llvm-readobj -s -section-data %t.so | FileCheck %s
4
5 call foo@plt
6
7// Check that the first .got.plt entry has the address of the dynamic table.
8
9// CHECK: Name: .got.plt
10// CHECK-NEXT: Type: SHT_PROGBITS
11// CHECK-NEXT: Flags [
12// CHECK-NEXT: SHF_ALLOC
13// CHECK-NEXT: SHF_WRITE
14// CHECK-NEXT: ]
15// CHECK-NEXT: Address: 0x2000
16// CHECK-NEXT: Offset: 0x2000
17// CHECK-NEXT: Size: 32
18// CHECK-NEXT: Link: 0
19// CHECK-NEXT: Info: 0
20// CHECK-NEXT: AddressAlignment: 8
21// CHECK-NEXT: EntrySize: 0
22// CHECK-NEXT: SectionData (
23// CHECK-NEXT: 0000: 00300000 00000000 00000000 00000000
24
25// CHECK: Type: SHT_DYNAMIC
26// CHECK-NEXT: Flags [
27// CHECK-NEXT: SHF_ALLOC
28// CHECK-NEXT: SHF_WRITE
29// CHECK-NEXT: ]
30// CHECK-NEXT: Address: 0x3000
deps/lld/test/ELF/got.s created+45
......@@ -0,0 +1,45 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o
3// RUN: ld.lld -shared %t2.o -o %t2.so
4// RUN: ld.lld %t.o %t2.so -o %t
5// RUN: llvm-readobj -s -r %t | FileCheck %s
6// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
7// REQUIRES: x86
8
9// CHECK: Name: .got
10// CHECK-NEXT: Type: SHT_PROGBITS
11// CHECK-NEXT: Flags [
12// CHECK-NEXT: SHF_ALLOC
13// CHECK-NEXT: SHF_WRITE
14// CHECK-NEXT: ]
15// CHECK-NEXT: Address: 0x2020B0
16// CHECK-NEXT: Offset:
17// CHECK-NEXT: Size: 16
18// CHECK-NEXT: Link: 0
19// CHECK-NEXT: Info: 0
20// CHECK-NEXT: AddressAlignment: 8
21
22// CHECK: Relocations [
23// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
24// CHECK-NEXT: 0x2020B0 R_X86_64_GLOB_DAT bar 0x0
25// CHECK-NEXT: 0x2020B8 R_X86_64_GLOB_DAT zed 0x0
26// CHECK-NEXT: }
27// CHECK-NEXT: ]
28
29
30// Unfortunately FileCheck can't do math, so we have to check for explicit
31// values:
32// 0x2020B0 - (0x201000 + 2) - 4 = 4266
33// 0x2020B0 - (0x201006 + 2) - 4 = 4260
34// 0x2020A8 - (0x20100c + 2) - 4 = 4262
35
36// DISASM: _start:
37// DISASM-NEXT: 201000: {{.*}} jmpq *4266(%rip)
38// DISASM-NEXT: 201006: {{.*}} jmpq *4260(%rip)
39// DISASM-NEXT: 20100c: {{.*}} jmpq *4262(%rip)
40
41.global _start
42_start:
43 jmp *bar@GOTPCREL(%rip)
44 jmp *bar@GOTPCREL(%rip)
45 jmp *zed@GOTPCREL(%rip)
deps/lld/test/ELF/got32-i386.s created+23
......@@ -0,0 +1,23 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
3# RUN: ld.lld %t.o -o %t
4# RUN: llvm-objdump -section-headers -d %t | FileCheck %s
5
6## We have R_386_GOT32 relocation here.
7.globl foo
8.type foo, @function
9foo:
10 nop
11
12_start:
13 movl foo@GOT, %ebx
14
15## 73728 == 0x12000 == ADDR(.got)
16# CHECK: _start:
17# CHECK-NEXT: 11001: 8b 1d {{.*}} movl 73728, %ebx
18# CHECK: Sections:
19# CHECK: Name Size Address
20# CHECK: .got 00000004 0000000000012000
21
22# RUN: not ld.lld %t.o -o %t -pie 2>&1 | FileCheck %s --check-prefix=ERR
23# ERR: relocation R_386_GOT32 against 'foo' without base register can not be used when PIC enabled
deps/lld/test/ELF/got32x-i386.s created+47
......@@ -0,0 +1,47 @@
1# REQUIRES: x86
2
3## i386-got32x-baseless.elf is a file produced using GNU as v.2.27
4## using following code and command line:
5## (as --32 -o base.o base.s)
6##
7## .text
8## .globl foo
9## .type foo, @function
10## foo:
11## nop
12##
13## _start:
14## movl foo@GOT, %eax
15## movl foo@GOT, %ebx
16## movl foo@GOT(%eax), %eax
17## movl foo@GOT(%ebx), %eax
18##
19## Result file contains four R_386_GOT32X relocations. Generated code
20## is also a four mov instructions. And first two has no base register:
21## <_start>:
22## 1: 8b 05 00 00 00 00 mov 0x0,%eax
23## 7: 8b 1d 00 00 00 00 mov 0x0,%ebx
24## d: 8b 80 00 00 00 00 mov 0x0(%eax),%eax
25## 13: 8b 83 00 00 00 00 mov 0x0(%ebx),%eax
26##
27## R_386_GOT32X is computed as G + A - GOT, but if it used without base
28## register, it should be calculated as G + A. Using without base register
29## is only allowed for non-PIC code.
30##
31# RUN: ld.lld %S/Inputs/i386-got32x-baseless.elf -o %t1
32# RUN: llvm-objdump -section-headers -d %t1 | FileCheck %s
33
34## 73728 == 0x12000 == ADDR(.got)
35# CHECK: _start:
36# CHECK-NEXT: 11001: 8b 05 {{.*}} movl 73728, %eax
37# CHECK-NEXT: 11007: 8b 1d {{.*}} movl 73728, %ebx
38# CHECK-NEXT: 1100d: 8b 80 {{.*}} movl -4(%eax), %eax
39# CHECK-NEXT: 11013: 8b 83 {{.*}} movl -4(%ebx), %eax
40# CHECK: Sections:
41# CHECK: Name Size Address
42# CHECK: .got 00000004 0000000000012000
43
44# RUN: not ld.lld %S/Inputs/i386-got32x-baseless.elf -o %t1 -pie 2>&1 | \
45# RUN: FileCheck %s --check-prefix=ERR
46# ERR: relocation R_386_GOT32X against 'foo' without base register can not be used when PIC enabled
47# ERR: relocation R_386_GOT32X against 'foo' without base register can not be used when PIC enabled
deps/lld/test/ELF/gotpc-relax-nopic.s created+87
......@@ -0,0 +1,87 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -relax-relocations -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: ld.lld %t.o -o %t1
4# RUN: llvm-readobj -symbols -r %t1 | FileCheck --check-prefix=SYMRELOC %s
5# RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s
6
7## There is no relocations.
8# SYMRELOC: Relocations [
9# SYMRELOC-NEXT: ]
10# SYMRELOC: Symbols [
11# SYMRELOC: Symbol {
12# SYMRELOC: Name: bar
13# SYMRELOC-NEXT: Value: 0x202000
14
15## 2105344 = 0x202000 (bar)
16# DISASM: Disassembly of section .text:
17# DISASM-NEXT: _start:
18# DISASM-NEXT: 201000: {{.*}} adcq $2105344, %rax
19# DISASM-NEXT: 201007: {{.*}} addq $2105344, %rbx
20# DISASM-NEXT: 20100e: {{.*}} andq $2105344, %rcx
21# DISASM-NEXT: 201015: {{.*}} cmpq $2105344, %rdx
22# DISASM-NEXT: 20101c: {{.*}} orq $2105344, %rdi
23# DISASM-NEXT: 201023: {{.*}} sbbq $2105344, %rsi
24# DISASM-NEXT: 20102a: {{.*}} subq $2105344, %rbp
25# DISASM-NEXT: 201031: {{.*}} xorq $2105344, %r8
26# DISASM-NEXT: 201038: {{.*}} testq $2105344, %r15
27
28# RUN: ld.lld -shared %t.o -o %t2
29# RUN: llvm-readobj -s -r -d %t2 | FileCheck --check-prefix=SEC-PIC %s
30# RUN: llvm-objdump -d %t2 | FileCheck --check-prefix=DISASM-PIC %s
31# SEC-PIC: Section {
32# SEC-PIC: Index:
33# SEC-PIC: Name: .got
34# SEC-PIC-NEXT: Type: SHT_PROGBITS
35# SEC-PIC-NEXT: Flags [
36# SEC-PIC-NEXT: SHF_ALLOC
37# SEC-PIC-NEXT: SHF_WRITE
38# SEC-PIC-NEXT: ]
39# SEC-PIC-NEXT: Address: 0x30A0
40# SEC-PIC-NEXT: Offset: 0x30A0
41# SEC-PIC-NEXT: Size: 8
42# SEC-PIC-NEXT: Link:
43# SEC-PIC-NEXT: Info:
44# SEC-PIC-NEXT: AddressAlignment:
45# SEC-PIC-NEXT: EntrySize:
46# SEC-PIC-NEXT: }
47# SEC-PIC: Relocations [
48# SEC-PIC-NEXT: Section ({{.*}}) .rela.dyn {
49# SEC-PIC-NEXT: 0x30A0 R_X86_64_RELATIVE - 0x2000
50# SEC-PIC-NEXT: }
51# SEC-PIC-NEXT: ]
52# SEC-PIC: 0x000000006FFFFFF9 RELACOUNT 1
53
54## Check that there was no relaxation performed. All values refer to got entry.
55## Ex: 0x1000 + 4249 + 7 = 0x20A0
56## 0x102a + 4207 + 7 = 0x20A0
57# DISASM-PIC: Disassembly of section .text:
58# DISASM-PIC-NEXT: _start:
59# DISASM-PIC-NEXT: 1000: {{.*}} adcq 8345(%rip), %rax
60# DISASM-PIC-NEXT: 1007: {{.*}} addq 8338(%rip), %rbx
61# DISASM-PIC-NEXT: 100e: {{.*}} andq 8331(%rip), %rcx
62# DISASM-PIC-NEXT: 1015: {{.*}} cmpq 8324(%rip), %rdx
63# DISASM-PIC-NEXT: 101c: {{.*}} orq 8317(%rip), %rdi
64# DISASM-PIC-NEXT: 1023: {{.*}} sbbq 8310(%rip), %rsi
65# DISASM-PIC-NEXT: 102a: {{.*}} subq 8303(%rip), %rbp
66# DISASM-PIC-NEXT: 1031: {{.*}} xorq 8296(%rip), %r8
67# DISASM-PIC-NEXT: 1038: {{.*}} testq 8289(%rip), %r15
68
69.data
70.type bar, @object
71bar:
72 .byte 1
73 .size bar, .-bar
74
75.text
76.globl _start
77.type _start, @function
78_start:
79 adcq bar@GOTPCREL(%rip), %rax
80 addq bar@GOTPCREL(%rip), %rbx
81 andq bar@GOTPCREL(%rip), %rcx
82 cmpq bar@GOTPCREL(%rip), %rdx
83 orq bar@GOTPCREL(%rip), %rdi
84 sbbq bar@GOTPCREL(%rip), %rsi
85 subq bar@GOTPCREL(%rip), %rbp
86 xorq bar@GOTPCREL(%rip), %r8
87 testq %r15, bar@GOTPCREL(%rip)
deps/lld/test/ELF/gotpc-relax-und-dso.s created+72
......@@ -0,0 +1,72 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -relax-relocations -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: llvm-mc -filetype=obj -relax-relocations -triple=x86_64-pc-linux %S/Inputs/gotpc-relax-und-dso.s -o %tdso.o
4# RUN: ld.lld -shared %tdso.o -o %t.so
5# RUN: ld.lld -shared %t.o %t.so -o %tout
6# RUN: llvm-readobj -r -s %tout | FileCheck --check-prefix=RELOC %s
7# RUN: llvm-objdump -d %tout | FileCheck --check-prefix=DISASM %s
8
9# RELOC: Relocations [
10# RELOC-NEXT: Section ({{.*}}) .rela.dyn {
11# RELOC-NEXT: R_X86_64_GLOB_DAT dsofoo 0x0
12# RELOC-NEXT: R_X86_64_GLOB_DAT foo 0x0
13# RELOC-NEXT: R_X86_64_GLOB_DAT und 0x0
14# RELOC-NEXT: }
15# RELOC-NEXT: ]
16
17# 0x101e + 7 - 36 = 0x1001
18# 0x1025 + 7 - 43 = 0x1001
19# DISASM: Disassembly of section .text:
20# DISASM-NEXT: foo:
21# DISASM-NEXT: nop
22# DISASM: hid:
23# DISASM-NEXT: nop
24# DISASM: _start:
25# DISASM-NEXT: movq 4247(%rip), %rax
26# DISASM-NEXT: movq 4240(%rip), %rax
27# DISASM-NEXT: movq 4241(%rip), %rax
28# DISASM-NEXT: movq 4234(%rip), %rax
29# DISASM-NEXT: leaq -36(%rip), %rax
30# DISASM-NEXT: leaq -43(%rip), %rax
31# DISASM-NEXT: movq 4221(%rip), %rax
32# DISASM-NEXT: movq 4214(%rip), %rax
33# DISASM-NEXT: movq 4191(%rip), %rax
34# DISASM-NEXT: movq 4184(%rip), %rax
35# DISASM-NEXT: movq 4185(%rip), %rax
36# DISASM-NEXT: movq 4178(%rip), %rax
37# DISASM-NEXT: leaq -92(%rip), %rax
38# DISASM-NEXT: leaq -99(%rip), %rax
39# DISASM-NEXT: movq 4165(%rip), %rax
40# DISASM-NEXT: movq 4158(%rip), %rax
41
42.text
43.globl foo
44.type foo, @function
45foo:
46 nop
47
48.globl hid
49.hidden hid
50.type hid, @function
51hid:
52 nop
53
54.globl _start
55.type _start, @function
56_start:
57 movq und@GOTPCREL(%rip), %rax
58 movq und@GOTPCREL(%rip), %rax
59 movq dsofoo@GOTPCREL(%rip), %rax
60 movq dsofoo@GOTPCREL(%rip), %rax
61 movq hid@GOTPCREL(%rip), %rax
62 movq hid@GOTPCREL(%rip), %rax
63 movq foo@GOTPCREL(%rip), %rax
64 movq foo@GOTPCREL(%rip), %rax
65 movq und@GOTPCREL(%rip), %rax
66 movq und@GOTPCREL(%rip), %rax
67 movq dsofoo@GOTPCREL(%rip), %rax
68 movq dsofoo@GOTPCREL(%rip), %rax
69 movq hid@GOTPCREL(%rip), %rax
70 movq hid@GOTPCREL(%rip), %rax
71 movq foo@GOTPCREL(%rip), %rax
72 movq foo@GOTPCREL(%rip), %rax
deps/lld/test/ELF/gotpc-relax.s created+98
......@@ -0,0 +1,98 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -relax-relocations -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: ld.lld %t.o -o %t1
4# RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=RELOC %s
5# RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s
6
7## There is no relocations.
8# RELOC: Relocations [
9# RELOC: ]
10
11# 0x201003 + 7 - 10 = 0x201000
12# 0x20100a + 7 - 17 = 0x201000
13# 0x201011 + 7 - 23 = 0x201001
14# 0x201018 + 7 - 30 = 0x201001
15# DISASM: Disassembly of section .text:
16# DISASM-NEXT: foo:
17# DISASM-NEXT: 201000: 90 nop
18# DISASM: hid:
19# DISASM-NEXT: 201001: 90 nop
20# DISASM: ifunc:
21# DISASM-NEXT: 201002: c3 retq
22# DISASM: _start:
23# DISASM-NEXT: leaq -10(%rip), %rax
24# DISASM-NEXT: leaq -17(%rip), %rax
25# DISASM-NEXT: leaq -23(%rip), %rax
26# DISASM-NEXT: leaq -30(%rip), %rax
27# DISASM-NEXT: movq 4058(%rip), %rax
28# DISASM-NEXT: movq 4051(%rip), %rax
29# DISASM-NEXT: leaq -52(%rip), %rax
30# DISASM-NEXT: leaq -59(%rip), %rax
31# DISASM-NEXT: leaq -65(%rip), %rax
32# DISASM-NEXT: leaq -72(%rip), %rax
33# DISASM-NEXT: movq 4016(%rip), %rax
34# DISASM-NEXT: movq 4009(%rip), %rax
35# DISASM-NEXT: callq -93 <foo>
36# DISASM-NEXT: callq -99 <foo>
37# DISASM-NEXT: callq -104 <hid>
38# DISASM-NEXT: callq -110 <hid>
39# DISASM-NEXT: callq *3979(%rip)
40# DISASM-NEXT: callq *3973(%rip)
41# DISASM-NEXT: jmp -128 <foo>
42# DISASM-NEXT: nop
43# DISASM-NEXT: jmp -134 <foo>
44# DISASM-NEXT: nop
45# DISASM-NEXT: jmp -139 <hid>
46# DISASM-NEXT: nop
47# DISASM-NEXT: jmp -145 <hid>
48# DISASM-NEXT: nop
49# DISASM-NEXT: jmpq *3943(%rip)
50# DISASM-NEXT: jmpq *3937(%rip)
51
52.text
53.globl foo
54.type foo, @function
55foo:
56 nop
57
58.globl hid
59.hidden hid
60.type hid, @function
61hid:
62 nop
63
64.text
65.type ifunc STT_GNU_IFUNC
66.globl ifunc
67.type ifunc, @function
68ifunc:
69 ret
70
71.globl _start
72.type _start, @function
73_start:
74 movq foo@GOTPCREL(%rip), %rax
75 movq foo@GOTPCREL(%rip), %rax
76 movq hid@GOTPCREL(%rip), %rax
77 movq hid@GOTPCREL(%rip), %rax
78 movq ifunc@GOTPCREL(%rip), %rax
79 movq ifunc@GOTPCREL(%rip), %rax
80 movq foo@GOTPCREL(%rip), %rax
81 movq foo@GOTPCREL(%rip), %rax
82 movq hid@GOTPCREL(%rip), %rax
83 movq hid@GOTPCREL(%rip), %rax
84 movq ifunc@GOTPCREL(%rip), %rax
85 movq ifunc@GOTPCREL(%rip), %rax
86
87 call *foo@GOTPCREL(%rip)
88 call *foo@GOTPCREL(%rip)
89 call *hid@GOTPCREL(%rip)
90 call *hid@GOTPCREL(%rip)
91 call *ifunc@GOTPCREL(%rip)
92 call *ifunc@GOTPCREL(%rip)
93 jmp *foo@GOTPCREL(%rip)
94 jmp *foo@GOTPCREL(%rip)
95 jmp *hid@GOTPCREL(%rip)
96 jmp *hid@GOTPCREL(%rip)
97 jmp *ifunc@GOTPCREL(%rip)
98 jmp *ifunc@GOTPCREL(%rip)
deps/lld/test/ELF/gotpcrelx.s created+30
......@@ -0,0 +1,30 @@
1// RUN: llvm-mc -filetype=obj -relax-relocations -triple x86_64-pc-linux-gnu \
2// RUN: %s -o %t.o
3// RUN: llvm-readobj -r %t.o | FileCheck --check-prefix=RELS %s
4// RUN: ld.lld %t.o -o %t.so -shared
5// RUN: llvm-readobj -s -r %t.so | FileCheck %s
6
7movq foo@GOTPCREL(%rip), %rax
8movq bar@GOTPCREL(%rip), %rax
9
10// RELS: Relocations [
11// RELS-NEXT: Section ({{.*}}) .rela.text {
12// RELS-NEXT: R_X86_64_REX_GOTPCRELX foo 0xFFFFFFFFFFFFFFFC
13// RELS-NEXT: R_X86_64_REX_GOTPCRELX bar 0xFFFFFFFFFFFFFFFC
14// RELS-NEXT: }
15// RELS-NEXT: ]
16
17// CHECK: Name: .got
18// CHECK-NEXT: Type: SHT_PROGBITS
19// CHECK-NEXT: Flags [
20// CHECK-NEXT: SHF_ALLOC
21// CHECK-NEXT: SHF_WRITE
22// CHECK-NEXT: ]
23// CHECK-NEXT: Address: 0x2090
24
25// CHECK: Relocations [
26// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
27// CHECK-NEXT: 0x2098 R_X86_64_GLOB_DAT bar 0x0
28// CHECK-NEXT: 0x2090 R_X86_64_GLOB_DAT foo 0x0
29// CHECK-NEXT: }
30// CHECK-NEXT: ]
deps/lld/test/ELF/hidden-vis-shared.s created+18
......@@ -0,0 +1,18 @@
1// REQUIRES: x86
2
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
4// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/shared.s -o %t2.o
5// RUN: ld.lld -shared %t2.o -o %t2.so
6// RUN: ld.lld %t.o %t2.so -o %t
7// RUN: llvm-readobj -r %t | FileCheck %s
8// RUN: ld.lld %t2.so %t.o -o %t
9// RUN: llvm-readobj -r %t | FileCheck %s
10
11// CHECK: Relocations [
12// CHECK-NEXT: ]
13
14.global _start
15_start:
16callq bar
17.hidden bar
18.weak bar
deps/lld/test/ELF/i386-got-and-copy.s created+25
......@@ -0,0 +1,25 @@
1# REQUIRES: x86
2
3# If there are two relocations such that the first one requires
4# dynamic COPY relocation, the second one requires GOT entry
5# creation, linker should create both - dynamic relocation
6# and GOT entry.
7
8# RUN: llvm-mc -filetype=obj -triple=i386-pc-linux \
9# RUN: %S/Inputs/copy-in-shared.s -o %t.so.o
10# RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t.o
11# RUN: ld.lld %t.so.o -shared -o %t.so
12# RUN: ld.lld %t.o %t.so -o %t.exe
13# RUN: llvm-readobj -r %t.exe | FileCheck %s
14
15# CHECK: Relocations [
16# CHECK-NEXT: Section (4) .rel.dyn {
17# CHECK-NEXT: 0x{{[0-9A-F]+}} R_386_COPY foo
18# CHECK-NEXT: }
19# CHECK-NEXT: ]
20
21 .text
22 .global _start
23_start:
24 movl $foo, (%esp) # R_386_32 - requires R_386_COPY relocation
25 movl foo@GOT, %eax # R_386_GOT32 - requires GOT entry
deps/lld/test/ELF/i386-gotoff-shared.s created+23
......@@ -0,0 +1,23 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
3// RUN: ld.lld %t.o -o %t.so -shared
4// RUN: llvm-readobj -s %t.so | FileCheck %s
5// RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=DISASM %s
6
7bar:
8 movl bar@GOTOFF(%ebx), %eax
9 mov bar@GOT, %eax
10
11// CHECK: Name: .got
12// CHECK-NEXT: Type: SHT_PROGBITS
13// CHECK-NEXT: Flags [
14// CHECK-NEXT: SHF_ALLOC
15// CHECK-NEXT: SHF_WRITE
16// CHECK-NEXT: ]
17// CHECK-NEXT: Address: 0x2050
18// CHECK-NEXT: Offset: 0x2050
19// CHECK-NEXT: Size: 4
20
21// 0x1000 - (0x2050 + 4) = -4180
22
23// DISASM: 1000: {{.*}} movl -4180(%ebx), %eax
deps/lld/test/ELF/i386-gotpc-dynamic.s created+32
......@@ -0,0 +1,32 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
3# RUN: ld.lld %t.o -o %t.so -shared
4# RUN: llvm-readobj -s %t.so | FileCheck %s
5# RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=DISASM %s
6
7# CHECK: Section {
8# CHECK: Index: 7
9# CHECK-NEXT: Name: .got
10# CHECK-NEXT: Type: SHT_PROGBITS
11# CHECK-NEXT: Flags [
12# CHECK-NEXT: SHF_ALLOC
13# CHECK-NEXT: SHF_WRITE
14# CHECK-NEXT: ]
15# CHECK-NEXT: Address: 0x2030
16# CHECK-NEXT: Offset:
17# CHECK-NEXT: Size:
18# CHECK-NEXT: Link:
19# CHECK-NEXT: Info:
20# CHECK-NEXT: AddressAlignment:
21# CHECK-NEXT: EntrySize:
22# CHECK-NEXT: }
23
24## 0x1000 + 4144 = 0x2030
25# DISASM: 1000: {{.*}} movl $4144, %eax
26
27.section .foo,"ax",@progbits
28foo:
29 movl $bar@got-., %eax # R_386_GOTPC
30
31.local bar
32bar:
deps/lld/test/ELF/i386-gotpc.s created+20
......@@ -0,0 +1,20 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
3// RUN: ld.lld %t.o -o %t.so -shared
4// RUN: llvm-readobj -s %t.so | FileCheck %s
5// RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=DISASM %s
6
7movl $_GLOBAL_OFFSET_TABLE_, %eax
8
9// CHECK: Name: .got
10// CHECK-NEXT: Type: SHT_PROGBITS
11// CHECK-NEXT: Flags [
12// CHECK-NEXT: SHF_ALLOC
13// CHECK-NEXT: SHF_WRITE
14// CHECK-NEXT: ]
15// CHECK-NEXT: Address: 0x2030
16
17// DISASM: Disassembly of section .text:
18// DISASM-NEXT: .text:
19// DISASM-NEXT: 1000: {{.*}} movl $4144, %eax
20// 0x2030 - 0x1000 = 4144
deps/lld/test/ELF/i386-merge.s created+50
......@@ -0,0 +1,50 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t.o
3// RUN: ld.lld %t.o -o %t -shared
4// RUN: llvm-readobj -s -section-data %t | FileCheck %s
5
6// CHECK: Name: .mysec
7// CHECK-NEXT: Type:
8// CHECK-NEXT: Flags [
9// CHECK-NEXT: SHF_ALLOC
10// CHECK-NEXT: SHF_MERGE
11// CHECK-NEXT: ]
12// CHECK-NEXT: Address: 0x114
13// CHECK-NEXT: Offset:
14// CHECK-NEXT: Size:
15// CHECK-NEXT: Link:
16// CHECK-NEXT: Info:
17// CHECK-NEXT: AddressAlignment:
18// CHECK-NEXT: EntrySize:
19// CHECK-NEXT: SectionData (
20// CHECK-NEXT: 0000: 42000000 |
21// CHECK-NEXT: )
22
23
24// CHECK: Name: .data
25// CHECK-NEXT: Type: SHT_PROGBITS
26// CHECK-NEXT: Flags [
27// CHECK-NEXT: SHF_ALLOC
28// CHECK-NEXT: SHF_WRITE
29// CHECK-NEXT: ]
30// CHECK-NEXT: Address: 0x1000
31// CHECK-NEXT: Offset: 0x1000
32// CHECK-NEXT: Size: 4
33// CHECK-NEXT: Link: 0
34// CHECK-NEXT: Info: 0
35// CHECK-NEXT: AddressAlignment: 1
36// CHECK-NEXT: EntrySize: 0
37// CHECK-NEXT: SectionData (
38// CHECK-NEXT: 0000: 14010000 |
39// CHECK-NEXT: )
40
41// The content of .data should be the address of .mysec. 14010000 is 0x114 in
42// little endian.
43
44 .data
45 .long .mysec+4
46
47 .section .mysec,"aM",@progbits,4
48 .align 4
49 .long 0x42
50 .long 0x42
deps/lld/test/ELF/i386-pc16.test created+40
......@@ -0,0 +1,40 @@
1# REQUIRES: x86
2
3# RUN: yaml2obj %s -o %t.o
4# RUN: ld.lld -Ttext 0x0 %t.o -o %t.exe
5# RUN: llvm-objdump -s -section=.text %t.exe 2>&1 | FileCheck %s
6
7# CHECK: Contents of section .text:
8# CHECK-NEXT: 0000 45231111 41231111
9
10!ELF
11FileHeader:
12 Class: ELFCLASS32
13 Data: ELFDATA2LSB
14 Type: ET_REL
15 Machine: EM_386
16Sections:
17 - Type: SHT_PROGBITS
18 Name: .text
19 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
20 AddressAlign: 0x04
21 Content: "1111111111111111"
22 - Type: SHT_REL
23 Name: .rel.text
24 Link: .symtab
25 Info: .text
26 AddressAlign: 0x04
27 Relocations:
28 - Offset: 0
29 Symbol: _start
30 Type: R_386_16
31 - Offset: 4
32 Symbol: _start
33 Type: R_386_PC16
34Symbols:
35 Global:
36 - Name: _start
37 Type: STT_FUNC
38 Section: .text
39 Value: 0x1234
40 Size: 4
deps/lld/test/ELF/i386-pc8-pc16-addend.s created+17
......@@ -0,0 +1,17 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=i386-pc-linux-gnu %s -o %t1.o
3
4# RUN: ld.lld %t1.o -o %t.out
5# RUN: llvm-objdump -s -t %t.out | FileCheck %s
6# CHECK: Contents of section .text:
7# CHECK-NEXT: 11000 020000
8## 0x11003 - 0x11000 + addend(-1) = 0x02
9## 0x11003 - 0x11001 + addend(-2) = 0x0000
10# CHECK: SYMBOL TABLE:
11# CHECK: 00011003 .und
12
13.byte und-.-1
14.short und-.-2
15
16.section .und, "ax"
17und:
deps/lld/test/ELF/i386-pc8.s created+15
......@@ -0,0 +1,15 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=i386-pc-linux-gnu %s -o %t1.o
3# RUN: ld.lld -Ttext 0x0 %t1.o -o %t.out
4# RUN: llvm-objdump -s -section=.text %t.out | FileCheck %s
5
6# CHECK: Contents of section .text:
7# CHECK-NEXT: 0000 15253748
8
9.byte und-.+0x11
10.byte und-.+0x22
11.byte und+0x33
12.byte und+0x44
13
14.section .und, "ax"
15und:
deps/lld/test/ELF/i386-relative.s created+14
......@@ -0,0 +1,14 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t.o
3// RUN: ld.lld -shared %t.o -o %t.so
4// RUN: llvm-readobj -r %t.so | FileCheck %s
5
6// CHECK: Relocations [
7// CHECK-NEXT: Section ({{.*}}) .rel.dyn {
8// CHECK-NEXT: R_386_RELATIVE - 0x0
9// CHECK-NEXT: }
10// CHECK-NEXT: ]
11
12 .data
13foo:
14 .long foo
deps/lld/test/ELF/i386-relax-reloc.s created+12
......@@ -0,0 +1,12 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o -relax-relocations
3// RUN: ld.lld -shared %t.o -o %t.so
4// RUN: llvm-objdump -d %t.so | FileCheck %s
5
6foo:
7 movl bar@GOT(%ebx), %eax
8 movl bar+8@GOT(%ebx), %eax
9
10// CHECK: foo:
11// CHECK-NEXT: movl -4(%ebx), %eax
12// CHECK-NEXT: movl 4(%ebx), %eax
deps/lld/test/ELF/i386-reloc-16.s created+14
......@@ -0,0 +1,14 @@
1// REQUIRES: x86
2
3// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %S/Inputs/x86-64-reloc-16.s -o %t1
4// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %S/Inputs/x86-64-reloc-16-error.s -o %t2
5// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t
6// RUN: ld.lld -shared %t %t1 -o %t3
7
8// CHECK: Contents of section .text:
9// CHECK-NEXT: 200000 42
10
11// RUN: not ld.lld -shared %t %t2 -o %t4 2>&1 | FileCheck --check-prefix=ERROR %s
12// ERROR: relocation R_386_16 out of range
13
14.short foo
deps/lld/test/ELF/i386-reloc-8.s created+14
......@@ -0,0 +1,14 @@
1// REQUIRES: x86
2
3// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %S/Inputs/i386-reloc-8.s -o %t1
4// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %S/Inputs/i386-reloc-8-error.s -o %t2
5// RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t
6// RUN: ld.lld -shared %t %t1 -o %t3
7
8// CHECK: Contents of section .text:
9// CHECK-NEXT: 200000 42
10
11// RUN: not ld.lld -shared %t %t2 -o %t4 2>&1 | FileCheck --check-prefix=ERROR %s
12// ERROR: relocation R_386_8 out of range
13
14.byte foo
deps/lld/test/ELF/i386-reloc-large-addend.s created+16
......@@ -0,0 +1,16 @@
1// REQUIRES: x86
2// RUN: llvm-mc %s -o %t.o -triple i386-pc-linux-code16 -filetype=obj
3
4// RUN: echo ".global foo; foo = 0x1" > %t1.s
5// RUN: llvm-mc %t1.s -o %t1.o -triple i386-pc-linux -filetype=obj
6
7// RUN: ld.lld -Ttext 0x7000 %t.o %t1.o -o %t
8// RUN: llvm-objdump -d -triple=i386-pc-linux-code16 %t | FileCheck %s
9
10// CHECK: Disassembly of section .text:
11// CHECK-NEXT: _start:
12// CHECK-NEXT: 7000: e9 fe 1f jmp 8190
13// 0x1 + 0x9000 - 0x7003 == 8190
14 .global _start
15_start:
16jmp foo + 0x9000
deps/lld/test/ELF/i386-reloc-range.s created+23
......@@ -0,0 +1,23 @@
1// REQUIRES: x86
2// RUN: llvm-mc %s -o %t.o -triple i386-pc-linux-code16 -filetype=obj
3
4// RUN: echo ".global foo; foo = 0x10202" > %t1.s
5// RUN: llvm-mc %t1.s -o %t1.o -triple i386-pc-linux -filetype=obj
6// RUN: echo ".global foo; foo = 0x10203" > %t2.s
7// RUN: llvm-mc %t2.s -o %t2.o -triple i386-pc-linux -filetype=obj
8
9// RUN: ld.lld -Ttext 0x200 %t.o %t1.o -o %t1
10// RUN: llvm-objdump -d -triple=i386-pc-linux-code16 %t1 | FileCheck %s
11
12// CHECK: Disassembly of section .text:
13// CHECK-NEXT: _start:
14// CHECK-NEXT: 200: {{.*}} jmp -1
15// 0x10202 - 0x203 == 0xffff
16
17// RUN: not ld.lld -Ttext 0x200 %t.o %t2.o -o %t2 2>&1 | FileCheck --check-prefix=ERR %s
18
19// ERR: {{.*}}:(.text+0x1): relocation R_386_PC16 out of range
20
21 .global _start
22_start:
23 jmp foo
deps/lld/test/ELF/i386-reloc8-reloc16-addend.s created+17
......@@ -0,0 +1,17 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=i386-pc-linux-gnu %s -o %t1.o
3
4# RUN: ld.lld -Ttext=0x0 %t1.o -o %t.out
5# RUN: llvm-objdump -s -t %t.out | FileCheck %s
6# CHECK: Contents of section .text:
7# CHECK-NEXT: 0000 020100
8## 0x3 + addend(-1) = 0x02
9## 0x3 + addend(-2) = 0x0100
10# CHECK: SYMBOL TABLE:
11# CHECK: 00000003 .und
12
13.byte und-1
14.short und-2
15
16.section .und, "ax"
17und:
deps/lld/test/ELF/i386-tls-got.s created+7
......@@ -0,0 +1,7 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %S/Inputs/i386-tls-got.s -o %t1.o
3# RUN: ld.lld %t1.o -o %t1.so -shared
4# RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t2.o
5# RUN: ld.lld %t2.o %t1.so -o %t
6
7 addl foobar@INDNTPOFF, %eax
deps/lld/test/ELF/i386-tls-ie-shared.s created+111
......@@ -0,0 +1,111 @@
1// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
2// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %p/Inputs/tls-opt-iele-i686-nopic.s -o %tso.o
3// RUN: ld.lld -shared %tso.o -o %tso
4// RUN: ld.lld -shared %t.o %tso -o %t1
5// RUN: llvm-readobj -s -r -d %t1 | FileCheck --check-prefix=GOTRELSHARED %s
6// RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASMSHARED %s
7
8// GOTRELSHARED: Section {
9// GOTRELSHARED: Index: 8
10// GOTRELSHARED: Name: .got
11// GOTRELSHARED-NEXT: Type: SHT_PROGBITS
12// GOTRELSHARED-NEXT: Flags [
13// GOTRELSHARED-NEXT: SHF_ALLOC
14// GOTRELSHARED-NEXT: SHF_WRITE
15// GOTRELSHARED-NEXT: ]
16// GOTRELSHARED-NEXT: Address: 0x2058
17// GOTRELSHARED-NEXT: Offset: 0x2058
18// GOTRELSHARED-NEXT: Size: 16
19// GOTRELSHARED-NEXT: Link: 0
20// GOTRELSHARED-NEXT: Info: 0
21// GOTRELSHARED-NEXT: AddressAlignment: 4
22// GOTRELSHARED-NEXT: EntrySize: 0
23// GOTRELSHARED-NEXT: }
24// GOTRELSHARED: Relocations [
25// GOTRELSHARED-NEXT: Section ({{.*}}) .rel.dyn {
26// GOTRELSHARED-NEXT: 0x1002 R_386_RELATIVE - 0x0
27// GOTRELSHARED-NEXT: 0x100A R_386_RELATIVE - 0x0
28// GOTRELSHARED-NEXT: 0x1013 R_386_RELATIVE - 0x0
29// GOTRELSHARED-NEXT: 0x101C R_386_RELATIVE - 0x0
30// GOTRELSHARED-NEXT: 0x1024 R_386_RELATIVE - 0x0
31// GOTRELSHARED-NEXT: 0x102D R_386_RELATIVE - 0x0
32// GOTRELSHARED-NEXT: 0x1036 R_386_RELATIVE - 0x0
33// GOTRELSHARED-NEXT: 0x103F R_386_RELATIVE - 0x0
34// GOTRELSHARED-NEXT: 0x2058 R_386_TLS_TPOFF tlslocal0 0x0
35// GOTRELSHARED-NEXT: 0x205C R_386_TLS_TPOFF tlslocal1 0x0
36// GOTRELSHARED-NEXT: 0x2060 R_386_TLS_TPOFF tlsshared0 0x0
37// GOTRELSHARED-NEXT: 0x2064 R_386_TLS_TPOFF tlsshared1 0x0
38// GOTRELSHARED-NEXT: }
39// GOTRELSHARED-NEXT: ]
40// GOTRELSHARED: 0x6FFFFFFA RELCOUNT 8
41
42// DISASMSHARED: Disassembly of section test:
43// DISASMSHARED-NEXT: _start:
44// (.got)[0] = 0x2058 = 8280
45// (.got)[1] = 0x205C = 8284
46// (.got)[2] = 0x2060 = 8288
47// (.got)[3] = 0x2064 = 8292
48// DISASMSHARED-NEXT: 1000: 8b 0d 58 20 00 00 movl 8280, %ecx
49// DISASMSHARED-NEXT: 1006: 65 8b 01 movl %gs:(%ecx), %eax
50// DISASMSHARED-NEXT: 1009: a1 58 20 00 00 movl 8280, %eax
51// DISASMSHARED-NEXT: 100e: 65 8b 00 movl %gs:(%eax), %eax
52// DISASMSHARED-NEXT: 1011: 03 0d 58 20 00 00 addl 8280, %ecx
53// DISASMSHARED-NEXT: 1017: 65 8b 01 movl %gs:(%ecx), %eax
54// DISASMSHARED-NEXT: 101a: 8b 0d 5c 20 00 00 movl 8284, %ecx
55// DISASMSHARED-NEXT: 1020: 65 8b 01 movl %gs:(%ecx), %eax
56// DISASMSHARED-NEXT: 1023: a1 5c 20 00 00 movl 8284, %eax
57// DISASMSHARED-NEXT: 1028: 65 8b 00 movl %gs:(%eax), %eax
58// DISASMSHARED-NEXT: 102b: 03 0d 5c 20 00 00 addl 8284, %ecx
59// DISASMSHARED-NEXT: 1031: 65 8b 01 movl %gs:(%ecx), %eax
60// DISASMSHARED-NEXT: 1034: 8b 0d 60 20 00 00 movl 8288, %ecx
61// DISASMSHARED-NEXT: 103a: 65 8b 01 movl %gs:(%ecx), %eax
62// DISASMSHARED-NEXT: 103d: 03 0d 64 20 00 00 addl 8292, %ecx
63// DISASMSHARED-NEXT: 1043: 65 8b 01 movl %gs:(%ecx), %eax
64
65.type tlslocal0,@object
66.section .tbss,"awT",@nobits
67.globl tlslocal0
68.align 4
69tlslocal0:
70 .long 0
71 .size tlslocal0, 4
72
73.type tlslocal1,@object
74.section .tbss,"awT",@nobits
75.globl tlslocal1
76.align 4
77tlslocal1:
78 .long 0
79 .size tlslocal1, 4
80
81.section .text
82.globl ___tls_get_addr
83.type ___tls_get_addr,@function
84___tls_get_addr:
85
86.section test, "axw"
87.globl _start
88_start:
89movl tlslocal0@indntpoff,%ecx
90movl %gs:(%ecx),%eax
91
92movl tlslocal0@indntpoff,%eax
93movl %gs:(%eax),%eax
94
95addl tlslocal0@indntpoff,%ecx
96movl %gs:(%ecx),%eax
97
98movl tlslocal1@indntpoff,%ecx
99movl %gs:(%ecx),%eax
100
101movl tlslocal1@indntpoff,%eax
102movl %gs:(%eax),%eax
103
104addl tlslocal1@indntpoff,%ecx
105movl %gs:(%ecx),%eax
106
107movl tlsshared0@indntpoff,%ecx
108movl %gs:(%ecx),%eax
109
110addl tlsshared1@indntpoff,%ecx
111movl %gs:(%ecx),%eax
deps/lld/test/ELF/icf-absolute.s created+20
......@@ -0,0 +1,20 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/icf-absolute.s -o %t2
5# RUN: ld.lld %t %t2 -o %t3 --icf=all --verbose | FileCheck %s
6
7# CHECK: selected .text.f1
8# CHECK: removed .text.f2
9
10.globl _start, f1, f2
11_start:
12 ret
13
14.section .text.f1, "ax"
15f1:
16 .byte a1
17
18.section .text.f2, "ax"
19f2:
20 .byte a2
deps/lld/test/ELF/icf-comdat.s created+23
......@@ -0,0 +1,23 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
4# RUN: ld.lld %t -o %t2 --icf=all --verbose | FileCheck %s
5
6# CHECK: selected .text.f1
7# CHECK: removed .text.f2
8
9.globl _start, f1, f2
10_start:
11 ret
12
13.section .text.f1,"ax"
14f1:
15 mov $60, %rax
16 mov $42, %rdi
17 syscall
18
19.section .text.f2,"axG",@progbits,foo,comdat
20f2:
21 mov $60, %rax
22 mov $42, %rdi
23 syscall
deps/lld/test/ELF/icf-i386.s created+25
......@@ -0,0 +1,25 @@
1# REQUIRES: x86
2# This test is to make sure that we can handle implicit addends properly.
3
4# RUN: llvm-mc -filetype=obj -triple=i386-unknown-linux %s -o %t
5# RUN: ld.lld %t -o %t2 --icf=all --verbose | FileCheck %s
6
7# CHECK: selected .text.f1
8# CHECK: removed .text.f2
9# CHECK-NOT: removed .text.f3
10
11.globl _start, f1, f2, f3
12_start:
13 ret
14
15.section .text.f1, "ax"
16f1:
17 movl $42, 4(%edi)
18
19.section .text.f2, "ax"
20f2:
21 movl $42, 4(%edi)
22
23.section .text.f3, "ax"
24f3:
25 movl $42, 8(%edi)
deps/lld/test/ELF/icf-merge-sec.s created+18
......@@ -0,0 +1,18 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/icf-merge-sec.s -o %t2
5# RUN: ld.lld %t %t2 -o %t3 --icf=all --verbose | FileCheck %s
6
7# CHECK: selected .text.f1
8# CHECK: removed .text.f2
9
10.section .rodata.str,"aMS",@progbits,1
11.asciz "foo"
12.asciz "string 1"
13.asciz "string 2"
14
15.section .text.f1,"ax"
16.globl f1
17f1:
18.quad .rodata.str
deps/lld/test/ELF/icf-merge.s created+27
......@@ -0,0 +1,27 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/icf-merge.s -o %t1
5# RUN: ld.lld %t %t1 -o %t1.out --icf=all --verbose | FileCheck %s
6
7# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/icf-merge2.s -o %t2
8# RUN: ld.lld %t %t2 -o %t3.out --icf=all --verbose | FileCheck --check-prefix=NOMERGE %s
9
10# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/icf-merge3.s -o %t3
11# RUN: ld.lld %t %t3 -o %t3.out --icf=all --verbose | FileCheck --check-prefix=NOMERGE %s
12
13# CHECK: selected .text.f1
14# CHECK: removed .text.f2
15
16# NOMERGE-NOT: selected .text.f
17
18.section .rodata.str,"aMS",@progbits,1
19foo:
20.asciz "foo"
21.asciz "string 1"
22.asciz "string 2"
23
24.section .text.f1,"ax"
25.globl f1
26f1:
27lea foo+42(%rip), %rax
deps/lld/test/ELF/icf-non-mergeable.s created+28
......@@ -0,0 +1,28 @@
1// REQUIRES: x86
2
3// This file contains two functions. They are themselves identical,
4// but because they have reloactions against different data section,
5// they are not mergeable.
6
7// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1
8// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
9// RUN: %p/Inputs/icf-non-mergeable.s -o %t2
10
11// RUN: ld.lld %t1 %t2 -o %t3 --icf=all --verbose | FileCheck %s
12
13// CHECK-NOT: selected .text.f1
14// CHECK-NOT: removed .text.f2
15
16.globl _start, f1, f2, d1, d2
17_start:
18 ret
19
20.section .text.f1, "ax"
21f1:
22 movl $5, d1
23 ret
24
25.section .text.f2, "ax"
26f2:
27 movl $5, d2
28 ret
deps/lld/test/ELF/icf-none.s created+22
......@@ -0,0 +1,22 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
4# RUN: ld.lld %t -o %t2 --icf=all --icf=none --verbose | FileCheck %s
5
6# CHECK-NOT: selected .text.f1
7
8.globl _start, f1, f2
9_start:
10 ret
11
12.section .text.f1, "ax"
13f1:
14 mov $60, %rax
15 mov $42, %rdi
16 syscall
17
18.section .text.f2, "ax"
19f2:
20 mov $60, %rax
21 mov $42, %rdi
22 syscall
deps/lld/test/ELF/icf1.s created+23
......@@ -0,0 +1,23 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
4# RUN: ld.lld %t -o %t2 --icf=all --verbose | FileCheck %s
5
6# CHECK: selected .text.f1
7# CHECK: removed .text.f2
8
9.globl _start, f1, f2
10_start:
11 ret
12
13.section .text.f1, "ax"
14f1:
15 mov $60, %rax
16 mov $42, %rdi
17 syscall
18
19.section .text.f2, "ax"
20f2:
21 mov $60, %rax
22 mov $42, %rdi
23 syscall
deps/lld/test/ELF/icf2.s created+17
......@@ -0,0 +1,17 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1
4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/icf2.s -o %t2
5# RUN: ld.lld %t1 %t2 -o %t --icf=all --verbose | FileCheck %s
6
7# CHECK: selected .text.f1
8# CHECK: removed .text.f2
9
10.globl _start, f1, f2
11_start:
12 ret
13
14.section .text.f1, "ax"
15f1:
16 mov $60, %rdi
17 call f2
deps/lld/test/ELF/icf3.s created+19
......@@ -0,0 +1,19 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1
4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/icf2.s -o %t2
5# RUN: ld.lld %t1 %t2 -o %t --icf=all --verbose | FileCheck %s
6
7# CHECK-NOT: Selected .text.f1
8# CHECK-NOT: Selected .text.f2
9
10.globl _start, f1, f2
11_start:
12 ret
13
14# This section is not mergeable because the content is different from f2.
15.section .text.f1, "ax"
16f1:
17 mov $60, %rdi
18 call f2
19 mov $0, %rax
deps/lld/test/ELF/icf4.s created+19
......@@ -0,0 +1,19 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
4# RUN: ld.lld %t -o %t2 --icf=all --verbose | FileCheck %s
5
6# CHECK-NOT: Selected .text.f1
7# CHECK-NOT: Selected .text.f2
8
9.globl _start, f1, f2
10_start:
11 ret
12
13.section .text.f1, "ax"
14f1:
15 mov $1, %rax
16
17.section .text.f2, "ax"
18f2:
19 mov $0, %rax
deps/lld/test/ELF/icf5.s created+19
......@@ -0,0 +1,19 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
4# RUN: ld.lld %t -o %t2 --icf=all --verbose | FileCheck %s
5
6# CHECK-NOT: Selected .text.f1
7# CHECK-NOT: Selected .text.f2
8
9.globl _start, f1, f2
10_start:
11 ret
12
13.section .text.f1, "ax"
14f1:
15 mov $0, %rax
16
17.section .text.f2, "awx"
18f2:
19 mov $0, %rax
deps/lld/test/ELF/icf6.s created+23
......@@ -0,0 +1,23 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
4# RUN: ld.lld %t -o %t2 --icf=all --verbose | FileCheck %s
5
6# CHECK-NOT: Selected .text.f1
7# CHECK-NOT: Selected .text.f2
8
9.globl _start, f1, f2
10_start:
11 ret
12
13.section .init, "ax"
14f1:
15 mov $60, %rax
16 mov $42, %rdi
17 syscall
18
19.section .fini, "ax"
20f2:
21 mov $60, %rax
22 mov $42, %rdi
23 syscall
deps/lld/test/ELF/icf7.s created+29
......@@ -0,0 +1,29 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
4# RUN: ld.lld %t -o %t2 --icf=all --verbose | FileCheck %s
5# RUN: llvm-objdump -t %t2 | FileCheck -check-prefix=ALIGN %s
6
7# CHECK: selected .text.f1
8# CHECK: removed .text.f2
9
10# ALIGN: 0000000000201000 .text 00000000 _start
11# ALIGN: 0000000000201100 .text 00000000 f1
12
13.globl _start, f1, f2
14_start:
15 ret
16
17.section .text.f1, "ax"
18 .align 1
19f1:
20 mov $60, %rax
21 mov $42, %rdi
22 syscall
23
24.section .text.f2, "ax"
25 .align 256
26f2:
27 mov $60, %rax
28 mov $42, %rdi
29 syscall
deps/lld/test/ELF/icf8.s created+14
......@@ -0,0 +1,14 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
4# RUN: ld.lld %t.o -o %t.so --icf=all -shared
5# RUN: llvm-objdump -t %t.so | FileCheck %s
6
7# CHECK: zed
8
9 .section .foo,"ax",@progbits
10 nop
11
12 .section .bar,"ax",@progbits
13zed:
14 nop
deps/lld/test/ELF/icf9.s created+20
......@@ -0,0 +1,20 @@
1# REQUIRES: x86
2
3### Make sure that we do not merge data.
4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
5# RUN: ld.lld %t -o %t2 --icf=all --verbose | FileCheck %s
6
7# CHECK-NOT: selected .data.d1
8# CHECK-NOT: selected .data.d2
9
10.globl _start, d1, d2
11_start:
12 ret
13
14.section .data.f1, "a"
15d1:
16 .byte 1
17
18.section .data.f2, "a"
19d2:
20 .byte 1
deps/lld/test/ELF/image-base.s created+64
......@@ -0,0 +1,64 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: ld.lld -image-base=0x1000000 %t -o %t1
4# RUN: llvm-readobj -program-headers %t1 | FileCheck %s
5
6# RUN: ld.lld -image-base=0x1000 -z max-page-size=0x2000 %t -o %t1 2>&1 | FileCheck --check-prefix=WARN %s
7# WARN: warning: -image-base: address isn't multiple of page size: 0x1000
8
9
10.global _start
11_start:
12 nop
13
14# CHECK: ProgramHeaders [
15# CHECK-NEXT: ProgramHeader {
16# CHECK-NEXT: Type: PT_PHDR (0x6)
17# CHECK-NEXT: Offset: 0x40
18# CHECK-NEXT: VirtualAddress: 0x1000040
19# CHECK-NEXT: PhysicalAddress: 0x1000040
20# CHECK-NEXT: FileSize: 224
21# CHECK-NEXT: MemSize: 224
22# CHECK-NEXT: Flags [ (0x4)
23# CHECK-NEXT: PF_R (0x4)
24# CHECK-NEXT: ]
25# CHECK-NEXT: Alignment: 8
26# CHECK-NEXT: }
27# CHECK-NEXT: ProgramHeader {
28# CHECK-NEXT: Type: PT_LOAD (0x1)
29# CHECK-NEXT: Offset: 0x0
30# CHECK-NEXT: VirtualAddress: 0x1000000
31# CHECK-NEXT: PhysicalAddress: 0x1000000
32# CHECK-NEXT: FileSize: 288
33# CHECK-NEXT: MemSize: 288
34# CHECK-NEXT: Flags [ (0x4)
35# CHECK-NEXT: PF_R (0x4)
36# CHECK-NEXT: ]
37# CHECK-NEXT: Alignment: 4096
38# CHECK-NEXT: }
39# CHECK-NEXT: ProgramHeader {
40# CHECK-NEXT: Type: PT_LOAD (0x1)
41# CHECK-NEXT: Offset: 0x1000
42# CHECK-NEXT: VirtualAddress: 0x1001000
43# CHECK-NEXT: PhysicalAddress: 0x1001000
44# CHECK-NEXT: FileSize: 1
45# CHECK-NEXT: MemSize: 1
46# CHECK-NEXT: Flags [ (0x5)
47# CHECK-NEXT: PF_R (0x4)
48# CHECK-NEXT: PF_X (0x1)
49# CHECK-NEXT: ]
50# CHECK-NEXT: Alignment: 4096
51# CHECK-NEXT: }
52# CHECK-NEXT: ProgramHeader {
53# CHECK-NEXT: Type: PT_GNU_STACK (0x6474E551)
54# CHECK-NEXT: Offset: 0x0
55# CHECK-NEXT: VirtualAddress: 0x0
56# CHECK-NEXT: PhysicalAddress: 0x0
57# CHECK-NEXT: FileSize: 0
58# CHECK-NEXT: MemSize: 0
59# CHECK-NEXT: Flags [ (0x6)
60# CHECK-NEXT: PF_R (0x4)
61# CHECK-NEXT: PF_W (0x2)
62# CHECK-NEXT: ]
63# CHECK-NEXT: Alignment: 0
64# CHECK-NEXT: }
deps/lld/test/ELF/incompatible-ar-first.s created+11
......@@ -0,0 +1,11 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/archive.s -o %ta.o
2// RUN: llvm-ar rc %t.a %ta.o
3// RUN: llvm-mc -filetype=obj -triple=i686-linux %s -o %tb.o
4// RUN: not ld.lld %t.a %tb.o 2>&1 | FileCheck %s
5
6// We used to crash when
7// * The first object seen by the symbol table is from an archive.
8// * -m was not used.
9// CHECK: .a({{.*}}a.o) is incompatible with {{.*}}b.o
10
11// REQUIRES: x86
deps/lld/test/ELF/incompatible-section-flags.s created+23
......@@ -0,0 +1,23 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
2// RUN: not ld.lld -shared %t.o -o %t 2>&1 | FileCheck %s
3
4// CHECK: error: incompatible section flags for .foo
5// CHECK-NEXT: >>> {{.*}}incompatible-section-flags.s.tmp.o:(.foo): 0x3
6// CHECK-NEXT: >>> output section .foo: 0x403
7
8// CHECK: error: incompatible section flags for .bar
9// CHECK-NEXT: >>> {{.*}}incompatible-section-flags.s.tmp.o:(.bar): 0x403
10// CHECK-NEXT: >>> output section .bar: 0x3
11
12.section .foo, "awT", @progbits, unique, 1
13.quad 0
14
15.section .foo, "aw", @progbits, unique, 2
16.quad 0
17
18
19.section .bar, "aw", @progbits, unique, 3
20.quad 0
21
22.section .bar, "awT", @progbits, unique, 4
23.quad 0
deps/lld/test/ELF/incompatible-section-types2.s created+9
......@@ -0,0 +1,9 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
2// RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s
3
4// CHECK: error: section type mismatch for .shstrtab
5// CHECK-NEXT: >>> <internal>:(.shstrtab): SHT_STRTAB
6// CHECK-NEXT: >>> output section .shstrtab: Unknown
7
8.section .shstrtab,"",@12345
9.short 20
deps/lld/test/ELF/incompatible.s created+59
......@@ -0,0 +1,59 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %ta.o
2// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %tb.o
3// RUN: ld.lld -shared %tb.o -o %ti686.so
4// RUN: llvm-mc -filetype=obj -triple=aarch64-unknown-linux %s -o %tc.o
5
6// RUN: not ld.lld %ta.o %tb.o -o %t 2>&1 | \
7// RUN: FileCheck --check-prefix=A-AND-B %s
8// A-AND-B: b.o is incompatible with {{.*}}a.o
9
10// RUN: not ld.lld %tb.o %tc.o -o %t 2>&1 | \
11// RUN: FileCheck --check-prefix=B-AND-C %s
12// B-AND-C: c.o is incompatible with {{.*}}b.o
13
14// RUN: not ld.lld %ta.o %ti686.so -o %t 2>&1 | \
15// RUN: FileCheck --check-prefix=A-AND-SO %s
16// A-AND-SO: i686.so is incompatible with {{.*}}a.o
17
18// RUN: not ld.lld %tc.o %ti686.so -o %t 2>&1 | \
19// RUN: FileCheck --check-prefix=C-AND-SO %s
20// C-AND-SO: i686.so is incompatible with {{.*}}c.o
21
22// RUN: not ld.lld %ti686.so %tc.o -o %t 2>&1 | \
23// RUN: FileCheck --check-prefix=SO-AND-C %s
24// SO-AND-C: c.o is incompatible with {{.*}}i686.so
25
26// RUN: not ld.lld -m elf64ppc %ta.o -o %t 2>&1 | \
27// RUN: FileCheck --check-prefix=A-ONLY %s
28// A-ONLY: a.o is incompatible with elf64ppc
29
30// RUN: not ld.lld -m elf64ppc %tb.o -o %t 2>&1 | \
31// RUN: FileCheck --check-prefix=B-ONLY %s
32// B-ONLY: b.o is incompatible with elf64ppc
33
34// RUN: not ld.lld -m elf64ppc %tc.o -o %t 2>&1 | \
35// RUN: FileCheck --check-prefix=C-ONLY %s
36// C-ONLY: c.o is incompatible with elf64ppc
37
38// RUN: not ld.lld -m elf_i386 %tc.o %ti686.so -o %t 2>&1 | \
39// RUN: FileCheck --check-prefix=C-AND-SO-I386 %s
40// C-AND-SO-I386: c.o is incompatible with elf_i386
41
42// RUN: not ld.lld -m elf_i386 %ti686.so %tc.o -o %t 2>&1 | \
43// RUN: FileCheck --check-prefix=SO-AND-C-I386 %s
44// SO-AND-C-I386: c.o is incompatible with elf_i386
45
46
47// We used to fail to identify this incompatibility and crash trying to
48// read a 64 bit file as a 32 bit one.
49// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/archive2.s -o %ta.o
50// RUN: llvm-ar rc %t.a %ta.o
51// RUN: llvm-mc -filetype=obj -triple=i686-linux %s -o %tb.o
52// RUN: not ld.lld %t.a %tb.o 2>&1 | FileCheck --check-prefix=ARCHIVE %s
53// ARCHIVE: .a({{.*}}a.o) is incompatible with {{.*}}b.o
54.global _start
55_start:
56.data
57 .long foo
58
59// REQUIRES: x86,aarch64
deps/lld/test/ELF/init-fini-progbits.s created+19
......@@ -0,0 +1,19 @@
1// REQUIRES: x86
2
3// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
4// RUN: ld.lld %t -o %t.exe
5// RUN: llvm-readobj -sections %t.exe | FileCheck %s
6
7// CHECK: Name: .init_array
8// CHECK-NEXT: Type: SHT_INIT_ARRAY
9// CHECK: Name: .fini_array
10// CHECK-NEXT: Type: SHT_FINI_ARRAY
11
12.globl _start
13_start:
14 nop
15
16.section .init_array.100, "aw", @progbits
17 .byte 0
18.section .fini_array.100, "aw", @progbits
19 .byte 0
deps/lld/test/ELF/init-fini.s created+54
......@@ -0,0 +1,54 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4// Should use "_init" and "_fini" by default when fills dynamic table
5// RUN: ld.lld -shared %t -o %t2
6// RUN: llvm-readobj -dynamic-table %t2 | FileCheck --check-prefix=BYDEF %s
7// BYDEF: INIT 0x11010
8// BYDEF: FINI 0x11020
9
10// -init and -fini override symbols to use
11// RUN: ld.lld -shared %t -o %t2 -init _foo -fini _bar
12// RUN: llvm-readobj -dynamic-table %t2 | FileCheck --check-prefix=OVR %s
13// OVR: INIT 0x11030
14// OVR: FINI 0x11040
15
16// Check aliases as well
17// RUN: ld.lld -shared %t -o %t2 -init=_foo -fini=_bar
18// RUN: llvm-readobj -dynamic-table %t2 | FileCheck --check-prefix=OVR %s
19
20// Don't add an entry for undef. The freebsd dynamic linker doesn't
21// check if the value is null. If it is, it will just call the
22// load address.
23// RUN: ld.lld -shared %t -o %t2 -init=_undef -fini=_undef
24// RUN: llvm-readobj -dynamic-table %t2 | FileCheck --check-prefix=UNDEF %s
25// UNDEF-NOT: INIT
26// UNDEF-NOT: FINI
27
28// Don't add an entry for shared. For the same reason as undef.
29// RUN: ld.lld -shared %t -o %t.so
30// RUN: echo > %t.s
31// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t.s -o %t2.o
32// RUN: ld.lld -shared %t2.o %t.so -o %t2
33// RUN: llvm-readobj -dynamic-table %t2 | FileCheck --check-prefix=SHARED %s
34// SHARED-NOT: INIT
35// SHARED-NOT: FINI
36
37// Should not add new entries to the symbol table
38// and should not require given symbols to be resolved
39// RUN: ld.lld -shared %t -o %t2 -init=_unknown -fini=_unknown
40// RUN: llvm-readobj -symbols -dynamic-table %t2 | FileCheck --check-prefix=NOENTRY %s
41// NOENTRY: Symbols [
42// NOENTRY-NOT: Name: _unknown
43// NOENTRY: ]
44// NOENTRY: DynamicSection [
45// NOENTRY-NOT: INIT
46// NOENTRY-NOT: FINI
47// NOENTRY: ]
48
49.global _start,_init,_fini,_foo,_bar,_undef
50_start:
51_init = 0x11010
52_fini = 0x11020
53_foo = 0x11030
54_bar = 0x11040
deps/lld/test/ELF/init_fini_priority.s created+37
......@@ -0,0 +1,37 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
2// RUN: ld.lld %t -o %t.exe
3// RUN: llvm-objdump -s %t.exe | FileCheck %s
4// REQUIRES: x86
5
6.globl _start
7_start:
8 nop
9
10.section .init_array, "aw", @init_array
11 .align 8
12 .byte 1
13.section .init_array.100, "aw", @init_array
14 .long 2
15.section .init_array.5, "aw", @init_array
16 .byte 3
17.section .init_array, "aw", @init_array
18 .byte 4
19.section .init_array, "aw", @init_array
20 .byte 5
21
22.section .fini_array, "aw", @fini_array
23 .align 8
24 .byte 0x11
25.section .fini_array.100, "aw", @fini_array
26 .long 0x12
27.section .fini_array.5, "aw", @fini_array
28 .byte 0x13
29.section .fini_array, "aw", @fini_array
30 .byte 0x14
31.section .fini_array, "aw", @fini_array
32 .byte 0x15
33
34// CHECK: Contents of section .init_array:
35// CHECK-NEXT: 03020000 00000000 010405
36// CHECK: Contents of section .fini_array:
37// CHECK-NEXT: 13120000 00000000 111415
deps/lld/test/ELF/invalid-cie-length.s created+10
......@@ -0,0 +1,10 @@
1// REQUIRES: x86
2
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
4// RUN: not ld.lld %t -o %t2 2>&1 | FileCheck %s
5
6.section .eh_frame
7.byte 0
8
9// CHECK: error: corrupted .eh_frame: CIE/FDE too small
10// CHECK-NEXT: >>> defined in {{.*}}:(.eh_frame+0x0)
deps/lld/test/ELF/invalid-cie-length2.s created+10
......@@ -0,0 +1,10 @@
1// REQUIRES: x86
2
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
4// RUN: not ld.lld %t -o %t2 2>&1 | FileCheck %s
5
6.section .eh_frame
7.long 42
8
9// CHECK: error: corrupted .eh_frame: CIE/FDE ends past the end of the section
10// CHECK-NEXT: >>> defined in {{.*}}:(.eh_frame+0x0)
deps/lld/test/ELF/invalid-cie-length3.s created+11
......@@ -0,0 +1,11 @@
1// REQUIRES: x86
2
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
4// RUN: not ld.lld %t -o %t2 2>&1 | FileCheck %s
5
6.section .eh_frame
7.long 0xFFFFFFFC
8
9// CHECK: error: corrupted .eh_frame: CIE/FDE ends past the end of the section
10// CHECK-NEXT: >>> defined in {{.*}}:(.eh_frame+0x0)
11
deps/lld/test/ELF/invalid-cie-length4.s created+11
......@@ -0,0 +1,11 @@
1// REQUIRES: x86
2
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
4// RUN: not ld.lld %t -o %t2 2>&1 | FileCheck %s
5
6.section .eh_frame
7.long 0xFFFFFFFF
8.byte 0
9
10// CHECK: error: corrupted .eh_frame: CIE/FDE too large
11// CHECK-NEXT: >>> defined in {{.*}}:(.eh_frame+0x0)
deps/lld/test/ELF/invalid-cie-length5.s created+10
......@@ -0,0 +1,10 @@
1// REQUIRES: x86
2
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
4// RUN: not ld.lld %t -o %t2 2>&1 | FileCheck %s
5
6 .section .eh_frame
7 .long 0xFFFFFFFF
8 .quad 0xFFFFFFFFFFFFFFF4
9
10// CHECK: CIE/FDE too large
deps/lld/test/ELF/invalid-cie-reference.s created+32
......@@ -0,0 +1,32 @@
1// REQUIRES: x86
2
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
4// RUN: not ld.lld %t -o %t2 2>&1 | FileCheck %s
5
6 .section .eh_frame
7 .long 0x14
8 .long 0x0
9 .byte 0x01
10 .byte 0x7a
11 .byte 0x52
12 .byte 0x00
13 .byte 0x01
14 .byte 0x78
15 .byte 0x10
16 .byte 0x01
17 .byte 0x1b
18 .byte 0x0c
19 .byte 0x07
20 .byte 0x08
21 .byte 0x90
22 .byte 0x01
23 .short 0x0
24
25 .long 0x14
26 .long 0x1b
27 .long .text
28 .long 0x0
29 .long 0x0
30 .long 0x0
31
32// CHECK: invalid CIE reference
deps/lld/test/ELF/invalid-dynamic-list.test created+37
......@@ -0,0 +1,37 @@
1## Different "echo" commands on Windows interpret quoted strings and
2## wildcards in similar but different way (On Windows, ARGV tokenization
3## and wildcard expansion are not done by the shell but by each command.)
4## Because of that reason, this test fails on some Windows environment.
5## We can't write quoted strings that are interpreted the same way
6## by all echo commands. So, we don't want to run this on Windows.
7
8# REQUIRES: shell
9
10# RUN: mkdir -p %t.dir
11
12# RUN: echo foobar > %t1
13# RUN: not ld.lld --dynamic-list %t1 2>&1 | FileCheck -check-prefix=ERR1 %s
14# ERR1: {{.*}}:1: { expected, but got foobar
15
16# RUN: echo "{ foobar;" > %t1
17# RUN: not ld.lld --dynamic-list %t1 2>&1 | FileCheck -check-prefix=ERR2 %s
18# ERR2: {{.*}}:1: unexpected EOF
19
20## Missing ';' before '}'
21# RUN: echo "{ foobar }" > %t1
22# RUN: not ld.lld --dynamic-list %t1 2>&1 | FileCheck -check-prefix=ERR3 %s
23# ERR3: {{.*}}:1: ; expected, but got }
24
25## Missing final ';'
26# RUN: echo "{ foobar; }" > %t1
27# RUN: not ld.lld --dynamic-list %t1 2>&1 | FileCheck -check-prefix=ERR4 %s
28# ERR4: {{.*}}:1: unexpected EOF
29
30## Missing \" in foobar definition
31# RUN echo "{ \"foobar; };" > %t1
32# RUN: not ld.lld --dynamic-list %t1 2>&1 | FileCheck -check-prefix=ERR5 %s
33# ERR5: {{.*}}:1: unexpected EOF
34
35# RUN: echo "{ extern \"BOGUS\" { test }; };" > %t1
36# RUN: not ld.lld --dynamic-list %t1 2>&1 | FileCheck -check-prefix=ERR6 %s
37# ERR6: {{.*}}:1: Unknown language
deps/lld/test/ELF/invalid-fde-rel.s created+36
......@@ -0,0 +1,36 @@
1// REQUIRES: x86
2
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
4// RUN: ld.lld %t -o %t2
5// RUN: llvm-objdump -h %t2 | FileCheck %s
6
7// This resembles what gold -r produces when it discards the section
8// the fde points to.
9
10 .section .eh_frame
11 .long 0x14
12 .long 0x0
13 .byte 0x01
14 .byte 0x7a
15 .byte 0x52
16 .byte 0x00
17 .byte 0x01
18 .byte 0x78
19 .byte 0x10
20 .byte 0x01
21 .byte 0x1b
22 .byte 0x0c
23 .byte 0x07
24 .byte 0x08
25 .byte 0x90
26 .byte 0x01
27 .short 0x0
28
29 .long 0x14
30 .long 0x1c
31 .long 0x0
32 .long 0x0
33 .long 0x0
34 .long 0x0
35
36// CHECK: 1 .eh_frame 00000018
deps/lld/test/ELF/invalid-linkerscript.test created+54
......@@ -0,0 +1,54 @@
1## Different "echo" commands on Windows interpret quoted strings and
2## wildcards in similar but different way (On Windows, ARGV tokenization
3## and wildcard expansion are not done by the shell but by each command.)
4## Because of that reason, this test fails on some Windows environment.
5## We can't write quoted strings that are interpreted the same way
6## by all echo commands. So, we don't want to run this on Windows.
7
8# REQUIRES: shell
9
10# RUN: mkdir -p %t.dir
11
12## Note that we are using "cannot open no-such-file: " as a marker that the
13## linker keep going when it found an error. That specific error message is not
14## related to the linker script tests.
15
16# RUN: echo foobar > %t1
17# RUN: not ld.lld %t1 no-such-file 2>&1 | FileCheck -check-prefix=ERR1 %s
18# ERR1: unexpected EOF
19# ERR1: cannot open no-such-file:
20
21# RUN: echo "foo \"bar" > %t2
22# RUN: not ld.lld %t2 no-such-file 2>&1 | FileCheck -check-prefix=ERR2 %s
23# ERR2: unclosed quote
24# ERR2: cannot open no-such-file:
25
26# RUN: echo "/*" > %t3
27# RUN: not ld.lld %t3 no-such-file 2>&1 | FileCheck -check-prefix=ERR3 %s
28# ERR3: unclosed comment
29# ERR3: cannot open no-such-file:
30
31# RUN: echo "EXTERN (" > %t4
32# RUN: not ld.lld %t4 no-such-file 2>&1 | FileCheck -check-prefix=ERR4 %s
33# ERR4: unexpected EOF
34# ERR4: cannot open no-such-file:
35
36# RUN: echo "EXTERN (" > %t5
37# RUN: not ld.lld %t5 no-such-file 2>&1 | FileCheck -check-prefix=ERR5 %s
38# ERR5: unexpected EOF
39# ERR5: cannot open no-such-file:
40
41# RUN: echo "EXTERN xyz" > %t6
42# RUN: not ld.lld %t6 no-such-file 2>&1 | FileCheck -check-prefix=ERR6 %s
43# ERR6: ( expected, but got xyz
44# ERR6: cannot open no-such-file:
45
46# RUN: echo "INCLUDE /no/such/file" > %t7
47# RUN: not ld.lld %t7 no-such-file 2>&1 | FileCheck -check-prefix=ERR7 %s
48# ERR7: cannot open /no/such/file
49# ERR7: cannot open no-such-file:
50
51# RUN: echo "OUTPUT_FORMAT(x y z)" > %t8
52# RUN: not ld.lld %t8 no-such-file 2>&1 | FileCheck -check-prefix=ERR8 %s
53# ERR8: , expected, but got y
54# ERR8: cannot open no-such-file:
deps/lld/test/ELF/invalid-relocations.test created+23
......@@ -0,0 +1,23 @@
1# RUN: yaml2obj %s -o %t
2# RUN: not ld.lld %t -o %tout 2>&1 | FileCheck %s
3
4!ELF
5FileHeader:
6 Class: ELFCLASS64
7 Data: ELFDATA2LSB
8 Type: ET_REL
9 Machine: EM_X86_64
10Sections:
11 - Type: SHT_PROGBITS
12 - Name: .rela.text
13 Type: SHT_RELA
14 Info: 12 # Invalid index
15 Relocations:
16 - Offset: 0x0000000000000001
17 Symbol: lulz
18 Type: R_X86_64_PC32
19Symbols:
20 Global:
21 - Name: lulz
22
23# CHECK: invalid relocated section index
deps/lld/test/ELF/invalid-z.s created+9
......@@ -0,0 +1,9 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: not ld.lld %t.o -o %t -z max-page-size 2>&1 | FileCheck %s
4# CHECK: invalid max-page-size
5# CHECK-NOT: error
6
7.global _start
8_start:
9 nop
deps/lld/test/ELF/invalid/Inputs/binding.elf created
Binary files /dev/null and b/deps/lld/test/ELF/invalid/Inputs/binding.elf differ
deps/lld/test/ELF/invalid/Inputs/broken-relaxation-x64.elf created
Binary files /dev/null and b/deps/lld/test/ELF/invalid/Inputs/broken-relaxation-x64.elf differ
deps/lld/test/ELF/invalid/Inputs/cie-version2.elf created
Binary files /dev/null and b/deps/lld/test/ELF/invalid/Inputs/cie-version2.elf differ
deps/lld/test/ELF/invalid/Inputs/common-symbol-alignment.elf created
Binary files /dev/null and b/deps/lld/test/ELF/invalid/Inputs/common-symbol-alignment.elf differ
deps/lld/test/ELF/invalid/Inputs/common-symbol-alignment2.elf created
Binary files /dev/null and b/deps/lld/test/ELF/invalid/Inputs/common-symbol-alignment2.elf differ
deps/lld/test/ELF/invalid/Inputs/data-encoding.a created
Binary files /dev/null and b/deps/lld/test/ELF/invalid/Inputs/data-encoding.a differ
deps/lld/test/ELF/invalid/Inputs/dynamic-section-sh_size.elf created
Binary files /dev/null and b/deps/lld/test/ELF/invalid/Inputs/dynamic-section-sh_size.elf differ
deps/lld/test/ELF/invalid/Inputs/file-class.a created
Binary files /dev/null and b/deps/lld/test/ELF/invalid/Inputs/file-class.a differ
deps/lld/test/ELF/invalid/Inputs/invalid-e_shnum.elf created
Binary files /dev/null and b/deps/lld/test/ELF/invalid/Inputs/invalid-e_shnum.elf differ
deps/lld/test/ELF/invalid/Inputs/mips-invalid-options-descriptor.elf created
Binary files /dev/null and b/deps/lld/test/ELF/invalid/Inputs/mips-invalid-options-descriptor.elf differ
deps/lld/test/ELF/invalid/Inputs/multiple-eh-relocs.elf created
Binary files /dev/null and b/deps/lld/test/ELF/invalid/Inputs/multiple-eh-relocs.elf differ
deps/lld/test/ELF/invalid/Inputs/section-alignment-notpow2.elf created
Binary files /dev/null and b/deps/lld/test/ELF/invalid/Inputs/section-alignment-notpow2.elf differ
deps/lld/test/ELF/invalid/Inputs/section-index.elf created
Binary files /dev/null and b/deps/lld/test/ELF/invalid/Inputs/section-index.elf differ
deps/lld/test/ELF/invalid/Inputs/section-index2.elf created
Binary files /dev/null and b/deps/lld/test/ELF/invalid/Inputs/section-index2.elf differ
deps/lld/test/ELF/invalid/Inputs/shentsize-zero.elf created
Binary files /dev/null and b/deps/lld/test/ELF/invalid/Inputs/shentsize-zero.elf differ
deps/lld/test/ELF/invalid/Inputs/sht-group.elf created
Binary files /dev/null and b/deps/lld/test/ELF/invalid/Inputs/sht-group.elf differ
deps/lld/test/ELF/invalid/Inputs/symbol-index.elf created
Binary files /dev/null and b/deps/lld/test/ELF/invalid/Inputs/symbol-index.elf differ
deps/lld/test/ELF/invalid/Inputs/symbol-name-offset.elf created
Binary files /dev/null and b/deps/lld/test/ELF/invalid/Inputs/symbol-name-offset.elf differ
deps/lld/test/ELF/invalid/Inputs/symtab-sh_info.elf created
Binary files /dev/null and b/deps/lld/test/ELF/invalid/Inputs/symtab-sh_info.elf differ
deps/lld/test/ELF/invalid/Inputs/symtab-sh_info2.elf created
Binary files /dev/null and b/deps/lld/test/ELF/invalid/Inputs/symtab-sh_info2.elf differ
deps/lld/test/ELF/invalid/Inputs/symtab-sh_info3.elf created
Binary files /dev/null and b/deps/lld/test/ELF/invalid/Inputs/symtab-sh_info3.elf differ
deps/lld/test/ELF/invalid/Inputs/tls-symbol.elf created
Binary files /dev/null and b/deps/lld/test/ELF/invalid/Inputs/tls-symbol.elf differ
deps/lld/test/ELF/invalid/Inputs/too-short.elf created
Binary files /dev/null and b/deps/lld/test/ELF/invalid/Inputs/too-short.elf differ
deps/lld/test/ELF/invalid/broken-relaxation-x64.test created+46
......@@ -0,0 +1,46 @@
1# REQUIRES: x86
2
3# RUN: yaml2obj %s -o %t.o
4# RUN: not ld.lld %t.o -o %t.exe 2>&1 | FileCheck --check-prefix=ERR %s
5# ERR: R_X86_64_GOTTPOFF must be used in MOVQ or ADDQ instructions only
6# ERR: R_X86_64_GOTTPOFF must be used in MOVQ or ADDQ instructions only
7
8## YAML below contains 2 relocations of type R_X86_64_GOTTPOFF, and a .text
9## with fake content filled by 0xFF. That means instructions for relaxation are
10## "broken", so they does not match any known valid relaxations. We also generate
11## .tls section because we need it for correct proccessing of STT_TLS symbol.
12!ELF
13FileHeader:
14 Class: ELFCLASS64
15 Data: ELFDATA2LSB
16 OSABI: ELFOSABI_FREEBSD
17 Type: ET_REL
18 Machine: EM_X86_64
19Sections:
20 - Type: SHT_PROGBITS
21 Name: .text
22 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
23 AddressAlign: 0x04
24 Content: "FFFFFFFFFFFFFFFF"
25 - Type: SHT_PROGBITS
26 Name: .tls
27 Flags: [ SHF_ALLOC, SHF_TLS ]
28 - Type: SHT_REL
29 Name: .rel.text
30 Link: .symtab
31 Info: .text
32 AddressAlign: 0x04
33 Relocations:
34 - Offset: 4
35 Symbol: foo
36 Type: R_X86_64_GOTTPOFF
37 - Offset: 4
38 Symbol: foo
39 Type: R_X86_64_GOTTPOFF
40Symbols:
41 Global:
42 - Name: foo
43 Type: STT_TLS
44 Section: .text
45 Value: 0x12345
46 Size: 4
deps/lld/test/ELF/invalid/common-symbol-alignment.s created+12
......@@ -0,0 +1,12 @@
1# REQUIRES: x86
2
3## common-symbol-alignment.elf contains common symbol with zero alignment.
4# RUN: not ld.lld %S/Inputs/common-symbol-alignment.elf \
5# RUN: -o %t 2>&1 | FileCheck %s
6# CHECK: common symbol 'bar' has invalid alignment: 0
7
8## common-symbol-alignment2.elf contains common symbol alignment greater
9## than UINT32_MAX.
10# RUN: not ld.lld %S/Inputs/common-symbol-alignment2.elf \
11# RUN: -o %t 2>&1 | FileCheck %s --check-prefix=BIG
12# BIG: common symbol 'bar' has invalid alignment: 271644049215
deps/lld/test/ELF/invalid/dynamic-section-size.s created+4
......@@ -0,0 +1,4 @@
1## dynamic-section-sh_size.elf has incorrect sh_size of dynamic section.
2# RUN: not ld.lld %p/Inputs/dynamic-section-sh_size.elf -o %t2 2>&1 | \
3# RUN: FileCheck %s
4# CHECK: error: {{.*}}: invalid sh_entsize
deps/lld/test/ELF/invalid/eh-frame-hdr-no-out.s created+6
......@@ -0,0 +1,6 @@
1// REQUIRES: x86
2// RUN: not ld.lld --eh-frame-hdr %p/Inputs/cie-version2.elf -o %t >& %t.log
3// RUN: FileCheck %s < %t.log
4
5// cie-version2.elf contains unsupported version of CIE = 2.
6// CHECK: FDE version 1 or 3 expected, but got 2
deps/lld/test/ELF/invalid/invalid-debug-relocations.test created+41
......@@ -0,0 +1,41 @@
1# REQUIRES: x86
2# RUN: yaml2obj %s -o %t.o
3# RUN: not ld.lld -gdb-index %t.o -o %t.exe 2>&1 | FileCheck %s
4
5# CHECK: error: {{.*}}.o: error parsing DWARF data:
6# CHECK-NEXT: >>> failed to compute relocation: Unknown, Invalid data was encountered while parsing the file
7
8!ELF
9FileHeader:
10 Class: ELFCLASS32
11 Data: ELFDATA2LSB
12 Type: ET_REL
13 Machine: EM_386
14Sections:
15 - Type: SHT_PROGBITS
16 Name: .text
17 Flags: [ ]
18 AddressAlign: 0x04
19 Content: "0000"
20 - Type: SHT_PROGBITS
21 Name: .debug_info
22 Flags: [ ]
23 AddressAlign: 0x04
24 Content: "0000"
25 - Type: SHT_REL
26 Name: .rel.debug_info
27 Link: .symtab
28 Info: .debug_info
29 Relocations:
30 - Offset: 0
31 Symbol: _start
32 Type: 0xFF
33 - Offset: 4
34 Symbol: _start
35 Type: 0xFF
36Symbols:
37 Global:
38 - Name: _start
39 Type: STT_FUNC
40 Section: .text
41 Value: 0x0
deps/lld/test/ELF/invalid/invalid-e_shnum.s created+3
......@@ -0,0 +1,3 @@
1## Spec says that "If a file has no section header table, e_shnum holds the value zero.", though
2## in this test case it holds non-zero and lld used to crash.
3# RUN: ld.lld %p/Inputs/invalid-e_shnum.elf -o %t2
deps/lld/test/ELF/invalid/invalid-elf.test created+31
......@@ -0,0 +1,31 @@
1# RUN: llvm-mc %s -o %t -filetype=obj -triple x86_64-pc-linux
2
3# RUN: not ld.lld %t %p/Inputs/data-encoding.a -o %t2 2>&1 | \
4# RUN: FileCheck --check-prefix=INVALID-DATA-ENC %s
5# INVALID-DATA-ENC: test.o: invalid data encoding
6
7# RUN: not ld.lld %t %p/Inputs/file-class.a -o %t2 2>&1 | \
8# RUN: FileCheck --check-prefix=INVALID-FILE-CLASS %s
9# INVALID-FILE-CLASS: test.o: invalid file class
10
11# RUN: not ld.lld %p/Inputs/symtab-sh_info.elf -o %t2 2>&1 | \
12# RUN: FileCheck --check-prefix=INVALID-SYMTAB-SHINFO %s
13# INVALID-SYMTAB-SHINFO: invalid sh_info in symbol table
14
15# RUN: not ld.lld %p/Inputs/binding.elf -o %t2 2>&1 | \
16# RUN: FileCheck --check-prefix=INVALID-BINDING %s
17# INVALID-BINDING: unexpected binding
18
19# RUN: not ld.lld %p/Inputs/section-index.elf -o %t2 2>&1 | \
20# RUN: FileCheck --check-prefix=INVALID-SECTION-INDEX-LLD %s
21# INVALID-SECTION-INDEX-LLD: invalid section index
22
23## section-index2.elf has local symbol with incorrect section index.
24# RUN: not ld.lld %p/Inputs/section-index2.elf -o %t2 2>&1 | \
25# RUN: FileCheck --check-prefix=INVALID-SECTION-INDEX-LLD %s
26
27# RUN: not ld.lld %p/Inputs/multiple-eh-relocs.elf -o %t2 2>&1 | \
28# RUN: FileCheck --check-prefix=INVALID-EH-RELOCS %s
29# INVALID-EH-RELOCS: multiple relocation sections to one section are not supported
30
31.long foo
deps/lld/test/ELF/invalid/invalid-relocation-x64.test created+27
......@@ -0,0 +1,27 @@
1# RUN: yaml2obj %s -o %t.o
2# RUN: not ld.lld %t.o -o /dev/null 2>&1 | FileCheck %s
3# CHECK: {{.*}}.o: unknown relocation type: Unknown (152)
4# CHECK: {{.*}}.o: unknown relocation type: Unknown (153)
5
6!ELF
7FileHeader:
8 Class: ELFCLASS64
9 Data: ELFDATA2LSB
10 OSABI: ELFOSABI_FREEBSD
11 Type: ET_REL
12 Machine: EM_X86_64
13Sections:
14 - Name: .text
15 Type: SHT_PROGBITS
16 Flags: [ SHF_ALLOC ]
17 - Name: .rela.text
18 Type: SHT_RELA
19 Link: .symtab
20 Info: .text
21 Relocations:
22 - Offset: 0x0000000000000000
23 Symbol: ''
24 Type: 0x98
25 - Offset: 0x0000000000000000
26 Symbol: ''
27 Type: 0x99
deps/lld/test/ELF/invalid/merge-invalid-size.s created+10
......@@ -0,0 +1,10 @@
1// REQUIRES: x86
2// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
3// RUN: not ld.lld %t.o -o %t.so 2>&1 | FileCheck %s
4// CHECK: SHF_MERGE section size must be a multiple of sh_entsize
5
6// Test that we accept a zero sh_entsize.
7// RUN: ld.lld %p/Inputs/shentsize-zero.elf -o %t2
8
9.section .foo,"aM",@progbits,4
10.short 42
deps/lld/test/ELF/invalid/mips-invalid-options-descriptor.s created+5
......@@ -0,0 +1,5 @@
1## mips-invalid-options-descriptor.elf has option descriptor in
2## .MIPS.options with size of zero.
3# RUN: not ld.lld %p/Inputs/mips-invalid-options-descriptor.elf -o %t2 2>&1 | \
4# RUN: FileCheck %s
5# CHECK: error: {{.*}}: invalid section offset
deps/lld/test/ELF/invalid/section-alignment.test created+19
......@@ -0,0 +1,19 @@
1# RUN: yaml2obj %s -o %t
2# RUN: not ld.lld %t -o %tout 2>&1 | FileCheck %s
3
4## In current lld implementation, we do not accept sh_addralign
5## larger than UINT32_MAX.
6!ELF
7FileHeader:
8 Class: ELFCLASS64
9 Data: ELFDATA2LSB
10 Type: ET_REL
11 Machine: EM_X86_64
12Sections:
13 - Name: .text
14 Type: SHT_PROGBITS
15 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
16 AddressAlign: 0x1000000000000000
17 Content: "00000000"
18
19# CHECK: section sh_addralign is too large
deps/lld/test/ELF/invalid/section-alignment2.s created+5
......@@ -0,0 +1,5 @@
1## section-alignment-notpow2.elf has section alignment
2## 0xFFFFFFFF which is not a power of 2.
3# RUN: not ld.lld %p/Inputs/section-alignment-notpow2.elf -o %t2 2>&1 | \
4# RUN: FileCheck %s
5# CHECK: section sh_addralign is not a power of 2
deps/lld/test/ELF/invalid/sht-group.s created+3
......@@ -0,0 +1,3 @@
1## sht-group.elf contains SHT_GROUP section with invalid sh_info.
2# RUN: not ld.lld %p/Inputs/sht-group.elf -o %t2 2>&1 | FileCheck %s
3# CHECK: invalid symbol index
deps/lld/test/ELF/invalid/symbol-index.s created+10
......@@ -0,0 +1,10 @@
1## symbol-index.elf has incorrect type of .symtab section.
2## There is no symbol bodies because of that and any symbol index becomes incorrect.
3## Section Headers:
4## [Nr] Name Type Address Off Size ES Flg Lk Inf Al
5## [ 0] NULL 0000000000000000 000000 000000 00 0 0 0
6## ...
7## [ 4] .symtab RELA 0000000000000000 000048 000030 18 1 2 8
8# RUN: not ld.lld %p/Inputs/symbol-index.elf -o %t2 2>&1 | \
9# RUN: FileCheck --check-prefix=INVALID-SYMBOL-INDEX %s
10# INVALID-SYMBOL-INDEX: invalid symbol index
deps/lld/test/ELF/invalid/symbol-name.s created+7
......@@ -0,0 +1,7 @@
1# REQUIRES: x86
2
3## symbol-name-offset.elf contains symbol with invalid (too large)
4## st_name value.
5# RUN: not ld.lld %S/Inputs/symbol-name-offset.elf \
6# RUN: -o %t 2>&1 | FileCheck %s
7# CHECK: invalid symbol name offset
deps/lld/test/ELF/invalid/symtab-sh-info.s created+9
......@@ -0,0 +1,9 @@
1## sh_info contains zero value. First entry in a symbol table is always completely zeroed,
2## so sh_info should be at least 1 in a valid ELF.
3# RUN: not ld.lld %p/Inputs/symtab-sh_info2.elf -o %t2 2>&1 | FileCheck %s
4# CHECK: invalid sh_info in symbol table
5
6## sh_info contains invalid value saying non-local symbol is local.
7# RUN: not ld.lld %p/Inputs/symtab-sh_info3.elf -o %t2 2>&1 | \
8# RUN: FileCheck --check-prefix=INVALID-SYMTAB-SHINFO %s
9# INVALID-SYMTAB-SHINFO: broken object: getLocalSymbols returns a non-local symbol
deps/lld/test/ELF/invalid/symtab-symbols.test created+25
......@@ -0,0 +1,25 @@
1# RUN: yaml2obj %s -o %t
2# RUN: ld.lld -shared %t -o %tout
3
4# GNU assembler 2.17.50 [FreeBSD] 2007-07-03 could generate
5# broken objects.
6# Verify that lld can handle STT_NOTYPE symbols associated
7# with SHT_SYMTAB section.
8
9!ELF
10FileHeader:
11 Class: ELFCLASS64
12 Data: ELFDATA2LSB
13 OSABI: ELFOSABI_FREEBSD
14 Type: ET_REL
15 Machine: EM_X86_64
16Sections:
17 - Name: .text
18 Type: SHT_PROGBITS
19 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
20 AddressAlign: 0x0000000000000010
21 Content: "00000000"
22Symbols:
23 Local:
24 - Type: STT_NOTYPE
25 Section: .symtab
deps/lld/test/ELF/invalid/tls-symbol.s created+5
......@@ -0,0 +1,5 @@
1# REQUIRES: x86
2
3## The test file contains an STT_TLS symbol but has no TLS section.
4# RUN: not ld.lld %S/Inputs/tls-symbol.elf -o %t 2>&1 | FileCheck %s
5# CHECK: has an STT_TLS symbol but doesn't have an SHF_TLS section
deps/lld/test/ELF/invalid/too-short.s created+5
......@@ -0,0 +1,5 @@
1# REQUIRES: x86
2
3## too-short.elf file is a truncated ELF.
4# RUN: not ld.lld %S/Inputs/too-short.elf -o %t 2>&1 | FileCheck %s
5# CHECK: file is too short
deps/lld/test/ELF/invalid/verdef-no-symtab.test created+26
......@@ -0,0 +1,26 @@
1# RUN: yaml2obj %s -o %t
2# RUN: not ld.lld %t -o %tout 2>&1 | FileCheck %s
3
4## When we have SHT_GNU_versym section, it is should be associated
5## with symbol table section.
6--- !ELF
7FileHeader:
8 Class: ELFCLASS64
9 Data: ELFDATA2LSB
10 Type: ET_DYN
11 Machine: EM_X86_64
12Sections:
13 - Name: .versym
14 Type: SHT_GNU_versym
15 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
16 AddressAlign: 0x1
17 Content: "00000000"
18
19 - Name: .verdef
20 Type: SHT_GNU_verdef
21 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
22 AddressAlign: 0x1
23 Content: "00000000"
24
25
26# CHECK: SHT_GNU_versym should be associated with symbol table
deps/lld/test/ELF/libsearch.s created+101
......@@ -0,0 +1,101 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
3// RUN: %p/Inputs/libsearch-dyn.s -o %tdyn.o
4// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
5// RUN: %p/Inputs/libsearch-st.s -o %tst.o
6// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
7// RUN: %p/Inputs/use-bar.s -o %tbar.o
8// RUN: mkdir -p %t.dir
9// RUN: ld.lld -shared %tdyn.o -o %t.dir/libls.so
10// RUN: cp -f %t.dir/libls.so %t.dir/libls2.so
11// RUN: rm -f %t.dir/libls.a
12// RUN: llvm-ar rcs %t.dir/libls.a %tst.o
13// REQUIRES: x86
14
15// Should fail if no library specified
16// RUN: not ld.lld -l 2>&1 \
17// RUN: | FileCheck --check-prefix=NOLIBRARY %s
18// NOLIBRARY: -l: missing argument
19
20// Should link normally, because _bar is not used
21// RUN: ld.lld -o %t3 %t.o
22// Should not link because of undefined symbol _bar
23// RUN: not ld.lld -o %t3 %t.o %tbar.o 2>&1 \
24// RUN: | FileCheck --check-prefix=UNDEFINED %s
25// UNDEFINED: error: undefined symbol: _bar
26// UNDEFINED: >>> referenced by {{.*}}:(.bar+0x0)
27
28// Should fail if cannot find specified library (without -L switch)
29// RUN: not ld.lld -o %t3 %t.o -lls 2>&1 \
30// RUN: | FileCheck --check-prefix=NOLIB %s
31// NOLIB: unable to find library -lls
32
33// Should use explicitly specified static library
34// Also ensure that we accept -L <arg>
35// RUN: ld.lld -o %t3 %t.o -L %t.dir -l:libls.a
36// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=STATIC %s
37// STATIC: Symbols [
38// STATIC: Name: _static
39// STATIC: ]
40
41// Should use explicitly specified dynamic library
42// RUN: ld.lld -o %t3 %t.o -L%t.dir -l:libls.so
43// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=DYNAMIC %s
44// DYNAMIC: Symbols [
45// DYNAMIC-NOT: Name: _static
46// DYNAMIC: ]
47
48// Should prefer dynamic to static
49// RUN: ld.lld -o %t3 %t.o -L%t.dir -lls
50// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=DYNAMIC %s
51
52// Check for library search order
53// RUN: mkdir -p %t.dir2
54// RUN: cp %t.dir/libls.a %t.dir2
55// RUN: ld.lld -o %t3 %t.o -L%t.dir2 -L%t.dir -lls
56// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=STATIC %s
57
58// -L can be placed after -l
59// RUN: ld.lld -o %t3 %t.o -lls -L%t.dir
60
61// Check long forms as well
62// RUN: ld.lld -o %t3 %t.o --library-path=%t.dir --library=ls
63
64// Should not search for dynamic libraries if -Bstatic is specified
65// RUN: ld.lld -o %t3 %t.o -L%t.dir -Bstatic -lls
66// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=STATIC %s
67// RUN: not ld.lld -o %t3 %t.o -L%t.dir -Bstatic -lls2 2>&1 \
68// RUN: | FileCheck --check-prefix=NOLIB2 %s
69// NOLIB2: unable to find library -lls2
70
71// -Bdynamic should restore default behaviour
72// RUN: ld.lld -o %t3 %t.o -L%t.dir -Bstatic -Bdynamic -lls
73// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=DYNAMIC %s
74
75// -Bstatic and -Bdynamic should affect only libraries which follow them
76// RUN: ld.lld -o %t3 %t.o -L%t.dir -lls -Bstatic -Bdynamic
77// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=DYNAMIC %s
78// RUN: ld.lld -o %t3 %t.o -L%t.dir -Bstatic -lls -Bdynamic
79// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=STATIC %s
80
81// Check aliases as well
82// RUN: ld.lld -o %t3 %t.o -L%t.dir -dn -lls
83// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=STATIC %s
84// RUN: ld.lld -o %t3 %t.o -L%t.dir -non_shared -lls
85// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=STATIC %s
86// RUN: ld.lld -o %t3 %t.o -L%t.dir -static -lls
87// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=STATIC %s
88// RUN: ld.lld -o %t3 %t.o -L%t.dir -Bstatic -dy -lls
89// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=DYNAMIC %s
90// RUN: ld.lld -o %t3 %t.o -L%t.dir -Bstatic -call_shared -lls
91// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=DYNAMIC %s
92
93// -nostdlib
94// RUN: echo 'SEARCH_DIR("'%t.dir'")' > %t.script
95// RUN: ld.lld -o %t3 %t.o -script %t.script -lls
96// RUN: not ld.lld -o %t3 %t.o -script %t.script -lls -nostdlib \
97// RUN: 2>&1 | FileCheck --check-prefix=NOSTDLIB %s
98// NOSTDLIB: unable to find library -lls
99
100.globl _start,_bar
101_start:
deps/lld/test/ELF/linkerscript/Inputs/comdat-gc.s created+5
......@@ -0,0 +1,5 @@
1.file 1 "test/ELF/linkerscript/Inputs/comdat_gc.s"
2
3.section .text._Z3fooIiEvv,"axG",@progbits,_Z3fooIiEvv,comdat
4.loc 1 5
5 ret
deps/lld/test/ELF/linkerscript/Inputs/compress-debug-sections.s created+3
......@@ -0,0 +1,3 @@
1.section .debug_str
2 .asciz "CCC"
3 .asciz "DDD"
deps/lld/test/ELF/linkerscript/Inputs/exclude-multiple1.s created+8
......@@ -0,0 +1,8 @@
1.section .foo.1,"a"
2 .quad 4
3
4.section .foo.2,"a"
5 .quad 5
6
7.section .foo.3,"a"
8 .quad 6
deps/lld/test/ELF/linkerscript/Inputs/exclude-multiple2.s created+8
......@@ -0,0 +1,8 @@
1.section .foo.1,"a"
2 .quad 7
3
4.section .foo.2,"a"
5 .quad 8
6
7.section .foo.3,"a"
8 .quad 9
deps/lld/test/ELF/linkerscript/Inputs/filename-spec.s created+2
......@@ -0,0 +1,2 @@
1.section .foo,"a"
2 .quad 0x11
deps/lld/test/ELF/linkerscript/Inputs/implicit-program-header.script created+12
......@@ -0,0 +1,12 @@
1PHDRS
2{
3 ph_write PT_LOAD FLAGS(2);
4 ph_exec PT_LOAD FLAGS(1);
5}
6
7SECTIONS
8{
9 .bar : { *(.bar) } : ph_exec
10 .foo : { *(.foo) }
11 .text : { *(.text) } : ph_write
12}
deps/lld/test/ELF/linkerscript/Inputs/include.s created+5
......@@ -0,0 +1,5 @@
1.section .text
2.globl _potato
3_potato:
4 nop
5 nop
deps/lld/test/ELF/linkerscript/Inputs/keep.s created+2
......@@ -0,0 +1,2 @@
1.section .keep, "a"
2 .long 0x41414141
deps/lld/test/ELF/linkerscript/Inputs/lazy-symbols.s created+2
......@@ -0,0 +1,2 @@
1.globl foo
2foo:
deps/lld/test/ELF/linkerscript/Inputs/libsearch-dyn.s created+3
......@@ -0,0 +1,3 @@
1.globl _bar,_dynamic
2_bar:
3_dynamic:
deps/lld/test/ELF/linkerscript/Inputs/libsearch-st.s created+3
......@@ -0,0 +1,3 @@
1.globl _bar,_static
2_bar:
3_static:
deps/lld/test/ELF/linkerscript/Inputs/merge-sections-reloc.s created+3
......@@ -0,0 +1,3 @@
1.globl _start
2_start:
3 .quad 0x11223344
deps/lld/test/ELF/linkerscript/Inputs/notinclude.s created+4
......@@ -0,0 +1,4 @@
1.section .text
2.globl tomato
3tomato:
4 movl $1, %eax
deps/lld/test/ELF/linkerscript/Inputs/segment-start.script created+7
......@@ -0,0 +1,7 @@
1SECTIONS
2{
3 PROVIDE (foobar1 = SEGMENT_START("text-segment", 0x8001));
4 PROVIDE (foobar2 = SEGMENT_START("data-segment", 0x8002));
5 PROVIDE (foobar3 = SEGMENT_START("bss-segment", 0x8000 + (4 - 1)));
6 PROVIDE (foobar4 = SEGMENT_START("abc-segment", 0x8004));
7}
deps/lld/test/ELF/linkerscript/Inputs/shared.s created+10
......@@ -0,0 +1,10 @@
1.global bar
2.type bar, @function
3bar:
4
5.global bar2
6.type bar2, @function
7bar2:
8
9.global zed
10zed:
deps/lld/test/ELF/linkerscript/Inputs/sort-nested.s created+7
......@@ -0,0 +1,7 @@
1.section .aaa.1, "a"
2.align 16
3.quad 0x11
4
5.section .aaa.2, "a"
6.align 4
7.quad 0x22
deps/lld/test/ELF/linkerscript/Inputs/sort.s created+19
......@@ -0,0 +1,19 @@
1.section .aaa.5, "a"
2.align 2
3.quad 0x55
4
5.section .aaa.1, "a"
6.align 32
7.quad 0x11
8
9.section .aaa.3, "a"
10.align 8
11.quad 0x33
12
13.section .aaa.2, "a"
14.align 16
15.quad 0x22
16
17.section .aaa.4, "a"
18.align 4
19.quad 0x44
deps/lld/test/ELF/linkerscript/absolute-expr.s created+82
......@@ -0,0 +1,82 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: echo "SECTIONS { \
4# RUN: .text : { \
5# RUN: bar1 = ALIGNOF(.text); \
6# RUN: bar2 = CONSTANT (MAXPAGESIZE); \
7# RUN: bar3 = SIZEOF (.text); \
8# RUN: bar4 = SIZEOF_HEADERS; \
9# RUN: bar5 = 0x42; \
10# RUN: bar6 = foo + 1; \
11# RUN: *(.text) \
12# RUN: } \
13# RUN: };" > %t.script
14# RUN: ld.lld -o %t.so --script %t.script %t.o -shared
15# RUN: llvm-readobj -t %t.so | FileCheck %s
16
17.global foo
18foo = 0x123
19
20# CHECK: Symbol {
21# CHECK: Name: foo
22# CHECK-NEXT: Value: 0x123
23# CHECK-NEXT: Size: 0
24# CHECK-NEXT: Binding: Global
25# CHECK-NEXT: Type: None
26# CHECK-NEXT: Other: 0
27# CHECK-NEXT: Section: Absolute (0xFFF1)
28# CHECK-NEXT: }
29# CHECK-NEXT: Symbol {
30# CHECK-NEXT: Name: bar1
31# CHECK-NEXT: Value: 0x4
32# CHECK-NEXT: Size: 0
33# CHECK-NEXT: Binding: Global
34# CHECK-NEXT: Type: None
35# CHECK-NEXT: Other: 0
36# CHECK-NEXT: Section: Absolute
37# CHECK-NEXT: }
38# CHECK-NEXT: Symbol {
39# CHECK-NEXT: Name: bar2
40# CHECK-NEXT: Value: 0x1000
41# CHECK-NEXT: Size: 0
42# CHECK-NEXT: Binding: Global
43# CHECK-NEXT: Type: None
44# CHECK-NEXT: Other: 0
45# CHECK-NEXT: Section: Absolute
46# CHECK-NEXT: }
47# CHECK-NEXT: Symbol {
48# CHECK-NEXT: Name: bar3
49# CHECK-NEXT: Value: 0x0
50# CHECK-NEXT: Size: 0
51# CHECK-NEXT: Binding: Global
52# CHECK-NEXT: Type: None
53# CHECK-NEXT: Other: 0
54# CHECK-NEXT: Section: Absolute
55# CHECK-NEXT: }
56# CHECK-NEXT: Symbol {
57# CHECK-NEXT: Name: bar4
58# CHECK-NEXT: Value: 0x190
59# CHECK-NEXT: Size: 0
60# CHECK-NEXT: Binding: Global
61# CHECK-NEXT: Type: None
62# CHECK-NEXT: Other: 0
63# CHECK-NEXT: Section: Absolute
64# CHECK-NEXT: }
65# CHECK-NEXT: Symbol {
66# CHECK-NEXT: Name: bar5
67# CHECK-NEXT: Value: 0x42
68# CHECK-NEXT: Size: 0
69# CHECK-NEXT: Binding: Global
70# CHECK-NEXT: Type: None
71# CHECK-NEXT: Other: 0
72# CHECK-NEXT: Section: Absolute
73# CHECK-NEXT: }
74# CHECK-NEXT: Symbol {
75# CHECK-NEXT: Name: bar6
76# CHECK-NEXT: Value: 0x124
77# CHECK-NEXT: Size: 0
78# CHECK-NEXT: Binding: Global (0x1)
79# CHECK-NEXT: Type: None (0x0)
80# CHECK-NEXT: Other: 0
81# CHECK-NEXT: Section: Absolute (0xFFF1)
82# CHECK-NEXT: }
deps/lld/test/ELF/linkerscript/absolute.s created+35
......@@ -0,0 +1,35 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: echo "SECTIONS { foo = ABSOLUTE(.) + 1; };" > %t.script
4# RUN: ld.lld -o %t --script %t.script %t.o
5# RUN: llvm-readobj --symbols %t | FileCheck %s
6
7# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
8# RUN: echo "PROVIDE(foo = 1 + ABSOLUTE(ADDR(.text)));" > %t.script
9# RUN: ld.lld -o %t --script %t.script %t.o
10# RUN: llvm-readobj --symbols %t | FileCheck --check-prefix=CHECK-RHS %s
11
12# CHECK: Name: foo
13# CHECK-NEXT: Value:
14# CHECK-NEXT: Size:
15# CHECK-NEXT: Binding:
16# CHECK-NEXT: Type:
17# CHECK-NEXT: Other:
18# CHECK-NEXT: Section: Absolute
19# CHECK-NEXT: }
20
21# CHECK-RHS: Name: foo
22# CHECK-RHS-NEXT: Value: 0x201001
23# CHECK-RHS-NEXT: Size:
24# CHECK-RHS-NEXT: Binding:
25# CHECK-RHS-NEXT: Type:
26# CHECK-RHS-NEXT: Other:
27# CHECK-RHS-NEXT: Section: Absolute
28# CHECK-RHS-NEXT: }
29
30.text
31.globl _start
32_start:
33 nop
34
35.global foo
deps/lld/test/ELF/linkerscript/addr-zero.s created+18
......@@ -0,0 +1,18 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: echo "SECTIONS { foo = ADDR(.text) - ABSOLUTE(ADDR(.text)); };" > %t.script
4# RUN: ld.lld -o %t.so --script %t.script %t.o -shared
5# RUN: llvm-readobj --symbols %t.so | FileCheck %s
6
7# Test that the script creates a non absolute symbol with value
8# 0 I.E., a symbol that refers to the load address.
9
10# CHECK: Symbol {
11# CHECK: Name: foo
12# CHECK-NEXT: Value: 0x0
13# CHECK-NEXT: Size: 0
14# CHECK-NEXT: Binding: Global
15# CHECK-NEXT: Type: None
16# CHECK-NEXT: Other: 0
17# CHECK-NEXT: Section: .text
18# CHECK-NEXT: }
deps/lld/test/ELF/linkerscript/addr.s created+32
......@@ -0,0 +1,32 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: echo "SECTIONS { \
4# RUN: . = 0x1000; \
5# RUN: .text : { *(.text*) } \
6# RUN: .foo.1 : { *(.foo.1) } \
7# RUN: .foo.2 ADDR(.foo.1) + 0x100 : { *(.foo.2) } \
8# RUN: .foo.3 : { *(.foo.3) } \
9# RUN: }" > %t.script
10# RUN: ld.lld %t --script %t.script -o %t1
11# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
12
13# CHECK: Sections:
14# CHECK-NEXT: Idx Name Size Address Type
15# CHECK-NEXT: 0 00000000 0000000000000000
16# CHECK-NEXT: 1 .text 00000000 0000000000001000 TEXT DATA
17# CHECK-NEXT: 2 .foo.1 00000008 0000000000001000 DATA
18# CHECK-NEXT: 3 .foo.2 00000008 0000000000001100 DATA
19# CHECK-NEXT: 4 .foo.3 00000008 0000000000001108 DATA
20
21.text
22.globl _start
23_start:
24
25.section .foo.1,"a"
26 .quad 1
27
28.section .foo.2,"a"
29 .quad 2
30
31.section .foo.3,"a"
32 .quad 3
deps/lld/test/ELF/linkerscript/align-empty.s created+18
......@@ -0,0 +1,18 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4# RUN: echo "SECTIONS { \
5# RUN: . = SIZEOF_HEADERS; \
6# RUN: abc : { } \
7# RUN: . = ALIGN(0x1000); \
8# RUN: foo : { *(foo) } \
9# RUN: }" > %t.script
10# RUN: ld.lld -o %t1 --script %t.script %t -shared
11# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
12# CHECK: Sections:
13# CHECK-NEXT: Idx Name Size Address
14# CHECK-NEXT: 0 00000000 0000000000000000
15# CHECK-NEXT: 1 foo 00000001 0000000000001000
16
17 .section foo, "a"
18 .byte 0
deps/lld/test/ELF/linkerscript/align.s created+80
......@@ -0,0 +1,80 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4## Check that ALIGN command workable using location counter
5# RUN: echo "SECTIONS { \
6# RUN: . = 0x10000; \
7# RUN: .aaa : { *(.aaa) } \
8# RUN: . = ALIGN(4096); \
9# RUN: .bbb : { *(.bbb) } \
10# RUN: . = ALIGN(4096 * 4); \
11# RUN: .ccc : { *(.ccc) } \
12# RUN: }" > %t.script
13# RUN: ld.lld -o %t1 --script %t.script %t
14# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
15
16## Check that the two argument version of ALIGN command works
17# RUN: echo "SECTIONS { \
18# RUN: . = ALIGN(0x1234, 0x10000); \
19# RUN: .aaa : { *(.aaa) } \
20# RUN: . = ALIGN(., 4096); \
21# RUN: .bbb : { *(.bbb) } \
22# RUN: . = ALIGN(., 4096 * 4); \
23# RUN: .ccc : { *(.ccc) } \
24# RUN: }" > %t.script
25# RUN: ld.lld -o %t1 --script %t.script %t
26# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
27
28# CHECK: Sections:
29# CHECK-NEXT: Idx Name Size Address Type
30# CHECK-NEXT: 0 00000000 0000000000000000
31# CHECK-NEXT: 1 .aaa 00000008 0000000000010000 DATA
32# CHECK-NEXT: 2 .bbb 00000008 0000000000011000 DATA
33# CHECK-NEXT: 3 .ccc 00000008 0000000000014000 DATA
34
35## Check output sections ALIGN modificator
36# RUN: echo "SECTIONS { \
37# RUN: . = 0x10000; \
38# RUN: .aaa : { *(.aaa) } \
39# RUN: .bbb : ALIGN(4096) { *(.bbb) } \
40# RUN: .ccc : ALIGN(4096 * 4) { *(.ccc) } \
41# RUN: }" > %t2.script
42# RUN: ld.lld -o %t2 --script %t2.script %t
43# RUN: llvm-objdump -section-headers %t2 | FileCheck %s
44
45## Check use of variables in align expressions:
46# RUN: echo "VAR = 0x1000; \
47# RUN: __code_base__ = 0x10000; \
48# RUN: SECTIONS { \
49# RUN: . = __code_base__; \
50# RUN: .aaa : { *(.aaa) } \
51# RUN: .bbb : ALIGN(VAR) { *(.bbb) } \
52# RUN: . = ALIGN(., VAR * 4); \
53# RUN: .ccc : { *(.ccc) } \
54# RUN: __start_bbb = ADDR(.bbb); \
55# RUN: __end_bbb = ALIGN(__start_bbb + SIZEOF(.bbb), VAR); \
56# RUN: }" > %t3.script
57# RUN: ld.lld -o %t3 --script %t3.script %t
58# RUN: llvm-objdump -section-headers %t3 | FileCheck %s
59# RUN: llvm-objdump -t %t3 | FileCheck -check-prefix SYMBOLS %s
60
61# SYMBOLS-LABEL: SYMBOL TABLE:
62# SYMBOLS-NEXT: 0000000000000000 *UND* 00000000
63# SYMBOLS-NEXT: 0000000000014008 .text 00000000 _start
64# SYMBOLS-NEXT: 0000000000010000 *ABS* 00000000 __code_base__
65# SYMBOLS-NEXT: 0000000000001000 *ABS* 00000000 VAR
66# SYMBOLS-NEXT: 0000000000011000 .bbb 00000000 __start_bbb
67# SYMBOLS-NEXT: 0000000000012000 .bbb 00000000 __end_bbb
68
69.global _start
70_start:
71 nop
72
73.section .aaa, "a"
74.quad 0
75
76.section .bbb, "a"
77.quad 0
78
79.section .ccc, "a"
80.quad 0
deps/lld/test/ELF/linkerscript/alignof.s created+41
......@@ -0,0 +1,41 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4# RUN: echo "SECTIONS { \
5# RUN: .aaa : { *(.aaa) } \
6# RUN: .bbb : { *(.bbb) } \
7# RUN: .ccc : { *(.ccc) } \
8# RUN: _aaa = ALIGNOF(.aaa); \
9# RUN: _bbb = ALIGNOF(.bbb); \
10# RUN: _ccc = ALIGNOF(.ccc); \
11# RUN: }" > %t.script
12# RUN: ld.lld -o %t1 --script %t.script %t
13# RUN: llvm-objdump -t %t1 | FileCheck %s
14# CHECK: SYMBOL TABLE:
15# CHECK: 0000000000000008 *ABS* 00000000 _aaa
16# CHECK-NEXT: 0000000000000010 *ABS* 00000000 _bbb
17# CHECK-NEXT: 0000000000000020 *ABS* 00000000 _ccc
18
19## Check that we error out if trying to get alignment of
20## section that does not exist.
21# RUN: echo "SECTIONS { \
22# RUN: _aaa = ALIGNOF(.foo); \
23# RUN: }" > %t.script
24# RUN: not ld.lld -o %t1 --script %t.script %t 2>&1 \
25# RUN: | FileCheck -check-prefix=ERR %s
26# ERR: {{.*}}.script:1: undefined section .foo
27.global _start
28_start:
29 nop
30
31.section .aaa,"a"
32 .align 8
33 .quad 0
34
35.section .bbb,"a"
36 .align 16
37 .quad 0
38
39.section .ccc,"a"
40 .align 32
41 .quad 0
deps/lld/test/ELF/linkerscript/alternate-sections.s created+36
......@@ -0,0 +1,36 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: echo "SECTIONS { abc : { *(foo) *(bar) *(zed) } }" > %t.script
4# RUN: ld.lld -o %t --script %t.script %t.o -shared
5# RUN: llvm-readobj -s -section-data %t | FileCheck %s
6
7# CHECK: Section {
8# CHECK: Index:
9# CHECK: Name: abc
10# CHECK-NEXT: Type: SHT_PROGBIT
11# CHECK-NEXT: Flags [
12# CHECK-NEXT: SHF_ALLOC
13# CHECK-NEXT: SHF_MERGE
14# CHECK-NEXT: SHF_STRINGS
15# CHECK-NEXT: ]
16# CHECK-NEXT: Address:
17# CHECK-NEXT: Offset:
18# CHECK-NEXT: Size:
19# CHECK-NEXT: Link:
20# CHECK-NEXT: Info:
21# CHECK-NEXT: AddressAlignment:
22# CHECK-NEXT: EntrySize:
23# CHECK-NEXT: SectionData (
24# CHECK-NEXT: 0000: 01000000 00000000 61626331 32330002 |........abc123..|
25# CHECK-NEXT: 0010: 00000000 000000 |.......|
26# CHECK-NEXT: )
27# CHECK-NEXT: }
28
29 .section foo, "a"
30 .quad 1
31
32 .section bar,"aMS",@progbits,1
33 .asciz "abc123"
34
35 .section zed, "a"
36 .quad 2
deps/lld/test/ELF/linkerscript/arm-exidx-phdrs.s created+16
......@@ -0,0 +1,16 @@
1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
3// RUN: echo "PHDRS { ph_text PT_LOAD; } \
4// RUN: SECTIONS { \
5// RUN: . = SIZEOF_HEADERS; \
6// RUN: .text : { *(.text) } : ph_text \
7// RUN: }" > %t.script
8// RUN: ld.lld -T %t.script %t.o -shared -o %t.so
9// RUN: llvm-readobj --program-headers %t.so | FileCheck %s
10
11// CHECK: Type: PT_ARM_EXIDX
12
13.fnstart
14bx lr
15.cantunwind
16.fnend
deps/lld/test/ELF/linkerscript/arm-lscript.s created+9
......@@ -0,0 +1,9 @@
1// REQUIRES: arm
2// RUN: llvm-mc -filetype=obj -triple=armv7a-none-linux-gnueabi %s -o %t.o
3// RUN: echo "SECTIONS { \
4// RUN: .rel.dyn : { } \
5// RUN: .zed : { PROVIDE_HIDDEN (foobar = .); } \
6// RUN: }" > %t.script
7// This is a test case for PR33029. Making sure that linker can digest
8// the above script without dumping core.
9// RUN: ld.lld -emit-relocs -T %t.script %t.o -shared -o %t.so
deps/lld/test/ELF/linkerscript/assert.s created+39
......@@ -0,0 +1,39 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
3
4# RUN: echo "SECTIONS { ASSERT(1, fail) }" > %t1.script
5# RUN: ld.lld -shared -o %t1 --script %t1.script %t1.o
6# RUN: llvm-readobj %t1 > /dev/null
7
8# RUN: echo "SECTIONS { ASSERT(0, fail) }" > %t3.script
9# RUN: not ld.lld -shared -o %t3 --script %t3.script %t1.o > %t.log 2>&1
10# RUN: FileCheck %s -check-prefix=FAIL < %t.log
11# FAIL: fail
12
13# RUN: echo "SECTIONS { . = ASSERT(0x1000, fail); }" > %t4.script
14# RUN: ld.lld -shared -o %t4 --script %t4.script %t1.o
15# RUN: llvm-readobj %t4 > /dev/null
16
17# RUN: echo "SECTIONS { .foo : { *(.foo) } }" > %t5.script
18# RUN: echo "ASSERT(SIZEOF(.foo) == 8, fail);" >> %t5.script
19# RUN: ld.lld -shared -o %t5 --script %t5.script %t1.o
20# RUN: llvm-readobj %t5 > /dev/null
21
22## Even without SECTIONS block we still use section names
23## in expressions
24# RUN: echo "ASSERT(SIZEOF(.foo) == 8, fail);" > %t5.script
25# RUN: ld.lld -shared -o %t5 --script %t5.script %t1.o
26# RUN: llvm-readobj %t5 > /dev/null
27
28## Test assertions inside of output section decriptions.
29# RUN: echo "SECTIONS { .foo : { *(.foo) ASSERT(SIZEOF(.foo) == 8, \"true\"); } }" > %t6.script
30# RUN: ld.lld -shared -o %t6 --script %t6.script %t1.o
31# RUN: llvm-readobj %t6 > /dev/null
32
33# RUN: echo "SECTIONS { .foo : { ASSERT(1, \"true\") } }" > %t7.script
34# RUN: not ld.lld -shared -o %t7 --script %t7.script %t1.o > %t.log 2>&1
35# RUN: FileCheck %s -check-prefix=CHECK-SEMI < %t.log
36# CHECK-SEMI: error: {{.*}}.script:1: ; expected, but got }
37
38.section .foo, "a"
39 .quad 0
deps/lld/test/ELF/linkerscript/at-addr.s created+39
......@@ -0,0 +1,39 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: echo "SECTIONS { . = 0x1000; \
4# RUN: .aaa : AT(ADDR(.aaa) - 0x500) { *(.aaa) } \
5# RUN: .bbb : AT(ADDR(.bbb) - 0x500) { *(.bbb) } \
6# RUN: .ccc : AT(ADDR(.ccc) - 0x500) { *(.ccc) } \
7# RUN: }" > %t.script
8# RUN: ld.lld %t --script %t.script -o %t2
9# RUN: llvm-readobj -program-headers %t2 | FileCheck %s
10
11# CHECK: Type: PT_LOAD
12# CHECK-NEXT: Offset: 0x0
13# CHECK-NEXT: VirtualAddress: 0x0
14# CHECK-NEXT: PhysicalAddress: 0x0
15# CHECK: Type: PT_LOAD
16# CHECK-NEXT: Offset: 0x1000
17# CHECK-NEXT: VirtualAddress: 0x1000
18# CHECK-NEXT: PhysicalAddress: 0xB00
19# CHECK: Type: PT_LOAD
20# CHECK-NEXT: Offset: 0x1008
21# CHECK-NEXT: VirtualAddress: 0x1008
22# CHECK-NEXT: PhysicalAddress: 0xB08
23# CHECK: Type: PT_LOAD
24# CHECK-NEXT: Offset: 0x1010
25# CHECK-NEXT: VirtualAddress: 0x1010
26# CHECK-NEXT: PhysicalAddress: 0xB10
27
28.global _start
29_start:
30 nop
31
32.section .aaa, "a"
33.quad 0
34
35.section .bbb, "a"
36.quad 0
37
38.section .ccc, "a"
39.quad 0
deps/lld/test/ELF/linkerscript/at.s created+124
......@@ -0,0 +1,124 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: echo "SECTIONS { \
4# RUN: . = 0x1000; \
5# RUN: .aaa : AT(0x2000) { *(.aaa) } \
6# RUN: .bbb : { *(.bbb) } \
7# RUN: .ccc : AT(0x3000) { *(.ccc) } \
8# RUN: .ddd : AT(0x4000) { *(.ddd) } \
9# RUN: .eee 0x5000 : AT(0x5000) { *(.eee) } \
10# RUN: }" > %t.script
11# RUN: ld.lld %t --script %t.script -o %t2
12# RUN: llvm-readobj -program-headers %t2 | FileCheck %s
13
14# CHECK: ProgramHeaders [
15# CHECK-NEXT: ProgramHeader {
16# CHECK-NEXT: Type: PT_PHDR
17# CHECK-NEXT: Offset: 0x40
18# CHECK-NEXT: VirtualAddress: 0x40
19# CHECK-NEXT: PhysicalAddress: 0x40
20# CHECK-NEXT: FileSize:
21# CHECK-NEXT: MemSize:
22# CHECK-NEXT: Flags [
23# CHECK-NEXT: PF_R
24# CHECK-NEXT: ]
25# CHECK-NEXT: Alignment: 8
26# CHECK-NEXT: }
27# CHECK-NEXT: ProgramHeader {
28# CHECK-NEXT: Type: PT_LOAD
29# CHECK-NEXT: Offset: 0x0
30# CHECK-NEXT: VirtualAddress: 0x0
31# CHECK-NEXT: PhysicalAddress: 0x0
32# CHECK-NEXT: FileSize:
33# CHECK-NEXT: MemSize:
34# CHECK-NEXT: Flags [
35# CHECK-NEXT: PF_R
36# CHECK-NEXT: PF_X
37# CHECK-NEXT: ]
38# CHECK-NEXT: Alignment:
39# CHECK-NEXT: }
40# CHECK-NEXT: ProgramHeader {
41# CHECK-NEXT: Type: PT_LOAD
42# CHECK-NEXT: Offset: 0x1000
43# CHECK-NEXT: VirtualAddress: 0x1000
44# CHECK-NEXT: PhysicalAddress: 0x2000
45# CHECK-NEXT: FileSize: 16
46# CHECK-NEXT: MemSize: 16
47# CHECK-NEXT: Flags [
48# CHECK-NEXT: PF_R
49# CHECK-NEXT: PF_X
50# CHECK-NEXT: ]
51# CHECK-NEXT: Alignment:
52# CHECK-NEXT: }
53# CHECK-NEXT: ProgramHeader {
54# CHECK-NEXT: Type: PT_LOAD
55# CHECK-NEXT: Offset: 0x1010
56# CHECK-NEXT: VirtualAddress: 0x1010
57# CHECK-NEXT: PhysicalAddress: 0x3000
58# CHECK-NEXT: FileSize: 8
59# CHECK-NEXT: MemSize: 8
60# CHECK-NEXT: Flags [
61# CHECK-NEXT: PF_R
62# CHECK-NEXT: PF_X
63# CHECK-NEXT: ]
64# CHECK-NEXT: Alignment: 4096
65# CHECK-NEXT: }
66# CHECK-NEXT: ProgramHeader {
67# CHECK-NEXT: Type: PT_LOAD
68# CHECK-NEXT: Offset: 0x1018
69# CHECK-NEXT: VirtualAddress: 0x1018
70# CHECK-NEXT: PhysicalAddress: 0x4000
71# CHECK-NEXT: FileSize: 8
72# CHECK-NEXT: MemSize: 8
73# CHECK-NEXT: Flags [
74# CHECK-NEXT: PF_R
75# CHECK-NEXT: PF_X
76# CHECK-NEXT: ]
77# CHECK-NEXT: Alignment: 4096
78# CHECK-NEXT: }
79# CHECK-NEXT: ProgramHeader {
80# CHECK-NEXT: Type: PT_LOAD
81# CHECK-NEXT: Offset: 0x2000
82# CHECK-NEXT: VirtualAddress: 0x5000
83# CHECK-NEXT: PhysicalAddress: 0x5000
84# CHECK-NEXT: FileSize: 9
85# CHECK-NEXT: MemSize: 9
86# CHECK-NEXT: Flags [
87# CHECK-NEXT: PF_R
88# CHECK-NEXT: PF_X
89# CHECK-NEXT: ]
90# CHECK-NEXT: Alignment: 4096
91# CHECK-NEXT: }
92# CHECK-NEXT: ProgramHeader {
93# CHECK-NEXT: Type: PT_GNU_STACK
94# CHECK-NEXT: Offset:
95# CHECK-NEXT: VirtualAddress: 0x0
96# CHECK-NEXT: PhysicalAddress: 0x0
97# CHECK-NEXT: FileSize:
98# CHECK-NEXT: MemSize:
99# CHECK-NEXT: Flags [
100# CHECK-NEXT: PF_R
101# CHECK-NEXT: PF_W
102# CHECK-NEXT: ]
103# CHECK-NEXT: Alignment: 0
104# CHECK-NEXT: }
105# CHECK-NEXT: ]
106
107.global _start
108_start:
109 nop
110
111.section .aaa, "a"
112.quad 0
113
114.section .bbb, "a"
115.quad 0
116
117.section .ccc, "a"
118.quad 0
119
120.section .ddd, "a"
121.quad 0
122
123.section .eee, "a"
124.quad 0
deps/lld/test/ELF/linkerscript/bss-fill.s created+7
......@@ -0,0 +1,7 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: echo "SECTIONS { .bss : { . += 0x10000; *(.bss) } =0xFF };" > %t.script
4# RUN: ld.lld -o %t --script %t.script %t.o
5
6.section .bss,"",@nobits
7.short 0
deps/lld/test/ELF/linkerscript/comdat-gc.s created+14
......@@ -0,0 +1,14 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/comdat-gc.s -o %t1
5# RUN: echo "SECTIONS { .text : { *(.text*) } }" > %t.script
6# RUN: ld.lld --gc-sections --script %t.script %t %t1 -o %t2
7# RUN: llvm-readobj -sections -symbols %t2 | FileCheck -check-prefix=GC1 %s
8
9# GC1: Name: .debug_line
10
11.file 1 "test/ELF/linkerscript/comdat_gc.s"
12.section .text._Z3fooIiEvv,"axG",@progbits,_Z3fooIiEvv,comdat
13.loc 1 14
14 ret
deps/lld/test/ELF/linkerscript/common-assign.s created+48
......@@ -0,0 +1,48 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: echo "SECTIONS { . = SIZEOF_HEADERS; pfoo = foo; pbar = bar; }" > %t.script
4# RUN: ld.lld -o %t1 --script %t.script %t
5# RUN: llvm-readobj -symbols %t1 | FileCheck %s
6
7# CHECK: Symbol {
8# CHECK: Name: bar
9# CHECK-NEXT: Value: 0x134
10# CHECK-NEXT: Size: 4
11# CHECK-NEXT: Binding: Global
12# CHECK-NEXT: Type: Object
13# CHECK-NEXT: Other: 0
14# CHECK-NEXT: Section: .bss
15# CHECK-NEXT: }
16# CHECK-NEXT: Symbol {
17# CHECK-NEXT: Name: foo
18# CHECK-NEXT: Value: 0x138
19# CHECK-NEXT: Size: 4
20# CHECK-NEXT: Binding: Global
21# CHECK-NEXT: Type: Object
22# CHECK-NEXT: Other: 0
23# CHECK-NEXT: Section: .bss
24# CHECK-NEXT: }
25# CHECK-NEXT: Symbol {
26# CHECK-NEXT: Name: pfoo
27# CHECK-NEXT: Value: 0x138
28# CHECK-NEXT: Size: 0
29# CHECK-NEXT: Binding: Global
30# CHECK-NEXT: Type: None
31# CHECK-NEXT: Other: 0
32# CHECK-NEXT: Section: .bss
33# CHECK-NEXT: }
34# CHECK-NEXT: Symbol {
35# CHECK-NEXT: Name: pbar
36# CHECK-NEXT: Value: 0x134
37# CHECK-NEXT: Size: 0
38# CHECK-NEXT: Binding: Global
39# CHECK-NEXT: Type: None
40# CHECK-NEXT: Other: 0
41# CHECK-NEXT: Section: .bss
42# CHECK-NEXT: }
43# CHECK-NEXT: ]
44
45.comm foo,4,4
46.comm bar,4,4
47movl $1, foo(%rip)
48movl $2, bar(%rip)
deps/lld/test/ELF/linkerscript/common.s created+49
......@@ -0,0 +1,49 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: echo "SECTIONS { . = SIZEOF_HEADERS; .common : { *(COMMON) } }" > %t.script
4# RUN: ld.lld -o %t1 --script %t.script %t
5# RUN: llvm-readobj -s -t %t1 | FileCheck %s
6
7# q2 alignment is greater than q1, so it should have smaller offset
8# because of sorting
9# CHECK: Section {
10# CHECK: Index:
11# CHECK: Name: .common
12# CHECK-NEXT: Type: SHT_NOBITS
13# CHECK-NEXT: Flags [
14# CHECK-NEXT: SHF_ALLOC
15# CHECK-NEXT: SHF_WRITE
16# CHECK-NEXT: ]
17# CHECK-NEXT: Address: 0x200
18# CHECK-NEXT: Offset: 0x
19# CHECK-NEXT: Size: 256
20# CHECK-NEXT: Link: 0
21# CHECK-NEXT: Info: 0
22# CHECK-NEXT: AddressAlignment: 256
23# CHECK-NEXT: EntrySize: 0
24# CHECK-NEXT: }
25# CHECK: Symbol {
26# CHECK: Name: q1
27# CHECK-NEXT: Value: 0x280
28# CHECK-NEXT: Size: 128
29# CHECK-NEXT: Binding: Global
30# CHECK-NEXT: Type: Object
31# CHECK-NEXT: Other: 0
32# CHECK-NEXT: Section: .common
33# CHECK-NEXT: }
34# CHECK-NEXT: Symbol {
35# CHECK-NEXT: Name: q2
36# CHECK-NEXT: Value: 0x200
37# CHECK-NEXT: Size: 128
38# CHECK-NEXT: Binding: Global
39# CHECK-NEXT: Type: Object
40# CHECK-NEXT: Other: 0
41# CHECK-NEXT: Section: .common
42# CHECK-NEXT: }
43
44.globl _start
45_start:
46 jmp _start
47
48.comm q1,128,8
49.comm q2,128,256
deps/lld/test/ELF/linkerscript/compress-debug-sections.s created+36
......@@ -0,0 +1,36 @@
1# REQUIRES: x86, zlib
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
4# RUN: %S/Inputs/compress-debug-sections.s -o %t1.o
5# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2.o
6
7## .debug_str section is mergeable. LLD would combine all of them into single
8## mergeable synthetic section. We use -O0 here to disable merging, that
9## allows to check that input sections has correctly assigned offsets.
10
11# RUN: echo "SECTIONS { }" > %t.script
12# RUN: ld.lld -O0 %t1.o %t2.o %t.script -o %t1 --compress-debug-sections=zlib
13# RUN: llvm-dwarfdump %t1 | FileCheck %s
14# RUN: llvm-readobj -s %t1 | FileCheck %s --check-prefix=ZLIBFLAGS
15
16# RUN: echo "SECTIONS { .debug_str 0 : { *(.debug_str) } }" > %t2.script
17# RUN: ld.lld -O0 %t1.o %t2.o %t2.script -o %t2 --compress-debug-sections=zlib
18# RUN: llvm-dwarfdump %t2 | FileCheck %s
19# RUN: llvm-readobj -s %t2 | FileCheck %s --check-prefix=ZLIBFLAGS
20
21# CHECK: .debug_str contents:
22# CHECK-NEXT: CCC
23# CHECK-NEXT: DDD
24# CHECK-NEXT: AAA
25# CHECK-NEXT: BBB
26
27# ZLIBFLAGS: Section {
28# ZLIBFLAGS: Index:
29# ZLIBFLAGS: Name: .debug_str
30# ZLIBFLAGS-NEXT: Type: SHT_PROGBITS
31# ZLIBFLAGS-NEXT: Flags [
32# ZLIBFLAGS-NEXT: SHF_COMPRESSED
33
34.section .debug_str
35 .asciz "AAA"
36 .asciz "BBB"
deps/lld/test/ELF/linkerscript/constructor.s created+13
......@@ -0,0 +1,13 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: echo "SECTIONS { foo : { *(.foo) CONSTRUCTORS } }" > %t.script
4# RUN: ld.lld -o %t1 --script %t.script %t.o
5
6# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
7# CHECK: Sections:
8# CHECK-NEXT: Idx Name Size
9# CHECK-NEXT: 0 00000000
10# CHECK-NEXT: 1 foo 00000001
11
12.section foo, "a"
13.byte 0
deps/lld/test/ELF/linkerscript/data-commands-gc.s created+17
......@@ -0,0 +1,17 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: echo "SECTIONS { .text : { *(.text*) QUAD(bar) } }" > %t.script
4# RUN: ld.lld --gc-sections -o %t %t.o --script %t.script
5# RUN: llvm-objdump -t %t | FileCheck %s
6
7# CHECK: 0000000000000011 .rodata 00000000 bar
8
9.section .rodata.bar
10.quad 0x1122334455667788
11.global bar
12bar:
13
14.section .text
15.global _start
16_start:
17 nop
deps/lld/test/ELF/linkerscript/data-commands.s created+81
......@@ -0,0 +1,81 @@
1# REQUIRES: x86,mips
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: echo "SECTIONS \
4# RUN: { \
5# RUN: .foo : { \
6# RUN: *(.foo.1) \
7# RUN: BYTE(0x11) \
8# RUN: *(.foo.2) \
9# RUN: SHORT(0x1122) \
10# RUN: *(.foo.3) \
11# RUN: LONG(0x11223344) \
12# RUN: *(.foo.4) \
13# RUN: QUAD(0x1122334455667788) \
14# RUN: } \
15# RUN: .bar : { \
16# RUN: *(.bar.1) \
17# RUN: BYTE(a + 1) \
18# RUN: *(.bar.2) \
19# RUN: SHORT(b) \
20# RUN: *(.bar.3) \
21# RUN: LONG(c + 2) \
22# RUN: *(.bar.4) \
23# RUN: QUAD(d) \
24# RUN: } \
25# RUN: }" > %t.script
26# RUN: ld.lld -o %t %t.o --script %t.script
27# RUN: llvm-objdump -s %t | FileCheck %s
28
29# CHECK: Contents of section .foo:
30# CHECK-NEXT: ff11ff22 11ff4433 2211ff88 77665544
31# CHECK-NEXT: 332211
32
33# CHECK: Contents of section .bar:
34# CHECK-NEXT: ff12ff22 11ff4633 2211ff88 77665544
35# CHECK-NEXT: 332211
36
37# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %tmips64be
38# RUN: ld.lld --script %t.script %tmips64be -o %t2
39# RUN: llvm-objdump -s %t2 | FileCheck %s --check-prefix=BE
40# BE: Contents of section .foo:
41# BE-NEXT: ff11ff11 22ff1122 3344ff11 22334455
42# BE-NEXT: 667788
43# BE-NEXT: Contents of section .bar:
44# BE-NEXT: ff12ff11 22ff1122 3346ff11 22334455
45# BE-NEXT: 667788
46
47.global a
48a = 0x11
49
50.global b
51b = 0x1122
52
53.global c
54c = 0x11223344
55
56.global d
57d = 0x1122334455667788
58
59.section .foo.1, "a"
60 .byte 0xFF
61
62.section .foo.2, "a"
63 .byte 0xFF
64
65.section .foo.3, "a"
66 .byte 0xFF
67
68.section .foo.4, "a"
69 .byte 0xFF
70
71.section .bar.1, "a"
72 .byte 0xFF
73
74.section .bar.2, "a"
75 .byte 0xFF
76
77.section .bar.3, "a"
78 .byte 0xFF
79
80.section .bar.4, "a"
81 .byte 0xFF
deps/lld/test/ELF/linkerscript/data-segment-relro.s created+70
......@@ -0,0 +1,70 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o
4# RUN: ld.lld -shared %t2.o -o %t2.so
5
6# RUN: echo "SECTIONS { \
7# RUN: . = SIZEOF_HEADERS; \
8# RUN: .plt : { *(.plt) } \
9# RUN: .text : { *(.text) } \
10# RUN: . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE)); \
11# RUN: .dynamic : { *(.dynamic) } \
12# RUN: .got : { *(.got) } \
13# RUN: . = DATA_SEGMENT_RELRO_END (1 ? 24 : 0, .); \
14# RUN: .got.plt : { *(.got.plt) } \
15# RUN: .data : { *(.data) } \
16# RUN: .bss : { *(.bss) } \
17# RUN: . = DATA_SEGMENT_END (.); \
18# RUN: }" > %t.script
19
20## With relro or without DATA_SEGMENT_RELRO_END just aligns to
21## page boundary.
22# RUN: ld.lld -z norelro %t1.o %t2.so --script %t.script -o %t
23# RUN: llvm-readobj -s %t | FileCheck %s
24# RUN: ld.lld -z relro %t1.o %t2.so --script %t.script -o %t2
25# RUN: llvm-readobj -s %t2 | FileCheck %s
26
27# CHECK: Section {
28# CHECK: Index:
29# CHECK: Name: .got
30# CHECK-NEXT: Type: SHT_PROGBITS
31# CHECK-NEXT: Flags [
32# CHECK-NEXT: SHF_ALLOC
33# CHECK-NEXT: SHF_WRITE
34# CHECK-NEXT: ]
35# CHECK-NEXT: Address: 0x10F0
36# CHECK-NEXT: Offset: 0x10F0
37# CHECK-NEXT: Size:
38# CHECK-NEXT: Link:
39# CHECK-NEXT: Info:
40# CHECK-NEXT: AddressAlignment:
41# CHECK-NEXT: EntrySize:
42# CHECK-NEXT: }
43# CHECK-NEXT: Section {
44# CHECK-NEXT: Index:
45# CHECK-NEXT: Name: .got.plt
46# CHECK-NEXT: Type: SHT_PROGBITS
47# CHECK-NEXT: Flags [
48# CHECK-NEXT: SHF_ALLOC
49# CHECK-NEXT: SHF_WRITE
50# CHECK-NEXT: ]
51# CHECK-NEXT: Address: 0x2000
52# CHECK-NEXT: Offset: 0x2000
53# CHECK-NEXT: Size:
54# CHECK-NEXT: Link:
55# CHECK-NEXT: Info:
56# CHECK-NEXT: AddressAlignment:
57# CHECK-NEXT: EntrySize:
58# CHECK-NEXT: }
59
60.global _start
61_start:
62 .long bar
63 jmp *bar2@GOTPCREL(%rip)
64
65.section .data,"aw"
66.quad 0
67
68.zero 4
69.section .foo,"aw"
70.section .bss,"",@nobits
deps/lld/test/ELF/linkerscript/define.s created+25
......@@ -0,0 +1,25 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4# RUN: echo "SECTIONS \
5# RUN: { \
6# RUN: . = DEFINED(defined) ? 0x11000 : .; \
7# RUN: .foo : { *(.foo*) } \
8# RUN: . = DEFINED(notdefined) ? 0x12000 : 0x13000; \
9# RUN: .bar : { *(.bar*) } \
10# RUN: }" > %t.script
11# RUN: ld.lld -o %t1 --script %t.script %t
12# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
13
14# CHECK: 1 .foo 00000008 0000000000011000 DATA
15# CHECK: 2 .bar 00000008 0000000000013000 DATA
16# CHECK: 3 .text 00000000 0000000000013008 TEXT DATA
17
18.global defined
19defined = 0
20
21.section .foo,"a"
22.quad 1
23
24.section .bar,"a"
25.quad 1
deps/lld/test/ELF/linkerscript/diagnostic.s created+106
......@@ -0,0 +1,106 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4## Take some valid script with multiline comments
5## and check it actually works:
6# RUN: echo "SECTIONS {" > %t.script
7# RUN: echo ".text : { *(.text) }" >> %t.script
8# RUN: echo ".keep : { *(.keep) } /*" >> %t.script
9# RUN: echo "comment line 1" >> %t.script
10# RUN: echo "comment line 2 */" >> %t.script
11# RUN: echo ".temp : { *(.temp) } }" >> %t.script
12# RUN: ld.lld -shared %t -o %t1 --script %t.script
13
14## Change ":" to "+" at line 2, check that error
15## message starts from correct line number:
16# RUN: echo "SECTIONS {" > %t.script
17# RUN: echo ".text + { *(.text) }" >> %t.script
18# RUN: echo ".keep : { *(.keep) } /*" >> %t.script
19# RUN: echo "comment line 1" >> %t.script
20# RUN: echo "comment line 2 */" >> %t.script
21# RUN: echo ".temp : { *(.temp) } }" >> %t.script
22# RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | FileCheck -check-prefix=ERR1 %s
23# ERR1: {{.*}}.script:2:
24
25## Change ":" to "+" at line 3 now, check correct error line number:
26# RUN: echo "SECTIONS {" > %t.script
27# RUN: echo ".text : { *(.text) }" >> %t.script
28# RUN: echo ".keep + { *(.keep) } /*" >> %t.script
29# RUN: echo "comment line 1" >> %t.script
30# RUN: echo "comment line 2 */" >> %t.script
31# RUN: echo ".temp : { *(.temp) } }" >> %t.script
32# RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | FileCheck -check-prefix=ERR2 %s
33# ERR2: {{.*}}.script:3:
34
35## Change ":" to "+" at line 6, after multiline comment,
36## check correct error line number:
37# RUN: echo "SECTIONS {" > %t.script
38# RUN: echo ".text : { *(.text) }" >> %t.script
39# RUN: echo ".keep : { *(.keep) } /*" >> %t.script
40# RUN: echo "comment line 1" >> %t.script
41# RUN: echo "comment line 2 */" >> %t.script
42# RUN: echo ".temp + { *(.temp) } }" >> %t.script
43# RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | FileCheck -check-prefix=ERR5 %s
44# ERR5: {{.*}}.script:6:
45
46## Check that text of lines and pointer to 'bad' token are working ok.
47# RUN: echo "UNKNOWN_TAG {" > %t.script
48# RUN: echo ".text : { *(.text) }" >> %t.script
49# RUN: echo ".keep : { *(.keep) }" >> %t.script
50# RUN: echo ".temp : { *(.temp) } }" >> %t.script
51# RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | \
52# RUN: FileCheck -check-prefix=ERR6 -strict-whitespace %s
53# ERR6: error: {{.*}}.script:1:
54# ERR6-NEXT: error: {{.*}}.script:1: UNKNOWN_TAG {
55# ERR6-NEXT: error: {{.*}}.script:1: ^
56
57## One more check that text of lines and pointer to 'bad' token are working ok.
58# RUN: echo "SECTIONS {" > %t.script
59# RUN: echo ".text : { *(.text) }" >> %t.script
60# RUN: echo ".keep : { *(.keep) }" >> %t.script
61# RUN: echo "boom .temp : { *(.temp) } }" >> %t.script
62# RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | \
63# RUN: FileCheck -check-prefix=ERR7 -strict-whitespace %s
64# ERR7: error: {{.*}}.script:4: malformed number: .temp
65# ERR7-NEXT: error: {{.*}}.script:4: boom .temp : { *(.temp) } }
66# ERR7-NEXT: error: {{.*}}.script:4: ^
67
68## Check tokenize() error
69# RUN: echo "SECTIONS {}" > %t.script
70# RUN: echo "\"" >> %t.script
71# RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | \
72# RUN: FileCheck -check-prefix=ERR8 -strict-whitespace %s
73# ERR8: {{.*}}.script:2: unclosed quote
74
75## Check tokenize() error in included script file
76# RUN: echo "SECTIONS {}" > %t.script.inc
77# RUN: echo "\"" >> %t.script.inc
78# RUN: echo "INCLUDE \"%t.script.inc\"" > %t.script
79# RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | \
80# RUN: FileCheck -check-prefix=ERR9 -strict-whitespace %s
81# ERR9: {{.*}}.script.inc:2: unclosed quote
82
83## Check error reporting correctness for included files.
84# RUN: echo "SECTIONS {" > %t.script.inc
85# RUN: echo ".text : { *(.text) }" >> %t.script.inc
86# RUN: echo ".keep : { *(.keep) }" >> %t.script.inc
87# RUN: echo "boom .temp : { *(.temp) } }" >> %t.script.inc
88# RUN: echo "INCLUDE \"%t.script.inc\"" > %t.script
89# RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | \
90# RUN: FileCheck -check-prefix=ERR10 -strict-whitespace %s
91# ERR10: error: {{.*}}.script.inc:4: malformed number: .temp
92# ERR10-NEXT: error: {{.*}}.script.inc:4: boom .temp : { *(.temp) } }
93# ERR10-NEXT: error: {{.*}}.script.inc:4: ^
94
95## Check error reporting in script with INCLUDE directive.
96# RUN: echo "SECTIONS {" > %t.script.inc
97# RUN: echo ".text : { *(.text) }" >> %t.script.inc
98# RUN: echo ".keep : { *(.keep) }" >> %t.script.inc
99# RUN: echo ".temp : { *(.temp) } }" >> %t.script.inc
100# RUN: echo "/* One line before INCLUDE */" > %t.script
101# RUN: echo "INCLUDE \"%t.script.inc\"" >> %t.script
102# RUN: echo "/* One line ater INCLUDE */" >> %t.script
103# RUN: echo "Error" >> %t.script
104# RUN: not ld.lld -shared %t -o %t1 --script %t.script 2>&1 | \
105# RUN: FileCheck -check-prefix=ERR11 -strict-whitespace %s
106# ERR11: error: {{.*}}.script:4: unexpected EOF
deps/lld/test/ELF/linkerscript/discard-interp.s created+12
......@@ -0,0 +1,12 @@
1// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o
2// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/../Inputs/shared.s -o %t2.o
3// RUN: ld.lld -shared %t2.o -o %t2.so
4// RUN: echo "PHDRS { text PT_LOAD FILEHDR PHDRS; } \
5// RUN: SECTIONS { . = SIZEOF_HEADERS; .text : { *(.text) } : text }" > %t.script
6// RUN: ld.lld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -rpath foo -rpath bar --script %t.script --export-dynamic %t.o %t2.so -o %t
7// RUN: llvm-readobj -s %t | FileCheck %s
8
9// CHECK-NOT: Name: .interp
10
11.global _start
12_start:
deps/lld/test/ELF/linkerscript/discard-print-gc.s created+19
......@@ -0,0 +1,19 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -triple x86_64-pc-linux %s -o %t.o -filetype=obj
4# RUN: ld.lld -o %t.so --gc-sections %t.o --print-gc-sections -shared 2>&1 | \
5# RUN: FileCheck -check-prefix=CHECK %s
6
7# RUN: echo "SECTIONS { /DISCARD/ : { *(.foo) } }" > %t.script
8# RUN: ld.lld -o %t.so -T %t.script %t.o --print-gc-sections -shared 2>&1 | \
9# RUN: FileCheck -check-prefix=QUIET --allow-empty %s
10
11# RUN: echo "SECTIONS { .foo : { *(.foo) } }" > %t2.script
12# RUN: ld.lld -o %t.so -T %t2.script --gc-sections %t.o --print-gc-sections -shared 2>&1 | \
13# RUN: FileCheck -check-prefix=CHECK %s
14
15.section .foo,"a"
16.quad 0
17
18# CHECK: removing unused section from '.foo'
19# QUIET-NOT: removing unused section from '.foo'
deps/lld/test/ELF/linkerscript/discard-section-err.s created+23
......@@ -0,0 +1,23 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
4
5# RUN: echo "SECTIONS { /DISCARD/ : { *(.shstrtab) } }" > %t.script
6# RUN: not ld.lld -o %t --script %t.script %t.o 2>&1 | \
7# RUN: FileCheck -check-prefix=SHSTRTAB %s
8# SHSTRTAB: discarding .shstrtab section is not allowed
9
10# RUN: echo "SECTIONS { /DISCARD/ : { *(.dynamic) } }" > %t.script
11# RUN: not ld.lld -pie -o %t --script %t.script %t.o 2>&1 | \
12# RUN: FileCheck -check-prefix=DYNAMIC %s
13# DYNAMIC: discarding .dynamic section is not allowed
14
15# RUN: echo "SECTIONS { /DISCARD/ : { *(.dynsym) } }" > %t.script
16# RUN: not ld.lld -pie -o %t --script %t.script %t.o 2>&1 | \
17# RUN: FileCheck -check-prefix=DYNSYM %s
18# DYNSYM: discarding .dynsym section is not allowed
19
20# RUN: echo "SECTIONS { /DISCARD/ : { *(.dynstr) } }" > %t.script
21# RUN: not ld.lld -pie -o %t --script %t.script %t.o 2>&1 | \
22# RUN: FileCheck -check-prefix=DYNSTR %s
23# DYNSTR: discarding .dynstr section is not allowed
deps/lld/test/ELF/linkerscript/discard-section-metadata.s created+32
......@@ -0,0 +1,32 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: echo "SECTIONS { /DISCARD/ : { *(.foo) } }" > %t.script
4# RUN: ld.lld -o %t1 --script %t.script %t
5# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
6
7# CHECK-NOT: .foo
8# CHECK-NOT: .bar
9# CHECK-NOT: .zed
10# CHECK-NOT: .moo
11
12## Sections dependency tree for testcase is:
13## (.foo)
14## | |
15## | --(.bar)
16## |
17## --(.zed)
18## |
19## --(.moo)
20##
21
22.section .foo,"a"
23.quad 0
24
25.section .bar,"ao",@progbits,.foo
26.quad 0
27
28.section .zed,"ao",@progbits,.foo
29.quad 0
30
31.section .moo,"ao",@progbits,.zed
32.quad 0
deps/lld/test/ELF/linkerscript/discard-section.s created+14
......@@ -0,0 +1,14 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: echo "SECTIONS { /DISCARD/ : { *(.aaa*) } }" > %t.script
4# RUN: ld.lld -o %t1 --script %t.script %t
5# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
6
7# CHECK-NOT: .aaa
8
9.section .aaa,"a"
10aab:
11 .quad 0
12
13.section .zzz,"a"
14 .quad aab
deps/lld/test/ELF/linkerscript/dot-is-not-abs.s created+53
......@@ -0,0 +1,53 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3
4# RUN: echo "SECTIONS { .text : { *(.text) } \
5# RUN: foo = .; \
6# RUN: .bar : { *(.bar) } }" > %t1.script
7# RUN: ld.lld -o %t1 --script %t1.script %t.o -shared
8# RUN: llvm-readobj -t -s -section-data %t1 | FileCheck %s
9
10.hidden foo
11.long foo - .
12
13.section .bar, "a"
14.long 0
15
16# The symbol foo is defined as a position in the file. This means that it is
17# not absolute and it is possible to compute the distance from foo to some other
18# position in the file. The symbol is not really in any output section, but
19# ELF has no magic constant for not absolute, but not in any section.
20# Fortunately the value of a symbol in a non relocatable file is a virtual
21# address, so the section can be arbitrary.
22
23# CHECK: Section {
24# CHECK: Index:
25# CHECK: Name: .text
26# CHECK-NEXT: Type: SHT_PROGBITS
27# CHECK-NEXT: Flags [
28# CHECK-NEXT: SHF_ALLOC
29# CHECK-NEXT: SHF_EXECINSTR
30# CHECK-NEXT: ]
31# CHECK-NEXT: Address: 0x0
32# CHECK-NEXT: Offset:
33# CHECK-NEXT: Size: 4
34# CHECK-NEXT: Link:
35# CHECK-NEXT: Info:
36# CHECK-NEXT: AddressAlignment:
37# CHECK-NEXT: EntrySize:
38# CHECK-NEXT: SectionData (
39# CHECK-NEXT: 0000: 04000000 |
40# CHECK-NEXT: )
41# CHECK-NEXT: }
42
43# CHECK: Symbol {
44# CHECK: Name: foo
45# CHECK-NEXT: Value: 0x4
46# CHECK-NEXT: Size: 0
47# CHECK-NEXT: Binding: Local
48# CHECK-NEXT: Type: None
49# CHECK-NEXT: Other [
50# CHECK-NEXT: STV_HIDDEN
51# CHECK-NEXT: ]
52# CHECK-NEXT: Section: .text
53# CHECK-NEXT: }
deps/lld/test/ELF/linkerscript/double-bss.s created+21
......@@ -0,0 +1,21 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: echo "SECTIONS { . = SIZEOF_HEADERS; " > %t.script
4# RUN: echo ".text : { *(.text*) }" >> %t.script
5# RUN: echo ".bss1 : { *(.bss) }" >> %t.script
6# RUN: echo ".bss2 : { *(COMMON) }" >> %t.script
7# RUN: echo "}" >> %t.script
8
9# RUN: ld.lld -o %t1 --script %t.script %t
10# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
11# CHECK: .bss1 00000004 0000000000000122 BSS
12# CHECK-NEXT: .bss2 00000080 0000000000000128 BSS
13
14.globl _start
15_start:
16 jmp _start
17
18.bss
19.zero 4
20
21.comm q,128,8
deps/lld/test/ELF/linkerscript/dynamic-sym.s created+17
......@@ -0,0 +1,17 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: echo "_DYNAMIC = 0x123;" > %t.script
4# RUN: ld.lld -T %t.script %t.o -shared -o %t.so
5# RUN: llvm-readobj -t %t.so | FileCheck %s
6
7# CHECK: Symbol {
8# CHECK: Name: _DYNAMIC
9# CHECK-NEXT: Value: 0x123
10# CHECK-NEXT: Size: 0
11# CHECK-NEXT: Binding: Local
12# CHECK-NEXT: Type: None
13# CHECK-NEXT: Other [
14# CHECK-NEXT: STV_HIDDEN
15# CHECK-NEXT: ]
16# CHECK-NEXT: Section: Absolute
17# CHECK-NEXT: }
deps/lld/test/ELF/linkerscript/dynamic.s created+28
......@@ -0,0 +1,28 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o
4# RUN: ld.lld -shared %t2.o -o %t2.so
5
6# RUN: echo "SECTIONS { }" > %t.script
7# RUN: ld.lld %t1.o %t2.so -o %t
8# RUN: llvm-readobj -dynamic-table %t | FileCheck %s
9
10# CHECK: DynamicSection [
11# CHECK-NEXT: Tag Type Name/Value
12# CHECK: 0x0000000000000021 PREINIT_ARRAYSZ 9 (bytes)
13# CHECK: 0x000000000000001B INIT_ARRAYSZ 8 (bytes)
14# CHECK: 0x000000000000001C FINI_ARRAYSZ 10 (bytes)
15
16.globl _start
17_start:
18
19.section .init_array,"aw",@init_array
20 .quad 0
21
22.section .preinit_array,"aw",@preinit_array
23 .quad 0
24 .byte 0
25
26.section .fini_array,"aw",@fini_array
27 .quad 0
28 .short 0
deps/lld/test/ELF/linkerscript/early-assign-symbol.s created+14
......@@ -0,0 +1,14 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3
4# RUN: echo "SECTIONS { aaa = 1 + ABSOLUTE(foo - 1); .text : { *(.text*) } }" > %t1.script
5# RUN: not ld.lld -o %t --script %t1.script %t.o 2>&1 | FileCheck %s
6
7# RUN: echo "SECTIONS { aaa = ABSOLUTE(foo - 1) + 1; .text : { *(.text*) } }" > %t2.script
8# RUN: not ld.lld -o %t --script %t2.script %t.o 2>&1 | FileCheck %s
9
10# CHECK: error: {{.*}}.script:1: unable to evaluate expression: input section .text has no output section assigned
11
12.section .text
13.globl foo
14foo:
deps/lld/test/ELF/linkerscript/edata-etext.s created+23
......@@ -0,0 +1,23 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: echo "SECTIONS { }" > %t.script
4# RUN: not ld.lld %t.o -script %t.script -o %t 2>&1 | FileCheck %s
5# CHECK: error: undefined symbol: _edata
6# CHECK: >>> referenced by {{.*}}:(.text+0x0)
7# CHECK: error: undefined symbol: _etext
8# CHECK: >>> referenced by {{.*}}:(.text+0x8)
9# CHECK: error: undefined symbol: _end
10# CHECK: >>> referenced by {{.*}}:(.text+0x10)
11
12.global _start,_end,_etext,_edata
13.text
14_start:
15 .quad _edata + 0x1
16 .quad _etext + 0x1
17 .quad _end + 0x1
18
19.data
20 .word 1
21.bss
22 .align 4
23 .space 6
deps/lld/test/ELF/linkerscript/eh-frame-hdr.s created+20
......@@ -0,0 +1,20 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: echo "SECTIONS { \
4# RUN: .eh_frame_hdr : {} \
5# RUN: .eh_frame : {} \
6# RUN: }" > %t.script
7# RUN: ld.lld -o %t1 --eh-frame-hdr --script %t.script %t
8# RUN: llvm-objdump -s -section=".eh_frame_hdr" %t1 | FileCheck %s
9
10# CHECK: 011b033b 14000000 01000000 49000000
11# CHECK-NEXT: 30000000
12
13.global _start
14_start:
15 nop
16
17.section .dah,"ax",@progbits
18.cfi_startproc
19 nop
20.cfi_endproc
deps/lld/test/ELF/linkerscript/eh-frame-reloc-out-of-range.s created+27
......@@ -0,0 +1,27 @@
1## Check that error is correctly reported when .eh_frame reloc
2## is out of range
3
4# REQUIRES: x86
5# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
6# RUN: echo "PHDRS { eh PT_LOAD; text PT_LOAD; } \
7# RUN: SECTIONS { . = 0x10000; \
8# RUN: .eh_frame_hdr : { *(.eh_frame_hdr*) } : eh \
9# RUN: .eh_frame : { *(.eh_frame) } : eh \
10# RUN: . = 0xF00000000; \
11# RUN: .text : { *(.text*) } : text \
12# RUN: }" > %t.script
13# RUN: not ld.lld %t.o -T %t.script -o %t 2>&1 | FileCheck %s
14
15# CHECK: error: {{.*}}:(.eh_frame+0x20): relocation R_X86_64_PC32 out of range
16
17 .text
18 .globl _start
19_start:
20 .cfi_startproc
21 .cfi_lsda 0, _ex
22 nop
23 .cfi_endproc
24
25 .data
26_ex:
27 .word 0
deps/lld/test/ELF/linkerscript/eh-frame.s created+19
......@@ -0,0 +1,19 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: echo "SECTIONS { \
4# RUN: .eh_frame : { *(.eh_frame) } \
5# RUN: }" > %t.script
6# RUN: ld.lld -o %t1 --script %t.script %t
7# RUN: llvm-objdump -s -section=".eh_frame" %t1 | FileCheck %s
8
9# CHECK: 0000 14000000 00000000 017a5200 01781001
10# CHECK-NEXT: 0010 1b0c0708 90010000
11
12.global _start
13_start:
14 nop
15
16.section .dah,"ax",@progbits
17.cfi_startproc
18 nop
19.cfi_endproc
deps/lld/test/ELF/linkerscript/ehdr_start.s created+20
......@@ -0,0 +1,20 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
4# RUN: echo "SECTIONS { }" > %t.script
5# RUN: ld.lld %t.o -script %t.script -o %t
6# RUN: llvm-readobj -symbols %t | FileCheck %s
7# CHECK: Name: __ehdr_start (1)
8# CHECK-NEXT: Value: 0x0
9# CHECK-NEXT: Size: 0
10# CHECK-NEXT: Binding: Local (0x0)
11# CHECK-NEXT: Type: None (0x0)
12# CHECK-NEXT: Other [ (0x2)
13# CHECK-NEXT: STV_HIDDEN (0x2)
14# CHECK-NEXT: ]
15# CHECK-NEXT: Section: .text (0x1)
16
17.text
18.global _start, __ehdr_start
19_start:
20 .quad __ehdr_start
deps/lld/test/ELF/linkerscript/emit-reloc.s created+17
......@@ -0,0 +1,17 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: echo "SECTIONS { .rela.dyn : { *(.rela.data) } }" > %t.script
4# RUN: ld.lld -T %t.script --emit-relocs %t.o -o %t.so -shared
5# RUN: llvm-readobj -r %t.so | FileCheck %s
6
7.data
8.quad .foo
9
10# CHECK: Relocations [
11# CHECK-NEXT: Section ({{.*}}) .rela.dyn {
12# CHECK-NEXT: 0x66 R_X86_64_64 .foo 0x0
13# CHECK-NEXT: }
14# CHECK-NEXT: Section ({{.*}}) .rela.data {
15# CHECK-NEXT: 0x66 R_X86_64_64 .foo 0x0
16# CHECK-NEXT: }
17# CHECK-NEXT: ]
deps/lld/test/ELF/linkerscript/emit-relocs-discard.s created+14
......@@ -0,0 +1,14 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: echo "SECTIONS { /DISCARD/ : { *(.bbb) } }" > %t.script
4# RUN: ld.lld --emit-relocs --script %t.script %t.o -o %t1
5# RUN: llvm-readobj -r %t1 | FileCheck %s
6
7# CHECK: Relocations [
8# CHECK-NEXT: ]
9
10.section .aaa,"",@progbits
11.Lfoo:
12
13.section .bbb,"",@progbits
14.long .Lfoo
deps/lld/test/ELF/linkerscript/emit-relocs-ehframe-discard.s created+11
......@@ -0,0 +1,11 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
3# RUN: echo "SECTIONS { /DISCARD/ : { *(.eh_frame) } }" > %t.script
4# RUN: ld.lld --emit-relocs --script %t.script %t1.o -o %t
5# RUN: llvm-objdump -section-headers %t | FileCheck %s
6
7# CHECK-NOT: .rela.eh_frame
8
9.section .foo,"ax",@progbits
10.cfi_startproc
11.cfi_endproc
deps/lld/test/ELF/linkerscript/emit-relocs-multiple.s created+20
......@@ -0,0 +1,20 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: echo "SECTIONS { .zed : { *(.foo) *(.bar) } }" > %t.script
4# RUN: ld.lld --emit-relocs --script %t.script %t.o -o %t1
5# RUN: llvm-readobj -r %t1 | FileCheck %s
6
7# CHECK: Relocations [
8# CHECK-NEXT: Section {{.*}} .rela.foo {
9# CHECK-NEXT: 0x1 R_X86_64_32 .zed 0x0
10# CHECK-NEXT: 0x6 R_X86_64_32 .zed 0x5
11# CHECK-NEXT: }
12# CHECK-NEXT: ]
13
14.section .foo,"ax",@progbits
15aaa:
16 movl $aaa, %edx
17
18.section .bar,"ax",@progbits
19bbb:
20 movl $bbb, %edx
deps/lld/test/ELF/linkerscript/empty-load.s created+21
......@@ -0,0 +1,21 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: echo "SECTIONS { .rw : { *(.rw) } .text : { *(.text) } }" > %t.script
4# RUN: ld.lld -o %t1 --script %t.script %t
5# RUN: llvm-objdump -private-headers %t1 | FileCheck %s
6
7## We expect 2 PT_LOAD segments
8# CHECK: Program Header:
9# CHECK-NEXT: LOAD
10# CHECK-NEXT: filesz {{0x[0-9a-f]+}} memsz {{0x[0-9a-f]+}} flags rw-
11# CHECK-NEXT: LOAD
12# CHECK-NEXT: filesz {{0x[0-9a-f]+}} memsz {{0x[0-9a-f]+}} flags r-x
13# CHECK-NEXT: STACK
14# CHECK-NEXT: filesz
15
16.globl _start
17_start:
18 jmp _start
19
20.section .rw, "aw"
21 .quad 0
deps/lld/test/ELF/linkerscript/empty-tls.s created+14
......@@ -0,0 +1,14 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: echo "PHDRS { ph_tls PT_TLS; }" > %t.script
4// RUN: ld.lld -o %t.so -T %t.script %t.o -shared
5// RUN: llvm-readobj -l %t.so | FileCheck %s
6
7// test that we don't crash with an empty PT_TLS
8
9// CHECK: Type: PT_TLS
10// CHECK-NEXT: Offset: 0x0
11// CHECK-NEXT: VirtualAddress: 0x0
12// CHECK-NEXT: PhysicalAddress: 0x0
13// CHECK-NEXT: FileSize: 0
14// CHECK-NEXT: MemSize: 0
deps/lld/test/ELF/linkerscript/entry.s created+42
......@@ -0,0 +1,42 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
4
5# RUN: echo "ENTRY(_label)" > %t.script
6# RUN: ld.lld -o %t2 %t.script %t
7# RUN: llvm-readobj %t2 > /dev/null
8
9# The entry symbol should not cause an undefined error.
10# RUN: echo "ENTRY(_wrong_label)" > %t.script
11# RUN: ld.lld -o %t2 %t.script %t
12# RUN: ld.lld --entry=abc -o %t2 %t
13
14# -e has precedence over linker script's ENTRY.
15# RUN: echo "ENTRY(_label)" > %t.script
16# RUN: ld.lld -e _start -o %t2 %t.script %t
17# RUN: llvm-readobj -file-headers -symbols %t2 | \
18# RUN: FileCheck -check-prefix=OVERLOAD %s
19
20# OVERLOAD: Entry: [[ENTRY:0x[0-9A-F]+]]
21# OVERLOAD: Name: _start
22# OVERLOAD-NEXT: Value: [[ENTRY]]
23
24# The entry symbol can be a linker-script-defined symbol.
25# RUN: echo "ENTRY(foo); foo = 1;" > %t.script
26# RUN: ld.lld -o %t2 %t.script %t
27# RUN: llvm-readobj -file-headers -symbols %t2 | \
28# RUN: FileCheck -check-prefix=SCRIPT %s
29
30# SCRIPT: Entry: 0x1
31
32# RUN: echo "ENTRY(no_such_symbol);" > %t.script
33# RUN: ld.lld -o %t2 %t.script %t 2>&1 | \
34# RUN: FileCheck -check-prefix=MISSING %s
35
36# MISSING: warning: cannot find entry symbol no_such_symbol
37
38.globl _start, _label
39_start:
40 ret
41_label:
42 ret
deps/lld/test/ELF/linkerscript/exclude-multiple.s created+37
......@@ -0,0 +1,37 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %tfile1.o
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/exclude-multiple1.s -o %tfile2.o
4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/exclude-multiple2.s -o %tfile3.o
5# RUN: echo "SECTIONS { \
6# RUN: .foo : { *(.foo.1 EXCLUDE_FILE (*file1.o) .foo.2 EXCLUDE_FILE (*file2.o) .foo.3) } \
7# RUN: }" > %t1.script
8# RUN: ld.lld -script %t1.script %tfile1.o %tfile2.o %tfile3.o -o %t1.o
9# RUN: llvm-objdump -s %t1.o | FileCheck %s
10
11# CHECK: Contents of section .foo:
12# CHECK-NEXT: 01000000 00000000 04000000 00000000
13# CHECK-NEXT: 07000000 00000000 05000000 00000000
14# CHECK-NEXT: 08000000 00000000 03000000 00000000
15# CHECK-NEXT: 09000000 00000000
16# CHECK-NEXT: Contents of section .foo.2:
17# CHECK-NEXT: 02000000 00000000
18# CHECK-NEXT: Contents of section .foo.3:
19# CHECK-NEXT: 06000000 00000000
20
21# RUN: echo "SECTIONS { .foo : { *(EXCLUDE_FILE (*file1.o) EXCLUDE_FILE (*file2.o) .foo.3) } }" > %t2.script
22# RUN: not ld.lld -script %t2.script %tfile1.o %tfile2.o %tfile3.o -o %t2.o 2>&1 | \
23# RUN: FileCheck %s --check-prefix=ERR
24# ERR: section pattern is expected
25
26# RUN: echo "SECTIONS { .foo : { *(EXCLUDE_FILE (*file1.o)) } }" > %t3.script
27# RUN: not ld.lld -script %t3.script %tfile1.o %tfile2.o %tfile3.o -o %t2.o 2>&1 | \
28# RUN: FileCheck %s --check-prefix=ERR
29
30.section .foo.1,"a"
31 .quad 1
32
33.section .foo.2,"a"
34 .quad 2
35
36.section .foo.3,"a"
37 .quad 3
deps/lld/test/ELF/linkerscript/excludefile.s created+49
......@@ -0,0 +1,49 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
4# RUN: %p/Inputs/include.s -o %t2
5# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
6# RUN: %p/Inputs/notinclude.s -o %t3.notinclude
7
8# RUN: echo "SECTIONS {} " > %t.script
9# RUN: ld.lld -o %t --script %t.script %t1 %t2 %t3.notinclude
10# RUN: llvm-objdump -d %t | FileCheck %s
11
12# CHECK: Disassembly of section .text:
13# CHECK: _start:
14# CHECK-NEXT: : 48 c7 c0 3c 00 00 00 movq $60, %rax
15# CHECK-NEXT: : 48 c7 c7 2a 00 00 00 movq $42, %rdi
16# CHECK-NEXT: : cc int3
17# CHECK-NEXT: : cc int3
18# CHECK: _potato:
19# CHECK-NEXT: : 90 nop
20# CHECK-NEXT: : 90 nop
21# CHECK-NEXT: : cc int3
22# CHECK-NEXT: : cc int3
23# CHECK: tomato:
24# CHECK-NEXT: : b8 01 00 00 00 movl $1, %eax
25
26# RUN: echo "SECTIONS { .patatino : \
27# RUN: { KEEP(*(EXCLUDE_FILE(*notinclude) .text)) } }" \
28# RUN: > %t.script
29# RUN: ld.lld -o %t4 --script %t.script %t1 %t2 %t3.notinclude
30# RUN: llvm-objdump -d %t4 | FileCheck %s --check-prefix=EXCLUDE
31
32# EXCLUDE: Disassembly of section .patatino:
33# EXCLUDE: _start:
34# EXCLUDE-NEXT: : 48 c7 c0 3c 00 00 00 movq $60, %rax
35# EXCLUDE-NEXT: : 48 c7 c7 2a 00 00 00 movq $42, %rdi
36# EXCLUDE-NEXT: : cc int3
37# EXCLUDE-NEXT: : cc int3
38# EXCLUDE: _potato:
39# EXCLUDE-NEXT: : 90 nop
40# EXCLUDE-NEXT: : 90 nop
41# EXCLUDE: Disassembly of section .text:
42# EXCLUDE: tomato:
43# EXCLUDE-NEXT: : b8 01 00 00 00 movl $1, %eax
44
45.section .text
46.globl _start
47_start:
48 mov $60, %rax
49 mov $42, %rdi
deps/lld/test/ELF/linkerscript/exidx-crash.s created+7
......@@ -0,0 +1,7 @@
1# REQUIRES: aarch64
2
3# We used to crash on this.
4
5# RUN: llvm-mc %s -o %t.o -filetype=obj -triple=aarch64-pc-linux
6# RUN: echo "SECTIONS { .ARM.exidx : { *(.foo) } }" > %t.script
7# RUN: ld.lld -T %t.script %t.o -o %t
deps/lld/test/ELF/linkerscript/expr-invalid-sec.s created+6
......@@ -0,0 +1,6 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: echo "SECTIONS { foo = ADDR(.text) + ADDR(.text); };" > %t.script
4# RUN: not ld.lld -o %t.so --script %t.script %t.o -shared 2>&1 | FileCheck %s
5
6# CHECK: error: {{.*}}.script:1: at least one side of the expression must be absolute
deps/lld/test/ELF/linkerscript/expr-sections.s created+22
......@@ -0,0 +1,22 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: echo "SECTIONS { \
4# RUN: . = . + 4; \
5# RUN: .text : { \
6# RUN: *(.text) \
7# RUN: foo1 = ADDR(.text) + 1; bar1 = 1 + ADDR(.text); \
8# RUN: foo2 = ADDR(.text) & 1; bar2 = 1 & ADDR(.text); \
9# RUN: foo3 = ADDR(.text) | 1; bar3 = 1 | ADDR(.text); \
10# RUN: } \
11# RUN: };" > %t.script
12# RUN: ld.lld -o %t.so --script %t.script %t.o -shared
13# RUN: llvm-objdump -t -h %t.so | FileCheck %s
14
15# CHECK: 1 .text 00000000 0000000000000004 TEXT DATA
16
17# CHECK: 0000000000000005 .text 00000000 foo1
18# CHECK: 0000000000000005 .text 00000000 bar1
19# CHECK: 0000000000000000 .text 00000000 foo2
20# CHECK: 0000000000000000 .text 00000000 bar2
21# CHECK: 0000000000000005 .text 00000000 foo3
22# CHECK: 0000000000000005 .text 00000000 bar3
deps/lld/test/ELF/linkerscript/extend-pt-load.s created+69
......@@ -0,0 +1,69 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3
4# This test demonstrates an odd consequence of the way we handle sections with just symbol
5# assignments.
6
7# First, run a test with no such section.
8
9# RUN: echo "SECTIONS { \
10# RUN: . = SIZEOF_HEADERS; \
11# RUN: .dynsym : { } \
12# RUN: .hash : { } \
13# RUN: .dynstr : { } \
14# RUN: .text : { *(.text) } \
15# RUN: . = ALIGN(0x1000); \
16# RUN: .data.rel.ro : { *(.data.rel.ro) } \
17# RUN: }" > %t.script
18# RUN: ld.lld -o %t1 --script %t.script %t.o -shared
19# RUN: llvm-readobj --elf-output-style=GNU -l -s %t1 | FileCheck --check-prefix=CHECK1 %s
20
21# CHECK1: .text PROGBITS 00000000000001bc 0001bc 000001 00 AX
22# CHECK1-NEXT: .data.rel.ro PROGBITS 0000000000001000 001000 000001 00 WA
23
24# CHECK1: LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x0001bd 0x0001bd R E
25# CHECK1-NEXT: LOAD 0x001000 0x0000000000001000 0x0000000000001000 0x000068 0x000068 RW
26
27# Then add the section bar. Note how bar is given AX flags, which causes the PT_LOAD to now
28# cover the padding bits created by ALIGN.
29
30# RUN: echo "SECTIONS { \
31# RUN: . = SIZEOF_HEADERS; \
32# RUN: .dynsym : { } \
33# RUN: .hash : { } \
34# RUN: .dynstr : { } \
35# RUN: .text : { *(.text) } \
36# RUN: . = ALIGN(0x1000); \
37# RUN: bar : { HIDDEN(bar_sym = .); } \
38# RUN: .data.rel.ro : { *(.data.rel.ro) } \
39# RUN: }" > %t.script
40# RUN: ld.lld -o %t2 --script %t.script %t.o -shared
41# RUN: llvm-readobj --elf-output-style=GNU -l -s %t2 | FileCheck --check-prefix=CHECK2 %s
42
43# CHECK2: .text PROGBITS 00000000000001bc 0001bc 000001 00 AX
44# CHECK2-NEXT: bar PROGBITS 0000000000001000 001000 000000 00 AX
45# CHECK2-NEXT: .data.rel.ro PROGBITS 0000000000001000 001000 000001 00 WA
46
47# CHECK2: LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x001000 0x001000 R E
48# CHECK2-NEXT: LOAD 0x001000 0x0000000000001000 0x0000000000001000 0x000068 0x000068 RW
49
50# If the current behavior becomes a problem we should consider just moving the commands out
51# of the section. That is, handle the above like the following test.
52
53# RUN: echo "SECTIONS { \
54# RUN: . = SIZEOF_HEADERS; \
55# RUN: .dynsym : { } \
56# RUN: .hash : { } \
57# RUN: .dynstr : { } \
58# RUN: .text : { *(.text) } \
59# RUN: . = ALIGN(0x1000); \
60# RUN: HIDDEN(bar_sym = .); \
61# RUN: .data.rel.ro : { *(.data.rel.ro) } \
62# RUN: }" > %t.script
63# RUN: ld.lld -o %t3 --script %t.script %t.o -shared
64# RUN: llvm-readobj --elf-output-style=GNU -l -s %t3 | FileCheck --check-prefix=CHECK1 %s
65
66nop
67
68.section .data.rel.ro, "aw"
69.byte 0
deps/lld/test/ELF/linkerscript/filename-spec.s created+59
......@@ -0,0 +1,59 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %tfirst.o
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
4# RUN: %p/Inputs/filename-spec.s -o %tsecond.o
5
6# RUN: echo "SECTIONS { .foo : { \
7# RUN: KEEP(*first.o(.foo)) \
8# RUN: KEEP(*second.o(.foo)) } }" > %t1.script
9# RUN: ld.lld -o %t1 --script %t1.script %tfirst.o %tsecond.o
10# RUN: llvm-objdump -s %t1 | FileCheck --check-prefix=FIRSTSECOND %s
11# FIRSTSECOND: Contents of section .foo:
12# FIRSTSECOND-NEXT: 01000000 00000000 11000000 00000000
13
14# RUN: echo "SECTIONS { .foo : { \
15# RUN: KEEP(*second.o(.foo)) \
16# RUN: KEEP(*first.o(.foo)) } }" > %t2.script
17# RUN: ld.lld -o %t2 --script %t2.script %tfirst.o %tsecond.o
18# RUN: llvm-objdump -s %t2 | FileCheck --check-prefix=SECONDFIRST %s
19# SECONDFIRST: Contents of section .foo:
20# SECONDFIRST-NEXT: 11000000 00000000 01000000 00000000
21
22## Now the same tests but without KEEP. Checking that file name inside
23## KEEP is parsed fine.
24# RUN: echo "SECTIONS { .foo : { \
25# RUN: *first.o(.foo) \
26# RUN: *second.o(.foo) } }" > %t3.script
27# RUN: ld.lld -o %t3 --script %t3.script %tfirst.o %tsecond.o
28# RUN: llvm-objdump -s %t3 | FileCheck --check-prefix=FIRSTSECOND %s
29
30# RUN: echo "SECTIONS { .foo : { \
31# RUN: *second.o(.foo) \
32# RUN: *first.o(.foo) } }" > %t4.script
33# RUN: ld.lld -o %t4 --script %t4.script %tfirst.o %tsecond.o
34# RUN: llvm-objdump -s %t4 | FileCheck --check-prefix=SECONDFIRST %s
35
36# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %T/filename-spec1.o
37# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
38# RUN: %p/Inputs/filename-spec.s -o %T/filename-spec2.o
39
40# RUN: echo "SECTIONS { .foo : { \
41# RUN: filename-spec2.o(.foo) \
42# RUN: filename-spec1.o(.foo) } }" > %t5.script
43# RUN: ld.lld -o %t5 --script %t5.script \
44# RUN: %T/filename-spec1.o %T/filename-spec2.o
45# RUN: llvm-objdump -s %t5 | FileCheck --check-prefix=SECONDFIRST %s
46
47# RUN: echo "SECTIONS { .foo : { \
48# RUN: filename-spec1.o(.foo) \
49# RUN: filename-spec2.o(.foo) } }" > %t6.script
50# RUN: ld.lld -o %t6 --script %t6.script \
51# RUN: %T/filename-spec1.o %T/filename-spec2.o
52# RUN: llvm-objdump -s %t6 | FileCheck --check-prefix=FIRSTSECOND %s
53
54.global _start
55_start:
56 nop
57
58.section .foo,"a"
59 .quad 1
deps/lld/test/ELF/linkerscript/fill-exec-sections.s created+40
......@@ -0,0 +1,40 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4## Check that padding of executable sections are filled with trap bytes if not
5## otherwise specified in the script.
6# RUN: echo "SECTIONS { .exec : { *(.exec*) } }" > %t.script
7# RUN: ld.lld -o %t.out --script %t.script %t
8# RUN: llvm-objdump -s %t.out | FileCheck %s --check-prefix=EXEC
9# EXEC: 0000 66cccccc cccccccc cccccccc cccccccc
10# EXEC-NEXT: 0010 66
11
12## Check that a fill expression or command overrides the default filler...
13# RUN: echo "SECTIONS { .exec : { *(.exec*) }=0x11223344 }" > %t2.script
14# RUN: ld.lld -o %t2.out --script %t2.script %t
15# RUN: llvm-objdump -s %t2.out | FileCheck %s --check-prefix=OVERRIDE
16# RUN: echo "SECTIONS { .exec : { FILL(0x11223344); *(.exec*) } }" > %t3.script
17# RUN: ld.lld -o %t3.out --script %t3.script %t
18# RUN: llvm-objdump -s %t3.out | FileCheck %s --check-prefix=OVERRIDE
19# OVERRIDE: Contents of section .exec:
20# OVERRIDE-NEXT: 0000 66112233 44112233 44112233 44112233
21# OVERRIDE-NEXT: 0010 66
22
23## ...even for a value of zero.
24# RUN: echo "SECTIONS { .exec : { *(.exec*) }=0x00000000 }" > %t4.script
25# RUN: ld.lld -o %t4.out --script %t4.script %t
26# RUN: llvm-objdump -s %t4.out | FileCheck %s --check-prefix=ZERO
27# RUN: echo "SECTIONS { .exec : { FILL(0x00000000); *(.exec*) } }" > %t5.script
28# RUN: ld.lld -o %t5.out --script %t5.script %t
29# RUN: llvm-objdump -s %t5.out | FileCheck %s --check-prefix=ZERO
30# ZERO: Contents of section .exec:
31# ZERO-NEXT: 0000 66000000 00000000 00000000 00000000
32# ZERO-NEXT: 0010 66
33
34.section .exec.1,"ax"
35.align 16
36.byte 0x66
37
38.section .exec.2,"ax"
39.align 16
40.byte 0x66
deps/lld/test/ELF/linkerscript/fill.s created+31
......@@ -0,0 +1,31 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: echo "SECTIONS { \
4# RUN: .out : { \
5# RUN: FILL(0x11111111) \
6# RUN: . += 2; \
7# RUN: *(.aaa) \
8# RUN: . += 4; \
9# RUN: *(.bbb) \
10# RUN: . += 4; \
11# RUN: FILL(0x22222222); \
12# RUN: . += 4; \
13# RUN: } \
14# RUN: }; " > %t.script
15# RUN: ld.lld -o %t --script %t.script %t.o
16# RUN: llvm-objdump -s %t | FileCheck %s
17
18# CHECK: Contents of section .out:
19# CHECK-NEXT: 2222aa22 222222bb 22222222 22222222
20
21.text
22.globl _start
23_start:
24
25.section .aaa, "a"
26.align 1
27.byte 0xAA
28
29.section .bbb, "a"
30.align 1
31.byte 0xBB
deps/lld/test/ELF/linkerscript/got-write-offset.s created+23
......@@ -0,0 +1,23 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux-gnu %s -o %t
3# RUN: echo "SECTIONS { \
4# RUN: .data 0x1000 : { *(.data) } \
5# RUN: .got 0x2000 : { \
6# RUN: LONG(0) \
7# RUN: *(.got) \
8# RUN: } \
9# RUN: };" > %t.script
10# RUN: ld.lld -shared -o %t.out --script %t.script %t
11# RUN: llvm-objdump -s %t.out | FileCheck %s
12.text
13.global foo
14foo:
15 movl bar@GOT, %eax
16.data
17.local bar
18bar:
19 .zero 4
20# CHECK: Contents of section .data:
21# CHECK-NEXT: 1000 00000000
22# CHECK: Contents of section .got:
23# CHECK-NEXT: 2000 00000000 00100000
deps/lld/test/ELF/linkerscript/group.s created+56
......@@ -0,0 +1,56 @@
1# REQUIRES: x86
2
3# RUN: mkdir -p %t.dir
4# RUN: rm -f %t.dir/libxyz.a
5# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
6# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
7# RUN: %p/Inputs/libsearch-st.s -o %t2.o
8# RUN: llvm-ar rcs %t.dir/libxyz.a %t2.o
9
10# RUN: echo "GROUP(\"%t\")" > %t.script
11# RUN: ld.lld -o %t2 %t.script
12# RUN: llvm-readobj %t2 > /dev/null
13
14# RUN: echo "INPUT(\"%t\")" > %t.script
15# RUN: ld.lld -o %t2 %t.script
16# RUN: llvm-readobj %t2 > /dev/null
17
18# RUN: echo "GROUP(\"%t\" libxyz.a )" > %t.script
19# RUN: not ld.lld -o %t2 %t.script 2>/dev/null
20# RUN: ld.lld -o %t2 %t.script -L%t.dir
21# RUN: llvm-readobj %t2 > /dev/null
22
23# RUN: echo "GROUP(\"%t\" =libxyz.a )" > %t.script
24# RUN: not ld.lld -o %t2 %t.script 2>/dev/null
25# RUN: ld.lld -o %t2 %t.script --sysroot=%t.dir
26# RUN: llvm-readobj %t2 > /dev/null
27
28# RUN: echo "GROUP(\"%t\" -lxyz )" > %t.script
29# RUN: not ld.lld -o %t2 %t.script 2>/dev/null
30# RUN: ld.lld -o %t2 %t.script -L%t.dir
31# RUN: llvm-readobj %t2 > /dev/null
32
33# RUN: echo "GROUP(\"%t\" libxyz.a )" > %t.script
34# RUN: not ld.lld -o %t2 %t.script 2>/dev/null
35# RUN: ld.lld -o %t2 %t.script -L%t.dir
36# RUN: llvm-readobj %t2 > /dev/null
37
38# RUN: echo "GROUP(\"%t\" /libxyz.a )" > %t.script
39# RUN: echo "GROUP(\"%t\" /libxyz.a )" > %t.dir/xyz.script
40# RUN: not ld.lld -o %t2 %t.script 2>/dev/null
41# RUN: not ld.lld -o %t2 %t.script --sysroot=%t.dir 2>/dev/null
42# RUN: ld.lld -o %t2 %t.dir/xyz.script --sysroot=%t.dir
43# RUN: llvm-readobj %t2 > /dev/null
44
45# RUN: echo "GROUP(\"%t.script2\")" > %t.script1
46# RUN: echo "GROUP(\"%t\")" > %t.script2
47# RUN: ld.lld -o %t2 %t.script1
48# RUN: llvm-readobj %t2 > /dev/null
49
50# RUN: echo "GROUP(AS_NEEDED(\"%t\"))" > %t.script
51# RUN: ld.lld -o %t2 %t.script
52# RUN: llvm-readobj %t2 > /dev/null
53
54.globl _start
55_start:
56 ret
deps/lld/test/ELF/linkerscript/header-addr.s created+47
......@@ -0,0 +1,47 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: echo "PHDRS {all PT_LOAD PHDRS;} \
4# RUN: SECTIONS { \
5# RUN: . = 0x2000; \
6# RUN: .text : {*(.text)} :all \
7# RUN: }" > %t.script
8# RUN: ld.lld -o %t.so --script %t.script %t.o -shared
9# RUN: llvm-readobj -program-headers %t.so | FileCheck %s
10
11# CHECK: ProgramHeaders [
12# CHECK-NEXT: ProgramHeader {
13# CHECK-NEXT: Type: PT_LOAD
14# CHECK-NEXT: Offset: 0x40
15# CHECK-NEXT: VirtualAddress: 0x1040
16# CHECK-NEXT: PhysicalAddress: 0x1040
17# CHECK-NEXT: FileSize: 4176
18# CHECK-NEXT: MemSize: 4176
19# CHECK-NEXT: Flags [
20# CHECK-NEXT: PF_R (0x4)
21# CHECK-NEXT: PF_W (0x2)
22# CHECK-NEXT: PF_X (0x1)
23# CHECK-NEXT: ]
24# CHECK-NEXT: Alignment: 4096
25# CHECK-NEXT: }
26# CHECK-NEXT: ]
27
28# RUN: ld.lld -o %t2.so --script %t.script %t.o -shared -z max-page-size=0x2000
29# RUN: llvm-readobj -program-headers %t2.so \
30# RUN: | FileCheck --check-prefix=MAXPAGE %s
31
32# MAXPAGE: ProgramHeaders [
33# MAXPAGE-NEXT: ProgramHeader {
34# MAXPAGE-NEXT: Type: PT_LOAD
35# MAXPAGE-NEXT: Offset: 0x40
36# MAXPAGE-NEXT: VirtualAddress: 0x40
37# MAXPAGE-NEXT: PhysicalAddress: 0x40
38# MAXPAGE-NEXT: FileSize: 8272
39# MAXPAGE-NEXT: MemSize: 8272
40# MAXPAGE-NEXT: Flags [
41# MAXPAGE-NEXT: PF_R
42# MAXPAGE-NEXT: PF_W
43# MAXPAGE-NEXT: PF_X
44# MAXPAGE-NEXT: ]
45# MAXPAGE-NEXT: Alignment: 8192
46# MAXPAGE-NEXT: }
47# MAXPAGE-NEXT: ]
deps/lld/test/ELF/linkerscript/huge-temporary-file.s created+12
......@@ -0,0 +1,12 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: echo "SECTIONS { .text 0x2000 : {. = 0x10 ; *(.text) } }" > %t.script
4# RUN: not ld.lld %t --script %t.script -o %t1
5
6## This inputs previously created a 4gb temporarily fine under 32 bit
7## configuration. Issue was fixed. There is no clean way to check that from here.
8## This testcase added for documentation purposes.
9
10.globl _start
11_start:
12nop
deps/lld/test/ELF/linkerscript/implicit-program-header.s created+13
......@@ -0,0 +1,13 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: ld.lld -o %t1 --script %S/Inputs/implicit-program-header.script \
4# RUN: %t.o -shared
5# RUN: llvm-readobj -elf-output-style=GNU -l %t1 | FileCheck %s
6
7# CHECK: Segment Sections...
8# CHECK-NEXT: 00 .text .dynsym .hash .dynstr .dynamic
9# CHECK-NEXT: 01 .foo
10
11.quad 0
12.section .foo,"ax"
13.quad 0
deps/lld/test/ELF/linkerscript/input-order.s created+38
......@@ -0,0 +1,38 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4# This test case should place input sections in script order:
5# .foo.1 .foo.2 .bar.1 .bar.2
6# RUN: echo "SECTIONS { . = 0x1000; .foo : {*(.foo.*) *(.bar.*) } }" > %t.script
7# RUN: ld.lld -o %t1 --script %t.script %t
8# RUN: llvm-objdump -section=.foo -s %t1 | FileCheck --check-prefix=SCRIPT_ORDER %s
9# SCRIPT_ORDER: Contents of section .foo:
10# SCRIPT_ORDER-NEXT: 1000 00000000 00000000 ffffffff eeeeeeee
11
12# This test case should place input sections in native order:
13# .bar.1 .foo.1 .bar.2 .foo.2
14# RUN: echo "SECTIONS { . = 0x1000; .foo : {*(.foo.* .bar.*)} }" > %t.script
15# RUN: ld.lld -o %t1 --script %t.script %t
16# RUN: llvm-objdump -section=.foo -s %t1 | FileCheck --check-prefix=FILE_ORDER %s
17# FILE_ORDER: Contents of section .foo:
18# FILE_ORDER-NEXT: 1000 ffffffff 00000000 eeeeeeee 00000000
19
20.global _start
21_start:
22 nop
23
24.section .bar.1,"a"
25bar1:
26 .long 0xFFFFFFFF
27
28.section .foo.1,"a"
29foo1:
30 .long 0
31
32.section .bar.2,"a"
33bar2:
34 .long 0xEEEEEEEE
35
36.section .foo.2,"a"
37foo2:
38 .long 0
deps/lld/test/ELF/linkerscript/input-sec-dup.s created+18
......@@ -0,0 +1,18 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4# RUN: echo "SECTIONS {.foo : { *(.foo) *(.foo) } }" > %t.script
5# RUN: ld.lld -o %t1 --script %t.script %t
6# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
7# CHECK: Sections:
8# CHECK-NEXT: Idx Name Size
9# CHECK-NEXT: 0 00000000
10# CHECK-NEXT: 1 .foo 00000004
11# CHECK-NEXT: 2 .text 00000001
12
13.global _start
14_start:
15 nop
16
17.section .foo,"a"
18 .long 0
deps/lld/test/ELF/linkerscript/lazy-symbols.s created+13
......@@ -0,0 +1,13 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/lazy-symbols.s -o %t1
3# RUN: llvm-ar rcs %tar %t1
4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2
5# RUN: echo "foo = 1;" > %t.script
6# RUN: ld.lld %t2 %tar --script %t.script -o %tout
7# RUN: llvm-readobj -symbols %tout | FileCheck %s
8
9# This test is to ensure a linker script can define a symbol which have the same
10# name as a lazy symbol.
11
12# CHECK: Name: foo
13# CHECK-NEXT: Value: 0x1
deps/lld/test/ELF/linkerscript/linkerscript.s created+54
......@@ -0,0 +1,54 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
4# RUN: %p/Inputs/libsearch-st.s -o %t2.o
5
6# RUN: echo "EXTERN( undef undef2 )" > %t.script
7# RUN: ld.lld %t -o %t2 %t.script
8# RUN: llvm-readobj %t2 > /dev/null
9
10# RUN: echo "OUTPUT_FORMAT(elf64-x86-64) /*/*/ GROUP(\"%t\" )" > %t.script
11# RUN: ld.lld -o %t2 %t.script
12# RUN: llvm-readobj %t2 > /dev/null
13
14# RUN: rm -f %t.out
15# RUN: echo "OUTPUT(\"%t.out\")" > %t.script
16# RUN: ld.lld %t.script %t
17# RUN: llvm-readobj %t.out > /dev/null
18
19# RUN: echo "SEARCH_DIR(/lib/foo/blah)" > %t.script
20# RUN: ld.lld %t.script %t
21# RUN: llvm-readobj %t.out > /dev/null
22
23# RUN: echo ";SEARCH_DIR(x);SEARCH_DIR(y);" > %t.script
24# RUN: ld.lld %t.script %t
25# RUN: llvm-readobj %t.out > /dev/null
26
27# RUN: echo ";" > %t.script
28# RUN: ld.lld %t.script %t
29# RUN: llvm-readobj %t.out > /dev/null
30
31# RUN: echo "INCLUDE \"%t.script2\" OUTPUT(\"%t.out\")" > %t.script1
32# RUN: echo "GROUP(\"%t\")" > %t.script2
33# RUN: ld.lld %t.script1
34# RUN: llvm-readobj %t2 > /dev/null
35
36# RUN: echo "INCLUDE \"foo.script\"" > %t.script
37# RUN: echo "OUTPUT(\"%t.out\")" > %T/foo.script
38# RUN: not ld.lld %t.script > %t.log 2>&1
39# RUN: FileCheck -check-prefix=INCLUDE_ERR %s < %t.log
40# INCLUDE_ERR: error: {{.+}}.script:1: cannot open foo.script
41# INCLUDE_ERR-NEXT: error: {{.+}}.script:1: INCLUDE "foo.script"
42# RUN: ld.lld -L %T %t.script %t
43
44# RUN: echo "FOO(BAR)" > %t.script
45# RUN: not ld.lld -o foo %t.script > %t.log 2>&1
46# RUN: FileCheck -check-prefix=ERR1 %s < %t.log
47
48# ERR1: unknown directive: FOO
49
50.globl _start, _label
51_start:
52 ret
53_label:
54 ret
deps/lld/test/ELF/linkerscript/loadaddr.s created+42
......@@ -0,0 +1,42 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: echo "SECTIONS { \
4# RUN: . = 0x1000; \
5# RUN: .aaa : AT(0x2000) { *(.aaa) } \
6# RUN: .bbb : { *(.bbb) } \
7# RUN: .ccc : AT(0x3000) { *(.ccc) } \
8# RUN: .ddd : AT(0x4000) { *(.ddd) } \
9# RUN: .text : { *(.text) } \
10# RUN: aaa_lma = LOADADDR(.aaa); \
11# RUN: bbb_lma = LOADADDR(.bbb); \
12# RUN: ccc_lma = LOADADDR(.ccc); \
13# RUN: ddd_lma = LOADADDR(.ddd); \
14# RUN: txt_lma = LOADADDR(.text); \
15# RUN: }" > %t.script
16# RUN: ld.lld %t --script %t.script -o %t2
17# RUN: llvm-objdump -t %t2 | FileCheck %s
18# RUN: echo "SECTIONS { v = LOADADDR(.zzz); }" > %t.script
19# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | FileCheck --check-prefix=ERROR %s
20
21# CHECK: 0000000000002000 *ABS* 00000000 aaa_lma
22# CHECK-NEXT: 0000000000002008 *ABS* 00000000 bbb_lma
23# CHECK-NEXT: 0000000000003000 *ABS* 00000000 ccc_lma
24# CHECK-NEXT: 0000000000004000 *ABS* 00000000 ddd_lma
25# CHECK-NEXT: 0000000000004008 *ABS* 00000000 txt_lma
26# ERROR: {{.*}}.script:1: undefined section .zzz
27
28.global _start
29_start:
30 nop
31
32.section .aaa, "a"
33.quad 0
34
35.section .bbb, "a"
36.quad 0
37
38.section .ccc, "a"
39.quad 0
40
41.section .ddd, "a"
42.quad 0
deps/lld/test/ELF/linkerscript/locationcountererr.s created+11
......@@ -0,0 +1,11 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4# RUN: echo "SECTIONS {" > %t.script
5# RUN: echo ".text 0x2000 : {. = 0x10 ; *(.text) } }" >> %t.script
6# RUN: not ld.lld %t --script %t.script -o %t1 2>&1 | FileCheck %s
7# CHECK: {{.*}}.script:2: unable to move location counter backward for: .text
8
9.globl _start
10_start:
11nop
deps/lld/test/ELF/linkerscript/locationcountererr2.s created+11
......@@ -0,0 +1,11 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: echo "SECTIONS {" > %t.script
4# RUN: echo ". = 0x20; . = 0x10; .text : {} }" >> %t.script
5# RUN: ld.lld %t.o --script %t.script -o %t -shared
6# RUN: llvm-objdump -section-headers %t | FileCheck %s
7# CHECK: Idx Name Size Address
8# CHECK: 1 .text 00000000 0000000000000010
9
10# RUN: echo "SECTIONS { . = 0x20; . = ASSERT(0x1, "foo"); }" > %t2.script
11# RUN: ld.lld %t.o --script %t2.script -o %t -shared
deps/lld/test/ELF/linkerscript/memory.s created+114
......@@ -0,0 +1,114 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4## Check simple RAM-only memory region.
5
6# RUN: echo "MEMORY { ram (rwx) : ORIGIN = 0x8000, LENGTH = 256K } \
7# RUN: SECTIONS { \
8# RUN: .text : { *(.text) } > ram \
9# RUN: .data : { *(.data) } > ram \
10# RUN: }" > %t.script
11# RUN: ld.lld -o %t1 --script %t.script %t
12# RUN: llvm-objdump -section-headers %t1 | FileCheck -check-prefix=RAM %s
13
14# RAM: 1 .text 00000001 0000000000008000 TEXT DATA
15# RAM-NEXT: 2 .data 00001000 0000000000008001 DATA
16
17## Check RAM and ROM memory regions.
18
19# RUN: echo "MEMORY { \
20# RUN: ram (rwx) : ORIGIN = 0, LENGTH = 1024M \
21# RUN: rom (rx) : org = (0x80 * 0x1000 * 0x1000), len = 64M \
22# RUN: } \
23# RUN: SECTIONS { \
24# RUN: .text : { *(.text) } > rom \
25# RUN: .data : { *(.data) } > ram \
26# RUN: }" > %t.script
27# RUN: ld.lld -o %t1 --script %t.script %t
28# RUN: llvm-objdump -section-headers %t1 | FileCheck -check-prefix=RAMROM %s
29
30# RAMROM: 1 .text 00000001 0000000080000000 TEXT DATA
31# RAMROM-NEXT: 2 .data 00001000 0000000000000000 DATA
32
33## Check memory region placement by attributes.
34
35# RUN: echo "MEMORY { \
36# RUN: ram (!rx) : ORIGIN = 0, LENGTH = 1024M \
37# RUN: rom (rx) : o = 0x80000000, l = 64M \
38# RUN: } \
39# RUN: SECTIONS { \
40# RUN: .text : { *(.text) } \
41# RUN: .data : { *(.data) } > ram \
42# RUN: }" > %t.script
43# RUN: ld.lld -o %t1 --script %t.script %t
44# RUN: llvm-objdump -section-headers %t1 | FileCheck -check-prefix=ATTRS %s
45
46# ATTRS: 1 .text 00000001 0000000080000000 TEXT DATA
47# ATTRS: 2 .data 00001000 0000000000000000 DATA
48
49## Check bad `ORIGIN`.
50
51# RUN: echo "MEMORY { ram (rwx) : XYZ = 0x8000 } }" > %t.script
52# RUN: not ld.lld -o %t2 --script %t.script %t 2>&1 \
53# RUN: | FileCheck -check-prefix=ERR1 %s
54# ERR1: {{.*}}.script:1: expected one of: ORIGIN, org, or o
55
56## Check bad `LENGTH`.
57
58# RUN: echo "MEMORY { ram (rwx) : ORIGIN = 0x8000, XYZ = 256K } }" > %t.script
59# RUN: not ld.lld -o %t2 --script %t.script %t 2>&1 \
60# RUN: | FileCheck -check-prefix=ERR2 %s
61# ERR2: {{.*}}.script:1: expected one of: LENGTH, len, or l
62
63## Check duplicate regions.
64
65# RUN: echo "MEMORY { ram (rwx) : o = 8, l = 256K ram (rx) : o = 0, l = 256K }" > %t.script
66# RUN: not ld.lld -o %t2 --script %t.script %t 2>&1 \
67# RUN: | FileCheck -check-prefix=ERR3 %s
68# ERR3: {{.*}}.script:1: region 'ram' already defined
69
70## Check no region available.
71
72# RUN: echo "MEMORY { ram (!rx) : ORIGIN = 0x8000, LENGTH = 256K } \
73# RUN: SECTIONS { \
74# RUN: .text : { *(.text) } \
75# RUN: .data : { *(.data) } > ram \
76# RUN: }" > %t.script
77# RUN: not ld.lld -o %t2 --script %t.script %t 2>&1 \
78# RUN: | FileCheck -check-prefix=ERR4 %s
79# ERR4: {{.*}}: no memory region specified for section '.text'
80
81## Check undeclared region.
82
83# RUN: echo "SECTIONS { .text : { *(.text) } > ram }" > %t.script
84# RUN: not ld.lld -o %t2 --script %t.script %t 2>&1 \
85# RUN: | FileCheck -check-prefix=ERR5 %s
86# ERR5: {{.*}}: memory region 'ram' not declared
87
88## Check region overflow.
89
90# RUN: echo "MEMORY { ram (rwx) : ORIGIN = 0, LENGTH = 2K } \
91# RUN: SECTIONS { \
92# RUN: .text : { *(.text) } > ram \
93# RUN: .data : { *(.data) } > ram \
94# RUN: }" > %t.script
95# RUN: not ld.lld -o %t2 --script %t.script %t 2>&1 \
96# RUN: | FileCheck -check-prefix=ERR6 %s
97# ERR6: {{.*}}: section '.data' will not fit in region 'ram': overflowed by 2049 bytes
98
99## Check invalid region attributes.
100
101# RUN: echo "MEMORY { ram (abc) : ORIGIN = 8000, LENGTH = 256K } }" > %t.script
102# RUN: not ld.lld -o %t2 --script %t.script %t 2>&1 \
103# RUN: | FileCheck -check-prefix=ERR7 %s
104# ERR7: {{.*}}.script:1: invalid memory region attribute
105
106.text
107.global _start
108_start:
109 nop
110
111.data
112b:
113 .long 1
114 .zero 4092
deps/lld/test/ELF/linkerscript/merge-sections-reloc.s created+16
......@@ -0,0 +1,16 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/merge-sections-reloc.s -o %t1.o
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2.o
4# RUN: echo "SECTIONS {}" > %t.script
5# RUN: ld.lld -o %t --script %t.script %t1.o %t2.o
6# RUN: llvm-objdump -s %t | FileCheck %s
7
8## Check that sections content is not corrupted.
9# CHECK: Contents of section .text:
10# CHECK-NEXT: 44332211 00000000 44332211 00000000
11# CHECK-NEXT: f0ffffff ffffffff
12
13.globl _start
14_foo:
15 .quad 0x11223344
16 .quad _start - .
deps/lld/test/ELF/linkerscript/merge-sections-syms.s created+49
......@@ -0,0 +1,49 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3
4# RUN: echo "SECTIONS { \
5# RUN: . = SIZEOF_HEADERS; \
6# RUN: .rodata : { *(.aaa) *(.bbb) A = .; *(.ccc) B = .; } \
7# RUN: }" > %t.script
8# RUN: ld.lld -o %t.so --script %t.script %t.o -shared
9# RUN: llvm-readobj --dyn-symbols %t.so | FileCheck %s
10
11# CHECK: DynamicSymbols [
12# CHECK-NEXT: Symbol {
13# CHECK-NEXT: Name:
14# CHECK-NEXT: Value:
15# CHECK-NEXT: Size:
16# CHECK-NEXT: Binding:
17# CHECK-NEXT: Type:
18# CHECK-NEXT: Other:
19# CHECK-NEXT: Section:
20# CHECK-NEXT: }
21# CHECK-NEXT: Symbol {
22# CHECK-NEXT: Name: A
23# CHECK-NEXT: Value: 0x195
24# CHECK-NEXT: Size:
25# CHECK-NEXT: Binding:
26# CHECK-NEXT: Type:
27# CHECK-NEXT: Other:
28# CHECK-NEXT: Section:
29# CHECK-NEXT: }
30# CHECK-NEXT: Symbol {
31# CHECK-NEXT: Name: B
32# CHECK-NEXT: Value: 0x196
33# CHECK-NEXT: Size:
34# CHECK-NEXT: Binding:
35# CHECK-NEXT: Type:
36# CHECK-NEXT: Other:
37# CHECK-NEXT: Section:
38# CHECK-NEXT: }
39# CHECK-NEXT: ]
40
41
42.section .aaa,"a"
43.byte 11
44
45.section .bbb,"aMS",@progbits,1
46.asciz "foo"
47
48.section .ccc,"a"
49.byte 33
deps/lld/test/ELF/linkerscript/merge-sections.s created+62
......@@ -0,0 +1,62 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4# RUN: echo "SECTIONS { \
5# RUN: . = SIZEOF_HEADERS; \
6# RUN: .foo : { begin = .; *(.foo.*) end = .;} \
7# RUN: }" > %t.script
8# RUN: ld.lld -o %t1 --script %t.script %t -shared
9# RUN: llvm-readobj -s -t %t1 | FileCheck %s
10
11# CHECK: Name: .foo
12# CHECK-NEXT: Type: SHT_PROGBITS
13# CHECK-NEXT: Flags [
14# CHECK-NEXT: SHF_ALLOC
15# CHECK-NEXT: SHF_MERGE
16# CHECK-NEXT: SHF_STRINGS
17# CHECK-NEXT: ]
18# CHECK-NEXT: Address: 0x[[ADDR1:.*]]
19# CHECK-NEXT: Offset: 0x[[ADDR1]]
20# CHECK-NEXT: Size: 14
21# CHECK-NEXT: Link: 0
22# CHECK-NEXT: Info: 0
23# CHECK-NEXT: AddressAlignment: 2
24# CHECK-NEXT: EntrySize: 0
25# CHECK-NEXT: }
26
27# CHECK: Name: begin
28# CHECK-NEXT: Value: 0x[[ADDR1]]
29
30# CHECK: Name: end
31# 0x19E = begin + sizeof(.foo) = 0x190 + 0xE
32# CHECK-NEXT: Value: 0x19E
33
34# Check that we don't crash with --gc-sections
35# RUN: ld.lld --gc-sections -o %t2 --script %t.script %t -shared
36# RUN: llvm-readobj -s -t %t2 | FileCheck %s --check-prefix=GC
37
38# GC: Name: .foo
39# GC-NEXT: Type: SHT_PROGBITS
40# GC-NEXT: Flags [
41# GC-NEXT: SHF_ALLOC
42# GC-NEXT: ]
43
44.section .foo.1a,"aMS",@progbits,1
45.asciz "foo"
46
47.section .foo.1b,"aMS",@progbits,1
48.asciz "foo"
49
50.section .foo.2a,"aM",@progbits,1
51.byte 42
52
53.section .foo.2b,"aM",@progbits,1
54.byte 42
55
56.section .foo.3a,"aM",@progbits,2
57.align 2
58.short 42
59
60.section .foo.3b,"aM",@progbits,2
61.align 2
62.short 42
deps/lld/test/ELF/linkerscript/multi-sections-constraint.s created+34
......@@ -0,0 +1,34 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: echo "SECTIONS { \
4# RUN: .text : { *(.text) } \
5# RUN: . = 0x1000; .aaa : ONLY_IF_RO { *(.aaa.*) } \
6# RUN: . = 0x2000; .aaa : ONLY_IF_RW { *(.aaa.*) } } " > %t.script
7# RUN: ld.lld -o %t1 --script %t.script %t
8# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
9
10# CHECK: Sections:
11# CHECK-NEXT: Idx Name Size Address Type
12# CHECK: .aaa 00000010 0000000000002000 DATA
13
14
15# RUN: echo "SECTIONS { \
16# RUN: .text : { *(.text) } \
17# RUN: . = 0x1000; .aaa : ONLY_IF_RW { *(.aaa.*) } \
18# RUN: . = 0x2000; .aaa : ONLY_IF_RO { *(.aaa.*) } } " > %t2.script
19# RUN: ld.lld -o %t2 --script %t2.script %t
20# RUN: llvm-objdump -section-headers %t2 | FileCheck %s --check-prefix=REV
21
22# REV: Sections:
23# REV-NEXT: Idx Name Size Address Type
24# REV: .aaa 00000010 0000000000001000 DATA
25
26.global _start
27_start:
28 nop
29
30.section .aaa.1, "aw"
31.quad 1
32
33.section .aaa.2, "aw"
34.quad 1
deps/lld/test/ELF/linkerscript/multiple-tbss.s created+45
......@@ -0,0 +1,45 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: echo "SECTIONS { }" > %t.script
4# RUN: ld.lld -T %t.script %t.o -o %t
5# RUN: llvm-readobj -l -s %t | FileCheck %s
6
7# CHECK: Name: .tbss
8# CHECK-NEXT: Type: SHT_NOBITS
9# CHECK-NEXT: Flags [
10# CHECK-NEXT: SHF_ALLOC
11# CHECK-NEXT: SHF_TLS
12# CHECK-NEXT: SHF_WRITE
13# CHECK-NEXT: ]
14# CHECK-NEXT: Address:
15# CHECK-NEXT: Offset:
16# CHECK-NEXT: Size: 8
17# CHECK-NEXT: Link:
18# CHECK-NEXT: Info:
19# CHECK-NEXT: AddressAlignment:
20# CHECK-NEXT: EntrySize:
21# CHECK-NEXT: }
22# CHECK-NEXT: Section {
23# CHECK-NEXT: Index:
24# CHECK-NEXT: Name: foo
25# CHECK-NEXT: Type: SHT_NOBITS
26# CHECK-NEXT: Flags [
27# CHECK-NEXT: SHF_ALLOC
28# CHECK-NEXT: SHF_TLS
29# CHECK-NEXT: SHF_WRITE
30# CHECK-NEXT: ]
31# CHECK-NEXT: Address:
32# CHECK-NEXT: Offset:
33# CHECK-NEXT: Size: 1
34
35# CHECK: Type: PT_TLS
36# CHECK-NEXT: Offset:
37# CHECK-NEXT: VirtualAddress:
38# CHECK-NEXT: PhysicalAddress:
39# CHECK-NEXT: FileSize: 0
40# CHECK-NEXT: MemSize: 9
41
42.section .tbss,"awT",@nobits
43.quad 0
44.section foo,"awT",@nobits
45.byte 0
deps/lld/test/ELF/linkerscript/no-pt-load.s created+5
......@@ -0,0 +1,5 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: echo "PHDRS {foo PT_DYNAMIC ;} " \
4# RUN: "SECTIONS { .text : { *(.text) } : foo }" > %t.script
5# RUN: ld.lld -o %t1 --script %t.script %t.o
deps/lld/test/ELF/linkerscript/no-space.s created+24
......@@ -0,0 +1,24 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3
4# RUN: echo "SECTIONS {foo 0 : {*(foo*)} }" > %t.script
5# RUN: ld.lld -o %t --script %t.script %t.o -shared
6# RUN: llvm-readobj -elf-output-style=GNU -l %t | FileCheck %s
7
8# RUN: echo "SECTIONS {foo : {*(foo*)} }" > %t.script
9# RUN: ld.lld -o %t --script %t.script %t.o -shared
10# RUN: llvm-readobj -elf-output-style=GNU -l %t | FileCheck %s
11
12# There is not enough address space available for the header, so just start the PT_LOAD
13# after it. Don't create a PT_PHDR as the header is not allocated.
14
15# CHECK: Program Headers:
16# CHECK-NEXT: Type Offset VirtAddr PhysAddr
17# CHECK-NEXT: LOAD 0x001000 0x0000000000000000 0x0000000000000000
18
19# CHECK: Section to Segment mapping:
20# CHECK-NEXT: Segment Sections...
21# CHECK-NEXT: 00 foo .text .dynsym .hash .dynstr
22
23.section foo, "a"
24.quad 0
deps/lld/test/ELF/linkerscript/noload.s created+46
......@@ -0,0 +1,46 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: echo "SECTIONS { \
4# RUN: .data_noload_a (NOLOAD) : { *(.data_noload_a) } \
5# RUN: .data_noload_b (0x10000) (NOLOAD) : { *(.data_noload_b) } };" > %t.script
6# RUN: ld.lld -o %t --script %t.script %t.o
7# RUN: llvm-readobj --symbols -sections %t
8
9# CHECK: Section {
10# CHECK-NEXT: Index: 2
11# CHECK-NEXT: Name: .data_noload_a
12# CHECK-NEXT: Type: SHT_NOBITS
13# CHECK-NEXT: Flags [
14# CHECK-NEXT: SHF_ALLOC
15# CHECK-NEXT: SHF_WRITE
16# CHECK-NEXT: ]
17# CHECK-NEXT: Address: 0x0
18# CHECK-NEXT: Offset: 0x1000
19# CHECK-NEXT: Size: 4096
20# CHECK-NEXT: Link: 0
21# CHECK-NEXT: Info: 0
22# CHECK-NEXT: AddressAlignment: 1
23# CHECK-NEXT: EntrySize: 0
24# CHECK-NEXT: }
25# CHECK-NEXT: Section {
26# CHECK-NEXT: Index: 3
27# CHECK-NEXT: Name: .data_noload_b
28# CHECK-NEXT: Type: SHT_NOBITS
29# CHECK-NEXT: Flags [
30# CHECK-NEXT: SHF_ALLOC
31# CHECK-NEXT: SHF_WRITE
32# CHECK-NEXT: ]
33# CHECK-NEXT: Address: 0x10000
34# CHECK-NEXT: Offset: 0x1000
35# CHECK-NEXT: Size: 4096
36# CHECK-NEXT: Link: 0
37# CHECK-NEXT: Info: 0
38# CHECK-NEXT: AddressAlignment: 1
39# CHECK-NEXT: EntrySize: 0
40# CHECK-NEXT: }
41
42.section .data_noload_a,"aw",@progbits
43.zero 4096
44
45.section .data_noload_b,"aw",@progbits
46.zero 4096
deps/lld/test/ELF/linkerscript/non-absolute.s created+30
......@@ -0,0 +1,30 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
3# RUN: echo "SECTIONS { A = . - 0x10; B = A + 0x1; }" > %t.script
4# RUN: ld.lld -shared %t1.o --script %t.script -o %t
5# RUN: llvm-objdump -d %t | FileCheck %s --check-prefix=DUMP
6# RUN: llvm-readobj -t %t | FileCheck %s --check-prefix=SYMBOL
7
8# DUMP: Disassembly of section .text:
9# DUMP-NEXT: foo:
10# DUMP-NEXT: 0: {{.*}} -21(%rip), %eax
11
12# SYMBOL: Symbol {
13# SYMBOL: Name: B
14# SYMBOL-NEXT: Value: 0xFFFFFFFFFFFFFFF1
15# SYMBOL-NEXT: Size: 0
16# SYMBOL-NEXT: Binding: Local
17# SYMBOL-NEXT: Type: None
18# SYMBOL-NEXT: Other [
19# SYMBOL-NEXT: STV_HIDDEN
20# SYMBOL-NEXT: ]
21# SYMBOL-NEXT: Section: .text
22# SYMBOL-NEXT: }
23
24.text
25.globl foo
26.type foo, @function
27foo:
28 movl B(%rip), %eax
29
30.hidden B
deps/lld/test/ELF/linkerscript/non-absolute2.s created+12
......@@ -0,0 +1,12 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
3# RUN: echo "SECTIONS { A = . + 0x1; . += 0x1000; }" > %t.script
4# RUN: ld.lld -shared %t1.o --script %t.script -o %t
5# RUN: llvm-objdump -section-headers -t %t | FileCheck %s
6
7# CHECK: Sections:
8# CHECK-NEXT: Idx Name Size Address
9# CHECK-NEXT: 0 00000000 0000000000000000
10# CHECK-NEXT: 1 .text 00000000 0000000000001000
11
12# CHECK: 0000000000000001 .text 00000000 A
deps/lld/test/ELF/linkerscript/non-alloc-segment.s created+44
......@@ -0,0 +1,44 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3
4################################################################################
5## Test that non-alloc section .foo can be assigned to a segment. Check that
6## the values of the offset and file size of this segment's PHDR are correct.
7##
8## This functionality allows non-alloc metadata, which is not required at
9## run-time, to be added to a custom segment in a file. This metadata may be
10## read/edited by tools/loader using the values of the offset and file size from
11## the custom segment's PHDR. This is particularly important if section headers
12## have been stripped.
13# RUN: echo "PHDRS {text PT_LOAD; foo 0x12345678;} \
14# RUN: SECTIONS { \
15# RUN: .text : {*(.text .text*)} :text \
16# RUN: .foo : {*(.foo)} :foo \
17# RUN: }" > %t.script
18# RUN: ld.lld -o %t --script %t.script %t.o
19# RUN: llvm-readobj -elf-output-style=GNU -s -l %t | FileCheck %s
20# RUN: llvm-readobj -l %t | FileCheck --check-prefix=PHDR %s
21
22# CHECK: Program Headers:
23# CHECK-NEXT: Type
24# CHECK-NEXT: LOAD
25# CHECK-NEXT: <unknown>: 0x12345678
26
27# CHECK: Section to Segment mapping:
28# CHECK-NEXT: Segment Sections...
29# CHECK-NEXT: 00 .text
30# CHECK-NEXT: 01 .foo
31
32# PHDR: Type: (0x12345678)
33# PHDR-NEXT: Offset: 0x1004
34# PHDR-NEXT: VirtualAddress
35# PHDR-NEXT: PhysicalAddress
36# PHDR-NEXT: FileSize: 4
37
38.global _start
39_start:
40 nop
41
42.section .foo
43 .align 4
44 .long 0
deps/lld/test/ELF/linkerscript/non-alloc.s created+23
......@@ -0,0 +1,23 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
3
4# RUN: echo "SECTIONS { .foo 0 : {*(foo)} }" > %t.script
5# RUN: ld.lld -o %t1 --script %t.script %t -shared
6# RUN: llvm-readobj -elf-output-style=GNU -s -l %t1 | FileCheck %s
7
8# Test that we create all necessary PT_LOAD. We use to stop at the first
9# non-alloc, causing us to not create PT_LOAD for linker generated sections.
10
11# CHECK: Program Headers:
12# CHECK-NEXT: Type
13# CHECK-NEXT: LOAD {{.*}} R E
14# CHECK-NEXT: LOAD {{.*}} RW
15
16# CHECK: Section to Segment mapping:
17# CHECK-NEXT: Segment Sections...
18# CHECK-NEXT: 00 .text .dynsym .hash .dynstr
19# CHECK-NEXT: 01 .dynamic
20
21nop
22.section foo
23.quad 0
deps/lld/test/ELF/linkerscript/numbers.s created+80
......@@ -0,0 +1,80 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: echo "SECTIONS { \
4# RUN: . = 1000h; \
5# RUN: .hex1 : { *(.hex.1) } \
6# RUN: . = 1010H; \
7# RUN: .hex2 : { *(.hex.2) } \
8# RUN: . = 10k; \
9# RUN: .kilo1 : { *(.kilo.1) } \
10# RUN: . = 11K; \
11# RUN: .kilo2 : { *(.kilo.2) } \
12# RUN: . = 1m; \
13# RUN: .mega1 : { *(.mega.1) } \
14# RUN: . = 2M; \
15# RUN: .mega2 : { *(.mega.2) } \
16# RUN: }" > %t.script
17# RUN: ld.lld %t --script %t.script -o %t2
18# RUN: llvm-objdump -section-headers %t2 | FileCheck %s
19
20# CHECK: Sections:
21# CHECK-NEXT: Idx Name Size Address
22# CHECK-NEXT: 0 00000000 0000000000000000
23# CHECK-NEXT: 1 .hex1 00000008 0000000000001000
24# CHECK-NEXT: 2 .hex2 00000008 0000000000001010
25# CHECK-NEXT: 3 .kilo1 00000008 0000000000002800
26# CHECK-NEXT: 4 .kilo2 00000008 0000000000002c00
27# CHECK-NEXT: 5 .mega1 00000008 0000000000100000
28# CHECK-NEXT: 6 .mega2 00000008 0000000000200000
29
30## Mailformed number errors.
31# RUN: echo "SECTIONS { . = 0x11h; }" > %t2.script
32# RUN: not ld.lld %t --script %t2.script -o %t3 2>&1 | \
33# RUN: FileCheck --check-prefix=ERR1 %s
34# ERR1: malformed number: 0x11h
35
36# RUN: echo "SECTIONS { . = 0x11k; }" > %t3.script
37# RUN: not ld.lld %t --script %t3.script -o %t4 2>&1 | \
38# RUN: FileCheck --check-prefix=ERR2 %s
39# ERR2: malformed number: 0x11k
40
41# RUN: echo "SECTIONS { . = 0x11m; }" > %t4.script
42# RUN: not ld.lld %t --script %t4.script -o %t5 2>&1 | \
43# RUN: FileCheck --check-prefix=ERR3 %s
44# ERR3: malformed number: 0x11m
45
46## Make sure that numbers can be followed by a ":" with and without a space,
47## e.g. "0x100 :" or "0x100:"
48# RUN: echo "SECTIONS { \
49# RUN: .hex1 0x400 : { *(.hex.1) } \
50# RUN: .hex2 0x500:{ *(.hex.2) } \
51# RUN: }" > %t5.script
52# RUN: ld.lld %t --script %t5.script -o %t6
53# RUN: llvm-objdump -section-headers %t6 | FileCheck -check-prefix=SECADDR %s
54# SECADDR: Sections:
55# SECADDR-NEXT: Idx Name Size Address
56# SECADDR-NEXT: 0 00000000 0000000000000000
57# SECADDR-NEXT: 1 .hex1 00000008 0000000000000400
58# SECADDR-NEXT: 2 .hex2 00000008 0000000000000500
59
60.globl _start
61_start:
62nop
63
64.section .hex.1, "a"
65.quad 0
66
67.section .kilo.1, "a"
68.quad 0
69
70.section .mega.1, "a"
71.quad 0
72
73.section .hex.2, "a"
74.quad 0
75
76.section .kilo.2, "a"
77.quad 0
78
79.section .mega.2, "a"
80.quad 0
deps/lld/test/ELF/linkerscript/obj-symbol-value.s created+19
......@@ -0,0 +1,19 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: echo "SECTIONS { foo = bar; .bar : { *(.bar*) } }" > %t.script
4# RUN: ld.lld %t.o --script %t.script -o %t.so -shared
5# RUN: llvm-readobj -t %t.so | FileCheck %s
6
7# CHECK: Symbol {
8# CHECK: Name: bar
9# CHECK-NEXT: Value: 0x[[VAL:.*]]
10# CHECK: Name: foo
11# CHECK-NEXT: Value: 0x[[VAL]]
12
13.section .bar.1, "a"
14.quad 0
15
16.section .bar.2, "a"
17.quad 0
18.global bar
19bar:
deps/lld/test/ELF/linkerscript/openbsd-bootdata.s created+7
......@@ -0,0 +1,7 @@
1# RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o
2# RUN: echo "PHDRS { boot PT_OPENBSD_BOOTDATA; }" > %t.script
3# RUN: ld.lld --script %t.script %t.o -o %t
4# RUN: llvm-readobj --program-headers -s %t | FileCheck %s
5
6# CHECK: ProgramHeader {
7# CHECK: Type: PT_OPENBSD_BOOTDATA (0x65A41BE6)
deps/lld/test/ELF/linkerscript/openbsd-randomize.s created+23
......@@ -0,0 +1,23 @@
1# RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o
2# RUN: echo "PHDRS { text PT_LOAD FILEHDR PHDRS; rand PT_OPENBSD_RANDOMIZE; } \
3# RUN: SECTIONS { . = SIZEOF_HEADERS; \
4# RUN: .text : { *(.text) } \
5# RUN: .openbsd.randomdata : { *(.openbsd.randomdata) } : rand }" > %t.script
6# RUN: ld.lld --script %t.script %t.o -o %t
7# RUN: llvm-readobj --program-headers -s %t | FileCheck %s
8
9# CHECK: ProgramHeader {
10# CHECK: Type: PT_OPENBSD_RANDOMIZE (0x65A3DBE6)
11# CHECK-NEXT: Offset: 0x74
12# CHECK-NEXT: VirtualAddress: 0x74
13# CHECK-NEXT: PhysicalAddress: 0x74
14# CHECK-NEXT: FileSize: 8
15# CHECK-NEXT: MemSize: 8
16# CHECK-NEXT: Flags [ (0x4)
17# CHECK-NEXT: PF_R (0x4)
18# CHECK-NEXT: ]
19# CHECK-NEXT: Alignment: 1
20# CHECK-NEXT: }
21
22.section .openbsd.randomdata, "a"
23.quad 0
deps/lld/test/ELF/linkerscript/openbsd-wxneeded.s created+17
......@@ -0,0 +1,17 @@
1# RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o
2# RUN: echo "PHDRS { text PT_LOAD FILEHDR PHDRS; wxneeded PT_OPENBSD_WXNEEDED; }" > %t.script
3# RUN: ld.lld -z wxneeded --script %t.script %t.o -o %t
4# RUN: llvm-readobj --program-headers %t | FileCheck %s
5
6# CHECK: ProgramHeader {
7# CHECK: Type: PT_OPENBSD_WXNEEDED (0x65A3DBE7)
8# CHECK-NEXT: Offset: 0x0
9# CHECK-NEXT: VirtualAddress: 0x0
10# CHECK-NEXT: PhysicalAddress: 0x0
11# CHECK-NEXT: FileSize: 0
12# CHECK-NEXT: MemSize: 0
13# CHECK-NEXT: Flags [
14# CHECK-NEXT: PF_R
15# CHECK-NEXT: ]
16# CHECK-NEXT: Alignment: 0
17# CHECK-NEXT: }
deps/lld/test/ELF/linkerscript/operators.s created+93
......@@ -0,0 +1,93 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: echo "SECTIONS { \
4# RUN: plus = 1 + 2 + 3; \
5# RUN: minus = 5 - 1; \
6# RUN: div = 6 / 2; \
7# RUN: mul = 1 + 2 * 3; \
8# RUN: nospace = 1+2*6/3; \
9# RUN: braces = 1 + (2 + 3) * 4; \
10# RUN: and = 0xbb & 0xee; \
11# RUN: ternary1 = 1 ? 1 : 2; \
12# RUN: ternary2 = 0 ? 1 : 2; \
13# RUN: less = 1 < 0 ? 1 : 2; \
14# RUN: lesseq = 1 <= 1 ? 1 : 2; \
15# RUN: greater = 0 > 1 ? 1 : 2; \
16# RUN: greatereq = 1 >= 1 ? 1 : 2; \
17# RUN: eq = 1 == 1 ? 1 : 2; \
18# RUN: neq = 1 != 1 ? 1 : 2; \
19# RUN: plusassign = 1; \
20# RUN: plusassign += 2; \
21# RUN: unary = -1 + 3; \
22# RUN: lshift = 1 << 5; \
23# RUN: rshift = 0xff >> 3; \
24# RUN: maxpagesize = CONSTANT (MAXPAGESIZE); \
25# RUN: commonpagesize = CONSTANT (COMMONPAGESIZE); \
26# RUN: . = 0xfff0; \
27# RUN: datasegmentalign = DATA_SEGMENT_ALIGN (0xffff, 0); \
28# RUN: }" > %t.script
29# RUN: ld.lld %t --script %t.script -o %t2
30# RUN: llvm-objdump -t %t2 | FileCheck %s
31
32# CHECK: 00000000000006 *ABS* 00000000 plus
33# CHECK: 00000000000004 *ABS* 00000000 minus
34# CHECK: 00000000000003 *ABS* 00000000 div
35# CHECK: 00000000000007 *ABS* 00000000 mul
36# CHECK: 00000000000005 *ABS* 00000000 nospace
37# CHECK: 00000000000015 *ABS* 00000000 braces
38# CHECK: 000000000000aa *ABS* 00000000 and
39# CHECK: 00000000000001 *ABS* 00000000 ternary1
40# CHECK: 00000000000002 *ABS* 00000000 ternary2
41# CHECK: 00000000000002 *ABS* 00000000 less
42# CHECK: 00000000000001 *ABS* 00000000 lesseq
43# CHECK: 00000000000002 *ABS* 00000000 greater
44# CHECK: 00000000000001 *ABS* 00000000 greatereq
45# CHECK: 00000000000001 *ABS* 00000000 eq
46# CHECK: 00000000000002 *ABS* 00000000 neq
47# CHECK: 00000000000003 *ABS* 00000000 plusassign
48# CHECK: 00000000000002 *ABS* 00000000 unary
49# CHECK: 00000000000020 *ABS* 00000000 lshift
50# CHECK: 0000000000001f *ABS* 00000000 rshift
51# CHECK: 00000000001000 *ABS* 00000000 maxpagesize
52# CHECK: 00000000001000 *ABS* 00000000 commonpagesize
53# CHECK: 0000000000ffff *ABS* 00000000 datasegmentalign
54
55## Mailformed number error.
56# RUN: echo "SECTIONS { . = 0x12Q41; }" > %t.script
57# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \
58# RUN: FileCheck --check-prefix=NUMERR %s
59# NUMERR: malformed number: 0x12Q41
60
61## Missing closing bracket.
62# RUN: echo "SECTIONS { . = (1; }" > %t.script
63# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \
64# RUN: FileCheck --check-prefix=BRACKETERR %s
65# BRACKETERR: ) expected, but got ;
66
67## Missing opening bracket.
68# RUN: echo "SECTIONS { . = 1); }" > %t.script
69# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \
70# RUN: FileCheck --check-prefix=BRACKETERR2 %s
71# BRACKETERR2: ; expected, but got )
72
73## Empty expression.
74# RUN: echo "SECTIONS { . = ; }" > %t.script
75# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \
76# RUN: FileCheck --check-prefix=ERREXPR %s
77# ERREXPR: malformed number: ;
78
79## Div by zero error.
80# RUN: echo "SECTIONS { . = 1 / 0; }" > %t.script
81# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \
82# RUN: FileCheck --check-prefix=DIVZERO %s
83# DIVZERO: division by zero
84
85## Broken ternary operator expression.
86# RUN: echo "SECTIONS { . = 1 ? 2; }" > %t.script
87# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \
88# RUN: FileCheck --check-prefix=TERNERR %s
89# TERNERR: : expected, but got ;
90
91.globl _start
92_start:
93nop
deps/lld/test/ELF/linkerscript/orphan-align.s created+28
......@@ -0,0 +1,28 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: echo "SECTIONS { \
4# RUN: . = SIZEOF_HEADERS; \
5# RUN: .text : { *(.text) } \
6# RUN: . = ALIGN(0x1000); \
7# RUN: .data.rel.ro : { *(.data.rel.ro) } \
8# RUN: }" > %t.script
9# RUN: ld.lld -o %t -T %t.script %t.o -shared
10# RUN: llvm-readobj -l %t | FileCheck %s
11
12
13# Test that the orphan section foo is placed before the ALIGN and so the second
14# PT_LOAD is aligned.
15
16
17# CHECK: Type: PT_LOAD
18# CHECK-NEXT: Offset: 0x0
19
20# CHECK: Type: PT_LOAD
21# CHECK-NEXT: Offset: 0x1000
22
23nop
24.section .data.rel.ro, "aw"
25.byte 0
26
27.section foo, "ax"
28nop
deps/lld/test/ELF/linkerscript/orphan-first-cmd.s created+20
......@@ -0,0 +1,20 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: echo "SECTIONS { \
4# RUN: foo = 123; \
5# RUN: . = 0x1000; \
6# RUN: . = 0x2000; \
7# RUN: .bar : { *(.bar) } \
8# RUN: }" > %t.script
9# RUN: ld.lld -o %t -T %t.script %t.o -shared
10# RUN: llvm-readobj -s %t | FileCheck %s
11
12# CHECK: Name: .text
13# CHECK-NEXT: Type: SHT_PROGBITS
14# CHECK-NEXT: Flags [
15# CHECK-NEXT: SHF_ALLOC
16# CHECK-NEXT: SHF_EXECINSTR
17# CHECK-NEXT: ]
18# CHECK-NEXT: Address: 0x1000
19
20.section .bar, "aw"
deps/lld/test/ELF/linkerscript/orphan.s created+36
......@@ -0,0 +1,36 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: echo "SECTIONS { \
4# RUN: .text : { *(.text) } \
5# RUN: .rw1 : { *(.rw1) } \
6# RUN: .rw2 : { *(.rw2) } \
7# RUN: .rw3 : { *(.rw3) } \
8# RUN: }" > %t.script
9# RUN: ld.lld -o %t1 --script %t.script %t
10# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
11
12## .jcr is a relro section and should be placed after other RW sections.
13## .bss is SHT_NOBITS section and should be last RW section, so some space
14## in ELF file could be saved.
15# CHECK: 0 00000000 0000000000000000
16# CHECK-NEXT: 1 .text 00000000 0000000000000000 TEXT DATA
17# CHECK-NEXT: 2 .rw1 00000008 0000000000000000 DATA
18# CHECK-NEXT: 3 .rw2 00000008 0000000000000008 DATA
19# CHECK-NEXT: 4 .rw3 00000008 0000000000000010 DATA
20# CHECK-NEXT: 5 .jcr 00000008 0000000000000018 DATA
21# CHECK-NEXT: 6 .bss 00000008 0000000000000020 BSS
22
23.section .rw1, "aw"
24 .quad 0
25
26.section .rw2, "aw"
27 .quad 0
28
29.section .rw3, "aw"
30 .quad 0
31
32.section .jcr, "aw"
33 .quad 0
34
35.section .bss, "aw",@nobits
36 .quad 0
deps/lld/test/ELF/linkerscript/orphans.s created+31
......@@ -0,0 +1,31 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4# RUN: echo "SECTIONS { .writable : { *(.writable) } }" > %t.script
5# RUN: ld.lld -o %t.out --script %t.script %t
6# RUN: llvm-objdump -section-headers %t.out | \
7# RUN: FileCheck -check-prefix=TEXTORPHAN %s
8
9# RUN: echo "SECTIONS { .text : { *(.text) } }" > %t.script
10# RUN: ld.lld -o %t.out --script %t.script %t
11# RUN: llvm-objdump -section-headers %t.out | \
12# RUN: FileCheck -check-prefix=WRITABLEORPHAN %s
13
14# TEXTORPHAN: Sections:
15# TEXTORPHAN-NEXT: Idx Name
16# TEXTORPHAN-NEXT: 0
17# TEXTORPHAN-NEXT: 1 .text
18# TEXTORPHAN-NEXT: 2 .writable
19
20# WRITABLEORPHAN: Sections:
21# WRITABLEORPHAN-NEXT: Idx Name
22# WRITABLEORPHAN-NEXT: 0
23# WRITABLEORPHAN-NEXT: 1 .text
24# WRITABLEORPHAN-NEXT: 2 .writable
25
26.global _start
27_start:
28 nop
29
30.section .writable,"aw"
31 .zero 4
deps/lld/test/ELF/linkerscript/ouputformat.s created+9
......@@ -0,0 +1,9 @@
1# REQUIRES: x86
2# RUN: echo "OUTPUT_FORMAT(x, y, z)" > %t.script
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %t1
4# RUN: ld.lld -shared -o %t2 %t1 %t.script
5# RUN: llvm-readobj %t2 > /dev/null
6
7# RUN: echo "OUTPUT_FORMAT(x, y)" > %t.script
8# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %t1
9# RUN: not ld.lld -shared -o %t2 %t1 %t.script
deps/lld/test/ELF/linkerscript/out-of-order.s created+19
......@@ -0,0 +1,19 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-linux %s -o %t.o
3# RUN: echo "SECTIONS { .data 0x4000 : { *(.data) } .text 0x2000 : { *(.text) } }" > %t.script
4# RUN: ld.lld -o %t.so --script %t.script %t.o -shared
5# RUN: llvm-objdump -section-headers %t.so | FileCheck %s
6
7# CHECK: Sections:
8# CHECK-NEXT: Idx Name Size Address Type
9# CHECK-NEXT: 0 00000000 0000000000000000
10# CHECK-NEXT: 1 .data 00000008 0000000000004000 DATA
11# CHECK-NEXT: 2 .dynamic 00000060 0000000000004008
12# CHECK-NEXT: 3 .text 00000008 0000000000002000 TEXT DATA
13# CHECK-NEXT: 4 .dynsym 00000018 0000000000002008
14# CHECK-NEXT: 5 .hash 00000010 0000000000002020
15# CHECK-NEXT: 6 .dynstr 00000001 0000000000002030
16
17.quad 0
18.data
19.quad 0
deps/lld/test/ELF/linkerscript/output-too-large.s created+9
......@@ -0,0 +1,9 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o
3# RUN: echo "SECTIONS { .text : { . = 0xffffffff; *(.text*); } }" > %t.script
4# RUN: not ld.lld --script %t.script %t.o -o %t 2>&1 | FileCheck %s
5# CHECK: error: output file too large
6
7.global _start
8_start:
9 nop
deps/lld/test/ELF/linkerscript/outputarch.s created+4
......@@ -0,0 +1,4 @@
1# REQUIRES: x86
2# RUN: echo "OUTPUT_ARCH(All data written here is ignored)" > %t.script
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %t1
4# RUN: ld.lld -shared -o %t2 %t1 %t.script
deps/lld/test/ELF/linkerscript/outsections-addr.s created+110
......@@ -0,0 +1,110 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: echo "SECTIONS { \
4# RUN: .aaa 0x2000 : { *(.aaa) } \
5# RUN: .bbb 0x1 ? 0x3000 : 0x4000 : { *(.bbb) } \
6# RUN: .ccc ALIGN(CONSTANT(MAXPAGESIZE)) + (. & (CONSTANT(MAXPAGESIZE) - 1)) : { *(.ccc) } \
7# RUN: .ddd 0x5001 : { *(.ddd) } \
8# RUN: }" > %t.script
9# RUN: ld.lld %t --script %t.script -o %tout
10# RUN: llvm-readobj -s %tout | FileCheck %s
11
12## Check:
13## 1) Simple constant as address.
14## 2) That something that contains ":" character, like ternary
15## operator works as expression.
16## 3) That complex expressions work.
17## 4) That section alignment still applied to explicitly specified address.
18
19#CHECK:Sections [
20#CHECK: Section {
21#CHECK: Index: 0
22#CHECK: Name:
23#CHECK: Type: SHT_NULL
24#CHECK: Flags [
25#CHECK: ]
26#CHECK: Address: 0x0
27#CHECK: Offset: 0x0
28#CHECK: Size: 0
29#CHECK: Link: 0
30#CHECK: Info: 0
31#CHECK: AddressAlignment: 0
32#CHECK: EntrySize: 0
33#CHECK: }
34#CHECK: Section {
35#CHECK: Index: 1
36#CHECK: Name: .aaa
37#CHECK: Type: SHT_PROGBITS
38#CHECK: Flags [
39#CHECK: SHF_ALLOC
40#CHECK: ]
41#CHECK: Address: 0x2000
42#CHECK: Offset: 0x1000
43#CHECK: Size: 8
44#CHECK: Link: 0
45#CHECK: Info: 0
46#CHECK: AddressAlignment: 1
47#CHECK: EntrySize: 0
48#CHECK: }
49#CHECK: Section {
50#CHECK: Index: 2
51#CHECK: Name: .bbb
52#CHECK: Type: SHT_PROGBITS
53#CHECK: Flags [
54#CHECK: SHF_ALLOC
55#CHECK: ]
56#CHECK: Address: 0x3000
57#CHECK: Offset: 0x2000
58#CHECK: Size: 8
59#CHECK: Link: 0
60#CHECK: Info: 0
61#CHECK: AddressAlignment: 1
62#CHECK: EntrySize: 0
63#CHECK: }
64#CHECK: Section {
65#CHECK: Index: 3
66#CHECK: Name: .ccc
67#CHECK: Type: SHT_PROGBITS
68#CHECK: Flags [
69#CHECK: SHF_ALLOC
70#CHECK: ]
71#CHECK: Address: 0x4008
72#CHECK: Offset: 0x3008
73#CHECK: Size: 8
74#CHECK: Link: 0
75#CHECK: Info: 0
76#CHECK: AddressAlignment: 1
77#CHECK: EntrySize: 0
78#CHECK: }
79#CHECK: Section {
80#CHECK: Index: 4
81#CHECK: Name: .ddd
82#CHECK: Type: SHT_PROGBITS
83#CHECK: Flags [
84#CHECK: SHF_ALLOC
85#CHECK: ]
86#CHECK: Address: 0x5010
87#CHECK: Offset: 0x4010
88#CHECK: Size: 8
89#CHECK: Link: 0
90#CHECK: Info: 0
91#CHECK: AddressAlignment: 16
92#CHECK: EntrySize: 0
93#CHECK: }
94
95.globl _start
96_start:
97nop
98
99.section .aaa, "a"
100.quad 0
101
102.section .bbb, "a"
103.quad 0
104
105.section .ccc, "a"
106.quad 0
107
108.section .ddd, "a"
109.align 16
110.quad 0
deps/lld/test/ELF/linkerscript/page-size-align.s created+22
......@@ -0,0 +1,22 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3
4# RUN: echo "SECTIONS { \
5# RUN: . = SIZEOF_HEADERS; \
6# RUN: .text : { *(.text) } \
7# RUN: . = ALIGN(CONSTANT(MAXPAGESIZE)); \
8# RUN: . = . + 0x3000; \
9# RUN: .dynamic : { *(.dynamic) } \
10# RUN: }" > %t.script
11
12# RUN: ld.lld -T %t.script -z max-page-size=0x4000 %t.o -o %t.so -shared
13# RUN: llvm-readobj -s %t.so | FileCheck %s
14
15# CHECK: Name: .dynamic
16# CHECK-NEXT: Type: SHT_DYNAMIC
17# CHECK-NEXT: Flags [
18# CHECK-NEXT: SHF_ALLOC
19# CHECK-NEXT: SHF_WRITE
20# CHECK-NEXT: ]
21# CHECK-NEXT: Address: 0x7000
22# CHECK-NEXT: Offset: 0x3000
deps/lld/test/ELF/linkerscript/page-size.s created+66
......@@ -0,0 +1,66 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4# RUN: ld.lld -z max-page-size=0x4000 %t -o %t2
5# RUN: llvm-readobj -program-headers %t2 | FileCheck %s
6
7# CHECK: ProgramHeaders [
8# CHECK: ProgramHeader {
9# CHECK: Type: PT_LOAD
10# CHECK-NEXT: Offset: 0x0
11# CHECK-NEXT: VirtualAddress: 0x200000
12# CHECK-NEXT: PhysicalAddress: 0x200000
13# CHECK-NEXT: FileSize: 344
14# CHECK-NEXT: MemSize: 344
15# CHECK-NEXT: Flags [
16# CHECK-NEXT: PF_R
17# CHECK-NEXT: ]
18# CHECK-NEXT: Alignment: 16384
19# CHECK-NEXT: }
20# CHECK-NEXT: ProgramHeader {
21# CHECK-NEXT: Type: PT_LOAD
22# CHECK-NEXT: Offset: 0x4000
23# CHECK-NEXT: VirtualAddress: 0x204000
24# CHECK-NEXT: PhysicalAddress: 0x204000
25# CHECK-NEXT: FileSize: 1
26# CHECK-NEXT: MemSize: 1
27# CHECK-NEXT: Flags [
28# CHECK-NEXT: PF_R
29# CHECK-NEXT: PF_X
30# CHECK-NEXT: ]
31# CHECK-NEXT: Alignment: 16384
32# CHECK-NEXT: }
33# CHECK-NEXT: ProgramHeader {
34# CHECK-NEXT: Type: PT_LOAD
35# CHECK-NEXT: Offset: 0x8000
36# CHECK-NEXT: VirtualAddress: 0x208000
37# CHECK-NEXT: PhysicalAddress: 0x208000
38# CHECK-NEXT: FileSize: 8
39# CHECK-NEXT: MemSize: 8
40# CHECK-NEXT: Flags [
41# CHECK-NEXT: PF_R
42# CHECK-NEXT: PF_W
43# CHECK-NEXT: ]
44# CHECK-NEXT: Alignment: 16384
45# CHECK-NEXT: }
46
47# RUN: echo "SECTIONS { symbol = CONSTANT(MAXPAGESIZE); }" > %t.script
48# RUN: ld.lld -z max-page-size=0x4000 -o %t1 --script %t.script %t
49# RUN: llvm-objdump -t %t1 | FileCheck -check-prefix CHECK-SCRIPT %s
50
51# CHECK-SCRIPT: 0000000000004000 *ABS* 00000000 symbol
52
53# RUN: not ld.lld -z max-page-size=0x1001 -o %t1 --script %t.script %t 2>&1 \
54# RUN: | FileCheck -check-prefix=ERR1 %s
55# ERR1: max-page-size: value isn't a power of 2
56
57# RUN: not ld.lld -z max-page-size=-0x1000 -o %t1 --script %t.script %t 2>&1 \
58# RUN: | FileCheck -check-prefix=ERR2 %s
59# ERR2: invalid max-page-size: -0x1000
60
61.global _start
62_start:
63 nop
64
65.section .a, "aw"
66.quad 0
deps/lld/test/ELF/linkerscript/phdr-check.s created+15
......@@ -0,0 +1,15 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4# RUN: echo "SECTIONS { . = 0x10000000; .text : {*(.text.*)} }" > %t.script
5# RUN: ld.lld -o %t1 --script %t.script %t
6# RUN: llvm-readobj -program-headers %t1 | FileCheck %s
7# CHECK: ProgramHeaders [
8# CHECK-NEXT: ProgramHeader {
9# CHECK-NEXT: Type: PT_PHDR (0x6)
10# CHECK-NEXT: Offset: 0x40
11# CHECK-NEXT: VirtualAddress: 0xFFFF040
12
13.global _start
14_start:
15 nop
deps/lld/test/ELF/linkerscript/phdrs-flags.s created+58
......@@ -0,0 +1,58 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: echo "PHDRS {all PT_LOAD FILEHDR PHDRS FLAGS (1 | 1 + 0x1);} \
4# RUN: SECTIONS { \
5# RUN: . = 0x10000200; \
6# RUN: .text : {*(.text*)} :all \
7# RUN: .foo : {*(.foo.*)} :all \
8# RUN: .data : {*(.data.*)} :all}" > %t.script
9# RUN: ld.lld -o %t1 --script %t.script %t
10# RUN: llvm-readobj -program-headers %t1 | FileCheck %s
11
12# RUN: echo "PHDRS {all PT_LOAD FILEHDR PHDRS FLAGS (0x1);} \
13# RUN: SECTIONS { \
14# RUN: . = 0x10000200; \
15# RUN: .text : {*(.text*)} :all \
16# RUN: .foo : {*(.foo.*)} \
17# RUN: .data : {*(.data.*)} }" > %t.script
18# RUN: ld.lld -o %t1 --script %t.script %t
19# RUN: llvm-readobj -program-headers %t1 | FileCheck --check-prefix=DEFHDR %s
20
21# CHECK: ProgramHeaders [
22# CHECK-NEXT: ProgramHeader {
23# CHECK-NEXT: Type: PT_LOAD (0x1)
24# CHECK-NEXT: Offset: 0x0
25# CHECK-NEXT: VirtualAddress: 0x10000000
26# CHECK-NEXT: PhysicalAddress: 0x10000000
27# CHECK-NEXT: FileSize: 521
28# CHECK-NEXT: MemSize: 521
29# CHECK-NEXT: Flags [
30# CHECK-NEXT: PF_W (0x2)
31# CHECK-NEXT: PF_X (0x1)
32# CHECK-NEXT: ]
33
34# DEFHDR: ProgramHeaders [
35# DEFHDR-NEXT: ProgramHeader {
36# DEFHDR-NEXT: Type: PT_LOAD (0x1)
37# DEFHDR-NEXT: Offset: 0x0
38# DEFHDR-NEXT: VirtualAddress: 0x10000000
39# DEFHDR-NEXT: PhysicalAddress: 0x10000000
40# DEFHDR-NEXT: FileSize: 521
41# DEFHDR-NEXT: MemSize: 521
42# DEFHDR-NEXT: Flags [ (0x1)
43# DEFHDR-NEXT: PF_X (0x1)
44# DEFHDR-NEXT: ]
45# DEFHDR-NEXT: Alignment: 4096
46# DEFHDR-NEXT: }
47
48.global _start
49_start:
50 nop
51
52.section .foo.1,"a"
53foo1:
54 .long 0
55
56.section .foo.2,"aw"
57foo2:
58 .long 0
deps/lld/test/ELF/linkerscript/phdrs.s created+143
......@@ -0,0 +1,143 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: echo "PHDRS {all PT_LOAD FILEHDR PHDRS ;} \
4# RUN: SECTIONS { \
5# RUN: . = 0x10000200; \
6# RUN: .text : {*(.text*)} :all \
7# RUN: .foo : {*(.foo.*)} :all \
8# RUN: .data : {*(.data.*)} :all}" > %t.script
9# RUN: ld.lld -o %t1 --script %t.script %t
10# RUN: llvm-readobj -program-headers %t1 | FileCheck %s
11
12## Check that program headers are not written, unless we explicitly tell
13## lld to do this.
14# RUN: echo "PHDRS {all PT_LOAD;} \
15# RUN: SECTIONS { \
16# RUN: . = 0x10000200; \
17# RUN: /DISCARD/ : {*(.text*)} \
18# RUN: .foo : {*(.foo.*)} :all \
19# RUN: }" > %t.script
20# RUN: ld.lld -o %t1 --script %t.script %t
21# RUN: llvm-readobj -program-headers %t1 | FileCheck --check-prefix=NOPHDR %s
22
23## Check the AT(expr)
24# RUN: echo "PHDRS {all PT_LOAD FILEHDR PHDRS AT(0x500 + 0x500) ;} \
25# RUN: SECTIONS { \
26# RUN: . = 0x10000200; \
27# RUN: .text : {*(.text*)} :all \
28# RUN: .foo : {*(.foo.*)} :all \
29# RUN: .data : {*(.data.*)} :all}" > %t.script
30# RUN: ld.lld -o %t1 --script %t.script %t
31# RUN: llvm-readobj -program-headers %t1 | FileCheck --check-prefix=AT %s
32
33# RUN: echo "PHDRS {all PT_LOAD FILEHDR PHDRS ;} \
34# RUN: SECTIONS { \
35# RUN: . = 0x10000200; \
36# RUN: .text : {*(.text*)} :all \
37# RUN: .foo : {*(.foo.*)} \
38# RUN: .data : {*(.data.*)} }" > %t.script
39# RUN: ld.lld -o %t1 --script %t.script %t
40# RUN: llvm-readobj -program-headers %t1 | FileCheck --check-prefix=DEFHDR %s
41
42## Check that error is reported when trying to use phdr which is not listed
43## inside PHDRS {} block
44## TODO: If script doesn't contain PHDRS {} block then default phdr is always
45## created and error is not reported.
46# RUN: echo "PHDRS { all PT_LOAD; } \
47# RUN: SECTIONS { .baz : {*(.foo.*)} :bar }" > %t.script
48# RUN: not ld.lld -o %t1 --script %t.script %t 2>&1 | FileCheck --check-prefix=BADHDR %s
49
50# CHECK: ProgramHeaders [
51# CHECK-NEXT: ProgramHeader {
52# CHECK-NEXT: Type: PT_LOAD (0x1)
53# CHECK-NEXT: Offset: 0x0
54# CHECK-NEXT: VirtualAddress: 0x10000000
55# CHECK-NEXT: PhysicalAddress: 0x10000000
56# CHECK-NEXT: FileSize: 521
57# CHECK-NEXT: MemSize: 521
58# CHECK-NEXT: Flags [ (0x7)
59# CHECK-NEXT: PF_R (0x4)
60# CHECK-NEXT: PF_W (0x2)
61# CHECK-NEXT: PF_X (0x1)
62# CHECK-NEXT: ]
63
64# NOPHDR: ProgramHeaders [
65# NOPHDR-NEXT: ProgramHeader {
66# NOPHDR-NEXT: Type: PT_LOAD (0x1)
67# NOPHDR-NEXT: Offset: 0x200
68# NOPHDR-NEXT: VirtualAddress: 0x10000200
69# NOPHDR-NEXT: PhysicalAddress: 0x10000200
70# NOPHDR-NEXT: FileSize: 8
71# NOPHDR-NEXT: MemSize: 8
72# NOPHDR-NEXT: Flags [ (0x6)
73# NOPHDR-NEXT: PF_R (0x4)
74# NOPHDR-NEXT: PF_W (0x2)
75# NOPHDR-NEXT: ]
76# NOPHDR-NEXT: Alignment: 4096
77# NOPHDR-NEXT: }
78# NOPHDR-NEXT: ]
79
80# AT: ProgramHeaders [
81# AT-NEXT: ProgramHeader {
82# AT-NEXT: Type: PT_LOAD (0x1)
83# AT-NEXT: Offset: 0x0
84# AT-NEXT: VirtualAddress: 0x10000000
85# AT-NEXT: PhysicalAddress: 0xA00
86# AT-NEXT: FileSize: 521
87# AT-NEXT: MemSize: 521
88# AT-NEXT: Flags [ (0x7)
89# AT-NEXT: PF_R (0x4)
90# AT-NEXT: PF_W (0x2)
91# AT-NEXT: PF_X (0x1)
92# AT-NEXT: ]
93
94## Check the numetic values for PHDRS.
95# RUN: echo "PHDRS {text PT_LOAD FILEHDR PHDRS; foo 0x11223344; } \
96# RUN: SECTIONS { . = SIZEOF_HEADERS; .foo : { *(.foo* .text*) } : text : foo}" > %t1.script
97# RUN: ld.lld -o %t2 --script %t1.script %t
98# RUN: llvm-readobj -program-headers %t2 | FileCheck --check-prefix=INT-PHDRS %s
99
100# INT-PHDRS: ProgramHeaders [
101# INT-PHDRS: ProgramHeader {
102# INT-PHDRS: Type: (0x11223344)
103# INT-PHDRS-NEXT: Offset: 0xB0
104# INT-PHDRS-NEXT: VirtualAddress: 0xB0
105# INT-PHDRS-NEXT: PhysicalAddress: 0xB0
106# INT-PHDRS-NEXT: FileSize:
107# INT-PHDRS-NEXT: MemSize:
108# INT-PHDRS-NEXT: Flags [
109# INT-PHDRS-NEXT: PF_R
110# INT-PHDRS-NEXT: PF_W
111# INT-PHDRS-NEXT: PF_X
112# INT-PHDRS-NEXT: ]
113# INT-PHDRS-NEXT: Alignment:
114# INT-PHDRS-NEXT: }
115# INT-PHDRS-NEXT: ]
116
117# DEFHDR: ProgramHeaders [
118# DEFHDR-NEXT: ProgramHeader {
119# DEFHDR-NEXT: Type: PT_LOAD (0x1)
120# DEFHDR-NEXT: Offset: 0x0
121# DEFHDR-NEXT: VirtualAddress: 0x10000000
122# DEFHDR-NEXT: PhysicalAddress: 0x10000000
123# DEFHDR-NEXT: FileSize: 521
124# DEFHDR-NEXT: MemSize: 521
125# DEFHDR-NEXT: Flags [ (0x7)
126# DEFHDR-NEXT: PF_R (0x4)
127# DEFHDR-NEXT: PF_W (0x2)
128# DEFHDR-NEXT: PF_X (0x1)
129# DEFHDR-NEXT: ]
130
131# BADHDR: {{.*}}.script:1: section header 'bar' is not listed in PHDRS
132
133.global _start
134_start:
135 nop
136
137.section .foo.1,"a"
138foo1:
139 .long 0
140
141.section .foo.2,"aw"
142foo2:
143 .long 0
deps/lld/test/ELF/linkerscript/pt_gnu_eh_frame.s created+13
......@@ -0,0 +1,13 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: echo "SECTIONS { /DISCARD/ : { *(.eh_frame*) *(.eh_frame_hdr*) } }" > %t.script
4# RUN: ld.lld -o %t1 --eh-frame-hdr --script %t.script %t
5
6.global _start
7_start:
8 nop
9
10.section .dah,"ax",@progbits
11.cfi_startproc
12 nop
13.cfi_endproc
deps/lld/test/ELF/linkerscript/repsection-symbol.s created+28
......@@ -0,0 +1,28 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4# RUN: echo "SECTIONS { \
5# RUN: . = SIZEOF_HEADERS; \
6# RUN: .text : { *(.text) } \
7# RUN: .foo : {foo1 = .; *(.foo.*) foo2 = .; *(.bar) foo3 = .;} \
8# RUN: }" > %t.script
9# RUN: ld.lld -o %t1 --script %t.script %t -shared
10# RUN: llvm-readobj -t %t1 | FileCheck %s
11
12# CHECK: Name: foo1
13# CHECK-NEXT: Value: 0x228
14
15# CHECK: Name: foo2
16# CHECK-NEXT: Value: 0x230
17
18# CHECK: Name: foo3
19# CHECK-NEXT: Value: 0x234
20
21.section .foo.1,"a"
22 .long 1
23
24.section .foo.2,"aw"
25 .long 2
26
27 .section .bar,"aw"
28 .long 3
deps/lld/test/ELF/linkerscript/repsection-va.s created+24
......@@ -0,0 +1,24 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4# RUN: echo "SECTIONS {.foo : {*(.foo.*)} }" > %t.script
5# RUN: ld.lld -o %t1 --script %t.script %t
6# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
7# CHECK: Sections:
8# CHECK-NEXT: Idx Name Size Address Type
9# CHECK-NOT: .foo
10# CHECK: .foo 00000008 {{.*}} DATA
11# CHECK-NOT: .foo
12
13
14.global _start
15_start:
16 nop
17
18.section .foo.1,"a"
19foo1:
20 .long 0
21
22.section .foo.2,"aw"
23foo2:
24 .long 0
deps/lld/test/ELF/linkerscript/rosegment.s created+24
......@@ -0,0 +1,24 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4# Test that with linker scripts we don't create a RO PT_LOAD.
5
6# RUN: echo "SECTIONS {}" > %t.script
7# RUN: ld.lld -o %t1 --script %t.script %t -shared
8# RUN: llvm-readobj -l %t1 | FileCheck %s
9
10# CHECK-NOT: Type: PT_LOAD
11
12# CHECK: Type: PT_LOAD
13# CHECK: Flags [
14# CHECK-NEXT: PF_R
15# CHECK-NEXT: PF_X
16# CHECK-NEXT: ]
17
18# CHECK: Type: PT_LOAD
19# CHECK: Flags [
20# CHECK-NEXT: PF_R
21# CHECK-NEXT: PF_W
22# CHECK-NEXT: ]
23
24# CHECK-NOT: Type: PT_LOAD
deps/lld/test/ELF/linkerscript/searchdir.s created+12
......@@ -0,0 +1,12 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd %s -o %t
4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-freebsd \
5# RUN: %p/Inputs/libsearch-dyn.s -o %tdyn.o
6# RUN: mkdir -p %t.dir
7# RUN: ld.lld -shared %tdyn.o -o %t.dir/libls.so
8# RUN: echo "SEARCH_DIR(\"%t.dir\")" > %t.script
9# RUN: ld.lld -o %t2 --script %t.script -lls %t
10
11.globl _start,_bar
12_start:
deps/lld/test/ELF/linkerscript/section-align.s created+62
......@@ -0,0 +1,62 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4# RUN: echo "SECTIONS { \
5# RUN: .aaa : ALIGN(4096) { *(.aaa) } \
6# RUN: .bbb : ALIGN(4096 * 4) { *(.bbb) } \
7# RUN: .ccc : ALIGN(4096 * 8) { *(.ccc) } \
8# RUN: }" > %t.script
9# RUN: ld.lld -o %t1 --script %t.script %t
10# RUN: llvm-readobj -sections %t1 | FileCheck %s
11
12.global _start
13_start:
14 nop
15
16// CHECK: Name: .aaa
17// CHECK-NEXT: Type: SHT_PROGBITS
18// CHECK-NEXT: Flags [
19// CHECK-NEXT: SHF_ALLOC
20// CHECK-NEXT: ]
21// CHECK-NEXT: Address:
22// CHECK-NEXT: Offset:
23// CHECK-NEXT: Size: 8
24// CHECK-NEXT: Link: 0
25// CHECK-NEXT: Info: 0
26// CHECK-NEXT: AddressAlignment: 4096
27// CHECK-NEXT: EntrySize:
28
29.section .aaa, "a"
30.quad 0
31
32// CHECK: Name: .bbb
33// CHECK-NEXT: Type: SHT_PROGBITS
34// CHECK-NEXT: Flags [
35// CHECK-NEXT: SHF_ALLOC
36// CHECK-NEXT: ]
37// CHECK-NEXT: Address:
38// CHECK-NEXT: Offset:
39// CHECK-NEXT: Size: 8
40// CHECK-NEXT: Link: 0
41// CHECK-NEXT: Info: 0
42// CHECK-NEXT: AddressAlignment: 16384
43// CHECK-NEXT: EntrySize:
44
45.section .bbb, "a"
46.quad 0
47
48// CHECK: Name: .ccc
49// CHECK-NEXT: Type: SHT_PROGBITS
50// CHECK-NEXT: Flags [
51// CHECK-NEXT: SHF_ALLOC
52// CHECK-NEXT: ]
53// CHECK-NEXT: Address:
54// CHECK-NEXT: Offset:
55// CHECK-NEXT: Size: 8
56// CHECK-NEXT: Link: 0
57// CHECK-NEXT: Info: 0
58// CHECK-NEXT: AddressAlignment: 32768
59// CHECK-NEXT: EntrySize:
60
61.section .ccc, "a"
62.quad 0
deps/lld/test/ELF/linkerscript/section-metadata.s created+33
......@@ -0,0 +1,33 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3
4# RUN: echo "SECTIONS { .text : { *(.text.bar) *(.text.foo) } }" > %t.script
5# RUN: ld.lld -o %t --script %t.script %t.o
6# RUN: llvm-objdump -s %t | FileCheck %s
7
8# RUN: echo "SECTIONS { .text : { *(.text.foo) *(.text.bar) } }" > %t.script
9# RUN: ld.lld -o %t --script %t.script %t.o
10# RUN: llvm-objdump -s %t | FileCheck --check-prefix=INV %s
11
12
13# CHECK: Contents of section .text:
14# CHECK-NEXT: 02000000 00000000 01000000 00000000
15# CHECK: Contents of section .rodata:
16# CHECK-NEXT: 02000000 00000000 01000000 00000000
17
18# INV: Contents of section .text:
19# INV-NEXT: 01000000 00000000 02000000 00000000
20# INV: Contents of section .rodata:
21# INV-NEXT: 01000000 00000000 02000000 00000000
22
23.global _start
24_start:
25
26.section .text.bar,"a",@progbits
27.quad 2
28.section .text.foo,"a",@progbits
29.quad 1
30.section .rodata.foo,"ao",@progbits,.text.foo
31.quad 1
32.section .rodata.bar,"ao",@progbits,.text.bar
33.quad 2
deps/lld/test/ELF/linkerscript/sections-constraint.s created+46
......@@ -0,0 +1,46 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: echo "SECTIONS { \
4# RUN: .writable : ONLY_IF_RW { *(.writable) } \
5# RUN: .readable : ONLY_IF_RO { *(.readable) }}" > %t.script
6# RUN: ld.lld -o %t1 --script %t.script %t
7# RUN: llvm-objdump -section-headers %t1 | \
8# RUN: FileCheck -check-prefix=BASE %s
9# BASE: Sections:
10# BASE-NEXT: Idx Name Size
11# BASE-NEXT: 0 00000000
12# BASE: .writable 00000004
13# BASE: .readable 00000004
14
15# RUN: echo "SECTIONS { \
16# RUN: .foo : ONLY_IF_RO { *(.foo.*) } \
17# RUN: .writable : ONLY_IF_RW { *(.writable) } \
18# RUN: .readable : ONLY_IF_RO { *(.readable) }}" > %t2.script
19# RUN: ld.lld -o %t2 --script %t2.script %t
20# RUN: llvm-objdump -section-headers %t2 | \
21# RUN: FileCheck -check-prefix=NO1 %s
22# NO1: Sections:
23# NO1-NEXT: Idx Name Size
24# NO1-NEXT: 0 00000000
25# NO1: .writable 00000004
26# NO1: .foo.2 00000004
27# NO1: .readable 00000004
28# NO1: .foo.1 00000004
29
30.global _start
31_start:
32 nop
33
34.section .writable, "aw"
35writable:
36 .long 1
37
38.section .readable, "a"
39readable:
40 .long 2
41
42.section .foo.1, "awx"
43 .long 0
44
45.section .foo.2, "aw"
46 .long 0
deps/lld/test/ELF/linkerscript/sections-constraint2.s created+14
......@@ -0,0 +1,14 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: echo "SECTIONS { zed : ONLY_IF_RO { *(foo) *(bar) } }" > %t.script
4# RUN: ld.lld -T %t.script %t.o -o %t.so -shared
5# RUN: llvm-readobj -s %t.so | FileCheck %s
6
7# CHECK: Sections [
8# CHECK-NOT: zed
9
10.section foo,"aw"
11.quad 1
12
13.section bar, "a"
14.quad 2
deps/lld/test/ELF/linkerscript/sections-constraint3.s created+11
......@@ -0,0 +1,11 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: echo "SECTIONS { zed : ONLY_IF_RO { abc = 1; *(foo) } }" > %t.script
4# RUN: ld.lld -T %t.script %t.o -o %t.so -shared
5# RUN: llvm-readobj -t %t.so | FileCheck %s
6
7# CHECK: Symbols [
8# CHECK-NOT: abc
9
10.section foo,"aw"
11.quad 1
deps/lld/test/ELF/linkerscript/sections-constraint4.s created+20
......@@ -0,0 +1,20 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: echo "SECTIONS { \
4# RUN: .foo : ONLY_IF_RO { *(.foo) } \
5# RUN: .bar : {bar1 = .; *(.bar) } }" > %t1.script
6# RUN: ld.lld -o %t1 --script %t1.script %t
7# RUN: llvm-readobj -t %t1 | FileCheck %s
8
9# CHECK: Name: bar1
10
11.global _start
12_start:
13 nop
14
15.section .bar, "aw"
16bar:
17 .long 1
18
19.section .foo, "aw"
20 .long 0
deps/lld/test/ELF/linkerscript/sections-constraint5.s created+32
......@@ -0,0 +1,32 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: echo "SECTIONS { \
4# RUN: bar : ONLY_IF_RO { sym1 = .; *(foo*) } \
5# RUN: bar : ONLY_IF_RW { sym2 = .; *(foo*) } \
6# RUN: }" > %t.script
7
8# RUN: ld.lld -o %t -T %t.script %t.o
9# RUN: llvm-readobj -s -t %t | FileCheck %s
10
11# CHECK: Sections [
12# CHECK: Name: bar
13# CHECK-NEXT: Type: SHT_PROGBITS
14# CHECK-NEXT: Flags [
15# CHECK-NEXT: SHF_ALLOC
16# CHECK-NEXT: SHF_WRITE
17# CHECK-NEXT: ]
18# CHECK-NEXT: Address:
19# CHECK-NEXT: Offset:
20# CHECK-NEXT: Size: 2
21
22# CHECK: Symbols [
23# CHECK-NOT: sym1
24# CHECK: sym2
25# CHECK-NOT: sym1
26
27.section foo1,"a"
28.byte 0
29
30.section foo2,"aw"
31.byte 0
32
deps/lld/test/ELF/linkerscript/sections-gc.s created+19
......@@ -0,0 +1,19 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: echo "SECTIONS { .text : { *(.text*) } }" > %t.script
4# RUN: ld.lld %t --gc-sections --script %t.script -o %t1
5# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
6
7# CHECK: Sections:
8# CHECK-NEXT: Name Size
9# CHECK: .text 00000001
10
11.section .text.foo, "ax"
12.global _start
13_start:
14 nop
15
16.section .text.bar, "ax"
17.global bar
18bar:
19 nop
deps/lld/test/ELF/linkerscript/sections-gc2.s created+31
......@@ -0,0 +1,31 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: echo "SECTIONS { \
4# RUN: used_in_reloc : { *(used_in_reloc) } \
5# RUN: used_in_script : { *(used_in_script) } \
6# RUN: .text : { *(.text) } \
7# RUN: }" > %t.script
8# RUN: ld.lld -T %t.script -o %t.so %t.o --gc-sections
9# RUN: llvm-objdump -h %t.so | FileCheck %s
10
11# CHECK: Idx Name Size Address Type
12# CHECK-NEXT: 0
13# CHECK-NEXT: used_in_reloc
14# CHECK-NEXT: .text
15# CHECK-NEXT: .comment
16# CHECK-NEXT: .symtab
17# CHECK-NEXT: .shstrtab
18# CHECK-NEXT: .strtab
19
20 .global _start
21_start:
22 .quad __start_used_in_reloc
23
24 .section unused,"a"
25 .quad 0
26
27 .section used_in_script,"a"
28 .quad __start_used_in_script
29
30 .section used_in_reloc,"a"
31 .quad 0
deps/lld/test/ELF/linkerscript/sections-keep.s created+95
......@@ -0,0 +1,95 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/keep.s -o %t2.o
4
5## First check that section "keep" is garbage collected without using KEEP
6# RUN: echo "SECTIONS { \
7# RUN: .text : { *(.text) } \
8# RUN: .keep : { *(.keep) } \
9# RUN: .temp : { *(.temp) }}" > %t.script
10# RUN: ld.lld --gc-sections -o %t1 --script %t.script %t
11# RUN: llvm-objdump -section-headers %t1 | \
12# RUN: FileCheck -check-prefix=SECGC %s
13# SECGC: Sections:
14# SECGC-NEXT: Idx Name Size
15# SECGC-NEXT: 0 00000000
16# SECGC-NEXT: 1 .text 00000007
17# SECGC-NEXT: 2 .temp 00000004
18
19## Now apply KEEP command to preserve the section.
20# RUN: echo "SECTIONS { \
21# RUN: .text : { *(.text) } \
22# RUN: .keep : { KEEP(*(.keep)) } \
23# RUN: .temp : { *(.temp) }}" > %t.script
24# RUN: ld.lld --gc-sections -o %t1 --script %t.script %t
25# RUN: llvm-objdump -section-headers %t1 | \
26# RUN: FileCheck -check-prefix=SECNOGC %s
27# SECNOGC: Sections:
28# SECNOGC-NEXT: Idx Name Size
29# SECNOGC-NEXT: 0 00000000
30# SECNOGC-NEXT: 1 .text 00000007
31# SECNOGC-NEXT: 2 .keep 00000004
32# SECNOGC-NEXT: 3 .temp 00000004
33
34## A section name matches two entries in the SECTIONS directive. The
35## first one doesn't have KEEP, the second one does. If section that have
36## KEEP is the first in order then section is NOT collected.
37# RUN: echo "SECTIONS { \
38# RUN: . = SIZEOF_HEADERS; \
39# RUN: .keep : { KEEP(*(.keep)) } \
40# RUN: .nokeep : { *(.keep) }}" > %t.script
41# RUN: ld.lld --gc-sections -o %t1 --script %t.script %t
42# RUN: llvm-objdump -section-headers %t1 | FileCheck -check-prefix=MIXED1 %s
43# MIXED1: Sections:
44# MIXED1-NEXT: Idx Name Size
45# MIXED1-NEXT: 0 00000000
46# MIXED1-NEXT: 1 .keep 00000004
47# MIXED1-NEXT: 2 .text 00000007 00000000000000ec TEXT DATA
48# MIXED1-NEXT: 3 .temp 00000004 00000000000000f3 DATA
49# MIXED1-NEXT: 4 .comment 00000008 0000000000000000
50# MIXED1-NEXT: 5 .symtab 00000060 0000000000000000
51# MIXED1-NEXT: 6 .shstrtab 00000036 0000000000000000
52# MIXED1-NEXT: 7 .strtab 00000012 0000000000000000
53
54## The same, but now section without KEEP is at first place.
55## gold and bfd linkers disagree here. gold collects .keep while
56## bfd keeps it. Our current behavior is compatible with bfd although
57## we can choose either way.
58# RUN: echo "SECTIONS { \
59# RUN: . = SIZEOF_HEADERS; \
60# RUN: .nokeep : { *(.keep) } \
61# RUN: .keep : { KEEP(*(.keep)) }}" > %t.script
62# RUN: ld.lld --gc-sections -o %t1 --script %t.script %t
63# RUN: llvm-objdump -section-headers %t1 | FileCheck -check-prefix=MIXED2 %s
64# MIXED2: Sections:
65# MIXED2-NEXT: Idx Name Size
66# MIXED2-NEXT: 0 00000000
67# MIXED2-NEXT: 1 .nokeep 00000004 00000000000000e8 DATA
68# MIXED2-NEXT: 2 .text 00000007 00000000000000ec TEXT DATA
69# MIXED2-NEXT: 3 .temp 00000004 00000000000000f3 DATA
70# MIXED2-NEXT: 4 .comment 00000008 0000000000000000
71# MIXED2-NEXT: 5 .symtab 00000060 0000000000000000
72# MIXED2-NEXT: 6 .shstrtab 00000038 0000000000000000
73# MIXED2-NEXT: 7 .strtab 00000012 0000000000000000
74
75# Check file pattern for kept sections.
76# RUN: echo "SECTIONS { \
77# RUN: . = SIZEOF_HEADERS; \
78# RUN: .keep : { KEEP(*2.o(.keep)) } \
79# RUN: }" > %t.script
80# RUN: ld.lld --gc-sections -o %t1 --script %t.script %t2.o %t
81# RUN: llvm-objdump -s %t1 | FileCheck -check-prefix=FILEMATCH %s
82# FILEMATCH: Contents of section .keep:
83# FILEMATCH-NEXT: 00e8 41414141 AAAA
84
85.global _start
86_start:
87 mov temp, %eax
88
89.section .keep, "a"
90keep:
91 .long 1
92
93.section .temp, "a"
94temp:
95 .long 2
deps/lld/test/ELF/linkerscript/sections-padding.s created+54
......@@ -0,0 +1,54 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4## Check that padding value works:
5# RUN: echo "SECTIONS { .mysec : { *(.mysec*) } =0x1122 }" > %t.script
6# RUN: ld.lld -o %t.out --script %t.script %t
7# RUN: llvm-objdump -s %t.out | FileCheck -check-prefix=YES %s
8# YES: 66000011 22000011 22000011 22000011
9
10## Confirming that address was correct:
11# RUN: echo "SECTIONS { .mysec : { *(.mysec*) } =0x99887766 }" > %t.script
12# RUN: ld.lld -o %t.out --script %t.script %t
13# RUN: llvm-objdump -s %t.out | FileCheck -check-prefix=YES2 %s
14# YES2: 66998877 66998877 66998877 66998877
15
16## Default padding value is 0x00:
17# RUN: echo "SECTIONS { .mysec : { *(.mysec*) } }" > %t.script
18# RUN: ld.lld -o %t.out --script %t.script %t
19# RUN: llvm-objdump -s %t.out | FileCheck -check-prefix=NO %s
20# NO: 66000000 00000000 00000000 00000000
21
22## Decimal value.
23# RUN: echo "SECTIONS { .mysec : { *(.mysec*) } =777 }" > %t.script
24# RUN: ld.lld -o %t.out --script %t.script %t
25# RUN: llvm-objdump -s %t.out | FileCheck -check-prefix=DEC %s
26# DEC: 66000003 09000003 09000003 09000003
27
28## Invalid hex value:
29# RUN: echo "SECTIONS { .mysec : { *(.mysec*) } =0x99XX }" > %t.script
30# RUN: not ld.lld -o %t.out --script %t.script %t 2>&1 \
31# RUN: | FileCheck --check-prefix=ERR2 %s
32# ERR2: invalid filler expression: 0x99XX
33
34## Check case with space between '=' and expression:
35# RUN: echo "SECTIONS { .mysec : { *(.mysec*) } = 0x1122 }" > %t.script
36# RUN: ld.lld -o %t.out --script %t.script %t
37# RUN: llvm-objdump -s %t.out | FileCheck -check-prefix=YES %s
38
39## Check case with optional comma following output section command:
40# RUN: echo "SECTIONS { .mysec : { *(.mysec*) } =0x1122, .a : { *(.a*) } }" > %t.script
41# RUN: ld.lld -o %t.out --script %t.script %t
42# RUN: llvm-objdump -s %t.out | FileCheck -check-prefix=YES %s
43
44.section .mysec.1,"a"
45.align 16
46.byte 0x66
47
48.section .mysec.2,"a"
49.align 16
50.byte 0x66
51
52.globl _start
53_start:
54 nop
deps/lld/test/ELF/linkerscript/sections-sort.s created+27
......@@ -0,0 +1,27 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3
4# RUN: echo "SECTIONS { .text : {*(.text)} foo : {*(foo)}}" > %t.script
5# RUN: ld.lld -o %t --script %t.script %t.o -shared
6# RUN: llvm-objdump --section-headers %t | FileCheck %s
7
8# Test the section order. This is a case where at least with libstdc++'s
9# stable_sort we used to get a different result.
10
11nop
12
13.section foo, "a"
14.byte 0
15
16# CHECK: Id
17# CHECK-NEXT: 0
18# CHECK-NEXT: 1 .text
19# CHECK-NEXT: 2 foo
20# CHECK-NEXT: 3 .dynsym
21# CHECK-NEXT: 4 .hash
22# CHECK-NEXT: 5 .dynstr
23# CHECK-NEXT: 6 .dynamic
24# CHECK-NEXT: 7 .comment
25# CHECK-NEXT: 8 .symtab
26# CHECK-NEXT: 9 .shstrtab
27# CHECK-NEXT: 10 .strtab
deps/lld/test/ELF/linkerscript/sections.s created+108
......@@ -0,0 +1,108 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4# Empty SECTIONS command.
5# RUN: echo "SECTIONS {}" > %t.script
6# RUN: ld.lld -o %t1 --script %t.script %t
7# RUN: llvm-objdump -section-headers %t1 | \
8# RUN: FileCheck -check-prefix=SEC-DEFAULT %s
9
10# SECTIONS command with the same order as default.
11# RUN: echo "SECTIONS { \
12# RUN: .text : { *(.text) } \
13# RUN: .data : { *(.data) } }" > %t.script
14# RUN: ld.lld -o %t2 --script %t.script %t
15# RUN: llvm-objdump -section-headers %t2 | \
16# RUN: FileCheck -check-prefix=SEC-DEFAULT %s
17
18# Idx Name Size
19# SEC-DEFAULT: 1 .text 0000000e {{[0-9a-f]*}} TEXT DATA
20# SEC-DEFAULT: 2 .data 00000020 {{[0-9a-f]*}} DATA
21# SEC-DEFAULT: 3 other 00000003 {{[0-9a-f]*}} DATA
22# SEC-DEFAULT: 4 .bss 00000002 {{[0-9a-f]*}} BSS
23# SEC-DEFAULT: 5 .comment 00000008 {{[0-9a-f]*}}
24# SEC-DEFAULT: 6 .symtab 00000030 {{[0-9a-f]*}}
25# SEC-DEFAULT: 7 .shstrtab 0000003b {{[0-9a-f]*}}
26# SEC-DEFAULT: 8 .strtab 00000008 {{[0-9a-f]*}}
27
28# Sections are put in order specified in linker script, other than alloc
29# sections going first.
30# RUN: echo "SECTIONS { \
31# RUN: .bss : { *(.bss) } \
32# RUN: other : { *(other) } \
33# RUN: .shstrtab : { *(.shstrtab) } \
34# RUN: .symtab : { *(.symtab) } \
35# RUN: .strtab : { *(.strtab) } \
36# RUN: .data : { *(.data) } \
37# RUN: .text : { *(.text) } }" > %t.script
38# RUN: ld.lld -o %t3 --script %t.script %t
39# RUN: llvm-objdump -section-headers %t3 | \
40# RUN: FileCheck -check-prefix=SEC-ORDER %s
41
42# Idx Name Size
43# SEC-ORDER: 1 .bss 00000002 {{[0-9a-f]*}} BSS
44# SEC-ORDER: 2 other 00000003 {{[0-9a-f]*}} DATA
45# SEC-ORDER: 3 .shstrtab 0000003b {{[0-9a-f]*}}
46# SEC-ORDER: 4 .symtab 00000030 {{[0-9a-f]*}}
47# SEC-ORDER: 5 .strtab 00000008 {{[0-9a-f]*}}
48# SEC-ORDER: 6 .comment 00000008 {{[0-9a-f]*}}
49# SEC-ORDER: 7 .data 00000020 {{[0-9a-f]*}} DATA
50# SEC-ORDER: 8 .text 0000000e {{[0-9a-f]*}} TEXT DATA
51
52# .text and .data have swapped names but proper sizes and types.
53# RUN: echo "SECTIONS { \
54# RUN: .data : { *(.text) } \
55# RUN: .text : { *(.data) } }" > %t.script
56# RUN: ld.lld -o %t4 --script %t.script %t
57# RUN: llvm-objdump -section-headers %t4 | \
58# RUN: FileCheck -check-prefix=SEC-SWAP-NAMES %s
59
60# Idx Name Size
61# SEC-SWAP-NAMES: 1 .data 0000000e {{[0-9a-f]*}} TEXT DATA
62# SEC-SWAP-NAMES: 2 .text 00000020 {{[0-9a-f]*}} DATA
63# SEC-SWAP-NAMES: 3 other 00000003 {{[0-9a-f]*}} DATA
64# SEC-SWAP-NAMES: 4 .bss 00000002 {{[0-9a-f]*}} BSS
65# SEC-SWAP-NAMES: 5 .comment 00000008 {{[0-9a-f]*}}
66# SEC-SWAP-NAMES: 6 .symtab 00000030 {{[0-9a-f]*}}
67# SEC-SWAP-NAMES: 7 .shstrtab 0000003b {{[0-9a-f]*}}
68# SEC-SWAP-NAMES: 8 .strtab 00000008 {{[0-9a-f]*}}
69
70# Multiple SECTIONS command specifying additional input section descriptions
71# for the same output section description - input sections are merged into
72# one output section.
73# RUN: echo "SECTIONS { \
74# RUN: .text : { *(.text) } \
75# RUN: .data : { *(.data) } } \
76# RUN: SECTIONS { \
77# RUN: .data : { *(other) } }" > %t.script
78# RUN: ld.lld -o %t6 --script %t.script %t
79# RUN: llvm-objdump -section-headers %t6 | \
80# RUN: FileCheck -check-prefix=SEC-MULTI %s
81
82# Idx Name Size
83# SEC-MULTI: 1 .text 0000000e {{[0-9a-f]*}} TEXT DATA
84# SEC-MULTI-NEXT: .data 00000020 {{[0-9a-f]*}} DATA
85# SEC-MULTI-NEXT: .data 00000003 {{[0-9a-f]*}} DATA
86# SEC-MULTI-NEXT: .bss 00000002 {{[0-9a-f]*}} BSS
87# SEC-MULTI-NEXT: .comment 00000008 {{[0-9a-f]*}}
88# SEC-MULTI-NEXT: .symtab 00000030 {{[0-9a-f]*}}
89# SEC-MULTI-NEXT: .shstrtab 00000035 {{[0-9a-f]*}}
90# SEC-MULTI-NEXT: .strtab 00000008 {{[0-9a-f]*}}
91
92# Input section pattern contains additional semicolon.
93# Case found in linux kernel script. Check we are able to parse it.
94# RUN: echo "SECTIONS { .text : { ;;*(.text);;S = 0;; } }" > %t.script
95# RUN: ld.lld -o /dev/null --script %t.script %t
96
97.globl _start
98_start:
99 mov $60, %rax
100 mov $42, %rdi
101
102.section .data,"aw"
103.quad 10, 10, 20, 20
104.section other,"aw"
105.short 10
106.byte 20
107.section .bss,"",@nobits
108.short 0
deps/lld/test/ELF/linkerscript/segment-none.s created+39
......@@ -0,0 +1,39 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3
4## Test that section .foo is not placed in any segment when assigned to segment
5## NONE in the linker script and segment NONE is not defined.
6# RUN: echo "PHDRS {text PT_LOAD;} \
7# RUN: SECTIONS { \
8# RUN: .text : {*(.text .text*)} :text \
9# RUN: .foo : {*(.foo)} :NONE \
10# RUN: }" > %t.script
11# RUN: ld.lld -o %t --script %t.script %t.o
12# RUN: llvm-readobj -elf-output-style=GNU -s -l %t | FileCheck %s
13
14## Test that section .foo is placed in segment NONE when assigned to segment
15## NONE in the linker script and segment NONE is defined.
16# RUN: echo "PHDRS {text PT_LOAD; NONE PT_LOAD;} \
17# RUN: SECTIONS { \
18# RUN: .text : {*(.text .text*)} :text \
19# RUN: .foo : {*(.foo)} :NONE \
20# RUN: }" > %t.script
21# RUN: ld.lld -o %t --script %t.script %t.o
22# RUN: llvm-readobj -elf-output-style=GNU -s -l %t | FileCheck --check-prefix=DEFINED %s
23
24# CHECK: Section to Segment mapping:
25# CHECK-NEXT: Segment Sections...
26# CHECK-NOT: .foo
27
28# DEFINED: Section to Segment mapping:
29# DEFINED-NEXT: Segment Sections...
30# DEFINED-NEXT: 00 .text
31# DEFINED-NEXT: 01 .foo
32
33.global _start
34_start:
35 nop
36
37.section .foo,"a"
38foo:
39 .long 0
deps/lld/test/ELF/linkerscript/segment-start.s created+27
......@@ -0,0 +1,27 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: ld.lld %t.o %S/Inputs/segment-start.script -shared -o %t.so
4// RUN: llvm-readobj --dyn-symbols %t.so | FileCheck %s
5
6// CHECK: Name: foobar1
7// CHECK-NEXT: Value: 0x8001
8
9// CHECK: Name: foobar2
10// CHECK-NEXT: Value: 0x8002
11
12// CHECK: Name: foobar3
13// CHECK-NEXT: Value: 0x8003
14
15// CHECK: Name: foobar4
16// CHECK-NEXT: Value: 0x8004
17
18.data
19.quad foobar1
20.quad foobar2
21.quad foobar3
22.quad foobar4
23
24// RUN: echo "SECTIONS { . = SEGMENT_START(\"foobar\", foo); }" > %t.script
25// RUN: not ld.lld %t.o %t.script -shared -o %t2.so 2>&1 \
26// RUN: | FileCheck --check-prefix=ERR %s
27// ERR: {{.*}}.script:1: symbol not found: foo
deps/lld/test/ELF/linkerscript/sizeof.s created+53
......@@ -0,0 +1,53 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4# RUN: echo "SECTIONS { \
5# RUN: .aaa : { *(.aaa) } \
6# RUN: .bbb : { *(.bbb) } \
7# RUN: .ccc : { *(.ccc) } \
8# RUN: _aaa = SIZEOF(.aaa); \
9# RUN: _bbb = SIZEOF(.bbb); \
10# RUN: _ccc = SIZEOF(.ccc); \
11# RUN: }" > %t.script
12# RUN: ld.lld -o %t1 --script %t.script %t
13# RUN: llvm-objdump -t -section-headers %t1 | FileCheck %s
14# CHECK: Sections:
15# CHECK-NEXT: Idx Name Size
16# CHECK-NEXT: 0 00000000
17# CHECK-NEXT: 1 .aaa 00000008
18# CHECK-NEXT: 2 .bbb 00000010
19# CHECK-NEXT: 3 .ccc 00000018
20# CHECK: SYMBOL TABLE:
21# CHECK-NEXT: 0000000000000000 *UND* 00000000
22# CHECK-NEXT: .text 00000000 _start
23# CHECK-NEXT: 0000000000000008 *ABS* 00000000 _aaa
24# CHECK-NEXT: 0000000000000010 *ABS* 00000000 _bbb
25# CHECK-NEXT: 0000000000000018 *ABS* 00000000 _ccc
26
27## SIZEOF(.nonexistent_section) should return 0.
28# RUN: echo "SECTIONS { \
29# RUN: .aaa : { *(.aaa) } \
30# RUN: .bbb : { *(.bbb) } \
31# RUN: .ccc : { *(.ccc) } \
32# RUN: _aaa = SIZEOF(.foo); \
33# RUN: }" > %t.script
34# RUN: ld.lld -o %t1 --script %t.script %t
35# RUN: llvm-objdump -t -section-headers %t1 | FileCheck -check-prefix=CHECK2 %s
36
37# CHECK2: 0000000000000000 *ABS* 00000000 _aaa
38
39.global _start
40_start:
41 nop
42
43.section .aaa,"a"
44 .quad 0
45
46.section .bbb,"a"
47 .quad 0
48 .quad 0
49
50.section .ccc,"a"
51 .quad 0
52 .quad 0
53 .quad 0
deps/lld/test/ELF/linkerscript/sizeofheaders.s created+18
......@@ -0,0 +1,18 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: echo " SECTIONS { \
4# RUN: . = SIZEOF_HEADERS; \
5# RUN: _size = SIZEOF_HEADERS; \
6# RUN: .text : {*(.text*)} \
7# RUN: }" > %t.script
8# RUN: ld.lld -o %t1 --script %t.script %t
9# RUN: llvm-objdump -t %t1 | FileCheck %s
10
11#CHECK: SYMBOL TABLE:
12#CHECK-NEXT: 0000000000000000 *UND* 00000000
13#CHECK-NEXT: 00000000000000e8 .text 00000000 _start
14#CHECK-NEXT: 00000000000000e8 *ABS* 00000000 _size
15
16.global _start
17_start:
18 nop
deps/lld/test/ELF/linkerscript/sort-constructors.s created+5
......@@ -0,0 +1,5 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
3# RUN: echo "SECTIONS { .aaa : { SORT(CONSTRUCTORS) } }" > %t1.script
4# RUN: ld.lld -shared -o %t1 --script %t1.script %t1.o
5# RUN: llvm-readobj %t1 > /dev/null
deps/lld/test/ELF/linkerscript/sort-init.s created+24
......@@ -0,0 +1,24 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
3# RUN: echo "SECTIONS { .init_array : { *(SORT_BY_INIT_PRIORITY(.init_array.*)) } }" > %t1.script
4# RUN: ld.lld --script %t1.script %t1.o -o %t2
5# RUN: llvm-objdump -s %t2 | FileCheck %s
6
7# CHECK: Contents of section .init_array:
8# CHECK-NEXT: 03020000 00000000 010405
9
10.globl _start
11_start:
12 nop
13
14.section .init_array, "aw", @init_array
15 .align 8
16 .byte 1
17.section .init_array.100, "aw", @init_array
18 .long 2
19.section .init_array.5, "aw", @init_array
20 .byte 3
21.section .init_array, "aw", @init_array
22 .byte 4
23.section .init_array, "aw", @init_array
24 .byte 5
deps/lld/test/ELF/linkerscript/sort-nested.s created+50
......@@ -0,0 +1,50 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
4# RUN: %p/Inputs/sort-nested.s -o %t2.o
5
6## Check sorting first by alignment and then by name.
7# RUN: echo "SECTIONS { .aaa : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.aaa.*))) } }" > %t1.script
8# RUN: ld.lld -o %t1 --script %t1.script %t1.o %t2.o
9# RUN: llvm-objdump -s %t1 | FileCheck -check-prefix=SORTED_AN %s
10# SORTED_AN: Contents of section .aaa:
11# SORTED_AN-NEXT: 01000000 00000000 00000000 00000000
12# SORTED_AN-NEXT: 11000000 00000000 00000000 00000000
13# SORTED_AN-NEXT: 55000000 00000000 22000000 00000000
14# SORTED_AN-NEXT: 02000000 00000000
15
16## Check sorting first by name and then by alignment.
17# RUN: echo "SECTIONS { .aaa : { *(SORT_BY_NAME(SORT_BY_ALIGNMENT(.aaa.*))) } }" > %t2.script
18# RUN: ld.lld -o %t2 --script %t2.script %t1.o %t2.o
19# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=SORTED_NA %s
20# SORTED_NA: Contents of section .aaa:
21# SORTED_NA: 01000000 00000000 00000000 00000000
22# SORTED_NA: 11000000 00000000 22000000 00000000
23# SORTED_NA: 02000000 00000000 00000000 00000000
24# SORTED_NA: 55000000 00000000
25
26## If the section sorting command in linker script isn't nested, the
27## command line option will make the section sorting command to be treated
28## as nested sorting command.
29# RUN: echo "SECTIONS { .aaa : { *(SORT_BY_ALIGNMENT(.aaa.*)) } }" > %t3.script
30# RUN: ld.lld --sort-section name -o %t3 --script %t3.script %t1.o %t2.o
31# RUN: llvm-objdump -s %t3 | FileCheck -check-prefix=SORTED_AN %s
32# RUN: echo "SECTIONS { .aaa : { *(SORT_BY_NAME(.aaa.*)) } }" > %t4.script
33# RUN: ld.lld --sort-section alignment -o %t4 --script %t4.script %t1.o %t2.o
34# RUN: llvm-objdump -s %t4 | FileCheck -check-prefix=SORTED_NA %s
35
36.global _start
37_start:
38 nop
39
40.section .aaa.1, "a"
41.align 32
42.quad 1
43
44.section .aaa.2, "a"
45.align 2
46.quad 2
47
48.section .aaa.5, "a"
49.align 16
50.quad 0x55
deps/lld/test/ELF/linkerscript/sort-non-script.s created+16
......@@ -0,0 +1,16 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
3
4# RUN: echo "SECTIONS { foo : {*(foo)} }" > %t.script
5# RUN: ld.lld -o %t1 --script %t.script %t -shared
6# RUN: llvm-readobj -elf-output-style=GNU -s %t1 | FileCheck %s
7
8# CHECK: .text {{.*}} AX
9# CHECK-NEXT: .dynsym {{.*}} A
10# CHECK-NEXT: .hash {{.*}} A
11# CHECK-NEXT: .dynstr {{.*}} A
12# CHECK-NEXT: foo {{.*}} WA
13# CHECK-NEXT: .dynamic {{.*}} WA
14
15.section foo, "aw"
16.byte 0
deps/lld/test/ELF/linkerscript/sort.s created+120
......@@ -0,0 +1,120 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
4# RUN: %p/Inputs/sort.s -o %t2.o
5
6# RUN: echo "SECTIONS { .aaa : { *(.aaa.*) } }" > %t1.script
7# RUN: ld.lld -o %t1 --script %t1.script %t2.o %t1.o
8# RUN: llvm-objdump -s %t1 | FileCheck -check-prefix=UNSORTED %s
9# UNSORTED: Contents of section .aaa:
10# UNSORTED-NEXT: 55000000 00000000 00000000 00000000
11# UNSORTED-NEXT: 00000000 00000000 00000000 00000000
12# UNSORTED-NEXT: 11000000 00000000 33000000 00000000
13# UNSORTED-NEXT: 22000000 00000000 44000000 00000000
14# UNSORTED-NEXT: 05000000 00000000 01000000 00000000
15# UNSORTED-NEXT: 03000000 00000000 02000000 00000000
16# UNSORTED-NEXT: 04000000 00000000
17
18## Check that SORT works (sorted by name of section).
19# RUN: echo "SECTIONS { .aaa : { *(SORT(.aaa.*)) } }" > %t2.script
20# RUN: ld.lld -o %t2 --script %t2.script %t2.o %t1.o
21# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=SORTED_A %s
22# SORTED_A: Contents of section .aaa:
23# SORTED_A-NEXT: 11000000 00000000 01000000 00000000
24# SORTED_A-NEXT: 22000000 00000000 02000000 00000000
25# SORTED_A-NEXT: 33000000 00000000 03000000 00000000
26# SORTED_A-NEXT: 44000000 00000000 00000000 00000000
27# SORTED_A-NEXT: 04000000 00000000 55000000 00000000
28# SORTED_A-NEXT: 00000000 00000000 00000000 00000000
29# SORTED_A-NEXT: 05000000 00000000
30
31## When we switch the order of files, check that sorting by
32## section names is stable.
33# RUN: echo "SECTIONS { .aaa : { *(SORT(.aaa.*)) } }" > %t3.script
34# RUN: ld.lld -o %t3 --script %t3.script %t1.o %t2.o
35# RUN: llvm-objdump -s %t3 | FileCheck -check-prefix=SORTED_B %s
36# SORTED_B: Contents of section .aaa:
37# SORTED_B-NEXT: 01000000 00000000 00000000 00000000
38# SORTED_B-NEXT: 00000000 00000000 00000000 00000000
39# SORTED_B-NEXT: 11000000 00000000 02000000 00000000
40# SORTED_B-NEXT: 22000000 00000000 03000000 00000000
41# SORTED_B-NEXT: 33000000 00000000 00000000 00000000
42# SORTED_B-NEXT: 04000000 00000000 44000000 00000000
43# SORTED_B-NEXT: 05000000 00000000 55000000 00000000
44
45## Check that SORT surrounded with KEEP also works.
46# RUN: echo "SECTIONS { .aaa : { KEEP (*(SORT(.aaa.*))) } }" > %t3.script
47# RUN: ld.lld -o %t3 --script %t3.script %t2.o %t1.o
48# RUN: llvm-objdump -s %t3 | FileCheck -check-prefix=SORTED_A %s
49
50## Check that SORT_BY_NAME works (SORT is alias).
51# RUN: echo "SECTIONS { .aaa : { *(SORT_BY_NAME(.aaa.*)) } }" > %t4.script
52# RUN: ld.lld -o %t4 --script %t4.script %t2.o %t1.o
53# RUN: llvm-objdump -s %t4 | FileCheck -check-prefix=SORTED_A %s
54
55## Check that sections ordered by alignment.
56# RUN: echo "SECTIONS { .aaa : { *(SORT_BY_ALIGNMENT(.aaa.*)) } }" > %t5.script
57# RUN: ld.lld -o %t5 --script %t5.script %t1.o %t2.o
58# RUN: llvm-objdump -s %t5 | FileCheck -check-prefix=SORTED_ALIGNMENT %s
59# SORTED_ALIGNMENT: Contents of section .aaa:
60# SORTED_ALIGNMENT-NEXT: 05000000 00000000 00000000 00000000
61# SORTED_ALIGNMENT-NEXT: 00000000 00000000 00000000 00000000
62# SORTED_ALIGNMENT-NEXT: 11000000 00000000 00000000 00000000
63# SORTED_ALIGNMENT-NEXT: 04000000 00000000 00000000 00000000
64# SORTED_ALIGNMENT-NEXT: 22000000 00000000 03000000 00000000
65# SORTED_ALIGNMENT-NEXT: 33000000 00000000 02000000 00000000
66# SORTED_ALIGNMENT-NEXT: 44000000 00000000 01000000 00000000
67# SORTED_ALIGNMENT-NEXT: 55000000 00000000
68
69## SORT_NONE itself does not sort anything.
70# RUN: echo "SECTIONS { .aaa : { *(SORT_NONE(.aaa.*)) } }" > %t6.script
71# RUN: ld.lld -o %t7 --script %t6.script %t2.o %t1.o
72# RUN: llvm-objdump -s %t7 | FileCheck -check-prefix=UNSORTED %s
73
74## Check --sort-section alignment option.
75# RUN: echo "SECTIONS { .aaa : { *(.aaa.*) } }" > %t7.script
76# RUN: ld.lld --sort-section alignment -o %t8 --script %t7.script %t1.o %t2.o
77# RUN: llvm-objdump -s %t8 | FileCheck -check-prefix=SORTED_ALIGNMENT %s
78
79## Check --sort-section= form.
80# RUN: ld.lld --sort-section=alignment -o %t8_1 --script %t7.script %t1.o %t2.o
81# RUN: llvm-objdump -s %t8_1 | FileCheck -check-prefix=SORTED_ALIGNMENT %s
82
83## Check --sort-section name option.
84# RUN: echo "SECTIONS { .aaa : { *(.aaa.*) } }" > %t8.script
85# RUN: ld.lld --sort-section name -o %t9 --script %t8.script %t1.o %t2.o
86# RUN: llvm-objdump -s %t9 | FileCheck -check-prefix=SORTED_B %s
87
88## SORT_NONE disables the --sort-section.
89# RUN: echo "SECTIONS { .aaa : { *(SORT_NONE(.aaa.*)) } }" > %t9.script
90# RUN: ld.lld --sort-section name -o %t10 --script %t9.script %t2.o %t1.o
91# RUN: llvm-objdump -s %t10 | FileCheck -check-prefix=UNSORTED %s
92
93## SORT_NONE as a inner sort directive.
94# RUN: echo "SECTIONS { .aaa : { *(SORT_BY_NAME(SORT_NONE(.aaa.*))) } }" > %t10.script
95# RUN: ld.lld -o %t11 --script %t10.script %t2.o %t1.o
96# RUN: llvm-objdump -s %t11 | FileCheck -check-prefix=SORTED_A %s
97
98.global _start
99_start:
100 nop
101
102.section .aaa.5, "a"
103.align 32
104.quad 5
105
106.section .aaa.1, "a"
107.align 2
108.quad 1
109
110.section .aaa.3, "a"
111.align 8
112.quad 3
113
114.section .aaa.2, "a"
115.align 4
116.quad 2
117
118.section .aaa.4, "a"
119.align 16
120.quad 4
deps/lld/test/ELF/linkerscript/sort2.s created+39
......@@ -0,0 +1,39 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %tfile1.o
3
4# RUN: echo "SECTIONS { .abc : { *(SORT(.foo.*) .bar.*) } }" > %t1.script
5# RUN: ld.lld -o %t1 --script %t1.script %tfile1.o
6# RUN: llvm-objdump -s %t1 | FileCheck %s
7
8# CHECK: Contents of section .abc:
9# CHECK: 01000000 00000000 02000000 00000000
10# CHECK: 03000000 00000000 04000000 00000000
11# CHECK: 06000000 00000000 05000000 00000000
12
13# RUN: echo "SECTIONS { \
14# RUN: .abc : { *(SORT(.foo.* EXCLUDE_FILE (*file1.o) .bar.*) .bar.*) } \
15# RUN: }" > %t2.script
16# RUN: ld.lld -o %t2 --script %t2.script %tfile1.o
17# RUN: llvm-objdump -s %t2 | FileCheck %s
18
19.text
20.globl _start
21_start:
22
23.section .foo.2,"a"
24 .quad 2
25
26.section .foo.3,"a"
27 .quad 3
28
29.section .foo.1,"a"
30 .quad 1
31
32.section .bar.4,"a"
33 .quad 4
34
35.section .bar.6,"a"
36 .quad 6
37
38.section .bar.5,"a"
39 .quad 5
deps/lld/test/ELF/linkerscript/start-end.s created+16
......@@ -0,0 +1,16 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: echo "SECTIONS { \
4# RUN: .init_array : { \
5# RUN: __init_array_start = .; \
6# RUN: *(.init_array) \
7# RUN: __init_array_end = .; } }" > %t.script
8# RUN: ld.lld %t.o -script %t.script -o %t 2>&1
9
10.globl _start
11.text
12_start:
13 nop
14
15.section .init_array, "aw"
16 .quad 0
deps/lld/test/ELF/linkerscript/subalign.s created+43
......@@ -0,0 +1,43 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
3
4# RUN: echo "SECTIONS { .aaa : { *(.aaa.*) } }" > %t1.script
5# RUN: ld.lld -o %t1 --script %t1.script %t1.o
6# RUN: llvm-objdump -s %t1 | FileCheck -check-prefix=NOALIGN %s
7# NOALIGN: Contents of section .aaa:
8# NOALIGN-NEXT: 01000000 00000000 00000000 00000000
9# NOALIGN-NEXT: 00000000 00000000 00000000 00000000
10# NOALIGN-NEXT: 02000000 00000000 00000000 00000000
11# NOALIGN-NEXT: 00000000 00000000 00000000 00000000
12# NOALIGN-NEXT: 03000000 00000000 00000000 00000000
13# NOALIGN-NEXT: 00000000 00000000 00000000 00000000
14# NOALIGN-NEXT: 00000000 00000000 00000000 00000000
15# NOALIGN-NEXT: 00000000 00000000 00000000 00000000
16# NOALIGN-NEXT: 04000000 00000000
17
18# RUN: echo "SECTIONS { .aaa : SUBALIGN(1) { *(.aaa.*) } }" > %t2.script
19# RUN: ld.lld -o %t2 --script %t2.script %t1.o
20# RUN: llvm-objdump -s %t2 | FileCheck -check-prefix=SUBALIGN %s
21# SUBALIGN: Contents of section .aaa:
22# SUBALIGN: 01000000 00000000 02000000 00000000
23# SUBALIGN: 03000000 00000000 04000000 00000000
24
25.global _start
26_start:
27 nop
28
29.section .aaa.1, "a"
30.align 16
31.quad 1
32
33.section .aaa.2, "a"
34.align 32
35.quad 2
36
37.section .aaa.3, "a"
38.align 64
39.quad 3
40
41.section .aaa.4, "a"
42.align 128
43.quad 4
deps/lld/test/ELF/linkerscript/symbol-assignexpr.s created+59
......@@ -0,0 +1,59 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4# RUN: echo "SECTIONS { \
5# RUN: symbol = CONSTANT(MAXPAGESIZE); \
6# RUN: symbol2 = symbol + 0x1234; \
7# RUN: symbol3 = symbol2; \
8# RUN: symbol4 = symbol + -4; \
9# RUN: symbol5 = symbol - ~ 0xfffb; \
10# RUN: symbol6 = symbol - ~(0xfff0 + 0xb); \
11# RUN: symbol7 = symbol - ~ 0xfffb + 4; \
12# RUN: symbol8 = ~ 0xffff + 4; \
13# RUN: symbol9 = - 4; \
14# RUN: symbol10 = 0xfedcba9876543210; \
15# RUN: symbol11 = ((0x28000 + 0x1fff) & ~(0x1000 + -1)); \
16# RUN: symbol12 = 0x1234; \
17# RUN: symbol12 += 1; \
18# RUN: bar = 0x5678; \
19# RUN: baz = 0x9abc; \
20# RUN: }" > %t.script
21# RUN: ld.lld -o %t1 --script %t.script %t
22# RUN: llvm-objdump -t %t1 | FileCheck %s
23
24# CHECK: SYMBOL TABLE:
25# CHECK-NEXT: 0000000000000000 *UND* 00000000
26# CHECK-NEXT: 0000000000000000 .text 00000000 _start
27# CHECK-NEXT: 0000000000005678 *ABS* 00000000 bar
28# CHECK-NEXT: 0000000000009abc *ABS* 00000000 baz
29# CHECK-NEXT: 0000000000000001 .text 00000000 foo
30# CHECK-NEXT: 0000000000001000 *ABS* 00000000 symbol
31# CHECK-NEXT: 0000000000002234 *ABS* 00000000 symbol2
32# CHECK-NEXT: 0000000000002234 *ABS* 00000000 symbol3
33# CHECK-NEXT: 0000000000000ffc *ABS* 00000000 symbol4
34# CHECK-NEXT: 0000000000010ffc *ABS* 00000000 symbol5
35# CHECK-NEXT: 0000000000010ffc *ABS* 00000000 symbol6
36# CHECK-NEXT: 0000000000011000 *ABS* 00000000 symbol7
37# CHECK-NEXT: ffffffffffff0004 *ABS* 00000000 symbol8
38# CHECK-NEXT: fffffffffffffffc *ABS* 00000000 symbol9
39# CHECK-NEXT: fedcba9876543210 *ABS* 00000000 symbol10
40# CHECK-NEXT: 0000000000029000 *ABS* 00000000 symbol11
41# CHECK-NEXT: 0000000000001235 *ABS* 00000000 symbol12
42
43# RUN: echo "SECTIONS { symbol2 = symbol; }" > %t2.script
44# RUN: not ld.lld -o %t2 --script %t2.script %t 2>&1 \
45# RUN: | FileCheck -check-prefix=ERR %s
46# ERR: {{.*}}.script:1: symbol not found: symbol
47
48.global _start
49_start:
50 nop
51
52.global foo
53foo:
54 nop
55
56.global bar
57bar = 0x1234
58
59.comm baz,8,8
deps/lld/test/ELF/linkerscript/symbol-conflict.s created+11
......@@ -0,0 +1,11 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4# RUN: echo "SECTIONS { . = SIZEOF_HEADERS; .text : {*(.text.*)} end = .;}" > %t.script
5# RUN: ld.lld -o %t1 --script %t.script %t
6# RUN: llvm-objdump -t %t1 | FileCheck %s
7# CHECK: 00000000000000e9 .text 00000000 end
8
9.global _start
10_start:
11 nop
deps/lld/test/ELF/linkerscript/symbol-memoryexpr.s created+33
......@@ -0,0 +1,33 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4# RUN: echo "MEMORY { \
5# RUN: ram (rwx) : ORIGIN = 0x8000, LENGTH = 256K \
6# RUN: } \
7# RUN: SECTIONS { \
8# RUN: origin = ORIGIN(ram); \
9# RUN: length = LENGTH(ram); \
10# RUN: end = ORIGIN(ram) + LENGTH(ram); \
11# RUN: }" > %t.script
12# RUN: ld.lld -o %t1 --script %t.script %t
13# RUN: llvm-objdump -t %t1 | FileCheck %s
14
15# CHECK: SYMBOL TABLE:
16# CHECK-NEXT: 0000000000000000 *UND* 00000000
17# CHECK-NEXT: 0000000000008000 .text 00000000 _start
18# CHECK-NEXT: 0000000000008000 *ABS* 00000000 origin
19# CHECK-NEXT: 0000000000040000 *ABS* 00000000 length
20# CHECK-NEXT: 0000000000048000 *ABS* 00000000 end
21
22# RUN: echo "SECTIONS { \
23# RUN: no_exist_origin = ORIGIN(ram); \
24# RUN: no_exist_length = LENGTH(ram); \
25# RUN: }" > %t2.script
26# RUN: not ld.lld -o %t2 --script %t2.script %t 2>&1 \
27# RUN: | FileCheck -check-prefix=ERR %s
28# ERR: {{.*}}.script:1: memory region not defined: ram
29
30
31.global _start
32_start:
33 nop
deps/lld/test/ELF/linkerscript/symbol-only.s created+21
......@@ -0,0 +1,21 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4# RUN: echo "SECTIONS { \
5# RUN: . = SIZEOF_HEADERS; \
6# RUN: abc : { foo = .; } \
7# RUN: . = ALIGN(0x1000); \
8# RUN: bar : { *(bar) } \
9# RUN: }" > %t.script
10# RUN: ld.lld -o %t1 --script %t.script %t -shared
11# RUN: llvm-objdump -section-headers -t %t1 | FileCheck %s
12# CHECK: Sections:
13# CHECK-NEXT: Idx Name Size Address
14# CHECK-NEXT: 0 00000000 0000000000000000
15# CHECK: abc 00000000 [[ADDR:[0-9a-f]*]] DATA
16# CHECK-NEXT: bar 00000000 0000000000001000 DATA
17
18# CHECK: SYMBOL TABLE:
19# CHECK: [[ADDR]] abc 00000000 foo
20
21.section bar, "a"
deps/lld/test/ELF/linkerscript/symbol-reserved.s created+22
......@@ -0,0 +1,22 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: echo "PROVIDE_HIDDEN(newsym = __ehdr_start + 5);" > %t.script
4# RUN: ld.lld -o %t1 %t.script %t
5# RUN: llvm-objdump -t %t1 | FileCheck %s
6
7# CHECK: 0000000000200005 .text 00000000 .hidden newsym
8
9# RUN: ld.lld -o %t1.so %t.script %t -shared
10# RUN: llvm-objdump -t %t1.so | FileCheck --check-prefix=SHARED %s
11
12# SHARED: 0000000000000005 .dynsym 00000000 .hidden newsym
13
14# RUN: echo "PROVIDE_HIDDEN(newsym = ALIGN(__ehdr_start, CONSTANT(MAXPAGESIZE)) + 5);" > %t.script
15# RUN: ld.lld -o %t1 %t.script %t
16# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=ALIGNED %s
17
18# ALIGNED: 0000000000200005 .text 00000000 .hidden newsym
19
20.global _start
21_start:
22 lea newsym(%rip),%rax
deps/lld/test/ELF/linkerscript/symbolreferenced.s created+22
......@@ -0,0 +1,22 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4# Provide new symbol. The value should be 1, like set in PROVIDE()
5# RUN: echo "SECTIONS { PROVIDE(newsym = 1);}" > %t.script
6# RUN: ld.lld -o %t1 --script %t.script %t
7# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=PROVIDE1 %s
8# PROVIDE1: 0000000000000001 *ABS* 00000000 newsym
9
10# Provide new symbol (hidden). The value should be 1
11# RUN: echo "SECTIONS { PROVIDE_HIDDEN(newsym = 1);}" > %t.script
12# RUN: ld.lld -o %t1 --script %t.script %t
13# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=HIDDEN1 %s
14# HIDDEN1: 0000000000000001 *ABS* 00000000 .hidden newsym
15
16.global _start
17_start:
18 nop
19
20.globl patatino
21patatino:
22 movl newsym, %eax
deps/lld/test/ELF/linkerscript/symbols-non-alloc.s created+19
......@@ -0,0 +1,19 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4# RUN: echo "SECTIONS { . = SIZEOF_HEADERS; \
5# RUN: .text : { *(.text) } \
6# RUN: .nonalloc : { *(.nonalloc) } \
7# RUN: Sym = .; \
8# RUN: }" > %t.script
9# RUN: ld.lld -o %t2 --script %t.script %t
10# RUN: llvm-objdump -section-headers -t %t2 | FileCheck %s
11
12# CHECK: Sections:
13# CHECK: .nonalloc 00000008 0000000000000000
14
15# CHECK: SYMBOL TABLE:
16# CHECK: 0000000000000008 .nonalloc 00000000 Sym
17
18.section .nonalloc,""
19 .quad 0
deps/lld/test/ELF/linkerscript/symbols-synthetic.s created+98
......@@ -0,0 +1,98 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# Simple symbol assignment within input section list. The '.' symbol
4# is not location counter but offset from the beginning of output
5# section .foo
6# RUN: echo "SECTIONS { \
7# RUN: . = SIZEOF_HEADERS; \
8# RUN: .foo : { \
9# RUN: begin_foo = .; \
10# RUN: PROVIDE(_begin_sec = .); \
11# RUN: *(.foo) \
12# RUN: end_foo = .; \
13# RUN: PROVIDE_HIDDEN(_end_sec = .); \
14# RUN: PROVIDE(_end_sec_abs = ABSOLUTE(.)); \
15# RUN: size_foo_1 = SIZEOF(.foo); \
16# RUN: size_foo_1_abs = ABSOLUTE(SIZEOF(.foo)); \
17# RUN: . = ALIGN(0x1000); \
18# RUN: begin_bar = .; \
19# RUN: *(.bar) \
20# RUN: end_bar = .; \
21# RUN: size_foo_2 = SIZEOF(.foo); } \
22# RUN: size_foo_3 = SIZEOF(.foo); \
23# RUN: .eh_frame_hdr : { \
24# RUN: __eh_frame_hdr_start = .; \
25# RUN: __eh_frame_hdr_start2 = ABSOLUTE(ALIGN(0x10)); \
26# RUN: *(.eh_frame_hdr) \
27# RUN: __eh_frame_hdr_end = .; \
28# RUN: __eh_frame_hdr_end2 = ABSOLUTE(ALIGN(0x10)); } \
29# RUN: .eh_frame : { } \
30# RUN: }" > %t.script
31# RUN: ld.lld -o %t1 --eh-frame-hdr --script %t.script %t
32# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=SIMPLE %s
33
34# Check that the following script is processed without errors
35# RUN: echo "SECTIONS { \
36# RUN: .eh_frame_hdr : { \
37# RUN: PROVIDE_HIDDEN(_begin_sec = .); \
38# RUN: *(.eh_frame_hdr) \
39# RUN: *(.eh_frame_hdr) \
40# RUN: PROVIDE_HIDDEN(_end_sec_abs = ABSOLUTE(.)); \
41# RUN: PROVIDE_HIDDEN(_end_sec = .); } \
42# RUN: }" > %t.script
43# RUN: ld.lld -o %t1 --eh-frame-hdr --script %t.script %t
44
45# Check that we can specify synthetic symbols without defining SECTIONS.
46# RUN: echo "PROVIDE_HIDDEN(_begin_sec = _start); \
47# RUN: PROVIDE_HIDDEN(_end_sec = ADDR(.text) + SIZEOF(.text));" > %t.script
48# RUN: ld.lld -o %t1 --eh-frame-hdr --script %t.script %t
49# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=NO-SEC %s
50
51# Check that we can do the same as above inside SECTIONS block.
52# RUN: echo "SECTIONS { \
53# RUN: . = 0x201000; \
54# RUN: .text : { *(.text) } \
55# RUN: PROVIDE_HIDDEN(_begin_sec = ADDR(.text)); \
56# RUN: PROVIDE_HIDDEN(_end_sec = ADDR(.text) + SIZEOF(.text)); }" > %t.script
57# RUN: ld.lld -o %t1 --eh-frame-hdr --script %t.script %t
58# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=IN-SEC %s
59
60# SIMPLE: 0000000000000128 .foo 00000000 .hidden _end_sec
61# SIMPLE-NEXT: 0000000000000120 .foo 00000000 _begin_sec
62# SIMPLE-NEXT: 0000000000000128 *ABS* 00000000 _end_sec_abs
63# SIMPLE-NEXT: 0000000000001048 .text 00000000 _start
64# SIMPLE-NEXT: 0000000000000120 .foo 00000000 begin_foo
65# SIMPLE-NEXT: 0000000000000128 .foo 00000000 end_foo
66# SIMPLE-NEXT: 0000000000000008 *ABS* 00000000 size_foo_1
67# SIMPLE-NEXT: 0000000000000008 *ABS* 00000000 size_foo_1_abs
68# SIMPLE-NEXT: 0000000000001000 .foo 00000000 begin_bar
69# SIMPLE-NEXT: 0000000000001004 .foo 00000000 end_bar
70# SIMPLE-NEXT: 0000000000000ee4 *ABS* 00000000 size_foo_2
71# SIMPLE-NEXT: 0000000000000ee4 *ABS* 00000000 size_foo_3
72# SIMPLE-NEXT: 0000000000001004 .eh_frame_hdr 00000000 __eh_frame_hdr_start
73# SIMPLE-NEXT: 0000000000001010 *ABS* 00000000 __eh_frame_hdr_start2
74# SIMPLE-NEXT: 0000000000001018 .eh_frame_hdr 00000000 __eh_frame_hdr_end
75# SIMPLE-NEXT: 0000000000001020 *ABS* 00000000 __eh_frame_hdr_end2
76
77# NO-SEC: 0000000000201000 .text 00000000 .hidden _begin_sec
78# NO-SEC-NEXT: 0000000000201001 .text 00000000 .hidden _end_sec
79
80# IN-SEC: 0000000000201000 .text 00000000 .hidden _begin_sec
81# IN-SEC-NEXT: 0000000000201001 .text 00000000 .hidden _end_sec
82
83.global _start
84_start:
85 nop
86
87.section .foo,"a"
88 .quad 0
89
90.section .bar,"a"
91 .long 0
92
93.section .dah,"ax",@progbits
94 .cfi_startproc
95 nop
96 .cfi_endproc
97
98.global _begin_sec, _end_sec, _end_sec_abs
deps/lld/test/ELF/linkerscript/symbols.s created+84
......@@ -0,0 +1,84 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4# Simple symbol assignment. Should raise conflict in case we
5# have duplicates in any input section, but currently simply
6# replaces the value.
7# RUN: echo "SECTIONS {.text : {*(.text.*)} text_end = .;}" > %t.script
8# RUN: ld.lld -o %t1 --script %t.script %t
9# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=SIMPLE %s
10# SIMPLE: .text 00000000 text_end
11
12# The symbol is not referenced. Don't provide it.
13# RUN: echo "SECTIONS { PROVIDE(newsym = 1);}" > %t.script
14# RUN: ld.lld -o %t1 --script %t.script %t
15# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=PROVIDE1 %s
16# PROVIDE1-NOT: 0000000000000001 *ABS* 00000000 newsym
17
18# The symbol is not referenced. Don't provide it.
19# RUN: echo "SECTIONS { PROVIDE_HIDDEN(newsym = 1);}" > %t.script
20# RUN: ld.lld -o %t1 --script %t.script %t
21# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=HIDDEN1 %s
22# HIDDEN1-NOT: 0000000000000001 *ABS* 00000000 .hidden newsym
23
24# Provide existing symbol. The value should be 0, even though we
25# have value of 1 in PROVIDE()
26# RUN: echo "SECTIONS { PROVIDE(somesym = 1);}" > %t.script
27# RUN: ld.lld -o %t1 --script %t.script %t
28# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=PROVIDE2 %s
29# PROVIDE2: 0000000000000000 *ABS* 00000000 somesym
30
31# Provide existing symbol. The value should be 0, even though we
32# have value of 1 in PROVIDE_HIDDEN(). Visibility should not change
33# RUN: echo "SECTIONS { PROVIDE_HIDDEN(somesym = 1);}" > %t.script
34# RUN: ld.lld -o %t1 --script %t.script %t
35# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=HIDDEN2 %s
36# HIDDEN2: 0000000000000000 *ABS* 00000000 somesym
37
38# Hidden symbol assignment.
39# RUN: echo "SECTIONS { HIDDEN(newsym = 1);}" > %t.script
40# RUN: ld.lld -o %t1 --script %t.script %t
41# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=HIDDEN3 %s
42# HIDDEN3: 0000000000000001 *ABS* 00000000 .hidden newsym
43
44# The symbol is not referenced. Don't provide it.
45# RUN: echo "PROVIDE(newsym = 1);" > %t.script
46# RUN: ld.lld -o %t1 --script %t.script %t
47# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=PROVIDE4 %s
48# PROVIDE4-NOT: 0000000000000001 *ABS* 00000000 newsym
49
50# The symbol is not referenced. Don't provide it.
51# RUN: echo "PROVIDE_HIDDEN(newsym = 1);" > %t.script
52# RUN: ld.lld -o %t1 --script %t.script %t
53# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=HIDDEN4 %s
54# HIDDEN4-NOT: 0000000000000001 *ABS* 00000000 .hidden newsym
55
56# Provide existing symbol. The value should be 0, even though we
57# have value of 1 in PROVIDE()
58# RUN: echo "PROVIDE(somesym = 1);" > %t.script
59# RUN: ld.lld -o %t1 --script %t.script %t
60# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=PROVIDE5 %s
61# PROVIDE5: 0000000000000000 *ABS* 00000000 somesym
62
63# Provide existing symbol. The value should be 0, even though we
64# have value of 1 in PROVIDE_HIDDEN(). Visibility should not change
65# RUN: echo "PROVIDE_HIDDEN(somesym = 1);" > %t.script
66# RUN: ld.lld -o %t1 --script %t.script %t
67# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=HIDDEN5 %s
68# HIDDEN5: 0000000000000000 *ABS* 00000000 somesym
69
70# Simple symbol assignment. All three symbols should have the
71# same value.
72# RUN: echo "foo = 0x100; SECTIONS { bar = foo; } baz = bar;" > %t.script
73# RUN: ld.lld -o %t1 --script %t.script %t
74# RUN: llvm-objdump -t %t1 | FileCheck --check-prefix=SIMPLE2 %s
75# SIMPLE2: 0000000000000100 *ABS* 00000000 foo
76# SIMPLE2: 0000000000000100 *ABS* 00000000 bar
77# SIMPLE2: 0000000000000100 *ABS* 00000000 baz
78
79.global _start
80_start:
81 nop
82
83.global somesym
84somesym = 0
deps/lld/test/ELF/linkerscript/tbss.s created+42
......@@ -0,0 +1,42 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: echo "SECTIONS { \
4# RUN: . = SIZEOF_HEADERS; \
5# RUN: .text : { *(.text) } \
6# RUN: foo : { *(foo) } \
7# RUN: bar : { *(bar) } \
8# RUN: }" > %t.script
9# RUN: ld.lld -T %t.script %t.o -o %t
10# RUN: llvm-readobj -s %t | FileCheck %s
11
12# test that a tbss section doesn't use address space.
13
14# CHECK: Name: foo
15# CHECK-NEXT: Type: SHT_NOBITS
16# CHECK-NEXT: Flags [
17# CHECK-NEXT: SHF_ALLOC
18# CHECK-NEXT: SHF_TLS
19# CHECK-NEXT: SHF_WRITE
20# CHECK-NEXT: ]
21# CHECK-NEXT: Address: 0x[[ADDR:.*]]
22# CHECK-NEXT: Offset: 0x[[ADDR]]
23# CHECK-NEXT: Size: 4
24# CHECK-NEXT: Link: 0
25# CHECK-NEXT: Info: 0
26# CHECK-NEXT: AddressAlignment: 1
27# CHECK-NEXT: EntrySize: 0
28# CHECK-NEXT: }
29# CHECK-NEXT: Section {
30# CHECK-NEXT: Index:
31# CHECK-NEXT: Name: bar
32# CHECK-NEXT: Type: SHT_PROGBITS
33# CHECK-NEXT: Flags [
34# CHECK-NEXT: SHF_ALLOC
35# CHECK-NEXT: SHF_WRITE
36# CHECK-NEXT: ]
37# CHECK-NEXT: Address: 0x[[ADDR]]
38
39 .section foo,"awT",@nobits
40 .long 0
41 .section bar, "aw"
42 .long 0
deps/lld/test/ELF/linkerscript/ttext-script.s created+11
......@@ -0,0 +1,11 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: echo "SECTIONS { .text 0x200000 : { *(.text) } }" > %t.script
4# RUN: ld.lld -T %t.script -Ttext 0x100000 %t.o -o %t
5# RUN: llvm-readobj --elf-output-style=GNU -s %t | FileCheck %s
6
7# CHECK: .text PROGBITS 0000000000100000
8
9.global _start
10_start:
11nop
deps/lld/test/ELF/linkerscript/undef.s created+11
......@@ -0,0 +1,11 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4# RUN: echo "SECTIONS { patatino = 0x1234; }" > %t.script
5# RUN: ld.lld -o %t1 --script %t.script %t
6# RUN: llvm-objdump -t %t1 | FileCheck %s
7# CHECK: 0000000000001234 *ABS* 00000000 patatino
8
9.global _start
10_start:
11 call patatino
deps/lld/test/ELF/linkerscript/unused-synthetic.s created+18
......@@ -0,0 +1,18 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: echo "SECTIONS { \
4# RUN: .got : { *(.got) } \
5# RUN: .plt : { *(.plt) } \
6# RUN: .text : { *(.text) } \
7# RUN: }" > %t.script
8# RUN: ld.lld -shared -o %t.so --script %t.script %t.o
9
10# RUN: llvm-objdump -section-headers %t.so | FileCheck %s
11# CHECK-NOT: .got
12# CHECK-NOT: .plt
13# CHECK: .text
14# CHECK-NEXT: .dynsym
15
16.global _start
17_start:
18 nop
deps/lld/test/ELF/linkerscript/va.s created+24
......@@ -0,0 +1,24 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4# RUN: echo "SECTIONS {}" > %t.script
5# RUN: ld.lld -o %t1 --script %t.script %t
6# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
7# CHECK: Sections:
8# CHECK-NEXT: Idx Name Size Address Type
9# CHECK-NEXT: 0 00000000 0000000000000000
10# CHECK-NEXT: 1 .text 00000001 0000000000000000 TEXT DATA
11# CHECK-NEXT: 2 .foo 00000004 0000000000000001 DATA
12# CHECK-NEXT: 3 .boo 00000004 0000000000000005 DATA
13
14.global _start
15_start:
16 nop
17
18.section .foo, "a"
19foo:
20 .long 0
21
22.section .boo, "a"
23boo:
24 .long 0
deps/lld/test/ELF/linkerscript/visibility.s created+22
......@@ -0,0 +1,22 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3
4# RUN: echo "SECTIONS { foo = .; }" > %t1.script
5# RUN: ld.lld -o %t1 --script %t1.script %t.o -shared
6# RUN: llvm-readobj -t %t1 | FileCheck %s
7
8# CHECK: Symbol {
9# CHECK: Name: foo
10# CHECK-NEXT: Value:
11# CHECK-NEXT: Size:
12# CHECK-NEXT: Binding: Local
13# CHECK-NEXT: Type:
14# CHECK-NEXT: Other [
15# CHECK-NEXT: STV_HIDDEN
16# CHECK-NEXT: ]
17# CHECK-NEXT: Section:
18# CHECK-NEXT: }
19
20 .data
21 .hidden foo
22 .long foo
deps/lld/test/ELF/linkerscript/wildcards.s created+83
......@@ -0,0 +1,83 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4## Default case: abc and abx included in text.
5# RUN: echo "SECTIONS { \
6# RUN: .text : { *(.abc .abx) } }" > %t.script
7# RUN: ld.lld -o %t.out --script %t.script %t
8# RUN: llvm-objdump -section-headers %t.out | \
9# RUN: FileCheck -check-prefix=SEC-DEFAULT %s
10# SEC-DEFAULT: Sections:
11# SEC-DEFAULT-NEXT: Idx Name Size
12# SEC-DEFAULT-NEXT: 0 00000000
13# SEC-DEFAULT-NEXT: 1 .text 00000008
14# SEC-DEFAULT-NEXT: 2 .abcd 00000004
15# SEC-DEFAULT-NEXT: 3 .ad 00000004
16# SEC-DEFAULT-NEXT: 4 .ag 00000004
17# SEC-DEFAULT-NEXT: 5 .comment 00000008 {{[0-9a-f]*}}
18# SEC-DEFAULT-NEXT: 6 .symtab 00000030
19# SEC-DEFAULT-NEXT: 7 .shstrtab 00000038
20# SEC-DEFAULT-NEXT: 8 .strtab 00000008
21
22## Now replace the symbol with '?' and check that results are the same.
23# RUN: echo "SECTIONS { \
24# RUN: .text : { *(.abc .ab?) } }" > %t.script
25# RUN: ld.lld -o %t.out --script %t.script %t
26# RUN: llvm-objdump -section-headers %t.out | \
27# RUN: FileCheck -check-prefix=SEC-DEFAULT %s
28
29## Now see how replacing '?' with '*' will consume whole abcd.
30# RUN: echo "SECTIONS { \
31# RUN: .text : { *(.abc .ab*) } }" > %t.script
32# RUN: ld.lld -o %t.out --script %t.script %t
33# RUN: llvm-objdump -section-headers %t.out | \
34# RUN: FileCheck -check-prefix=SEC-ALL %s
35# SEC-ALL: Sections:
36# SEC-ALL-NEXT: Idx Name Size
37# SEC-ALL-NEXT: 0 00000000
38# SEC-ALL-NEXT: 1 .text 0000000c
39# SEC-ALL-NEXT: 2 .ad 00000004
40# SEC-ALL-NEXT: 3 .ag 00000004
41# SEC-ALL-NEXT: 4 .comment 00000008
42# SEC-ALL-NEXT: 5 .symtab 00000030
43# SEC-ALL-NEXT: 6 .shstrtab 00000032
44# SEC-ALL-NEXT: 7 .strtab 00000008
45
46## All sections started with .a are merged.
47# RUN: echo "SECTIONS { \
48# RUN: .text : { *(.a*) } }" > %t.script
49# RUN: ld.lld -o %t.out --script %t.script %t
50# RUN: llvm-objdump -section-headers %t.out | \
51# RUN: FileCheck -check-prefix=SEC-NO %s
52# SEC-NO: Sections:
53# SEC-NO-NEXT: Idx Name Size
54# SEC-NO-NEXT: 0 00000000
55# SEC-NO-NEXT: 1 .text 00000014
56# SEC-NO-NEXT: 2 .comment 00000008
57# SEC-NO-NEXT: 3 .symtab 00000030
58# SEC-NO-NEXT: 4 .shstrtab 0000002a
59# SEC-NO-NEXT: 5 .strtab 00000008
60
61.text
62.section .abc,"ax",@progbits
63.long 0
64
65.text
66.section .abx,"ax",@progbits
67.long 0
68
69.text
70.section .abcd,"ax",@progbits
71.long 0
72
73.text
74.section .ad,"ax",@progbits
75.long 0
76
77.text
78.section .ag,"ax",@progbits
79.long 0
80
81
82.globl _start
83_start:
deps/lld/test/ELF/linkerscript/wildcards2.s created+25
......@@ -0,0 +1,25 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
4## Check that aabc is not included in text.
5# RUN: echo "SECTIONS { \
6# RUN: .text : { *(.abc) } }" > %t.script
7# RUN: ld.lld -o %t.out --script %t.script %t
8# RUN: llvm-objdump -section-headers %t.out | \
9# RUN: FileCheck %s
10# CHECK: Sections:
11# CHECK-NEXT: Idx Name Size
12# CHECK-NEXT: 0 00000000
13# CHECK-NEXT: 1 .text 00000004
14# CHECK-NEXT: 2 aabc 00000004
15
16.text
17.section .abc,"ax",@progbits
18.long 0
19
20.text
21.section aabc,"ax",@progbits
22.long 0
23
24.globl _start
25_start:
deps/lld/test/ELF/lit.local.cfg created+2
......@@ -0,0 +1,2 @@
1config.suffixes = ['.test', '.s', '.ll']
2
deps/lld/test/ELF/llvm33-rela-outside-group.s created+11
......@@ -0,0 +1,11 @@
1// Input file generated with:
2// llvm33/llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %S/Inputs/llvm33-rela-outside-group.o
3//
4// RUN: ld.lld -shared %S/Inputs/llvm33-rela-outside-group.o %S/Inputs/llvm33-rela-outside-group.o
5
6 .global bar
7 .weak _Z3fooIiEvv
8
9 .section .text._Z3fooIiEvv,"axG",@progbits,_Z3fooIiEvv,comdat
10_Z3fooIiEvv:
11 callq bar@PLT
deps/lld/test/ELF/local-dynamic.s created+94
......@@ -0,0 +1,94 @@
1// Check that local symbols are not inserted into dynamic table.
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
3// RUN: ld.lld %t -shared -o %t1.so
4// RUN: llvm-readobj -t -dyn-symbols %t1.so | FileCheck %s
5// REQUIRES: x86
6
7// CHECK: Symbols [
8// CHECK-NEXT: Symbol {
9// CHECK-NEXT: Name:
10// CHECK-NEXT: Value: 0x0
11// CHECK-NEXT: Size: 0
12// CHECK-NEXT: Binding: Local
13// CHECK-NEXT: Type: None
14// CHECK-NEXT: Other: 0
15// CHECK-NEXT: Section: Undefined
16// CHECK-NEXT: }
17// CHECK-NEXT: Symbol {
18// CHECK-NEXT: Name: blah
19// CHECK-NEXT: Value:
20// CHECK-NEXT: Size: 0
21// CHECK-NEXT: Binding: Local
22// CHECK-NEXT: Type: None
23// CHECK-NEXT: Other: 0
24// CHECK-NEXT: Section: .text
25// CHECK-NEXT: }
26// CHECK-NEXT: Symbol {
27// CHECK-NEXT: Name: foo
28// CHECK-NEXT: Value:
29// CHECK-NEXT: Size: 0
30// CHECK-NEXT: Binding: Local
31// CHECK-NEXT: Type: None
32// CHECK-NEXT: Other: 0
33// CHECK-NEXT: Section: .text
34// CHECK-NEXT: }
35// CHECK-NEXT: Symbol {
36// CHECK-NEXT: Name: goo
37// CHECK-NEXT: Value:
38// CHECK-NEXT: Size: 0
39// CHECK-NEXT: Binding: Local
40// CHECK-NEXT: Type: None
41// CHECK-NEXT: Other: 0
42// CHECK-NEXT: Section: .text
43// CHECK-NEXT: }
44// CHECK-NEXT: Symbol {
45// CHECK-NEXT: Name: _DYNAMIC
46// CHECK-NEXT: Value:
47// CHECK-NEXT: Size: 0
48// CHECK-NEXT: Binding: Local
49// CHECK-NEXT: Type: None
50// CHECK-NEXT: Other [ (0x2)
51// CHECK-NEXT: STV_HIDDEN
52// CHECK-NEXT: ]
53// CHECK-NEXT: Section: .dynamic
54// CHECK-NEXT: }
55// CHECK-NEXT: Symbol {
56// CHECK-NEXT: Name: _start
57// CHECK-NEXT: Value:
58// CHECK-NEXT: Size: 0
59// CHECK-NEXT: Binding: Global
60// CHECK-NEXT: Type: None
61// CHECK-NEXT: Other: 0
62// CHECK-NEXT: Section: .text
63// CHECK-NEXT: }
64// CHECK-NEXT: ]
65
66// CHECK: DynamicSymbols [
67// CHECK-NEXT: Symbol {
68// CHECK-NEXT: Name: @
69// CHECK-NEXT: Value: 0x0
70// CHECK-NEXT: Size: 0
71// CHECK-NEXT: Binding: Local
72// CHECK-NEXT: Type: None
73// CHECK-NEXT: Other: 0
74// CHECK-NEXT: Section: Undefined
75// CHECK-NEXT: }
76// CHECK-NEXT: Symbol {
77// CHECK-NEXT: Name: _start@
78// CHECK-NEXT: Value:
79// CHECK-NEXT: Size: 0
80// CHECK-NEXT: Binding: Global
81// CHECK-NEXT: Type: None
82// CHECK-NEXT: Other: 0
83// CHECK-NEXT: Section: .text
84// CHECK-NEXT: }
85// CHECK-NEXT: ]
86
87.global _start
88_start:
89
90blah:
91foo:
92goo:
93
94
deps/lld/test/ELF/local-got-pie.s created+37
......@@ -0,0 +1,37 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
2// RUN: ld.lld %t.o -o %t -pie
3// RUN: llvm-readobj -s -r -d %t | FileCheck %s
4// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
5
6.globl _start
7_start:
8 call foo@gotpcrel
9
10 .hidden foo
11 .global foo
12foo:
13 nop
14
15// 0x20B0 - 1001 - 5 = 4266
16// DISASM: Disassembly of section .text:
17// DISASM-NEXT: _start:
18// DISASM-NEXT: 1000: {{.*}} callq 4267
19// DISASM: foo:
20// DISASM-NEXT: 1005: {{.*}} nop
21
22// CHECK: Name: .got
23// CHECK-NEXT: Type: SHT_PROGBITS
24// CHECK-NEXT: Flags [
25// CHECK-NEXT: SHF_ALLOC
26// CHECK-NEXT: SHF_WRITE
27// CHECK-NEXT: ]
28// CHECK-NEXT: Address: 0x20B0
29// CHECK-NEXT: Offset:
30// CHECK-NEXT: Size: 8
31
32// CHECK: Relocations [
33// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
34// CHECK-NEXT: 0x20B0 R_X86_64_RELATIVE - 0x1005
35// CHECK-NEXT: }
36// CHECK-NEXT: ]
37// CHECK: 0x000000006FFFFFF9 RELACOUNT 1
deps/lld/test/ELF/local-got-shared.s created+36
......@@ -0,0 +1,36 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
2// RUN: ld.lld %t.o -o %t -shared
3// RUN: llvm-readobj -s -r -d %t | FileCheck %s
4// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
5
6bar:
7 call foo@gotpcrel
8
9 .hidden foo
10 .global foo
11foo:
12 nop
13
14// 0x20A0 - 0x1000 - 5 = 4251
15// DISASM: bar:
16// DISASM-NEXT: 1000: {{.*}} callq 4251
17
18// DISASM: foo:
19// DISASM-NEXT: 1005: {{.*}} nop
20
21// CHECK: Name: .got
22// CHECK-NEXT: Type: SHT_PROGBITS
23// CHECK-NEXT: Flags [
24// CHECK-NEXT: SHF_ALLOC
25// CHECK-NEXT: SHF_WRITE
26// CHECK-NEXT: ]
27// CHECK-NEXT: Address: 0x20A0
28// CHECK-NEXT: Offset:
29// CHECK-NEXT: Size: 8
30
31// CHECK: Relocations [
32// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
33// CHECK-NEXT: 0x20A0 R_X86_64_RELATIVE - 0x1005
34// CHECK-NEXT: }
35// CHECK-NEXT: ]
36// CHECK: 0x000000006FFFFFF9 RELACOUNT 1
deps/lld/test/ELF/local-got.s created+48
......@@ -0,0 +1,48 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o
3// RUN: ld.lld -shared %t2.o -o %t2.so
4// RUN: ld.lld %t.o %t2.so -o %t
5// RUN: llvm-readobj -s -r -section-data %t | FileCheck %s
6// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
7
8 .globl _start
9_start:
10 call bar@gotpcrel
11 call foo@gotpcrel
12
13 .global foo
14foo:
15 nop
16
17// 0x2020B0 - 0x201000 - 5 = 4251
18// 0x2020B8 - 0x201005 - 5 = 4254
19// DISASM: _start:
20// DISASM-NEXT: 201000: {{.*}} callq 4267
21// DISASM-NEXT: 201005: {{.*}} callq 4270
22
23// DISASM: foo:
24// DISASM-NEXT: 20100a: {{.*}} nop
25
26// CHECK: Name: .got
27// CHECK-NEXT: Type: SHT_PROGBITS
28// CHECK-NEXT: Flags [
29// CHECK-NEXT: SHF_ALLOC
30// CHECK-NEXT: SHF_WRITE
31// CHECK-NEXT: ]
32// CHECK-NEXT: Address: 0x2020B0
33// CHECK-NEXT: Offset:
34// CHECK-NEXT: Size: 16
35// CHECK-NEXT: Link: 0
36// CHECK-NEXT: Info: 0
37// CHECK-NEXT: AddressAlignment: 8
38// CHECK-NEXT: EntrySize: 0
39// CHECK-NEXT: SectionData (
40// 0x20200a in little endian
41// CHECK-NEXT: 0000: 00000000 00000000 0A102000 00000000
42// CHECK-NEXT: )
43
44// CHECK: Relocations [
45// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
46// CHECK-NEXT: 0x2020B0 R_X86_64_GLOB_DAT bar 0x0
47// CHECK-NEXT: }
48// CHECK-NEXT: ]
deps/lld/test/ELF/local-undefined-symbol.s created+13
......@@ -0,0 +1,13 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: ld.lld %t -o %t1
4# RUN: llvm-readobj -t %t1 | FileCheck %s
5
6# CHECK: Symbols [
7# CHECK-NOT: Name: foo
8
9.global _start
10_start:
11 jmp foo
12
13.local foo
deps/lld/test/ELF/local.s created+92
......@@ -0,0 +1,92 @@
1// Check that symbol table is correctly populated with local symbols.
2// RUN: llvm-mc -save-temp-labels -filetype=obj -triple=x86_64-pc-linux %s -o %t
3// RUN: ld.lld %t -o %t1
4// RUN: llvm-readobj -t -s %t1 | FileCheck %s
5// REQUIRES: x86
6
7// Check that Info is equal to the number of local symbols.
8// CHECK: Section {
9// CHECK: Name: .symtab
10// CHECK-NEXT: Type: SHT_SYMTAB
11// CHECK-NEXT: Flags [
12// CHECK-NEXT: ]
13// CHECK-NEXT: Address:
14// CHECK-NEXT: Offset:
15// CHECK-NEXT: Size:
16// CHECK-NEXT: Link:
17// CHECK-NEXT: Info: 6
18
19// CHECK: Symbols [
20// CHECK-NEXT: Symbol {
21// CHECK-NEXT: Name:
22// CHECK-NEXT: Value: 0x0
23// CHECK-NEXT: Size: 0
24// CHECK-NEXT: Binding: Local
25// CHECK-NEXT: Type: None
26// CHECK-NEXT: Other: 0
27// CHECK-NEXT: Section: Undefined
28// CHECK-NEXT: }
29// CHECK-NEXT: Symbol {
30// CHECK-NEXT: Name: .Labs
31// CHECK-NEXT: Value:
32// CHECK-NEXT: Size: 0
33// CHECK-NEXT: Binding: Local
34// CHECK-NEXT: Type: None
35// CHECK-NEXT: Other: 0
36// CHECK-NEXT: Section: Absolute
37// CHECK-NEXT: }
38// CHECK-NEXT: Symbol {
39// CHECK-NEXT: Name: abs
40// CHECK-NEXT: Value:
41// CHECK-NEXT: Size: 0
42// CHECK-NEXT: Binding: Local
43// CHECK-NEXT: Type: None
44// CHECK-NEXT: Other: 0
45// CHECK-NEXT: Section: Absolute
46// CHECK-NEXT: }
47// CHECK-NEXT: Symbol {
48// CHECK-NEXT: Name: blah
49// CHECK-NEXT: Value:
50// CHECK-NEXT: Size: 0
51// CHECK-NEXT: Binding: Local
52// CHECK-NEXT: Type: None
53// CHECK-NEXT: Other: 0
54// CHECK-NEXT: Section: .text
55// CHECK-NEXT: }
56// CHECK-NEXT: Symbol {
57// CHECK-NEXT: Name: foo
58// CHECK-NEXT: Value:
59// CHECK-NEXT: Size: 0
60// CHECK-NEXT: Binding: Local
61// CHECK-NEXT: Type: None
62// CHECK-NEXT: Other: 0
63// CHECK-NEXT: Section: .text
64// CHECK-NEXT: }
65// CHECK-NEXT: Symbol {
66// CHECK-NEXT: Name: goo
67// CHECK-NEXT: Value:
68// CHECK-NEXT: Size: 0
69// CHECK-NEXT: Binding: Local
70// CHECK-NEXT: Type: None
71// CHECK-NEXT: Other: 0
72// CHECK-NEXT: Section: .text
73// CHECK-NEXT: }
74// CHECK-NEXT: Symbol {
75// CHECK-NEXT: Name: _start
76// CHECK-NEXT: Value:
77// CHECK-NEXT: Size: 0
78// CHECK-NEXT: Binding: Global
79// CHECK-NEXT: Type: None
80// CHECK-NEXT: Other: 0
81// CHECK-NEXT: Section: .text
82// CHECK-NEXT: }
83// CHECK-NEXT: ]
84
85.global _start
86_start:
87
88blah:
89foo:
90goo:
91abs = 42
92.Labs = 43
deps/lld/test/ELF/lto/Inputs/archive-2.ll created+6
......@@ -0,0 +1,6 @@
1target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-unknown-linux-gnu"
3
4define void @_start() {
5 ret void
6}
deps/lld/test/ELF/lto/Inputs/archive-3.ll created+5
......@@ -0,0 +1,5 @@
1target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-unknown-linux-gnu"
3define void @foo() {
4 ret void
5}
deps/lld/test/ELF/lto/Inputs/archive.ll created+6
......@@ -0,0 +1,6 @@
1target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-unknown-linux-gnu"
3
4define void @f() {
5 ret void
6}
deps/lld/test/ELF/lto/Inputs/available-externally.ll created+6
......@@ -0,0 +1,6 @@
1target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-unknown-linux-gnu"
3
4define void @zed() {
5 ret void
6}
deps/lld/test/ELF/lto/Inputs/cache.ll created+10
......@@ -0,0 +1,10 @@
1target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-unknown-linux-gnu"
3
4define i32 @_start() {
5entry:
6 call void (...) @globalfunc()
7 ret i32 0
8}
9
10declare void @globalfunc(...)
deps/lld/test/ELF/lto/Inputs/comdat.s created+5
......@@ -0,0 +1,5 @@
1 .section .text.f,"axG",@progbits,c,comdat
2 .globl foo
3
4foo:
5 retq
deps/lld/test/ELF/lto/Inputs/common.s created+1
......@@ -0,0 +1 @@
1 .comm a,8,4
deps/lld/test/ELF/lto/Inputs/common3.ll created+3
......@@ -0,0 +1,3 @@
1target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-unknown-linux-gnu"
3@a = common hidden global i64 0, align 4
deps/lld/test/ELF/lto/Inputs/defsym-bar.ll created+21
......@@ -0,0 +1,21 @@
1target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-unknown-linux-gnu"
3
4declare void @this_is_bar1()
5declare void @this_is_bar2()
6declare void @this_is_bar3()
7
8define hidden void @bar1() {
9 call void @this_is_bar1()
10 ret void
11}
12
13define hidden void @bar2() {
14 call void @this_is_bar2()
15 ret void
16}
17
18define hidden void @bar3() {
19 call void @this_is_bar3()
20 ret void
21}
deps/lld/test/ELF/lto/Inputs/drop-debug-info.bc created
Binary files /dev/null and b/deps/lld/test/ELF/lto/Inputs/drop-debug-info.bc differ
deps/lld/test/ELF/lto/Inputs/drop-linkage.ll created+12
......@@ -0,0 +1,12 @@
1target triple = "x86_64-unknown-linux-gnu"
2target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
3
4$foo = comdat any
5define linkonce void @foo() comdat {
6 ret void
7}
8
9define void @bar() {
10 call void @foo()
11 ret void
12}
deps/lld/test/ELF/lto/Inputs/duplicated-name.ll created+6
......@@ -0,0 +1,6 @@
1target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-unknown-linux-gnu"
3
4define void @f2() {
5 ret void
6}
deps/lld/test/ELF/lto/Inputs/dynsym.s created+3
......@@ -0,0 +1,3 @@
1.globl foo
2foo:
3ret
deps/lld/test/ELF/lto/Inputs/internalize-exportdyn.ll created+6
......@@ -0,0 +1,6 @@
1target triple = "x86_64-unknown-linux-gnu"
2target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
3
4define weak_odr void @bah() {
5 ret void
6}
deps/lld/test/ELF/lto/Inputs/internalize-undef.ll created+6
......@@ -0,0 +1,6 @@
1target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-unknown-linux-gnu"
3
4define void @f() {
5 ret void
6}
deps/lld/test/ELF/lto/Inputs/irmover-error.ll created+6
......@@ -0,0 +1,6 @@
1target triple = "x86_64-unknown-linux-gnu"
2target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
3
4!0 = !{ i32 1, !"foo", i32 2 }
5
6!llvm.module.flags = !{ !0 }
deps/lld/test/ELF/lto/Inputs/linkonce-odr.ll created+6
......@@ -0,0 +1,6 @@
1target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-unknown-linux-gnu"
3
4define linkonce_odr void @f() {
5 ret void
6}
deps/lld/test/ELF/lto/Inputs/linkonce.ll created+6
......@@ -0,0 +1,6 @@
1target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-unknown-linux-gnu"
3
4define linkonce void @f() {
5 ret void
6}
deps/lld/test/ELF/lto/Inputs/relocation-model-pic.ll created+11
......@@ -0,0 +1,11 @@
1target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-unknown-linux-gnu"
3
4@foo = external global i32
5define i32 @main() {
6 %t = load i32, i32* @foo
7 ret i32 %t
8}
9
10!llvm.module.flags = !{!0}
11!0 = !{i32 1, !"PIC Level", i32 2}
deps/lld/test/ELF/lto/Inputs/resolution.s created+4
......@@ -0,0 +1,4 @@
1 .data
2 .global a
3a:
4 .long 9
deps/lld/test/ELF/lto/Inputs/save-temps.ll created+6
......@@ -0,0 +1,6 @@
1target triple = "x86_64-unknown-linux-gnu"
2target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
3
4define void @bar() {
5 ret void
6}
deps/lld/test/ELF/lto/Inputs/shared.s created+7
......@@ -0,0 +1,7 @@
1.globl printf
2.type printf, @function
3printf:
4
5.globl puts
6.type puts, @function
7puts:
deps/lld/test/ELF/lto/Inputs/start-lib1.ll created+8
......@@ -0,0 +1,8 @@
1target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-unknown-linux-gnu"
3
4declare void @bar()
5
6define void @foo() {
7 ret void
8}
deps/lld/test/ELF/lto/Inputs/start-lib2.ll created+6
......@@ -0,0 +1,6 @@
1target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-unknown-linux-gnu"
3
4define void @bar() {
5 ret void
6}
deps/lld/test/ELF/lto/Inputs/thin1.ll created+12
......@@ -0,0 +1,12 @@
1target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-scei-ps4"
3
4define i32 @foo(i32 %goo) {
5entry:
6 %goo.addr = alloca i32, align 4
7 store i32 %goo, i32* %goo.addr, align 4
8 %0 = load i32, i32* %goo.addr, align 4
9 %1 = load i32, i32* %goo.addr, align 4
10 %mul = mul nsw i32 %0, %1
11 ret i32 %mul
12}
deps/lld/test/ELF/lto/Inputs/thin2.ll created+11
......@@ -0,0 +1,11 @@
1target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-scei-ps4"
3
4define i32 @blah(i32 %meh) #0 {
5entry:
6 %meh.addr = alloca i32, align 4
7 store i32 %meh, i32* %meh.addr, align 4
8 %0 = load i32, i32* %meh.addr, align 4
9 %sub = sub nsw i32 %0, 48
10 ret i32 %sub
11}
deps/lld/test/ELF/lto/Inputs/thinlto.ll created+7
......@@ -0,0 +1,7 @@
1target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-unknown-linux-gnu"
3
4define void @g() {
5entry:
6 ret void
7}
deps/lld/test/ELF/lto/Inputs/tls-mixed.s created+4
......@@ -0,0 +1,4 @@
1.globl foo
2.section .tbss,"awT",@nobits
3foo:
4.long 0
deps/lld/test/ELF/lto/Inputs/type-merge.ll created+8
......@@ -0,0 +1,8 @@
1target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-unknown-linux-gnu"
3
4define void @zed() {
5 call void @bar()
6 ret void
7}
8declare void @bar()
deps/lld/test/ELF/lto/Inputs/type-merge2.ll created+8
......@@ -0,0 +1,8 @@
1target triple = "x86_64-unknown-linux-gnu"
2target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
3
4%zed = type { i16 }
5define void @bar(%zed* %this) {
6 store %zed* %this, %zed** null
7 ret void
8}
deps/lld/test/ELF/lto/Inputs/undef-mixed.s created+3
......@@ -0,0 +1,3 @@
1 .globl bar
2bar:
3 retq
deps/lld/test/ELF/lto/Inputs/unnamed-addr-drop.ll created+4
......@@ -0,0 +1,4 @@
1target triple = "x86_64-unknown-linux-gnu"
2target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
3
4@foo = unnamed_addr constant i32 42
deps/lld/test/ELF/lto/Inputs/unnamed-addr-lib.s created+6
......@@ -0,0 +1,6 @@
1 .protected foo
2 .global foo
3foo:
4
5 .global bar
6bar:
deps/lld/test/ELF/lto/Inputs/visibility.s created+8
......@@ -0,0 +1,8 @@
1 .global g
2g:
3 ret
4
5 .data
6 .global a
7a:
8 .long 41
deps/lld/test/ELF/lto/Inputs/wrap-bar.ll created+14
......@@ -0,0 +1,14 @@
1target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
2target triple = "x86_64-unknown-linux-gnu"
3
4define hidden void @bar() {
5 ret void
6}
7
8define hidden void @__real_bar() {
9 ret void
10}
11
12define hidden void @__wrap_bar() {
13 ret void
14}
deps/lld/test/ELF/lto/archive-2.ll created+28
......@@ -0,0 +1,28 @@
1; REQUIRES: x86
2; RUN: llvm-as %S/Inputs/archive-2.ll -o %t1.o
3; RUN: rm -f %t.a
4; RUN: llvm-ar rcs %t.a %t1.o
5; RUN: llvm-as %s -o %t2.o
6; RUN: ld.lld -m elf_x86_64 %t2.o %t.a -o %t3
7; RUN: llvm-readobj -t %t3 | FileCheck %s
8; RUN: ld.lld -m elf_x86_64 %t2.o --whole-archive %t.a -o %t3 -shared
9; RUN: llvm-readobj -t %t3 | FileCheck %s
10
11; CHECK: Name: _start (
12; CHECK-NEXT: Value:
13; CHECK-NEXT: Size:
14; CHECK-NEXT: Binding: Global
15; CHECK-NEXT: Type: Function
16; CHECK-NEXT: Other: 0
17; CHECK-NEXT: Section: .text
18
19target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
20target triple = "x86_64-unknown-linux-gnu"
21
22define void @g() {
23 call void @_start()
24 ret void
25}
26
27declare void @_start()
28
deps/lld/test/ELF/lto/archive-3.ll created+19
......@@ -0,0 +1,19 @@
1; REQUIRES: x86
2; RUN: llvm-as %S/Inputs/archive-3.ll -o %t1.o
3; RUN: llvm-as %s -o %t2.o
4
5; RUN: ld.lld -m elf_x86_64 %t1.o %t2.o -o %t3 -save-temps
6; RUN: llvm-dis %t3.0.2.internalize.bc -o - | FileCheck %s
7
8; RUN: rm -f %t.a
9; RUN: llvm-ar rcs %t.a %t1.o
10; RUN: ld.lld -m elf_x86_64 %t.a %t1.o %t2.o -o %t3 -save-temps
11; RUN: llvm-dis %t3.0.2.internalize.bc -o - | FileCheck %s
12
13; CHECK: define internal void @foo() {
14
15target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
16target triple = "x86_64-unknown-linux-gnu"
17define void @_start() {
18 ret void
19}
deps/lld/test/ELF/lto/archive-no-index.ll created+25
......@@ -0,0 +1,25 @@
1; REQUIRES: x86
2; Tests that we suggest that LTO symbols missing from an archive index
3; may be the cause of undefined references, but only if we both
4; encountered an empty archive index and undefined references (to prevent
5; noisy false alarms).
6
7; RUN: llvm-as -o %t1.o %s
8; RUN: llvm-as -o %t2.o %S/Inputs/archive.ll
9
10; RUN: rm -f %t1.a %t2.a
11; RUN: llvm-ar crS %t1.a %t2.o
12; RUN: llvm-ar crs %t2.a %t2.o
13
14; RUN: ld.lld -o %t -emain -m elf_x86_64 %t1.o %t1.a
15; RUN: ld.lld -o %t -emain -m elf_x86_64 %t1.o %t2.a
16
17target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
18target triple = "x86_64-unknown-linux-gnu"
19
20declare void @f()
21
22define i32 @main() {
23 call void @f()
24 ret i32 0
25}
deps/lld/test/ELF/lto/archive.ll created+36
......@@ -0,0 +1,36 @@
1; REQUIRES: x86
2; RUN: llvm-as %S/Inputs/archive.ll -o %t1.o
3; RUN: rm -f %t.a
4; RUN: llvm-ar rcs %t.a %t1.o
5; RUN: llvm-as %s -o %t2.o
6; RUN: ld.lld -m elf_x86_64 %t2.o %t.a -o %t3 -shared
7; RUN: llvm-readobj -t %t3 | FileCheck %s
8; RUN: ld.lld -m elf_x86_64 %t2.o --whole-archive %t.a -o %t3 -shared
9; RUN: llvm-readobj -t %t3 | FileCheck %s
10
11; CHECK: Name: g (
12; CHECK-NEXT: Value:
13; CHECK-NEXT: Size:
14; CHECK-NEXT: Binding: Global
15; CHECK-NEXT: Type: Function
16; CHECK-NEXT: Other: 0
17; CHECK-NEXT: Section: .text
18
19; CHECK: Name: f (
20; CHECK-NEXT: Value:
21; CHECK-NEXT: Size:
22; CHECK-NEXT: Binding: Global
23; CHECK-NEXT: Type: Function
24; CHECK-NEXT: Other: 0
25; CHECK-NEXT: Section: .text
26
27target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
28target triple = "x86_64-unknown-linux-gnu"
29
30define void @g() {
31 call void @f()
32 ret void
33}
34
35declare void @f()
36
deps/lld/test/ELF/lto/asmundef.ll created+24
......@@ -0,0 +1,24 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.o
3; RUN: ld.lld -m elf_x86_64 %t.o -o %t -save-temps
4; RUN: llvm-dis %t.0.4.opt.bc -o - | FileCheck %s
5
6target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
7target triple = "x86_64-unknown-linux-gnu"
8
9module asm ".weak patatino"
10module asm ".equ patatino, foo"
11
12declare void @patatino()
13
14define void @foo() {
15 ret void
16}
17
18define void @_start() {
19 call void @patatino()
20 ret void
21}
22
23; CHECK: define void @foo
24
deps/lld/test/ELF/lto/available-externally.ll created+23
......@@ -0,0 +1,23 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t1.o
3; RUN: llvm-as %p/Inputs/available-externally.ll -o %t2.o
4; RUN: ld.lld %t1.o %t2.o -m elf_x86_64 -o %t.so -shared -save-temps
5; RUN: llvm-dis < %t.so.0.2.internalize.bc | FileCheck %s
6
7target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
8target triple = "x86_64-unknown-linux-gnu"
9
10define void @foo() {
11 call void @bar()
12 call void @zed()
13 ret void
14}
15define available_externally void @bar() {
16 ret void
17}
18define available_externally void @zed() {
19 ret void
20}
21
22; CHECK: define available_externally void @bar() {
23; CHECK: define void @zed() {
deps/lld/test/ELF/lto/bitcode-nodatalayout.ll created+13
......@@ -0,0 +1,13 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.o
3; RUN: not ld.lld -m elf_x86_64 %t.o -o %t 2>&1 | FileCheck %s
4
5; CHECK: input module has no datalayout
6
7; This bitcode file has no datalayout.
8; Check that we error out producing a reasonable diagnostic.
9target triple = "x86_64-unknown-linux-gnu"
10
11define void @_start() {
12 ret void
13}
deps/lld/test/ELF/lto/cache.ll created+32
......@@ -0,0 +1,32 @@
1; REQUIRES: x86
2
3; RUN: opt -module-hash -module-summary %s -o %t.o
4; RUN: opt -module-hash -module-summary %p/Inputs/cache.ll -o %t2.o
5
6; RUN: rm -Rf %t.cache && mkdir %t.cache
7; Create two files that would be removed by cache pruning due to age.
8; We should only remove files matching the pattern "llvmcache-*".
9; RUN: touch -t 197001011200 %t.cache/llvmcache-foo %t.cache/foo
10; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy prune_after=1h -o %t3 %t2.o %t.o
11
12; Two cached objects, plus a timestamp file and "foo", minus the file we removed.
13; RUN: ls %t.cache | count 4
14
15; Create a file of size 64KB.
16; RUN: %python -c "print(' ' * 65536)" > %t.cache/llvmcache-foo
17
18; This should leave the file in place.
19; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy cache_size_bytes=128k -o %t3 %t2.o %t.o
20; RUN: ls %t.cache | count 5
21
22; This should remove it.
23; RUN: ld.lld --thinlto-cache-dir=%t.cache --thinlto-cache-policy cache_size_bytes=32k -o %t3 %t2.o %t.o
24; RUN: ls %t.cache | count 4
25
26target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
27target triple = "x86_64-unknown-linux-gnu"
28
29define void @globalfunc() #0 {
30entry:
31 ret void
32}
deps/lld/test/ELF/lto/codemodel.ll created+20
......@@ -0,0 +1,20 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.o
3; RUN: ld.lld -m elf_x86_64 %t.o -o %ts -mllvm -code-model=small
4; RUN: ld.lld -m elf_x86_64 %t.o -o %tl -mllvm -code-model=large
5; RUN: llvm-objdump -d %ts | FileCheck %s --check-prefix=CHECK-SMALL
6; RUN: llvm-objdump -d %tl | FileCheck %s --check-prefix=CHECK-LARGE
7
8target triple = "x86_64-unknown-linux-gnu"
9target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
10
11@data = internal constant [0 x i32] []
12
13define i32* @_start() nounwind readonly {
14entry:
15; CHECK-SMALL-LABEL: _start:
16; CHECK-SMALL: movl $2097440, %eax
17; CHECK-LARGE-LABEL: _start:
18; CHECK-LARGE: movabsq $2097440, %rax
19 ret i32* getelementptr ([0 x i32], [0 x i32]* @data, i64 0, i64 0)
20}
deps/lld/test/ELF/lto/combined-lto-object-name.ll created+16
......@@ -0,0 +1,16 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.o
3; RUN: not ld.lld -m elf_x86_64 %t.o -o %t2 2>&1 | FileCheck %s
4
5target triple = "x86_64-unknown-linux-gnu"
6target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
7
8declare void @foo()
9define void @_start() {
10 call void @foo()
11 ret void
12}
13
14; CHECK: error: undefined symbol: foo
15; CHECK: >>> referenced by ld-temp.o
16; CHECK: {{.*}}:(_start)
deps/lld/test/ELF/lto/comdat.ll created+21
......@@ -0,0 +1,21 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.o
3; RUN: ld.lld -m elf_x86_64 %t.o %t.o -o %t.so -shared
4; RUN: llvm-readobj -t %t.so | FileCheck %s
5
6; CHECK: Name: foo
7; CHECK-NEXT: Value:
8; CHECK-NEXT: Size: 1
9; CHECK-NEXT: Binding: Global
10; CHECK-NEXT: Type: Function
11; CHECK-NEXT: Other: 0
12; CHECK-NEXT: Section: .text
13
14target triple = "x86_64-unknown-linux-gnu"
15target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
16
17$foo = comdat any
18define void @foo() comdat {
19 ret void
20}
21
deps/lld/test/ELF/lto/comdat2.ll created+41
......@@ -0,0 +1,41 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.o
3; RUN: llvm-mc -triple=x86_64-pc-linux %p/Inputs/comdat.s -o %t2.o -filetype=obj
4; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t.so -shared
5; RUN: llvm-readobj -t %t.so | FileCheck %s
6; RUN: ld.lld -m elf_x86_64 %t2.o %t.o -o %t2.so -shared
7; RUN: llvm-readobj -t %t2.so | FileCheck %s --check-prefix=OTHER
8
9
10target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
11target triple = "x86_64-unknown-linux-gnu"
12
13$c = comdat any
14
15define protected void @foo() comdat($c) {
16 ret void
17}
18
19; CHECK: Symbol {
20; CHECK: Name: foo
21; CHECK-NEXT: Value: 0x1000
22; CHECK-NEXT: Size: 1
23; CHECK-NEXT: Binding: Global
24; CHECK-NEXT: Type: Function
25; CHECK-NEXT: Other [
26; CHECK-NEXT: STV_PROTECTED
27; CHECK-NEXT: ]
28; CHECK-NEXT: Section: .text
29; CHECK-NEXT: }
30
31; OTHER: Symbol {
32; OTHER: Name: foo
33; OTHER-NEXT: Value: 0x1000
34; OTHER-NEXT: Size: 0
35; OTHER-NEXT: Binding: Global
36; OTHER-NEXT: Type: None
37; OTHER-NEXT: Other [
38; OTHER-NEXT: STV_PROTECTED
39; OTHER-NEXT: ]
40; OTHER-NEXT: Section: .text
41; OTHER-NEXT: }
deps/lld/test/ELF/lto/common.ll created+31
......@@ -0,0 +1,31 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t1.o
3; RUN: llvm-mc -triple=x86_64-pc-linux %p/Inputs/common.s -o %t2.o -filetype=obj
4; RUN: ld.lld %t1.o %t2.o -o %t.so -shared
5; RUN: llvm-readobj -s -t %t.so | FileCheck %s
6
7; CHECK: Name: .bss
8; CHECK-NEXT: Type: SHT_NOBITS
9; CHECK-NEXT: Flags [
10; CHECK-NEXT: SHF_ALLOC
11; CHECK-NEXT: SHF_WRITE
12; CHECK-NEXT: ]
13; CHECK-NEXT: Address:
14; CHECK-NEXT: Offset:
15; CHECK-NEXT: Size: 8
16; CHECK-NEXT: Link: 0
17; CHECK-NEXT: Info: 0
18; CHECK-NEXT: AddressAlignment: 8
19
20; CHECK: Name: a
21; CHECK-NEXT: Value:
22; CHECK-NEXT: Size: 8
23; CHECK-NEXT: Binding: Global
24; CHECK-NEXT: Type: Object
25; CHECK-NEXT: Other: 0
26; CHECK-NEXT: Section: .bss
27
28target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
29target triple = "x86_64-unknown-linux-gnu"
30
31@a = common global i32 0, align 8
deps/lld/test/ELF/lto/common2.ll created+28
......@@ -0,0 +1,28 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t1.o
3; RUN: ld.lld -m elf_x86_64 %t1.o -o %t -shared -save-temps
4; RUN: llvm-dis < %t.0.2.internalize.bc | FileCheck %s
5; RUN: llvm-readobj -t %t | FileCheck %s --check-prefix=SHARED
6
7target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
8target triple = "x86_64-unknown-linux-gnu"
9
10@a = common global i8 0, align 8
11; CHECK-DAG: @a = common global i8 0, align 8
12
13@b = common hidden global i32 0, align 4
14define i32 @f() {
15 %t = load i32, i32* @b, align 4
16 ret i32 %t
17}
18; CHECK-DAG: @b = internal global i32 0, align 4
19
20; SHARED: Symbol {
21; SHARED: Name: a
22; SHARED-NEXT: Value:
23; SHARED-NEXT: Size: 1
24; SHARED-NEXT: Binding: Global
25; SHARED-NEXT: Type: Object
26; SHARED-NEXT: Other: 0
27; SHARED-NEXT: Section: .bss
28; SHARED-NEXT: }
deps/lld/test/ELF/lto/common3.ll created+15
......@@ -0,0 +1,15 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t1.o
3; RUN: llvm-as %S/Inputs/common3.ll -o %t2.o
4; RUN: ld.lld -m elf_x86_64 %t1.o %t2.o -o %t -shared -save-temps
5; RUN: llvm-dis < %t.0.2.internalize.bc | FileCheck %s
6
7target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
8target triple = "x86_64-unknown-linux-gnu"
9@a = common hidden global i32 0, align 8
10define i32 @f() {
11 %t = load i32, i32* @a, align 4
12 ret i32 %t
13}
14
15; CHECK: @a = internal global i64 0, align 8
deps/lld/test/ELF/lto/ctors.ll created+18
......@@ -0,0 +1,18 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.o
3; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -shared
4; RUN: llvm-readobj -sections %t.so | FileCheck %s
5
6target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
7target triple = "x86_64-unknown-linux-gnu"
8
9@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @ctor, i8* null }]
10define void @ctor() {
11 call void asm "nop", ""()
12 ret void
13}
14
15; The llvm.global_ctors should end up producing constructors.
16; On x86-64 (linux) we should always emit .init_array and never .ctors.
17; CHECK: Name: .init_array
18; CHECK-NOT: Name: .ctors
deps/lld/test/ELF/lto/defsym.ll created+42
......@@ -0,0 +1,42 @@
1; REQUIRES: x86
2; LTO
3; RUN: llvm-as %s -o %t.o
4; RUN: llvm-as %S/Inputs/defsym-bar.ll -o %t1.o
5; RUN: ld.lld %t.o %t1.o -shared -o %t.so -defsym=bar2=bar3
6; RUN: llvm-objdump -d %t.so | FileCheck %s
7
8; ThinLTO
9; RUN: opt -module-summary %s -o %t.o
10; RUN: opt -module-summary %S/Inputs/defsym-bar.ll -o %t1.o
11; RUN: ld.lld %t.o %t1.o -shared -o %t.so -defsym=bar2=bar3
12; RUN: llvm-objdump -d %t.so | FileCheck %s --check-prefix=THIN
13
14; Call to bar2() should not be inlined and should be routed to bar3()
15; Symbol bar3 should not be eliminated
16
17; CHECK: foo:
18; CHECK-NEXT: pushq %rax
19; CHECK-NEXT: callq
20; CHECK-NEXT: callq{{.*}}<bar3>
21; CHECK-NEXT: callq
22
23; THIN: foo
24; THIN-NEXT: pushq %rax
25; THIN-NEXT: callq
26; THIN-NEXT: callq{{.*}}<bar3>
27; THIN-NEXT: popq %rax
28; THIN-NEXT: jmp
29
30target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
31target triple = "x86_64-unknown-linux-gnu"
32
33declare void @bar1()
34declare void @bar2()
35declare void @bar3()
36
37define void @foo() {
38 call void @bar1()
39 call void @bar2()
40 call void @bar3()
41 ret void
42}
deps/lld/test/ELF/lto/discard-value-names.ll created+24
......@@ -0,0 +1,24 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.o
3
4; RUN: ld.lld -m elf_x86_64 -shared -save-temps %t.o -o %t2.o
5; RUN: llvm-dis < %t2.o.0.0.preopt.bc | FileCheck %s
6
7; CHECK: @GlobalValueName
8; CHECK: @foo(i32 %in)
9; CHECK: somelabel:
10; CHECK: %GV = load i32, i32* @GlobalValueName
11; CHECK: %add = add i32 %in, %GV
12; CHECK: ret i32 %add
13
14target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
15target triple = "x86_64-unknown-linux-gnu"
16
17@GlobalValueName = global i32 0
18
19define i32 @foo(i32 %in) {
20somelabel:
21 %GV = load i32, i32* @GlobalValueName
22 %add = add i32 %in, %GV
23 ret i32 %add
24}
deps/lld/test/ELF/lto/drop-debug-info.ll created+9
......@@ -0,0 +1,9 @@
1; REQUIRES: x86
2;
3; drop-debug-info.bc was created from "void f(void) {}" with clang 3.5 and
4; -gline-tables-only, so it contains old debug info.
5;
6; RUN: ld.lld -m elf_x86_64 -shared %p/Inputs/drop-debug-info.bc \
7; RUN: -disable-verify 2>&1 | FileCheck %s
8; CHECK: ignoring debug info with an invalid version (1) in {{.*}}drop-debug-info.bc
9
deps/lld/test/ELF/lto/drop-linkage.ll created+14
......@@ -0,0 +1,14 @@
1target triple = "x86_64-unknown-linux-gnu"
2target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
3
4; REQUIRES: x86
5; RUN: llc %s -o %t.o -filetype=obj
6; RUN: llvm-as %p/Inputs/drop-linkage.ll -o %t2.o
7; RUN: ld.lld %t.o %t2.o -o %t.so -save-temps -shared
8; RUN: llvm-dis %t.so.0.4.opt.bc -o - | FileCheck %s
9
10define void @foo() {
11 ret void
12}
13
14; CHECK: declare void @foo()
deps/lld/test/ELF/lto/duplicated-name.ll created+15
......@@ -0,0 +1,15 @@
1; REQUIRES: x86
2; Cretae two archive with the same member name
3; RUN: rm -f %t1.a %t2.a
4; RUN: opt -module-summary %s -o %t.o
5; RUN: llvm-ar rcS %t1.a %t.o
6; RUN: opt -module-summary %p/Inputs/duplicated-name.ll -o %t.o
7; RUN: llvm-ar rcS %t2.a %t.o
8; RUN: ld.lld -m elf_x86_64 -shared -o %t.so -uf1 -uf2 %t1.a %t2.a
9
10target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
11target triple = "x86_64-unknown-linux-gnu"
12
13define void @f1() {
14 ret void
15}
deps/lld/test/ELF/lto/duplicated.ll created+14
......@@ -0,0 +1,14 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.o
3; RUN: not ld.lld -m elf_x86_64 %t.o %t.o -o %t.so -shared 2>&1 | FileCheck %s
4
5; CHECK: duplicate symbol: f
6; CHECK-NEXT: >>> defined in {{.*}}.o
7; CHECK-NEXT: >>> defined in {{.*}}.o
8
9target triple = "x86_64-unknown-linux-gnu"
10target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
11
12define void @f() {
13 ret void
14}
deps/lld/test/ELF/lto/dynamic-list.ll created+25
......@@ -0,0 +1,25 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.o
3; RUN: echo "{ foo; };" > %t.list
4; RUN: ld.lld -m elf_x86_64 -o %t --dynamic-list %t.list -pie %t.o
5; RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
6
7; CHECK: Name: foo@
8; CHECK-NEXT: Value: 0x1010
9; CHECK-NEXT: Size: 1
10; CHECK-NEXT: Binding: Global (0x1)
11; CHECK-NEXT: Type: Function
12; CHECK-NEXT: Other: 0
13; CHECK-NEXT: Section: .text
14; CHECK-NEXT: }
15
16target triple = "x86_64-unknown-linux-gnu"
17target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
18
19define void @_start() {
20 ret void
21}
22
23define void @foo() {
24 ret void
25}
deps/lld/test/ELF/lto/dynsym.ll created+30
......@@ -0,0 +1,30 @@
1; REQUIRES: x86
2; RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux -o %t.o %p/Inputs/dynsym.s
3; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -shared
4; RUN: llvm-as %s -o %t2.o
5; RUN: ld.lld -m elf_x86_64 %t2.o %t.so -o %t
6; RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
7
8; Check that we don't crash when gc'ing sections and printing the result.
9; RUN: ld.lld -m elf_x86_64 %t2.o %t.so --gc-sections --print-gc-sections \
10; RUN: -o %t
11; RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
12
13target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
14target triple = "x86_64-unknown-linux-gnu"
15
16define void @_start() {
17 call void @foo()
18 ret void
19}
20
21; CHECK: Name: foo
22; CHECK-NEXT: Value:
23; CHECK-NEXT: Size:
24; CHECK-NEXT: Binding:
25; CHECK-NEXT: Type:
26; CHECK-NEXT: Other:
27; CHECK-NEXT: Section: .text
28define void @foo() {
29 ret void
30}
deps/lld/test/ELF/lto/inline-asm.ll created+11
......@@ -0,0 +1,11 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.o
3; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -shared
4
5target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
6target triple = "x86_64-unknown-linux-gnu"
7
8define void @foo() {
9 call void asm "nop", ""()
10 ret void
11}
deps/lld/test/ELF/lto/internalize-basic.ll created+21
......@@ -0,0 +1,21 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.o
3; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -save-temps
4; RUN: llvm-dis < %t2.0.2.internalize.bc | FileCheck %s
5
6target triple = "x86_64-unknown-linux-gnu"
7target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
8
9define void @_start() {
10 ret void
11}
12
13define hidden void @foo() {
14 ret void
15}
16
17; Check that _start is not internalized.
18; CHECK: define void @_start()
19
20; Check that foo function is correctly internalized.
21; CHECK: define internal void @foo()
deps/lld/test/ELF/lto/internalize-exportdyn.ll created+47
......@@ -0,0 +1,47 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.o
3; RUN: llvm-as %p/Inputs/internalize-exportdyn.ll -o %t2.o
4; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t2 --export-dynamic -save-temps
5; RUN: llvm-dis < %t2.0.2.internalize.bc | FileCheck %s
6
7target triple = "x86_64-unknown-linux-gnu"
8target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
9
10define void @_start() {
11 ret void
12}
13
14define void @foo() {
15 ret void
16}
17
18define hidden void @bar() {
19 ret void
20}
21
22define linkonce_odr void @zed() local_unnamed_addr {
23 ret void
24}
25
26define linkonce_odr void @zed2() unnamed_addr {
27 ret void
28}
29
30define linkonce_odr void @bah() {
31 ret void
32}
33
34define linkonce_odr void @baz() {
35 ret void
36}
37
38@use_baz = global void ()* @baz
39
40; Check what gets internalized.
41; CHECK: define void @_start()
42; CHECK: define void @foo()
43; CHECK: define internal void @bar()
44; CHECK: define internal void @zed()
45; CHECK: define internal void @zed2()
46; CHECK: define weak_odr void @bah()
47; CHECK: define weak_odr void @baz()
deps/lld/test/ELF/lto/internalize-llvmused.ll created+20
......@@ -0,0 +1,20 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.o
3; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -save-temps
4; RUN: llvm-dis < %t2.0.2.internalize.bc | FileCheck %s
5
6target triple = "x86_64-unknown-linux-gnu"
7target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
8
9define void @_start() {
10 ret void
11}
12
13define hidden void @f() {
14 ret void
15}
16
17@llvm.used = appending global [1 x i8*] [ i8* bitcast (void ()* @f to i8*)]
18
19; Check that f is not internalized.
20; CHECK: define hidden void @f()
deps/lld/test/ELF/lto/internalize-undef.ll created+16
......@@ -0,0 +1,16 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.o
3; RUN: llvm-as %p/Inputs/internalize-undef.ll -o %t2.o
4; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t -save-temps
5; RUN: llvm-dis < %t.0.2.internalize.bc | FileCheck %s
6
7target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
8target triple = "x86_64-unknown-linux-gnu"
9
10declare void @f()
11define void @_start() {
12 call void @f()
13 ret void
14}
15
16; CHECK: define internal void @f()
deps/lld/test/ELF/lto/internalize-version-script.ll created+22
......@@ -0,0 +1,22 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.o
3; RUN: echo "{ global: foo; local: *; };" > %t.script
4; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -shared --version-script %t.script -save-temps
5; RUN: llvm-dis < %t2.0.2.internalize.bc | FileCheck %s
6
7target triple = "x86_64-unknown-linux-gnu"
8target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
9
10define void @foo() {
11 ret void
12}
13
14define void @bar() {
15 ret void
16}
17
18; Check that foo is not internalized.
19; CHECK: define void @foo()
20
21; Check that bar is correctly internalized.
22; CHECK: define internal void @bar()
deps/lld/test/ELF/lto/irmover-error.ll created+12
......@@ -0,0 +1,12 @@
1; RUN: llvm-as -o %t1.bc %s
2; RUN: llvm-as -o %t2.bc %S/Inputs/irmover-error.ll
3; RUN: not ld.lld -m elf_x86_64 %t1.bc %t2.bc -o %t 2>&1 | FileCheck %s
4
5; CHECK: linking module flags 'foo': IDs have conflicting values
6
7target triple = "x86_64-unknown-linux-gnu"
8target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
9
10!0 = !{ i32 1, !"foo", i32 1 }
11
12!llvm.module.flags = !{ !0 }
deps/lld/test/ELF/lto/linkage.ll created+20
......@@ -0,0 +1,20 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t1.o
3; RUN: ld.lld -m elf_x86_64 %t1.o %t1.o -o %t.so -shared
4; RUN: llvm-nm %t.so | FileCheck %s
5
6target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
7target triple = "x86_64-unknown-linux-gnu"
8
9; Should not encounter a duplicate symbol error for @.str
10@.str = private unnamed_addr constant [4 x i8] c"Hey\00", align 1
11
12; Should not encounter a duplicate symbol error for @llvm.global_ctors
13@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @ctor, i8* null }]
14define internal void @ctor() {
15 ret void
16}
17
18; Should not try to merge a declaration into the combined module.
19declare i32 @llvm.ctpop.i32(i32)
20; CHECK-NOT: llvm.ctpop.i32
deps/lld/test/ELF/lto/linkonce-odr.ll created+17
......@@ -0,0 +1,17 @@
1; REQUIRES: x86
2; RUN: llvm-as %p/Inputs/linkonce-odr.ll -o %t1.o
3; RUN: llc -relocation-model=pic %s -o %t2.o -filetype=obj
4; RUN: ld.lld %t1.o %t2.o -o %t.so -shared -save-temps
5; RUN: llvm-dis %t.so.0.4.opt.bc -o - | FileCheck %s
6
7target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
8target triple = "x86_64-unknown-linux-gnu"
9declare void @f()
10
11define void @g() {
12 call void @f()
13 ret void
14}
15
16; Be sure that 'f' is kept and has weak_odr linkage.
17; CHECK: define weak_odr void @f()
deps/lld/test/ELF/lto/linkonce.ll created+17
......@@ -0,0 +1,17 @@
1; REQUIRES: x86
2; RUN: llvm-as %p/Inputs/linkonce.ll -o %t1.o
3; RUN: llc -relocation-model=pic %s -o %t2.o -filetype=obj
4; RUN: ld.lld %t1.o %t2.o -o %t.so -shared -save-temps
5; RUN: llvm-dis %t.so.0.4.opt.bc -o - | FileCheck %s
6
7target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
8target triple = "x86_64-unknown-linux-gnu"
9declare void @f()
10
11define void @g() {
12 call void @f()
13 ret void
14}
15
16; Be sure that 'f' is kept and has weak linkage.
17; CHECK: define weak void @f()
deps/lld/test/ELF/lto/lto-start.ll created+23
......@@ -0,0 +1,23 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.o
3; RUN: ld.lld -m elf_x86_64 %t.o -o %t2
4; RUN: llvm-readobj -t %t2 | FileCheck %s
5
6; CHECK: Format: ELF64-x86-64
7; CHECK-NEXT: Arch: x86_64
8; CHECK-NEXT: AddressSize: 64bit
9
10; CHECK: Name: _start
11; CHECK-NEXT: Value:
12; CHECK-NEXT: Size: 1
13; CHECK-NEXT: Binding: Global
14; CHECK-NEXT: Type: Function
15; CHECK-NEXT: Other:
16; CHECK-NEXT: Section: .text
17
18target triple = "x86_64-unknown-linux-gnu"
19target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
20
21define void @_start() {
22 ret void
23}
deps/lld/test/ELF/lto/ltopasses-basic.ll created+17
......@@ -0,0 +1,17 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.o
3; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -save-temps -mllvm -debug-pass=Arguments -shared 2>&1 | FileCheck %s --check-prefix=MLLVM
4; RUN: llvm-dis %t.so.0.4.opt.bc -o - | FileCheck %s
5
6target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
7target triple = "x86_64-unknown-linux-gnu"
8
9@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @ctor, i8* null }]
10define void @ctor() {
11 ret void
12}
13
14; `@ctor` doesn't do anything and so the optimizer should kill it, leaving no ctors
15; CHECK: @llvm.global_ctors = appending global [0 x { i32, void ()*, i8* }] zeroinitializer
16
17; MLLVM: Pass Arguments:
deps/lld/test/ELF/lto/ltopasses-custom.ll created+37
......@@ -0,0 +1,37 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.o
3; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -save-temps --lto-aa-pipeline=basic-aa \
4; RUN: --lto-newpm-passes=ipsccp -shared
5; RUN: ld.lld -m elf_x86_64 %t.o -o %t2.so -save-temps --lto-newpm-passes=loweratomic -shared
6; RUN: llvm-dis %t.so.0.4.opt.bc -o - | FileCheck %s
7; RUN: llvm-dis %t2.so.0.4.opt.bc -o - | FileCheck %s --check-prefix=ATOMIC
8
9target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
10target triple = "x86_64-unknown-linux-gnu"
11
12define void @barrier() {
13 fence seq_cst
14 ret void
15}
16
17; IPSCCP won't remove the fence.
18; CHECK: define void @barrier() {
19; CHECK-NEXT: fence seq_cst
20; CHECK-NEXT: ret void
21
22; LowerAtomic will remove the fence.
23; ATOMIC: define void @barrier() {
24; ATOMIC-NEXT: ret void
25
26; Check that invalid passes are rejected gracefully.
27; RUN: not ld.lld -m elf_x86_64 %t.o -o %t2.so \
28; RUN: --lto-newpm-passes=iamnotapass -shared 2>&1 | \
29; RUN: FileCheck %s --check-prefix=INVALID
30; INVALID: unable to parse pass pipeline description: iamnotapass
31
32; Check that invalid AA pipelines are rejected gracefully.
33; RUN: not ld.lld -m elf_x86_64 %t.o -o %t2.so \
34; RUN: --lto-newpm-passes=globaldce --lto-aa-pipeline=patatino \
35; RUN: -shared 2>&1 | \
36; RUN: FileCheck %s --check-prefix=INVALIDAA
37; INVALIDAA: unable to parse AA pipeline description: patatino
deps/lld/test/ELF/lto/metadata.ll created+15
......@@ -0,0 +1,15 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t1.o
3; RUN: ld.lld -m elf_x86_64 %t1.o %t1.o -o %t.so -shared
4
5target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
6target triple = "x86_64-unknown-linux-gnu"
7
8define weak void @foo(i32* %p) {
9 store i32 5, i32* %p, align 4, !tbaa !0
10 ret void
11}
12
13!0 = !{!1, !1, i64 0}
14!1 = !{!"int", !2}
15!2 = !{!"Simple C/C++ TBAA"}
deps/lld/test/ELF/lto/mix-platforms.ll created+10
......@@ -0,0 +1,10 @@
1; REQUIRES: x86
2; RUN: llvm-mc %p/Inputs/shared.s -o %t386.o -filetype=obj -triple=i386-pc-linux
3; RUN: ld.lld %t386.o -o %ti386.so -shared
4; RUN: llvm-as %s -o %tx64.o
5; RUN: not ld.lld %ti386.so %tx64.o -o %t 2>&1 | FileCheck %s
6
7target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
8target triple = "x86_64-unknown-linux-gnu"
9
10; CHECK: {{.*}}x64.o is incompatible with {{.*}}i386.so
deps/lld/test/ELF/lto/module-asm.ll created+19
......@@ -0,0 +1,19 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.o
3; RUN: ld.lld -m elf_x86_64 %t.o -o %t
4; RUN: llvm-nm %t | FileCheck %s
5
6target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
7target triple = "x86_64-unknown-linux-gnu"
8
9module asm ".text"
10module asm ".globl foo"
11; CHECK: T foo
12module asm "foo: ret"
13
14declare void @foo()
15
16define void @_start() {
17 call void @foo()
18 ret void
19}
deps/lld/test/ELF/lto/opt-level.ll created+30
......@@ -0,0 +1,30 @@
1; REQUIRES: x86
2; RUN: llvm-as -o %t.o %s
3; RUN: ld.lld -o %t0 -m elf_x86_64 -e main --lto-O0 %t.o
4; RUN: llvm-nm %t0 | FileCheck --check-prefix=CHECK-O0 %s
5; RUN: ld.lld -o %t2 -m elf_x86_64 -e main --lto-O2 %t.o
6; RUN: llvm-nm %t2 | FileCheck --check-prefix=CHECK-O2 %s
7; RUN: ld.lld -o %t2a -m elf_x86_64 -e main %t.o
8; RUN: llvm-nm %t2a | FileCheck --check-prefix=CHECK-O2 %s
9
10; Reject invalid optimization levels.
11; RUN: not ld.lld -o %t3 -m elf_x86_64 -e main --lto-O6 %t.o 2>&1 | \
12; RUN: FileCheck --check-prefix=INVALID %s
13; INVALID: invalid optimization level for LTO: 6
14; RUN: not ld.lld -o %t3 -m elf_x86_64 -e main --lto-O-1 %t.o 2>&1 | \
15; RUN: FileCheck --check-prefix=INVALIDNEGATIVE %s
16; INVALIDNEGATIVE: invalid optimization level for LTO: -1
17
18target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
19target triple = "x86_64-unknown-linux-gnu"
20
21; CHECK-O0: foo
22; CHECK-O2-NOT: foo
23define internal void @foo() {
24 ret void
25}
26
27define void @main() {
28 call void @foo()
29 ret void
30}
deps/lld/test/ELF/lto/opt-remarks.ll created+69
......@@ -0,0 +1,69 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.o
3
4; RUN: rm -f %t.yaml
5; RUN: ld.lld --opt-remarks-filename %t.yaml %t.o -o %t -shared -save-temps
6; RUN: llvm-dis %t.0.4.opt.bc -o - | FileCheck %s
7; RUN: ld.lld --opt-remarks-with-hotness --opt-remarks-filename %t.hot.yaml \
8; RUN: %t.o -o %t -shared
9; RUN: cat %t.yaml | FileCheck %s -check-prefix=YAML
10; RUN: cat %t.hot.yaml | FileCheck %s -check-prefix=YAML-HOT
11
12; Check that @tinkywinky is inlined after optimizations.
13; CHECK-LABEL: define i32 @main
14; CHECK-NEXT: %a.i = call i32 @patatino()
15; CHECK-NEXT: ret i32 %a.i
16; CHECK-NEXT: }
17
18; YAML: --- !Analysis
19; YAML-NEXT: Pass: inline
20; YAML-NEXT: Name: CanBeInlined
21; YAML-NEXT: Function: main
22; YAML-NEXT: Args:
23; YAML-NEXT: - Callee: tinkywinky
24; YAML-NEXT: - String: ' can be inlined into '
25; YAML-NEXT: - Caller: main
26; YAML-NEXT: - String: ' with cost='
27; YAML-NEXT: - Cost: '0'
28; YAML-NEXT: - String: ' (threshold='
29; YAML-NEXT: - Threshold: '337'
30; YAML-NEXT: - String: ')'
31; YAML-NEXT: ...
32; YAML-NEXT: --- !Passed
33; YAML-NEXT: Pass: inline
34; YAML-NEXT: Name: Inlined
35; YAML-NEXT: Function: main
36; YAML-NEXT: Args:
37; YAML-NEXT: - Callee: tinkywinky
38; YAML-NEXT: - String: ' inlined into '
39; YAML-NEXT: - Caller: main
40; YAML-NEXT: ...
41
42; YAML-HOT: ...
43; YAML-HOT: --- !Passed
44; YAML-HOT: Pass: inline
45; YAML-HOT-NEXT: Name: Inlined
46; YAML-HOT-NEXT: Function: main
47; YAML-HOT-NEXT: Hotness: 300
48; YAML-HOT-NEXT: Args:
49; YAML-HOT-NEXT: - Callee: tinkywinky
50; YAML-HOT-NEXT: - String: ' inlined into '
51; YAML-HOT-NEXT: - Caller: main
52; YAML-HOT-NEXT: ...
53
54target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
55target triple = "x86_64-scei-ps4"
56
57declare i32 @patatino()
58
59define i32 @tinkywinky() {
60 %a = call i32 @patatino()
61 ret i32 %a
62}
63
64define i32 @main() !prof !0 {
65 %i = call i32 @tinkywinky()
66 ret i32 %i
67}
68
69!0 = !{!"function_entry_count", i64 300}
deps/lld/test/ELF/lto/parallel-internalize.ll created+59
......@@ -0,0 +1,59 @@
1; REQUIRES: x86
2; RUN: llvm-as -o %t.bc %s
3; RUN: rm -f %t.lto.o %t1.lto.o
4; RUN: ld.lld -m elf_x86_64 --lto-partitions=2 -save-temps -o %t %t.bc \
5; RUN: -e foo --lto-O0
6; RUN: llvm-readobj -t -dyn-symbols %t | FileCheck %s
7; RUN: llvm-nm %t.lto.o | FileCheck --check-prefix=CHECK0 %s
8; RUN: llvm-nm %t1.lto.o | FileCheck --check-prefix=CHECK1 %s
9
10; CHECK: Symbols [
11; CHECK-NEXT: Symbol {
12; CHECK-NEXT: Name: (0)
13; CHECK-NEXT: Value: 0x0
14; CHECK-NEXT: Size: 0
15; CHECK-NEXT: Binding: Local (0x0)
16; CHECK-NEXT: Type: None (0x0)
17; CHECK-NEXT: Other: 0
18; CHECK-NEXT: Section: Undefined (0x0)
19; CHECK-NEXT: }
20; CHECK-NEXT: Symbol {
21; CHECK-NEXT: Name: bar
22; CHECK-NEXT: Value: 0x201010
23; CHECK-NEXT: Size: 8
24; CHECK-NEXT: Binding: Local (0x0)
25; CHECK-NEXT: Type: Function (0x2)
26; CHECK-NEXT: Other [ (0x2)
27; CHECK-NEXT: STV_HIDDEN (0x2)
28; CHECK-NEXT: ]
29; CHECK-NEXT: Section: .text (0x2)
30; CHECK-NEXT: }
31; CHECK-NEXT: Symbol {
32; CHECK-NEXT: Name: foo
33; CHECK-NEXT: Value: 0x201000
34; CHECK-NEXT: Size: 8
35; CHECK-NEXT: Binding: Global (0x1)
36; CHECK-NEXT: Type: Function (0x2)
37; CHECK-NEXT: Other: 0
38; CHECK-NEXT: Section: .text (0x2)
39; CHECK-NEXT: }
40; CHECK-NEXT: ]
41; CHECK-NEXT: DynamicSymbols [
42; CHECK-NEXT: ]
43
44target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
45target triple = "x86_64-unknown-linux-gnu"
46
47; CHECK0: U bar
48; CHECK0: T foo
49define void @foo() {
50 call void @bar()
51 ret void
52}
53
54; CHECK1: T bar
55; CHECK1: U foo
56define void @bar() {
57 call void @foo()
58 ret void
59}
deps/lld/test/ELF/lto/parallel.ll created+25
......@@ -0,0 +1,25 @@
1; REQUIRES: x86
2; RUN: llvm-as -o %t.bc %s
3; RUN: rm -f %t.lto.o %t1.lto.o
4; RUN: ld.lld -m elf_x86_64 --lto-partitions=2 -save-temps -o %t %t.bc -shared
5; RUN: llvm-nm %t.lto.o | FileCheck --check-prefix=CHECK0 %s
6; RUN: llvm-nm %t1.lto.o | FileCheck --check-prefix=CHECK1 %s
7
8target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
9target triple = "x86_64-unknown-linux-gnu"
10
11; CHECK0-NOT: bar
12; CHECK0: T foo
13; CHECK0-NOT: bar
14define void @foo() {
15 call void @bar()
16 ret void
17}
18
19; CHECK1-NOT: foo
20; CHECK1: T bar
21; CHECK1-NOT: foo
22define void @bar() {
23 call void @foo()
24 ret void
25}
deps/lld/test/ELF/lto/pic.ll created+20
......@@ -0,0 +1,20 @@
1; REQUIRES: x86
2
3; RUN: llvm-as %s -o %t.o
4; RUN: ld.lld %t.o -o %t.so -shared
5; RUN: llvm-readobj -r %t.so | FileCheck %s
6
7; CHECK: Relocations [
8; CHECK-NEXT: Section ({{.*}}) .rela.plt {
9; CHECK-NEXT: R_X86_64_JUMP_SLOT bar 0x0
10; CHECK-NEXT: }
11; CHECK-NEXT: ]
12
13target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
14target triple = "x86_64-unknown-linux-gnu"
15
16declare void @bar()
17define void @foo() {
18 call void @bar()
19 ret void
20}
deps/lld/test/ELF/lto/relax-relocs.ll created+16
......@@ -0,0 +1,16 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.o
3; RUN: ld.lld -m elf_x86_64 -save-temps -shared %t.o -o %t.so
4; RUN: llvm-readobj -r %t.so.lto.o | FileCheck %s
5
6; Test that we produce R_X86_64_REX_GOTPCRELX instead of R_X86_64_GOTPCREL
7; CHECK: R_X86_64_REX_GOTPCRELX foo
8
9target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
10target triple = "x86_64-unknown-linux-gnu"
11
12@foo = external global i32
13define i32 @bar() {
14 %t = load i32, i32* @foo
15 ret i32 %t
16}
deps/lld/test/ELF/lto/relocation-model.ll created+46
......@@ -0,0 +1,46 @@
1; REQUIRES: x86
2
3; RUN: llvm-as %s -o %t.o
4; RUN: llvm-as %p/Inputs/relocation-model-pic.ll -o %t.pic.o
5
6;; Non-PIC source.
7
8; RUN: ld.lld %t.o -o %t-out -save-temps -shared
9; RUN: llvm-readobj -r %t-out.lto.o | FileCheck %s --check-prefix=PIC
10
11; RUN: ld.lld %t.o -o %t-out -save-temps --export-dynamic --noinhibit-exec -pie
12; RUN: llvm-readobj -r %t-out.lto.o | FileCheck %s --check-prefix=PIC
13
14; RUN: ld.lld %t.o -o %t-out -save-temps --export-dynamic --noinhibit-exec
15; RUN: llvm-readobj -r %t-out.lto.o | FileCheck %s --check-prefix=STATIC
16
17; RUN: ld.lld %t.o -o %t-out -save-temps -r --export-dynamic
18; RUN: llvm-readobj -r %t-out.lto.o | FileCheck %s --check-prefix=STATIC
19
20
21;; PIC source.
22
23; RUN: ld.lld %t.pic.o -o %t-out -save-temps -shared
24; RUN: llvm-readobj -r %t-out.lto.o | FileCheck %s --check-prefix=PIC
25
26; RUN: ld.lld %t.pic.o -o %t-out -save-temps --export-dynamic --noinhibit-exec -pie
27; RUN: llvm-readobj -r %t-out.lto.o | FileCheck %s --check-prefix=PIC
28
29; RUN: ld.lld %t.pic.o -o %t-out -save-temps --export-dynamic --noinhibit-exec
30; RUN: llvm-readobj -r %t-out.lto.o | FileCheck %s --check-prefix=STATIC
31
32; RUN: ld.lld %t.pic.o -o %t-out -save-temps -r --export-dynamic
33; RUN: llvm-readobj -r %t-out.lto.o | FileCheck %s --check-prefix=PIC
34
35
36; PIC: R_X86_64_REX_GOTPCRELX foo
37; STATIC: R_X86_64_PC32 foo
38
39target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
40target triple = "x86_64-unknown-linux-gnu"
41
42@foo = external global i32
43define i32 @main() {
44 %t = load i32, i32* @foo
45 ret i32 %t
46}
deps/lld/test/ELF/lto/resolution.ll created+27
......@@ -0,0 +1,27 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t1.o
3; RUN: llvm-mc -triple=x86_64-pc-linux %p/Inputs/resolution.s -o %t2.o -filetype=obj
4; RUN: ld.lld %t1.o %t2.o -o %t.so -shared
5; RUN: llvm-readobj -s --section-data %t.so | FileCheck %s
6
7; CHECK: Name: .data
8; CHECK-NEXT: Type: SHT_PROGBITS
9; CHECK-NEXT: Flags [
10; CHECK-NEXT: SHF_ALLOC
11; CHECK-NEXT: SHF_WRITE
12; CHECK-NEXT: ]
13; CHECK-NEXT: Address:
14; CHECK-NEXT: Offset:
15; CHECK-NEXT: Size: 4
16; CHECK-NEXT: Link: 0
17; CHECK-NEXT: Info: 0
18; CHECK-NEXT: AddressAlignment: 1
19; CHECK-NEXT: EntrySize: 0
20; CHECK-NEXT: SectionData (
21; CHECK-NEXT: 0000: 09000000 |{{.*}}|
22; CHECK-NEXT: )
23
24target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
25target triple = "x86_64-unknown-linux-gnu"
26
27@a = weak global i32 8
deps/lld/test/ELF/lto/save-temps.ll created+20
......@@ -0,0 +1,20 @@
1; REQUIRES: x86
2; RUN: cd %T
3; RUN: rm -f a.out a.out.lto.bc a.out.lto.o
4; RUN: llvm-as %s -o %t.o
5; RUN: llvm-as %p/Inputs/save-temps.ll -o %t2.o
6; RUN: ld.lld -shared -m elf_x86_64 %t.o %t2.o -save-temps
7; RUN: llvm-nm a.out | FileCheck %s
8; RUN: llvm-nm a.out.0.0.preopt.bc | FileCheck %s
9; RUN: llvm-nm a.out.lto.o | FileCheck %s
10; RUN: llvm-dis a.out.0.0.preopt.bc
11
12target triple = "x86_64-unknown-linux-gnu"
13target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
14
15define void @foo() {
16 ret void
17}
18
19; CHECK: T bar
20; CHECK: T foo
deps/lld/test/ELF/lto/shlib-undefined.ll created+27
......@@ -0,0 +1,27 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.o
3; RUN: echo .global __progname > %t2.s
4; RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %t2.s -o %t2.o
5; RUN: ld.lld -shared %t2.o -o %t2.so
6; RUN: ld.lld -o %t %t.o %t2.so
7; RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
8
9; CHECK: Name: __progname@
10; CHECK-NEXT: Value: 0x201010
11; CHECK-NEXT: Size: 1
12; CHECK-NEXT: Binding: Global (0x1)
13; CHECK-NEXT: Type: Function
14; CHECK-NEXT: Other: 0
15; CHECK-NEXT: Section: .text
16; CHECK-NEXT: }
17
18target triple = "x86_64-unknown-linux-gnu"
19target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
20
21define void @_start() {
22 ret void
23}
24
25define void @__progname() {
26 ret void
27}
deps/lld/test/ELF/lto/start-lib.ll created+27
......@@ -0,0 +1,27 @@
1; REQUIRES: x86
2;
3; RUN: llvm-as %s -o %t1.o
4; RUN: llvm-as %p/Inputs/start-lib1.ll -o %t2.o
5; RUN: llvm-as %p/Inputs/start-lib2.ll -o %t3.o
6;
7; RUN: ld.lld -m elf_x86_64 -shared -o %t3 %t1.o %t2.o %t3.o
8; RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TEST1 %s
9; TEST1: Name: bar
10; TEST1: Name: foo
11;
12; RUN: ld.lld -m elf_x86_64 -shared -o %t3 -u bar %t1.o --start-lib %t2.o %t3.o
13; RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TEST2 %s
14; TEST2: Name: bar
15; TEST2-NOT: Name: foo
16;
17; RUN: ld.lld -m elf_x86_64 -shared -o %t3 %t1.o --start-lib %t2.o %t3.o
18; RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TEST3 %s
19; TEST3-NOT: Name: bar
20; TEST3-NOT: Name: foo
21
22target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
23target triple = "x86_64-unknown-linux-gnu"
24
25define void @_start() {
26 ret void
27}
deps/lld/test/ELF/lto/thin-archivecollision.ll created+37
......@@ -0,0 +1,37 @@
1; REQUIRES: x86
2; RUN: opt -module-summary %s -o %t.o
3; RUN: mkdir -p %t1 %t2
4; RUN: opt -module-summary %p/Inputs/thin1.ll -o %t1/t.coll.o
5; RUN: opt -module-summary %p/Inputs/thin2.ll -o %t2/t.coll.o
6
7; RUN: rm -f %t.a
8; RUN: llvm-ar rcs %t.a %t1/t.coll.o %t2/t.coll.o
9; RUN: ld.lld %t.o %t.a -o %t
10; RUN: llvm-nm %t | FileCheck %s
11
12; Check without a archive symbol table
13; RUN: rm -f %t.a
14; RUN: llvm-ar rcS %t.a %t1/t.coll.o %t2/t.coll.o
15; RUN: ld.lld %t.o %t.a -o %t
16; RUN: llvm-nm %t | FileCheck %s
17
18; Check we handle this case correctly even in presence of --whole-archive.
19; RUN: ld.lld %t.o --whole-archive %t.a -o %t
20; RUN: llvm-nm %t | FileCheck %s
21
22; CHECK: T _start
23; CHECK: T blah
24; CHECK: T foo
25
26target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
27target triple = "x86_64-scei-ps4"
28
29define i32 @_start() {
30entry:
31 %call = call i32 @foo(i32 23)
32 %call1 = call i32 @blah(i32 37)
33 ret i32 0
34}
35
36declare i32 @foo(i32) #1
37declare i32 @blah(i32) #1
deps/lld/test/ELF/lto/thinlto.ll created+37
......@@ -0,0 +1,37 @@
1; REQUIRES: x86
2; Basic ThinLTO tests.
3; RUN: opt -module-summary %s -o %t.o
4; RUN: opt -module-summary %p/Inputs/thinlto.ll -o %t2.o
5
6; First force single-threaded mode
7; RUN: rm -f %t.lto.o %t1.lto.o
8; RUN: ld.lld -save-temps --thinlto-jobs=1 -shared %t.o %t2.o -o %t
9; RUN: llvm-nm %t.lto.o | FileCheck %s --check-prefix=NM1
10; RUN: llvm-nm %t1.lto.o | FileCheck %s --check-prefix=NM2
11
12; Next force multi-threaded mode
13; RUN: rm -f %t2.lto.o %t21.lto.o
14; RUN: ld.lld -save-temps --thinlto-jobs=2 -shared %t.o %t2.o -o %t2
15; RUN: llvm-nm %t2.lto.o | FileCheck %s --check-prefix=NM1
16; RUN: llvm-nm %t21.lto.o | FileCheck %s --check-prefix=NM2
17
18; NM1: T f
19; NM1-NOT: U g
20
21; NM2: T g
22
23; Then check without --thinlto-jobs (which currently default to hardware_concurrency)
24; We just check that we don't crash or fail (as it's not sure which tests are
25; stable on the final output file itself.
26; RUN: ld.lld -shared %t.o %t2.o -o %t2
27
28target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
29target triple = "x86_64-unknown-linux-gnu"
30
31declare void @g(...)
32
33define void @f() {
34entry:
35 call void (...) @g()
36 ret void
37}
deps/lld/test/ELF/lto/timepasses.ll created+15
......@@ -0,0 +1,15 @@
1; We use lld -flavor gnu because llvm-lit will append --full-shutdown to
2; the ld.lld invocation.
3; REQUIRES: x86
4; RUN: llvm-as %s -o %t.o
5; RUN: lld -flavor gnu %t.o -o %t.so -shared -mllvm -time-passes 2>&1 | FileCheck %s
6
7target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
8target triple = "x86_64-unknown-linux-gnu"
9
10define void @patatino() {
11 ret void
12}
13
14; We should get the output of -time-passes even when --full-shutdown is not specified.
15; CHECK: Total Execution Time
deps/lld/test/ELF/lto/tls-mixed.ll created+10
......@@ -0,0 +1,10 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t1.o
3; RUN: llvm-mc %p/Inputs/tls-mixed.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux
4; RUN: ld.lld -m elf_x86_64 %t1.o %t2.o -o %t.so -shared
5
6target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
7target triple = "x86_64-unknown-linux-gnu"
8
9; Should not encounter TLS-ness mismatch for @foo
10@foo = external thread_local global i32, align 4
deps/lld/test/ELF/lto/tls-preserve.ll created+25
......@@ -0,0 +1,25 @@
1; TLS attribute needs to be preserved.
2; REQUIRES: x86
3; RUN: llvm-as %s -o %t1.o
4; RUN: ld.lld -shared %t1.o -m elf_x86_64 -o %t1
5; RUN: llvm-readobj -t %t1 | FileCheck %s
6
7target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
8target triple = "x86_64-unknown-linux-gnu"
9
10@tsp_int = thread_local global i32 1
11
12define void @_start() {
13 %val = load i32, i32* @tsp_int
14 ret void
15}
16
17; CHECK: Symbol {
18; CHECK: Name: tsp_int
19; CHECK-NEXT: Value: 0x0
20; CHECK-NEXT: Size: 4
21; CHECK-NEXT: Binding: Global
22; CHECK-NEXT: Type: TLS
23; CHECK-NEXT: Other: 0
24; CHECK-NEXT: Section: .tdata
25; CHECK-NEXT: }
deps/lld/test/ELF/lto/type-merge.ll created+26
......@@ -0,0 +1,26 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.o
3; RUN: llvm-as %p/Inputs/type-merge.ll -o %t2.o
4; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t -shared -save-temps
5; RUN: llvm-dis < %t.0.0.preopt.bc | FileCheck %s
6
7target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
8target triple = "x86_64-unknown-linux-gnu"
9
10define void @foo() {
11 call void @bar(i8* null)
12 ret void
13}
14declare void @bar(i8*)
15
16; CHECK: define void @foo() {
17; CHECK-NEXT: call void @bar(i8* null)
18; CHECK-NEXT: ret void
19; CHECK-NEXT: }
20
21; CHECK: declare void @bar(i8*)
22
23; CHECK: define void @zed() {
24; CHECK-NEXT: call void bitcast (void (i8*)* @bar to void ()*)()
25; CHECK-NEXT: ret void
26; CHECK-NEXT: }
deps/lld/test/ELF/lto/type-merge2.ll created+28
......@@ -0,0 +1,28 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.o
3; RUN: llvm-as %p/Inputs/type-merge2.ll -o %t2.o
4; RUN: ld.lld -m elf_x86_64 %t.o %t2.o -o %t.so -shared -save-temps
5; RUN: llvm-dis %t.so.0.0.preopt.bc -o - | FileCheck %s
6
7target triple = "x86_64-unknown-linux-gnu"
8target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
9
10%zed = type { i8 }
11define void @foo() {
12 call void @bar(%zed* null)
13 ret void
14}
15declare void @bar(%zed*)
16
17; CHECK: %zed = type { i8 }
18; CHECK-NEXT: %zed.0 = type { i16 }
19
20; CHECK: define void @foo() {
21; CHECK-NEXT: call void bitcast (void (%zed.0*)* @bar to void (%zed*)*)(%zed* null)
22; CHECK-NEXT: ret void
23; CHECK-NEXT: }
24
25; CHECK: define void @bar(%zed.0* %this) {
26; CHECK-NEXT: store %zed.0* %this, %zed.0** null
27; CHECK-NEXT: ret void
28; CHECK-NEXT: }
deps/lld/test/ELF/lto/undef-mixed.ll created+22
......@@ -0,0 +1,22 @@
1; REQUIRES: x86
2; RUN: llvm-mc %p/Inputs/undef-mixed.s -o %t.o -filetype=obj -triple=x86_64-pc-linux
3; RUN: llvm-as %s -o %t2.o
4; RUN: ld.lld %t2.o %t.o -o %t.so -shared
5; RUN: llvm-readobj -t %t.so | FileCheck %s
6
7; CHECK: Name: bar
8; CHECK-NEXT: Value:
9; CHECK-NEXT: Size: 0
10; CHECK-NEXT: Binding: Global
11; CHECK-NEXT: Type: None
12; CHECK-NEXT: Other: 0
13; CHECK-NEXT: Section: .text
14
15target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
16target triple = "x86_64-unknown-linux-gnu"
17
18declare void @bar()
19define void @foo() {
20 call void @bar()
21 ret void
22}
deps/lld/test/ELF/lto/undef-weak.ll created+29
......@@ -0,0 +1,29 @@
1; REQUIRES: x86
2
3; RUN: llvm-as %S/Inputs/archive.ll -o %t1.o
4; RUN: rm -f %t.a
5; RUN: llvm-ar rcs %t.a %t1.o
6
7
8; RUN: llvm-as %s -o %t2.o
9; RUN: ld.lld -m elf_x86_64 %t2.o -o %t2.so %t.a -shared
10; RUN: llvm-readobj -t %t2.so | FileCheck %s
11target triple = "x86_64-unknown-linux-gnu"
12target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
13
14declare extern_weak void @f()
15define void @foo() {
16 call void @f()
17 ret void
18}
19
20; We should not fetch the archive member.
21
22; CHECK: Name: f ({{.*}})
23; CHECK-NEXT: Value: 0x0
24; CHECK-NEXT: Size: 0
25; CHECK-NEXT: Binding: Weak
26; CHECK-NEXT: Type: None
27; CHECK-NEXT: Other: 0
28; CHECK-NEXT: Section: Undefined
29
deps/lld/test/ELF/lto/undef.ll created+20
......@@ -0,0 +1,20 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.o
3; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -shared
4; RUN: llvm-readobj -t %t.so | FileCheck %s
5target triple = "x86_64-unknown-linux-gnu"
6target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
7
8declare void @bar()
9define void @foo() {
10 call void @bar()
11 ret void
12}
13
14; CHECK: Name: bar
15; CHECK-NEXT: Value: 0x0
16; CHECK-NEXT: Size: 0
17; CHECK-NEXT: Binding: Global
18; CHECK-NEXT: Type: None
19; CHECK-NEXT: Other: 0
20; CHECK-NEXT: Section: Undefined
deps/lld/test/ELF/lto/undefined-puts.ll created+28
......@@ -0,0 +1,28 @@
1; REQUIRES: x86
2; RUN: llvm-mc %p/Inputs/shared.s -o %t1.o -filetype=obj -triple=x86_64-unknown-linux
3; RUN: ld.lld %t1.o -o %t1.so -shared
4; RUN: llvm-as %s -o %t2.o
5; RUN: ld.lld %t1.so %t2.o -m elf_x86_64 -o %t
6; RUN: llvm-readobj -dyn-symbols -dyn-relocations %t | FileCheck %s
7
8target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
9target triple = "x86_64-unknown-linux-gnu"
10
11@.str = private unnamed_addr constant [6 x i8] c"blah\0A\00", align 1
12
13define i32 @_start() {
14 %str = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0))
15 ret i32 0
16}
17
18declare i32 @printf(i8*, ...)
19
20; Check that puts symbol is present in the dynamic symbol table and
21; there's a relocation for it.
22; CHECK: Dynamic Relocations {
23; CHECK-NEXT: 0x202018 R_X86_64_JUMP_SLOT puts 0x0
24; CHECK-NEXT: }
25
26; CHECK: DynamicSymbols [
27; CHECK: Symbol {
28; CHECK: Name: puts@
deps/lld/test/ELF/lto/unnamed-addr-comdat.ll created+12
......@@ -0,0 +1,12 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.o
3; RUN: ld.lld -m elf_x86_64 %t.o %t.o -o %t.so -save-temps -shared
4; RUN: llvm-dis %t.so.0.2.internalize.bc -o - | FileCheck %s
5
6target triple = "x86_64-unknown-linux-gnu"
7target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
8
9$foo = comdat any
10@foo = linkonce_odr unnamed_addr constant i32 42, comdat
11
12; CHECK: @foo = internal unnamed_addr constant i32 42, comdat
deps/lld/test/ELF/lto/unnamed-addr-drop.ll created+13
......@@ -0,0 +1,13 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t1.o
3; RUN: llvm-as %S/Inputs/unnamed-addr-drop.ll -o %t2.o
4; RUN: ld.lld -m elf_x86_64 %t1.o %t2.o -o %t.so -save-temps -shared
5; RUN: llvm-dis %t.so.0.2.internalize.bc -o - | FileCheck %s
6
7target triple = "x86_64-unknown-linux-gnu"
8target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
9
10@foo = weak constant i32 41
11
12; Check that unnamed_addr is dropped during the merge.
13; CHECK: @foo = constant i32 42
deps/lld/test/ELF/lto/unnamed-addr-lib.ll created+21
......@@ -0,0 +1,21 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.o
3; RUN: llvm-mc %p/Inputs/unnamed-addr-lib.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux
4; RUN: ld.lld %t2.o -shared -o %t2.so
5; RUN: ld.lld -m elf_x86_64 %t.o %t2.so -o %t.so -save-temps -shared
6; RUN: llvm-dis %t.so.0.2.internalize.bc -o - | FileCheck %s
7
8; This documents a small limitation of lld's internalization logic. We decide
9; that bar should be in the symbol table because if it is it will preempt the
10; one in the shared library.
11; We could add one extra bit for ODR so that we know that preemption is not
12; necessary, but that is probably not worth it.
13
14; CHECK: @foo = internal unnamed_addr constant i8 42
15; CHECK: @bar = weak_odr unnamed_addr constant i8 42
16
17target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
18target triple = "x86_64-unknown-linux-gnu"
19
20@foo = linkonce_odr unnamed_addr constant i8 42
21@bar = linkonce_odr unnamed_addr constant i8 42
deps/lld/test/ELF/lto/unnamed-addr.ll created+15
......@@ -0,0 +1,15 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.o
3; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -save-temps -shared
4; RUN: llvm-dis %t.so.0.4.opt.bc -o - | FileCheck %s
5
6target triple = "x86_64-unknown-linux-gnu"
7target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
8
9@a = internal unnamed_addr constant i8 42
10
11define i8* @f() {
12 ret i8* @a
13}
14
15; CHECK: @a = internal unnamed_addr constant i8 42
deps/lld/test/ELF/lto/verify-invalid.ll created+17
......@@ -0,0 +1,17 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.o
3; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -mllvm -debug-pass=Arguments \
4; RUN: 2>&1 | FileCheck -check-prefix=DEFAULT %s
5; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -mllvm -debug-pass=Arguments \
6; RUN: -disable-verify 2>&1 | FileCheck -check-prefix=DISABLE %s
7
8target triple = "x86_64-unknown-linux-gnu"
9target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
10
11define void @_start() {
12 ret void
13}
14
15; -disable-verify should disable the verification of bitcode.
16; DEFAULT: Pass Arguments: {{.*}} -verify {{.*}} -verify
17; DISABLE-NOT: Pass Arguments: {{.*}} -verify {{.*}} -verify
deps/lld/test/ELF/lto/version-script.ll created+50
......@@ -0,0 +1,50 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.o
3; RUN: echo "VERSION_1.0{ global: foo; local: *; }; VERSION_2.0{ global: bar; local: *; };" > %t.script
4; RUN: ld.lld -m elf_x86_64 %t.o -o %t2 -shared --version-script %t.script -save-temps
5; RUN: llvm-dis < %t2.0.0.preopt.bc | FileCheck %s
6; RUN: llvm-readobj -V -dyn-symbols %t2 | FileCheck --check-prefix=DSO %s
7
8target triple = "x86_64-unknown-linux-gnu"
9target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
10
11define void @foo() {
12 ret void
13}
14
15define void @bar() {
16 ret void
17}
18
19; CHECK: define void @foo()
20; CHECK: define void @bar()
21
22; DSO: DynamicSymbols [
23; DSO: Symbol {
24; DSO: Name: @ (0)
25; DSO: Value: 0x0
26; DSO: Size: 0
27; DSO: Binding: Local
28; DSO: Type: None
29; DSO: Other: 0
30; DSO: Section: Undefined
31; DSO: }
32; DSO: Symbol {
33; DSO: Name: foo@@VERSION_1.0
34; DSO: Value: 0x1000
35; DSO: Size: 1
36; DSO: Binding: Global
37; DSO: Type: Function
38; DSO: Other: 0
39; DSO: Section: .text
40; DSO: }
41; DSO: Symbol {
42; DSO: Name: bar@@VERSION_2.0
43; DSO: Value: 0x1010
44; DSO: Size: 1
45; DSO: Binding: Global
46; DSO: Type: Function
47; DSO: Other: 0
48; DSO: Section: .text
49; DSO: }
50; DSO: ]
deps/lld/test/ELF/lto/visibility.ll created+35
......@@ -0,0 +1,35 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t1.o
3; RUN: llvm-mc -triple=x86_64-pc-linux %p/Inputs/visibility.s -o %t2.o -filetype=obj
4; RUN: ld.lld %t1.o %t2.o -o %t.so -shared
5; RUN: llvm-readobj -t %t.so | FileCheck %s
6
7; CHECK: Name: g
8; CHECK-NEXT: Value: 0x1000
9; CHECK-NEXT: Size: 0
10; CHECK-NEXT: Binding: Local
11; CHECK-NEXT: Type: None
12; CHECK-NEXT: Other [ (0x2)
13; CHECK-NEXT: STV_HIDDEN
14; CHECK-NEXT: ]
15; CHECK-NEXT: Section: .text
16
17; CHECK: Name: a
18; CHECK-NEXT: Value: 0x2000
19; CHECK-NEXT: Size: 0
20; CHECK-NEXT: Binding: Local
21; CHECK-NEXT: Type: None
22; CHECK-NEXT: Other [ (0x2)
23; CHECK-NEXT: STV_HIDDEN
24; CHECK-NEXT: ]
25; CHECK-NEXT: Section: .data
26
27target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
28target triple = "x86_64-unknown-linux-gnu"
29
30declare hidden void @g()
31define void @f() {
32 call void @g()
33 ret void
34}
35@a = weak hidden global i32 42
deps/lld/test/ELF/lto/weak.ll created+16
......@@ -0,0 +1,16 @@
1; REQUIRES: x86
2; RUN: llvm-as %s -o %t.o
3; RUN: ld.lld -m elf_x86_64 %t.o %t.o -o %t.so -shared
4; RUN: llvm-readobj -t %t.so | FileCheck %s
5
6target triple = "x86_64-unknown-linux-gnu"
7target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
8
9define weak void @f() {
10 ret void
11}
12
13; CHECK: Name: f
14; CHECK-NEXT: Value: 0x1000
15; CHECK-NEXT: Size: 1
16; CHECK-NEXT: Binding: Weak
deps/lld/test/ELF/lto/wrap-1.ll created+42
......@@ -0,0 +1,42 @@
1; REQUIRES: x86
2; LTO
3; RUN: llvm-as %s -o %t.o
4; RUN: ld.lld %t.o -o %t.out -wrap=bar -save-temps
5; RUN: llvm-readobj -t %t.out | FileCheck %s
6; RUN: cat %t.out.resolution.txt | FileCheck -check-prefix=RESOLS %s
7
8; ThinLTO
9; RUN: opt -module-summary %s -o %t.o
10; RUN: ld.lld %t.o -o %t.out -wrap=bar -save-temps
11; RUN: llvm-readobj -t %t.out | FileCheck %s
12; RUN: cat %t.out.resolution.txt | FileCheck -check-prefix=RESOLS %s
13
14; CHECK: Name: __wrap_bar
15; CHECK-NEXT: Value:
16; CHECK-NEXT: Size:
17; CHECK-NEXT: Binding: Global
18; CHECK-NEXT: Type: Function
19
20; Make sure that the 'r' (linker redefined) bit is set for bar and __wrap_bar
21; in the resolutions file.
22; RESOLS: ,bar,r
23; RESOLS: ,__wrap_bar,px
24; RESOLS: ,__real_bar,pxr
25
26target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
27target triple = "x86_64-unknown-linux-gnu"
28
29declare void @bar()
30
31define void @_start() {
32 call void @bar()
33 ret void
34}
35
36define void @__wrap_bar() {
37 ret void
38}
39
40define void @__real_bar() {
41 ret void
42}
deps/lld/test/ELF/lto/wrap-2.ll created+50
......@@ -0,0 +1,50 @@
1; REQUIRES: x86
2; LTO
3; RUN: llvm-as %s -o %t.o
4; RUN: llvm-as %S/Inputs/wrap-bar.ll -o %t1.o
5; RUN: ld.lld %t.o %t1.o -shared -o %t.so -wrap=bar
6; RUN: llvm-objdump -d %t.so | FileCheck %s
7; RUN: llvm-readobj -t %t.so | FileCheck -check-prefix=BIND %s
8
9; ThinLTO
10; RUN: opt -module-summary %s -o %t.o
11; RUN: opt -module-summary %S/Inputs/wrap-bar.ll -o %t1.o
12; RUN: ld.lld %t.o %t1.o -shared -o %t.so -wrap=bar
13; RUN: llvm-objdump -d %t.so | FileCheck %s -check-prefix=THIN
14; RUN: llvm-readobj -t %t.so | FileCheck -check-prefix=BIND %s
15
16; Make sure that calls in foo() are not eliminated and that bar is
17; routed to __wrap_bar and __real_bar is routed to bar.
18
19; CHECK: foo:
20; CHECK-NEXT: pushq %rax
21; CHECK-NEXT: callq{{.*}}<__wrap_bar>
22; CHECK-NEXT: callq{{.*}}<bar>
23
24; THIN: foo:
25; THIN-NEXT: pushq %rax
26; THIN-NEXT: callq{{.*}}<__wrap_bar>
27; THIN-NEXT: popq %rax
28; THIN-NEXT: jmp{{.*}}<bar>
29
30; Check that bar and __wrap_bar retain their original binding.
31; BIND: Name: bar
32; BIND-NEXT: Value:
33; BIND-NEXT: Size:
34; BIND-NEXT: Binding: Local
35; BIND: Name: __wrap_bar
36; BIND-NEXT: Value:
37; BIND-NEXT: Size:
38; BIND-NEXT: Binding: Local
39
40target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
41target triple = "x86_64-unknown-linux-gnu"
42
43declare void @bar()
44declare void @__real_bar()
45
46define void @foo() {
47 call void @bar()
48 call void @__real_bar()
49 ret void
50}
deps/lld/test/ELF/many-alloc-sections.s created+107
......@@ -0,0 +1,107 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t.o
3// RUN: echo "SECTIONS { . = SIZEOF_HEADERS; .text : { *(.text) } }" > %t.script
4// FIXME: threads are disable because the test is too slow with them (PR32942).
5// RUN: ld.lld -T %t.script %t.o -o %t --no-threads
6// RUN: llvm-readobj -t %t | FileCheck %s
7
8// Test that _start is in the correct section.
9// CHECK: Name: _start
10// CHECK-NEXT: Value: 0x120
11// CHECK-NEXT: Size: 0
12// CHECK-NEXT: Binding: Global
13// CHECK-NEXT: Type: None
14// CHECK-NEXT: Other: 0
15// CHECK-NEXT: Section: dm
16
17.macro gen_sections4 x
18 .section a\x,"a"
19 .section b\x,"a"
20 .section c\x,"a"
21 .section d\x,"a"
22.endm
23
24.macro gen_sections8 x
25 gen_sections4 a\x
26 gen_sections4 b\x
27.endm
28
29.macro gen_sections16 x
30 gen_sections8 a\x
31 gen_sections8 b\x
32.endm
33
34.macro gen_sections32 x
35 gen_sections16 a\x
36 gen_sections16 b\x
37.endm
38
39.macro gen_sections64 x
40 gen_sections32 a\x
41 gen_sections32 b\x
42.endm
43
44.macro gen_sections128 x
45 gen_sections64 a\x
46 gen_sections64 b\x
47.endm
48
49.macro gen_sections256 x
50 gen_sections128 a\x
51 gen_sections128 b\x
52.endm
53
54.macro gen_sections512 x
55 gen_sections256 a\x
56 gen_sections256 b\x
57.endm
58
59.macro gen_sections1024 x
60 gen_sections512 a\x
61 gen_sections512 b\x
62.endm
63
64.macro gen_sections2048 x
65 gen_sections1024 a\x
66 gen_sections1024 b\x
67.endm
68
69.macro gen_sections4096 x
70 gen_sections2048 a\x
71 gen_sections2048 b\x
72.endm
73
74.macro gen_sections8192 x
75 gen_sections4096 a\x
76 gen_sections4096 b\x
77.endm
78
79.macro gen_sections16384 x
80 gen_sections8192 a\x
81 gen_sections8192 b\x
82.endm
83
84.macro gen_sections32768 x
85 gen_sections16384 a\x
86 gen_sections16384 b\x
87.endm
88
89 .bss
90 .section bar
91
92gen_sections32768 a
93gen_sections16384 b
94gen_sections8192 c
95gen_sections4096 d
96gen_sections2048 e
97gen_sections1024 f
98gen_sections512 g
99gen_sections128 h
100gen_sections64 i
101gen_sections32 j
102gen_sections16 k
103gen_sections8 l
104gen_sections4 m
105
106.global _start
107_start:
deps/lld/test/ELF/many-sections.s created+124
......@@ -0,0 +1,124 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o %t
3// RUN: llvm-readobj -t %t | FileCheck %s
4
5// Verify that the symbol _start is in a section with an index >= SHN_LORESERVE.
6// CHECK: Name: _start
7// CHECK-NEXT: Value: 0x0
8// CHECK-NEXT: Size: 0
9// CHECK-NEXT: Binding: Global
10// CHECK-NEXT: Type: None
11// CHECK-NEXT: Other: 0
12// CHECK-NEXT: Section: dm (0xFF00)
13
14
15// FIXME: threads are disable because the test is too slow with them (PR32942).
16// RUN: ld.lld %t -o %t2 --no-threads
17// RUN: llvm-readobj -t %t2 | FileCheck --check-prefix=LINKED %s
18
19// Test also with a linker script.
20// RUN: echo "SECTIONS { . = SIZEOF_HEADERS; .text : { *(.text) } }" > %t.script
21// FIXME: threads are disable because the test is too slow with them (PR32942).
22// RUN: ld.lld -T %t.script %t -o %t2 --no-threads
23// RUN: llvm-readobj -t %t2 | FileCheck --check-prefix=LINKED %s
24
25// Test that _start is in the correct section.
26// LINKED: Name: _start
27// LINKED-NEXT: Value: 0x0
28// LINKED-NEXT: Size: 0
29// LINKED-NEXT: Binding: Global
30// LINKED-NEXT: Type: None
31// LINKED-NEXT: Other: 0
32// LINKED-NEXT: Section: dm
33
34.macro gen_sections4 x
35 .section a\x
36 .section b\x
37 .section c\x
38 .section d\x
39.endm
40
41.macro gen_sections8 x
42 gen_sections4 a\x
43 gen_sections4 b\x
44.endm
45
46.macro gen_sections16 x
47 gen_sections8 a\x
48 gen_sections8 b\x
49.endm
50
51.macro gen_sections32 x
52 gen_sections16 a\x
53 gen_sections16 b\x
54.endm
55
56.macro gen_sections64 x
57 gen_sections32 a\x
58 gen_sections32 b\x
59.endm
60
61.macro gen_sections128 x
62 gen_sections64 a\x
63 gen_sections64 b\x
64.endm
65
66.macro gen_sections256 x
67 gen_sections128 a\x
68 gen_sections128 b\x
69.endm
70
71.macro gen_sections512 x
72 gen_sections256 a\x
73 gen_sections256 b\x
74.endm
75
76.macro gen_sections1024 x
77 gen_sections512 a\x
78 gen_sections512 b\x
79.endm
80
81.macro gen_sections2048 x
82 gen_sections1024 a\x
83 gen_sections1024 b\x
84.endm
85
86.macro gen_sections4096 x
87 gen_sections2048 a\x
88 gen_sections2048 b\x
89.endm
90
91.macro gen_sections8192 x
92 gen_sections4096 a\x
93 gen_sections4096 b\x
94.endm
95
96.macro gen_sections16384 x
97 gen_sections8192 a\x
98 gen_sections8192 b\x
99.endm
100
101.macro gen_sections32768 x
102 gen_sections16384 a\x
103 gen_sections16384 b\x
104.endm
105
106 .bss
107 .section bar
108
109gen_sections32768 a
110gen_sections16384 b
111gen_sections8192 c
112gen_sections4096 d
113gen_sections2048 e
114gen_sections1024 f
115gen_sections512 g
116gen_sections128 h
117gen_sections64 i
118gen_sections32 j
119gen_sections16 k
120gen_sections8 l
121gen_sections4 m
122
123.global _start
124_start:
deps/lld/test/ELF/map-file.s created+59
......@@ -0,0 +1,59 @@
1// REQUIRES: x86
2
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
4// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/map-file2.s -o %t2.o
5// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/map-file3.s -o %t3.o
6// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/map-file4.s -o %t4.o
7// RUN: rm -f %t4.a
8// RUN: llvm-ar rc %t4.a %t4.o
9// RUN: ld.lld %t1.o %t2.o %t3.o %t4.a -o %t -M | FileCheck -strict-whitespace %s
10// RUN: ld.lld %t1.o %t2.o %t3.o %t4.a -o %t -print-map | FileCheck -strict-whitespace %s
11// RUN: ld.lld %t1.o %t2.o %t3.o %t4.a -o %t -Map=%t.map
12// RUN: FileCheck -strict-whitespace %s < %t.map
13
14.global _start
15_start:
16 call baz
17.global _Z1fi
18_Z1fi:
19.cfi_startproc
20.cfi_endproc
21nop
22.weak bar
23bar:
24.long bar - .
25.long zed - .
26local:
27.comm common,4,16
28
29// CHECK: Address Size Align Out In Symbol
30// CHECK-NEXT: 0000000000200158 0000000000000030 8 .eh_frame
31// CHECK-NEXT: 0000000000200158 0000000000000030 8 <internal>:(.eh_frame)
32// CHECK-NEXT: 0000000000201000 0000000000000015 4 .text
33// CHECK-NEXT: 0000000000201000 000000000000000e 4 {{.*}}{{/|\\}}map-file.s.tmp1.o:(.text)
34// CHECK-NEXT: 0000000000201000 0000000000000000 0 _start
35// CHECK-NEXT: 0000000000201005 0000000000000000 0 f(int)
36// CHECK-NEXT: 000000000020100e 0000000000000000 0 local
37// CHECK-NEXT: 0000000000201010 0000000000000002 4 {{.*}}{{/|\\}}map-file.s.tmp2.o:(.text)
38// CHECK-NEXT: 0000000000201010 0000000000000000 0 foo
39// CHECK-NEXT: 0000000000201011 0000000000000000 0 bar
40// CHECK-NEXT: 0000000000201012 0000000000000000 1 {{.*}}{{/|\\}}map-file.s.tmp2.o:(.text.zed)
41// CHECK-NEXT: 0000000000201012 0000000000000000 0 zed
42// CHECK-NEXT: 0000000000201014 0000000000000000 4 {{.*}}{{/|\\}}map-file.s.tmp3.o:(.text)
43// CHECK-NEXT: 0000000000201014 0000000000000000 0 bah
44// CHECK-NEXT: 0000000000201014 0000000000000001 4 {{.*}}{{/|\\}}map-file.s.tmp4.a(map-file.s.tmp4.o):(.text)
45// CHECK-NEXT: 0000000000201014 0000000000000000 0 baz
46// CHECK-NEXT: 0000000000202000 0000000000000004 16 .bss
47// CHECK-NEXT: 0000000000202000 0000000000000004 16 <internal>:(COMMON)
48// CHECK-NEXT: 0000000000000000 0000000000000008 1 .comment
49// CHECK-NEXT: 0000000000000000 0000000000000008 1 <internal>:(.comment)
50// CHECK-NEXT: 0000000000000000 00000000000000f0 8 .symtab
51// CHECK-NEXT: 0000000000000000 00000000000000f0 8 <internal>:(.symtab)
52// CHECK-NEXT: 0000000000000000 0000000000000039 1 .shstrtab
53// CHECK-NEXT: 0000000000000000 0000000000000039 1 <internal>:(.shstrtab)
54// CHECK-NEXT: 0000000000000000 000000000000002f 1 .strtab
55// CHECK-NEXT: 0000000000000000 000000000000002f 1 <internal>:(.strtab)
56
57// RUN: not ld.lld %t1.o %t2.o %t3.o %t4.a -o %t -Map=/ 2>&1 \
58// RUN: | FileCheck -check-prefix=FAIL %s
59// FAIL: cannot open map file /
deps/lld/test/ELF/map-gc-sections.s created+9
......@@ -0,0 +1,9 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
2// RUN: ld.lld %t.o -o %t -Map=- --gc-sections | FileCheck %s
3
4.section .tbss,"awT",@nobits
5// CHECK-NOT: foo
6.globl foo
7foo:
8.align 8
9.long 0
deps/lld/test/ELF/merge-reloc.s created+92
......@@ -0,0 +1,92 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: ld.lld %t.o -r -o %t-rel
4# RUN: llvm-readobj -s -section-data %t-rel | FileCheck %s
5
6# When linker generates a relocatable object it should keep "merge"
7# sections as-is: do not merge content, do not join regular and
8# "merge" sections, do not joint "merge" sections with different
9# entry size.
10
11# CHECK: Section {
12# CHECK: Index:
13# CHECK: Name: .rodata
14# CHECK-NEXT: Type: SHT_PROGBITS
15# CHECK-NEXT: Flags [
16# CHECK-NEXT: SHF_ALLOC
17# CHECK-NEXT: SHF_MERGE
18# CHECK-NEXT: ]
19# CHECK-NEXT: Address:
20# CHECK-NEXT: Offset:
21# CHECK-NEXT: Size: 12
22# CHECK-NEXT: Link: 0
23# CHECK-NEXT: Info: 0
24# CHECK-NEXT: AddressAlignment: 4
25# CHECK-NEXT: EntrySize: 4
26# CHECK-NEXT: SectionData (
27# CHECK-NEXT: 0000: 42000000 42000000 42000000
28# CHECK-NEXT: )
29# CHECK-NEXT: }
30# CHECK: Section {
31# CHECK: Index:
32# CHECK: Name: .rodata
33# CHECK-NEXT: Type: SHT_PROGBITS
34# CHECK-NEXT: Flags [
35# CHECK-NEXT: SHF_ALLOC
36# CHECK-NEXT: SHF_MERGE
37# CHECK-NEXT: ]
38# CHECK-NEXT: Address:
39# CHECK-NEXT: Offset:
40# CHECK-NEXT: Size: 16
41# CHECK-NEXT: Link: 0
42# CHECK-NEXT: Info: 0
43# CHECK-NEXT: AddressAlignment: 8
44# CHECK-NEXT: EntrySize: 8
45# CHECK-NEXT: SectionData (
46# CHECK-NEXT: 0000: 42000000 42000000 42000000 42000000
47# CHECK-NEXT: )
48# CHECK-NEXT: }
49# CHECK: Section {
50# CHECK: Index:
51# CHECK: Name: .data
52# CHECK-NEXT: Type: SHT_PROGBITS
53# CHECK-NEXT: Flags [
54# CHECK-NEXT: SHF_ALLOC
55# CHECK-NEXT: SHF_WRITE
56# CHECK-NEXT: ]
57# CHECK-NEXT: Address:
58# CHECK-NEXT: Offset:
59# CHECK-NEXT: Size: 16
60# CHECK-NEXT: Link: 0
61# CHECK-NEXT: Info: 0
62# CHECK-NEXT: AddressAlignment: 1
63# CHECK-NEXT: EntrySize: 0
64# CHECK-NEXT: SectionData (
65# CHECK-NEXT: 0000: 42000000 42000000 42000000 42000000
66# CHECK-NEXT: )
67# CHECK-NEXT: }
68
69 .section .rodata.1,"aM",@progbits,4
70 .align 4
71 .global foo
72foo:
73 .long 0x42
74 .long 0x42
75 .long 0x42
76
77 .section .rodata.2,"aM",@progbits,8
78 .align 8
79 .global bar
80bar:
81 .long 0x42
82 .long 0x42
83 .long 0x42
84 .long 0x42
85
86 .data
87 .global gar
88zed:
89 .long 0x42
90 .long 0x42
91 .long 0x42
92 .long 0x42
deps/lld/test/ELF/merge-section-types.s created+20
......@@ -0,0 +1,20 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: ld.lld -shared %t.o -o %t
4// RUN: llvm-readobj -s %t | FileCheck %s
5
6// CHECK: Name: .foo
7// CHECK-NEXT: Type: SHT_PROGBITS
8// CHECK-NEXT: Flags [
9// CHECK-NEXT: SHF_ALLOC
10// CHECK-NEXT: SHF_WRITE
11// CHECK-NEXT: ]
12// CHECK-NEXT: Address: 0x1000
13// CHECK-NEXT: Offset: 0x1000
14// CHECK-NEXT: Size: 16
15
16.section .foo, "aw", @progbits, unique, 1
17.quad 0
18
19.section .foo, "aw", @nobits, unique, 2
20.quad 0
deps/lld/test/ELF/merge-shared-str.s created+28
......@@ -0,0 +1,28 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: ld.lld %t.o -o %t.so -shared -O3
4// RUN: llvm-readobj -r -s %t.so | FileCheck %s
5
6
7 .section foo,"aMS",@progbits,1
8 .asciz "bar"
9 .asciz "ar"
10
11 .data
12 .quad foo + 4
13
14
15// CHECK: Name: foo
16// CHECK-NEXT: Type: SHT_PROGBITS
17// CHECK-NEXT: Flags [
18// CHECK-NEXT: SHF_ALLOC
19// CHECK-NEXT: SHF_MERGE
20// CHECK-NEXT: SHF_STRINGS
21// CHECK-NEXT: ]
22// CHECK-NEXT: Address: 0x1C8
23
24// CHECK: Relocations [
25// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
26// CHECK-NEXT: 0x{{.*}} R_X86_64_RELATIVE - 0x1C9
27// CHECK-NEXT: }
28// CHECK-NEXT: ]
deps/lld/test/ELF/merge-shared.s created+26
......@@ -0,0 +1,26 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: ld.lld %t.o -o %t.so -shared
4// RUN: llvm-readobj -r -s %t.so | FileCheck %s
5
6 .section foo,"aM",@progbits,4
7 .long 42
8 .long 42
9
10 .data
11 .quad foo + 6
12
13
14// CHECK: Name: foo
15// CHECK-NEXT: Type: SHT_PROGBITS
16// CHECK-NEXT: Flags [
17// CHECK-NEXT: SHF_ALLOC
18// CHECK-NEXT: SHF_MERGE
19// CHECK-NEXT: ]
20// CHECK-NEXT: Address: 0x1C8
21
22// CHECK: Relocations [
23// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
24// CHECK-NEXT: 0x{{.*}} R_X86_64_RELATIVE - 0x1CA
25// CHECK-NEXT: }
26// CHECK-NEXT: ]
deps/lld/test/ELF/merge-string-align.s created+56
......@@ -0,0 +1,56 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: ld.lld %t.o -o %t.so -shared
4// RUN: llvm-readobj -s -section-data %t.so | FileCheck %s
5
6 .section .rodata.foo,"aMS",@progbits,1
7 .align 16
8 .asciz "foo"
9
10 .section .rodata.foo2,"aMS",@progbits,1
11 .align 16
12 .asciz "foo"
13
14 .section .rodata.bar,"aMS",@progbits,1
15 .align 16
16 .asciz "bar"
17
18// CHECK: Name: .rodata
19// CHECK-NEXT: Type: SHT_PROGBITS
20// CHECK-NEXT: Flags [
21// CHECK-NEXT: SHF_ALLOC
22// CHECK-NEXT: SHF_MERGE
23// CHECK-NEXT: SHF_STRINGS
24// CHECK-NEXT: ]
25// CHECK-NEXT: Address:
26// CHECK-NEXT: Offset:
27// CHECK-NEXT: Size: 20
28// CHECK-NEXT: Link: 0
29// CHECK-NEXT: Info: 0
30// CHECK-NEXT: AddressAlignment: 16
31// CHECK-NEXT: EntrySize:
32// CHECK-NEXT: SectionData (
33// CHECK-NEXT: 0000: 666F6F00 00000000 00000000 00000000 |foo.............|
34// CHECK-NEXT: 0010: 62617200 |bar.|
35// CHECK-NEXT: )
36
37 .section .rodata2,"aMS",@progbits,1
38 .asciz "foo"
39
40// CHECK: Name: .rodata2
41// CHECK-NEXT: Type: SHT_PROGBITS
42// CHECK-NEXT: Flags [
43// CHECK-NEXT: SHF_ALLOC
44// CHECK-NEXT: SHF_MERGE
45// CHECK-NEXT: SHF_STRINGS
46// CHECK-NEXT: ]
47// CHECK-NEXT: Address:
48// CHECK-NEXT: Offset:
49// CHECK-NEXT: Size: 4
50// CHECK-NEXT: Link: 0
51// CHECK-NEXT: Info: 0
52// CHECK-NEXT: AddressAlignment: 1
53// CHECK-NEXT: EntrySize:
54// CHECK-NEXT: SectionData (
55// CHECK-NEXT: 0000: 666F6F00 |foo.|
56// CHECK-NEXT: )
deps/lld/test/ELF/merge-string-empty.s created+12
......@@ -0,0 +1,12 @@
1// Ensure that a mergeable string with size 0 does not cause any issue.
2
3// REQUIRES: x86
4// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
5// RUN: ld.lld %t.o -o %t
6
7.globl _start, s
8.section .rodata.str1.1,"aMS",@progbits,1
9s:
10.text
11_start:
12 .quad s
deps/lld/test/ELF/merge-string-error.s created+11
......@@ -0,0 +1,11 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s
4
5 .section .rodata.str1.1,"aMS",@progbits,1
6 .asciz "abc"
7
8 .data
9 .long .rodata.str1.1 + 4
10
11// CHECK: merge-string-error.s.tmp.o:(.rodata.str1.1): entry is past the end of the section
deps/lld/test/ELF/merge-string-no-null.s created+8
......@@ -0,0 +1,8 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s
4
5 .section .rodata.str1.1,"aMS",@progbits,1
6 .ascii "abc"
7
8// CHECK: string is not null terminated
deps/lld/test/ELF/merge-string.s created+105
......@@ -0,0 +1,105 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: ld.lld -O2 %t.o -o %t.so -shared
4// RUN: llvm-readobj -s -section-data -t %t.so | FileCheck %s
5// RUN: ld.lld -O1 %t.o -o %t.so -shared
6// RUN: llvm-readobj -s -section-data -t %t.so | FileCheck --check-prefix=NOTAIL %s
7// RUN: ld.lld -O0 %t.o -o %t.so -shared
8// RUN: llvm-readobj -s -section-data -t %t.so | FileCheck --check-prefix=NOMERGE %s
9
10 .section .rodata1,"aMS",@progbits,1
11 .asciz "abc"
12foo:
13 .ascii "a"
14bar:
15 .asciz "bc"
16 .asciz "bc"
17
18 .section .rodata2,"aMS",@progbits,2
19 .align 2
20zed:
21 .short 20
22 .short 0
23
24// CHECK: Name: .rodata1
25// CHECK-NEXT: Type: SHT_PROGBITS
26// CHECK-NEXT: Flags [
27// CHECK-NEXT: SHF_ALLOC
28// CHECK-NEXT: SHF_MERGE
29// CHECK-NEXT: SHF_STRINGS
30// CHECK-NEXT: ]
31// CHECK-NEXT: Address: 0x1C8
32// CHECK-NEXT: Offset: 0x1C8
33// CHECK-NEXT: Size: 4
34// CHECK-NEXT: Link: 0
35// CHECK-NEXT: Info: 0
36// CHECK-NEXT: AddressAlignment: 1
37// CHECK-NEXT: EntrySize: 0
38// CHECK-NEXT: SectionData (
39// CHECK-NEXT: 0000: 61626300 |abc.|
40// CHECK-NEXT: )
41
42// NOTAIL: Name: .rodata1
43// NOTAIL-NEXT: Type: SHT_PROGBITS
44// NOTAIL-NEXT: Flags [
45// NOTAIL-NEXT: SHF_ALLOC
46// NOTAIL-NEXT: SHF_MERGE
47// NOTAIL-NEXT: SHF_STRINGS
48// NOTAIL-NEXT: ]
49// NOTAIL-NEXT: Address: 0x1C8
50// NOTAIL-NEXT: Offset: 0x1C8
51// NOTAIL-NEXT: Size: 7
52// NOTAIL-NEXT: Link: 0
53// NOTAIL-NEXT: Info: 0
54// NOTAIL-NEXT: AddressAlignment: 1
55// NOTAIL-NEXT: EntrySize: 0
56// NOTAIL-NEXT: SectionData (
57// NOTAIL-NEXT: 0000: 61626300 626300 |abc.bc.|
58// NOTAIL-NEXT: )
59
60// NOMERGE: Name: .rodata1
61// NOMERGE-NEXT: Type: SHT_PROGBITS
62// NOMERGE-NEXT: Flags [
63// NOMERGE-NEXT: SHF_ALLOC
64// NOMERGE-NEXT: SHF_MERGE
65// NOMERGE-NEXT: SHF_STRINGS
66// NOMERGE-NEXT: ]
67// NOMERGE-NEXT: Address: 0x1C8
68// NOMERGE-NEXT: Offset: 0x1C8
69// NOMERGE-NEXT: Size: 11
70// NOMERGE-NEXT: Link: 0
71// NOMERGE-NEXT: Info: 0
72// NOMERGE-NEXT: AddressAlignment: 1
73// NOMERGE-NEXT: EntrySize: 1
74// NOMERGE-NEXT: SectionData (
75// NOMERGE-NEXT: 0000: 61626300 61626300 626300 |abc.abc.bc.|
76// NOMERGE-NEXT: )
77
78// CHECK: Name: .rodata2
79// CHECK-NEXT: Type: SHT_PROGBITS
80// CHECK-NEXT: Flags [
81// CHECK-NEXT: SHF_ALLOC
82// CHECK-NEXT: SHF_MERGE
83// CHECK-NEXT: SHF_STRINGS
84// CHECK-NEXT: ]
85// CHECK-NEXT: Address: 0x1CC
86// CHECK-NEXT: Offset: 0x1CC
87// CHECK-NEXT: Size: 4
88// CHECK-NEXT: Link: 0
89// CHECK-NEXT: Info: 0
90// CHECK-NEXT: AddressAlignment: 2
91// CHECK-NEXT: EntrySize: 0
92// CHECK-NEXT: SectionData (
93// CHECK-NEXT: 0000: 14000000 |....|
94// CHECK-NEXT: )
95
96
97// CHECK: Name: bar
98// CHECK-NEXT: Value: 0x1C9
99
100// CHECK: Name: foo
101// CHECK-NEXT: Value: 0x1C8
102
103// CHECK: Name: zed
104// CHECK-NEXT: Value: 0x1CC
105// CHECK-NEXT: Size: 0
deps/lld/test/ELF/merge-sym.s created+21
......@@ -0,0 +1,21 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: ld.lld %t.o -o %t.so -shared
4// RUN: llvm-readobj -t -s %t.so | FileCheck %s
5
6 .section .rodata.cst4,"aM",@progbits,4
7 .short 0
8foo:
9 .short 42
10
11
12// CHECK: Name: .rodata
13// CHECK-NEXT: Type: SHT_PROGBITS
14// CHECK-NEXT: Flags [
15// CHECK-NEXT: SHF_ALLOC
16// CHECK-NEXT: SHF_MERGE
17// CHECK-NEXT: ]
18// CHECK-NEXT: Address: 0x1C8
19
20// CHECK: Name: foo
21// CHECK-NEXT: Value: 0x1CA
deps/lld/test/ELF/merge.s created+111
......@@ -0,0 +1,111 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/merge.s -o %t2.o
4// RUN: ld.lld %t.o %t2.o -o %t
5// RUN: llvm-readobj -s -section-data -t %t | FileCheck %s
6// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
7
8 .section .mysec,"aM",@progbits,4
9 .align 4
10 .global foo
11 .hidden foo
12 .long 0x10
13foo:
14 .long 0x42
15bar:
16 .long 0x42
17zed:
18 .long 0x42
19
20// CHECK: Name: .mysec
21// CHECK-NEXT: Type: SHT_PROGBITS
22// CHECK-NEXT: Flags [
23// CHECK-NEXT: SHF_ALLOC
24// CHECK-NEXT: SHF_MERGE
25// CHECK-NEXT: ]
26// CHECK-NEXT: Address: 0x200120
27// CHECK-NEXT: Offset: 0x120
28// CHECK-NEXT: Size: 8
29// CHECK-NEXT: Link: 0
30// CHECK-NEXT: Info: 0
31// CHECK-NEXT: AddressAlignment: 4
32// CHECK-NEXT: EntrySize: 0
33// CHECK-NEXT: SectionData (
34// CHECK-NEXT: 0000: 10000000 42000000
35// CHECK-NEXT: )
36
37
38// Address of the constant 0x10 = 0x200120 = 2097440
39// Address of the constant 0x42 = 0x200124 = 2097444
40
41// CHECK: Symbols [
42
43// CHECK: Name: bar
44// CHECK-NEXT: Value: 0x200124
45// CHECK-NEXT: Size: 0
46// CHECK-NEXT: Binding: Loca
47// CHECK-NEXT: Type: None
48// CHECK-NEXT: Other: 0
49// CHECK-NEXT: Section: .mysec
50
51// CHECK: Name: zed
52// CHECK-NEXT: Value: 0x200124
53// CHECK-NEXT: Size: 0
54// CHECK-NEXT: Binding: Local
55// CHECK-NEXT: Type: None
56// CHECK-NEXT: Other: 0
57// CHECK-NEXT: Section: .mysec
58
59// CHECK: Name: foo
60// CHECK-NEXT: Value: 0x200124
61// CHECK-NEXT: Size: 0
62// CHECK-NEXT: Binding: Local
63// CHECK-NEXT: Type: None
64// CHECK-NEXT: Other [ (0x2)
65// CHECK-NEXT: STV_HIDDEN
66// CHECK-NEXT: ]
67// CHECK-NEXT: Section: .mysec
68
69 // CHECK: ]
70
71 .text
72 .globl _start
73_start:
74// DISASM: Disassembly of section .text:
75// DISASM-NEXT: _start:
76
77 movl .mysec, %eax
78// addr(0x10) = 2097440
79// DISASM-NEXT: movl 2097440, %eax
80
81 movl .mysec+7, %eax
82// addr(0x42) + 3 = 2097444 + 3 = 2097447
83// DISASM-NEXT: movl 2097447, %eax
84
85 movl .mysec+8, %eax
86// addr(0x42) = 2097444
87// DISASM-NEXT: movl 2097444, %eax
88
89 movl bar+7, %eax
90// addr(0x42) + 7 = 2097444 + 7 = 2097451
91// DISASM-NEXT: movl 2097451, %eax
92
93 movl bar+8, %eax
94// addr(0x42) + 8 = 2097444 + 8 = 2097452
95// DISASM-NEXT: movl 2097452, %eax
96
97 movl foo, %eax
98// addr(0x42) = 2097444
99// DISASM-NEXT: movl 2097444, %eax
100
101 movl foo+7, %eax
102// addr(0x42) + 7 = = 2097444 + 7 = 2097451
103// DISASM-NEXT: movl 2097451, %eax
104
105 movl foo+8, %eax
106// addr(0x42) + 8 = = 2097444 + 8 = 2097452
107// DISASM-NEXT: movl 2097452, %eax
108
109// From the other file: movl .mysec, %eax
110// addr(0x42) = 2097444
111// DISASM-NEXT: movl 2097444, %eax
deps/lld/test/ELF/mips-26-mask.s created+16
......@@ -0,0 +1,16 @@
1# Check reading/writing implicit addend for R_MIPS_26 relocation.
2
3# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
4# RUN: ld.lld %t.o -o %t.exe
5# RUN: llvm-objdump -d %t.exe | FileCheck %s
6
7# REQUIRES: mips
8
9# CHECK: Disassembly of section .text:
10# CHECK: __start:
11# CHECK-NEXT: 20000: 0e 00 80 00 jal 134348800
12
13 .text
14 .global __start
15__start:
16 jal __start+0x8000000
deps/lld/test/ELF/mips-26.s created+95
......@@ -0,0 +1,95 @@
1# Check R_MIPS_26 relocation handling.
2
3# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t1.o
4# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
5# RUN: %S/Inputs/mips-dynamic.s -o %t2.o
6# RUN: ld.lld %t2.o -shared -o %t.so
7# RUN: ld.lld %t1.o %t.so -o %t.exe
8# RUN: llvm-objdump -d %t.exe | FileCheck %s
9# RUN: llvm-readobj -dynamic-table -s -r -mips-plt-got %t.exe \
10# RUN: | FileCheck -check-prefix=REL %s
11
12# REQUIRES: mips
13
14# CHECK: Disassembly of section .text:
15# CHECK-NEXT: bar:
16# CHECK-NEXT: 20000: 0c 00 80 06 jal 131096 <loc>
17# CHECK-NEXT: 20004: 00 00 00 00 nop
18#
19# CHECK: __start:
20# CHECK-NEXT: 20008: 0c 00 80 00 jal 131072 <bar>
21# CHECK-NEXT: 2000c: 00 00 00 00 nop
22# CHECK-NEXT: 20010: 0c 00 80 10 jal 131136
23# ^-- 0x20040 gotplt[foo0]
24# CHECK-NEXT: 20014: 00 00 00 00 nop
25#
26# CHECK: loc:
27# CHECK-NEXT: 20018: 00 00 00 00 nop
28# CHECK-NEXT: Disassembly of section .plt:
29# CHECK-NEXT: .plt:
30# CHECK-NEXT: 20020: 3c 1c 00 03 lui $gp, 3
31# CHECK-NEXT: 20024: 8f 99 00 04 lw $25, 4($gp)
32# CHECK-NEXT: 20028: 27 9c 00 04 addiu $gp, $gp, 4
33# CHECK-NEXT: 2002c: 03 1c c0 23 subu $24, $24, $gp
34# CHECK-NEXT: 20030: 03 e0 78 25 move $15, $ra
35# CHECK-NEXT: 20034: 00 18 c0 82 srl $24, $24, 2
36# CHECK-NEXT: 20038: 03 20 f8 09 jalr $25
37# CHECK-NEXT: 2003c: 27 18 ff fe addiu $24, $24, -2
38# CHECK-NEXT: 20040: 3c 0f 00 03 lui $15, 3
39# CHECK-NEXT: 20044: 8d f9 00 0c lw $25, 12($15)
40# CHECK-NEXT: 20048: 03 20 00 08 jr $25
41# CHECK-NEXT: 2004c: 25 f8 00 0c addiu $24, $15, 12
42
43# REL: Name: .plt
44# REL-NEXT: Type: SHT_PROGBITS
45# REL-NEXT: Flags [ (0x6)
46# REL-NEXT: SHF_ALLOC
47# REL-NEXT: SHF_EXECINSTR
48# REL-NEXT: ]
49# REL-NEXT: Address: 0x[[PLTADDR:[0-9A-F]+]]
50
51# REL: Name: .got.plt
52# REL-NEXT: Type: SHT_PROGBITS
53# REL-NEXT: Flags [ (0x3)
54# REL-NEXT: SHF_ALLOC
55# REL-NEXT: SHF_WRITE
56# REL-NEXT: ]
57# REL-NEXT: Address: 0x[[GOTPLTADDR:[0-9A-F]+]]
58
59# REL: Relocations [
60# REL-NEXT: Section (7) .rel.plt {
61# REL-NEXT: 0x[[PLTSLOT:[0-9A-F]+]] R_MIPS_JUMP_SLOT foo0 0x0
62# REL-NEXT: }
63# REL-NEXT: ]
64
65# REL: 0x70000032 MIPS_PLTGOT 0x[[GOTPLTADDR]]
66
67# REL: Primary GOT {
68# REL: Local entries [
69# REL-NEXT: ]
70# REL-NEXT: Global entries [
71# REL-NEXT: ]
72# REL: PLT GOT {
73# REL: Entries [
74# REL-NEXT: Entry {
75# REL-NEXT: Address: 0x[[PLTSLOT]]
76# REL-NEXT: Initial: 0x[[PLTADDR]]
77# REL-NEXT: Value: 0x0
78# REL-NEXT: Type: Function
79# REL-NEXT: Section: Undefined
80# REL-NEXT: Name: foo0
81# REL-NEXT: }
82# REL-NEXT: ]
83
84 .text
85 .globl bar
86bar:
87 jal loc # R_MIPS_26 against .text + offset
88
89 .globl __start
90__start:
91 jal bar # R_MIPS_26 against global 'bar' from object file
92 jal foo0 # R_MIPS_26 against 'foo0' from DSO
93
94loc:
95 nop
deps/lld/test/ELF/mips-32.s created+79
......@@ -0,0 +1,79 @@
1# Check R_MIPS_32 relocation calculation.
2
3# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-be.o
4# RUN: ld.lld -shared %t-be.o -o %t-be.so
5# RUN: llvm-objdump -t -s %t-be.so \
6# RUN: | FileCheck -check-prefix=SYM -check-prefix=BE %s
7# RUN: llvm-readobj -r -dynamic-table -mips-plt-got %t-be.so \
8# RUN: | FileCheck -check-prefix=REL %s
9
10# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %t-el.o
11# RUN: ld.lld -shared %t-el.o -o %t-el.so
12# RUN: llvm-objdump -t -s %t-el.so \
13# RUN: | FileCheck -check-prefix=SYM -check-prefix=EL %s
14# RUN: llvm-readobj -r -dynamic-table -mips-plt-got %t-el.so \
15# RUN: | FileCheck -check-prefix=REL %s
16
17# REQUIRES: mips
18
19 .globl __start
20__start:
21 nop
22
23 .data
24 .type v1,@object
25 .size v1,4
26v1:
27 .word 0
28
29 .globl v2
30 .type v2,@object
31 .size v2,8
32v2:
33 .word v2+4 # R_MIPS_32 target v2 addend 4
34 .word v1 # R_MIPS_32 target v1 addend 0
35
36# BE: Contents of section .data:
37# BE-NEXT: 20000 00000000 00000004 00020000
38# ^-- v2+4 ^-- v1
39
40# EL: Contents of section .data:
41# EL-NEXT: 20000 00000000 04000000 00000200
42# ^-- v2+4 ^-- v1
43
44# SYM: SYMBOL TABLE:
45# SYM: 00020000 l .data 00000004 v1
46# SYM: 00020004 g .data 00000008 v2
47
48# REL: Relocations [
49# REL-NEXT: Section (7) .rel.dyn {
50# REL-NEXT: 0x20008 R_MIPS_REL32 - 0x0
51# REL-NEXT: 0x20004 R_MIPS_REL32 v2 0x0
52# REL-NEXT: }
53# REL-NEXT: ]
54
55# REL: DynamicSection [
56# REL: Tag Type Name/Value
57# REL: 0x00000012 RELSZ 16 (bytes)
58# REL: 0x00000013 RELENT 8 (bytes)
59# REL-NOT: 0x6FFFFFFA RELCOUNT
60
61# REL: Primary GOT {
62# REL-NEXT: Canonical gp value:
63# REL-NEXT: Reserved entries [
64# REL: ]
65# REL-NEXT: Local entries [
66# REL-NEXT: ]
67# REL-NEXT: Global entries [
68# REL-NEXT: Entry {
69# REL-NEXT: Address:
70# REL-NEXT: Access:
71# REL-NEXT: Initial: 0x20004
72# REL-NEXT: Value: 0x20004
73# REL-NEXT: Type: Object
74# REL-NEXT: Section: .data
75# REL-NEXT: Name: v2
76# REL-NEXT: }
77# REL-NEXT: ]
78# REL-NEXT: Number of TLS and multi-GOT entries: 0
79# REL-NEXT: }
deps/lld/test/ELF/mips-64-disp.s created+88
......@@ -0,0 +1,88 @@
1# Check R_MIPS_GOT_DISP relocations against various kind of symbols.
2
3# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \
4# RUN: %p/Inputs/mips-pic.s -o %t.so.o
5# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t.exe.o
6# RUN: ld.lld %t.so.o -shared -o %t.so
7# RUN: ld.lld %t.exe.o %t.so -o %t.exe
8# RUN: llvm-objdump -d -t %t.exe | FileCheck %s
9# RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck -check-prefix=GOT %s
10
11# REQUIRES: mips
12
13# CHECK: __start:
14# CHECK-NEXT: 20000: 24 42 80 40 addiu $2, $2, -32704
15# CHECK-NEXT: 20004: 24 42 80 20 addiu $2, $2, -32736
16# CHECK-NEXT: 20008: 24 42 80 28 addiu $2, $2, -32728
17# CHECK-NEXT: 2000c: 24 42 80 30 addiu $2, $2, -32720
18# CHECK-NEXT: 20010: 24 42 80 38 addiu $2, $2, -32712
19
20# CHECK: 0000000000020014 .text 00000000 foo
21# CHECK: 0000000000020000 .text 00000000 __start
22# CHECK: 0000000000000000 g F *UND* 00000000 foo1a
23
24# GOT: Relocations [
25# GOT-NEXT: ]
26# GOT-NEXT: Primary GOT {
27# GOT-NEXT: Canonical gp value:
28# GOT-NEXT: Reserved entries [
29# GOT-NEXT: Entry {
30# GOT-NEXT: Address:
31# GOT-NEXT: Access: -32752
32# GOT-NEXT: Initial: 0x0
33# GOT-NEXT: Purpose: Lazy resolver
34# GOT-NEXT: }
35# GOT-NEXT: Entry {
36# GOT-NEXT: Address:
37# GOT-NEXT: Access: -32744
38# GOT-NEXT: Initial: 0x8000000000000000
39# GOT-NEXT: Purpose: Module pointer (GNU extension)
40# GOT-NEXT: }
41# GOT-NEXT: ]
42# GOT-NEXT: Local entries [
43# GOT-NEXT: Entry {
44# GOT-NEXT: Address:
45# GOT-NEXT: Access: -32736
46# GOT-NEXT: Initial: 0x20014
47# GOT-NEXT: }
48# GOT-NEXT: Entry {
49# GOT-NEXT: Address:
50# GOT-NEXT: Access: -32728
51# GOT-NEXT: Initial: 0x20004
52# GOT-NEXT: }
53# GOT-NEXT: Entry {
54# GOT-NEXT: Address:
55# GOT-NEXT: Access: -32720
56# GOT-NEXT: Initial: 0x20008
57# GOT-NEXT: }
58# GOT-NEXT: Entry {
59# GOT-NEXT: Address:
60# GOT-NEXT: Access: -32712
61# GOT-NEXT: Initial: 0x2000C
62# GOT-NEXT: }
63# GOT-NEXT: ]
64# GOT-NEXT: Global entries [
65# GOT-NEXT: Entry {
66# GOT-NEXT: Address:
67# GOT-NEXT: Access: -32704
68# GOT-NEXT: Initial: 0x0
69# GOT-NEXT: Value: 0x0
70# GOT-NEXT: Type: Function
71# GOT-NEXT: Section: Undefined
72# GOT-NEXT: Name: foo1a
73# GOT-NEXT: }
74# GOT-NEXT: ]
75# GOT-NEXT: Number of TLS and multi-GOT entries: 0
76# GOT-NEXT: }
77
78 .text
79 .global __start
80__start:
81 addiu $v0,$v0,%got_disp(foo1a) # R_MIPS_GOT_DISP
82 addiu $v0,$v0,%got_disp(foo) # R_MIPS_GOT_DISP
83 addiu $v0,$v0,%got_disp(.text+4) # R_MIPS_GOT_DISP
84 addiu $v0,$v0,%got_disp(.text+8) # R_MIPS_GOT_DISP
85 addiu $v0,$v0,%got_disp(.text+12) # R_MIPS_GOT_DISP
86
87foo:
88 nop
deps/lld/test/ELF/mips-64-got.s created+91
......@@ -0,0 +1,91 @@
1# Check MIPS N64 ABI GOT relocations
2
3# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \
4# RUN: %p/Inputs/mips-pic.s -o %t.so.o
5# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t.exe.o
6# RUN: ld.lld %t.so.o -shared -o %t.so
7# RUN: ld.lld %t.exe.o %t.so -o %t.exe
8# RUN: llvm-objdump -d -t %t.exe | FileCheck %s
9# RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck -check-prefix=GOT %s
10
11# REQUIRES: mips
12
13# CHECK: __start:
14
15# CHECK-NEXT: 20000: df 82 80 20 ld $2, -32736($gp)
16# CHECK-NEXT: 20004: 64 42 00 18 daddiu $2, $2, 24
17# CHECK-NEXT: 20008: 24 42 80 40 addiu $2, $2, -32704
18# CHECK-NEXT: 2000c: 24 42 80 30 addiu $2, $2, -32720
19# CHECK-NEXT: 20010: 24 42 80 38 addiu $2, $2, -32712
20
21# CHECK: 0000000000020018 .text 00000000 foo
22# CHECK: 0000000000020000 .text 00000000 __start
23# CHECK: 0000000000020014 .text 00000000 bar
24
25# GOT: Relocations [
26# GOT-NEXT: ]
27# GOT-NEXT: Primary GOT {
28# GOT-NEXT: Canonical gp value:
29# GOT-NEXT: Reserved entries [
30# GOT-NEXT: Entry {
31# GOT-NEXT: Address:
32# GOT-NEXT: Access: -32752
33# GOT-NEXT: Initial: 0x0
34# GOT-NEXT: Purpose: Lazy resolver
35# GOT-NEXT: }
36# GOT-NEXT: Entry {
37# GOT-NEXT: Address:
38# GOT-NEXT: Access: -32744
39# GOT-NEXT: Initial: 0x8000000000000000
40# GOT-NEXT: Purpose: Module pointer (GNU extension)
41# GOT-NEXT: }
42# GOT-NEXT: ]
43# GOT-NEXT: Local entries [
44# GOT-NEXT: Entry {
45# GOT-NEXT: Address:
46# GOT-NEXT: Access: -32736
47# GOT-NEXT: Initial: 0x20000
48# GOT-NEXT: }
49# GOT-NEXT: Entry {
50# GOT-NEXT: Address:
51# GOT-NEXT: Access: -32728
52# GOT-NEXT: Initial: 0x30000
53# GOT-NEXT: }
54# GOT-NEXT: Entry {
55# GOT-NEXT: Address:
56# GOT-NEXT: Access: -32720
57# GOT-NEXT: Initial: 0x20014
58# GOT-NEXT: }
59# GOT-NEXT: Entry {
60# GOT-NEXT: Address:
61# GOT-NEXT: Access: -32712
62# GOT-NEXT: Initial: 0x20018
63# GOT-NEXT: }
64# GOT-NEXT: ]
65# GOT-NEXT: Global entries [
66# GOT-NEXT: Entry {
67# GOT-NEXT: Address:
68# GOT-NEXT: Access: -32704
69# GOT-NEXT: Initial: 0x0
70# GOT-NEXT: Value: 0x0
71# GOT-NEXT: Type: Function
72# GOT-NEXT: Section: Undefined
73# GOT-NEXT: Name: foo1a
74# GOT-NEXT: }
75# GOT-NEXT: ]
76# GOT-NEXT: Number of TLS and multi-GOT entries: 0
77# GOT-NEXT: }
78
79 .text
80 .global __start, bar
81__start:
82 ld $v0,%got_page(foo)($gp) # R_MIPS_GOT_PAGE
83 daddiu $v0,$v0,%got_ofst(foo) # R_MIPS_GOT_OFST
84 addiu $v0,$v0,%got_disp(foo1a) # R_MIPS_GOT_DISP
85 addiu $v0,$v0,%got_disp(bar) # R_MIPS_GOT_DISP
86 addiu $v0,$v0,%got_disp(foo) # R_MIPS_GOT_DISP
87
88bar:
89 nop
90foo:
91 nop
deps/lld/test/ELF/mips-64-gprel-so.s created+23
......@@ -0,0 +1,23 @@
1# Check setup of GP relative offsets in a function's prologue.
2
3# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t.o
4# RUN: ld.lld %t.o -shared -o %t.so
5# RUN: llvm-objdump -d -t %t.so | FileCheck %s
6
7# REQUIRES: mips
8
9# CHECK: Disassembly of section .text:
10# CHECK-NEXT: foo:
11# CHECK-NEXT: 10000: 3c 1c 00 01 lui $gp, 1
12# CHECK-NEXT: 10004: 03 99 e0 2d daddu $gp, $gp, $25
13# CHECK-NEXT: 10008: 67 9c 7f f0 daddiu $gp, $gp, 32752
14
15# CHECK: 0000000000027ff0 *ABS* 00000000 .hidden _gp
16# CHECK: 0000000000010000 .text 00000000 foo
17
18 .text
19 .global foo
20foo:
21 lui $gp,%hi(%neg(%gp_rel(foo)))
22 daddu $gp,$gp,$t9
23 daddiu $gp,$gp,%lo(%neg(%gp_rel(foo)))
deps/lld/test/ELF/mips-64-rels.s created+46
......@@ -0,0 +1,46 @@
1# Check handling multiple MIPS N64 ABI relocations packed
2# into the single relocation record.
3
4# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t.o
5# RUN: ld.lld %t.o -o %t.exe
6# RUN: llvm-objdump -d -s -t %t.exe | FileCheck %s
7# RUN: llvm-readobj -r %t.exe | FileCheck -check-prefix=REL %s
8
9# REQUIRES: mips
10
11# CHECK: __start:
12# CHECK-NEXT: 20000: 3c 1c 00 01 lui $gp, 1
13# ^-- 0x20000 - 0x37ff0
14# ^-- 0 - 0xfffffffffffe8010
15# ^-- %hi(0x17ff0)
16# CHECK: loc:
17# CHECK-NEXT: 20004: 67 9c 7f f0 daddiu $gp, $gp, 32752
18# ^-- 0x20000 - 0x37ff0
19# ^-- 0 - 0xfffffffffffe8010
20# ^-- %lo(0x17ff0)
21
22# CHECK: Contents of section .rodata:
23# CHECK-NEXT: 10158 ffffffff fffe8014
24# ^-- 0x20004 - 0x37ff0 = 0xfffffffffffe8014
25
26# CHECK: 0000000000020004 .text 00000000 loc
27# CHECK: 0000000000037ff0 *ABS* 00000000 .hidden _gp
28# CHECK: 0000000000020000 .text 00000000 __start
29
30# REL: Relocations [
31# REL-NEXT: ]
32
33 .text
34 .global __start
35__start:
36 lui $gp,%hi(%neg(%gp_rel(__start))) # R_MIPS_GPREL16
37 # R_MIPS_SUB
38 # R_MIPS_HI16
39loc:
40 daddiu $gp,$gp,%lo(%neg(%gp_rel(__start))) # R_MIPS_GPREL16
41 # R_MIPS_SUB
42 # R_MIPS_LO16
43
44 .section .rodata,"a",@progbits
45 .gpdword(loc) # R_MIPS_GPREL32
46 # R_MIPS_64
deps/lld/test/ELF/mips-64.s created+63
......@@ -0,0 +1,63 @@
1# Check R_MIPS_64 relocation calculation.
2
3# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t.o
4# RUN: ld.lld -shared %t.o -o %t.so
5# RUN: llvm-objdump -t %t.so | FileCheck -check-prefix=SYM %s
6# RUN: llvm-readobj -r -dynamic-table -mips-plt-got %t.so | FileCheck %s
7
8# REQUIRES: mips
9
10 .global __start
11__start:
12 nop
13
14 .data
15 .type v1,@object
16 .size v1,4
17v1:
18 .quad 0
19
20 .globl v2
21 .type v2,@object
22 .size v2,8
23v2:
24 .quad v2+8 # R_MIPS_64 target v2 addend 8
25 .quad v1 # R_MIPS_64 target v1 addend 0
26
27
28# SYM: SYMBOL TABLE:
29# SYM: 00020000 l .data 00000004 v1
30# SYM: 00020008 g .data 00000008 v2
31
32# CHECK: Relocations [
33# CHECK-NEXT: Section (7) .rela.dyn {
34# CHECK-NEXT: 0x20010 R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE - 0x20000
35# ^-- v1
36# CHECK-NEXT: 0x20008 R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE v2 0x8
37# CHECK-NEXT: }
38# CHECK-NEXT: ]
39
40# CHECK: DynamicSection [
41# CHECK: Tag Type Name/Value
42# CHECK: 0x0000000000000008 RELASZ 48 (bytes)
43# CHECK: 0x0000000000000009 RELAENT 24 (bytes)
44
45# CHECK: Primary GOT {
46# CHECK-NEXT: Canonical gp value:
47# CHECK-NEXT: Reserved entries [
48# CHECK: ]
49# CHECK-NEXT: Local entries [
50# CHECK-NEXT: ]
51# CHECK-NEXT: Global entries [
52# CHECK-NEXT: Entry {
53# CHECK-NEXT: Address:
54# CHECK-NEXT: Access:
55# CHECK-NEXT: Initial: 0x20008
56# CHECK-NEXT: Value: 0x20008
57# CHECK-NEXT: Type: Object
58# CHECK-NEXT: Section: .data
59# CHECK-NEXT: Name: v2
60# CHECK-NEXT: }
61# CHECK-NEXT: ]
62# CHECK-NEXT: Number of TLS and multi-GOT entries: 0
63# CHECK-NEXT: }
deps/lld/test/ELF/mips-align-err.s created+12
......@@ -0,0 +1,12 @@
1# REQUIRES: mips
2# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o \
3# RUN: -mcpu=mips32r6
4# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
5# RUN: -mcpu=mips32r6 %S/Inputs/mips-align-err.s -o %t2.o
6# RUN: not ld.lld %t.o %t2.o -o %t.exe 2>&1 | FileCheck %s
7# CHECK: {{.*}}:(.text+0x1): improper alignment for relocation R_MIPS_PC16
8
9 .globl __start
10__start:
11.zero 1
12 beqc $5, $6, _foo # R_MIPS_PC16
deps/lld/test/ELF/mips-call-hilo.s created+62
......@@ -0,0 +1,62 @@
1# Check R_MIPS_CALL_HI16 / R_MIPS_CALL_LO16 relocations calculation.
2
3# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
4# RUN: ld.lld %t.o -shared -o %t.so
5# RUN: llvm-objdump -d %t.so | FileCheck %s
6# RUN: llvm-readobj -r -mips-plt-got %t.so | FileCheck -check-prefix=GOT %s
7
8# REQUIRES: mips
9
10# CHECK: Disassembly of section .text:
11# CHECK-NEXT: foo:
12# CHECK-NEXT: 10000: 3c 02 00 00 lui $2, 0
13# CHECK-NEXT: 10004: 8c 42 80 20 lw $2, -32736($2)
14# CHECK-NEXT: 10008: 3c 02 00 00 lui $2, 0
15# CHECK-NEXT: 1000c: 8c 42 80 18 lw $2, -32744($2)
16# CHECK-NEXT: 10010: 3c 02 00 00 lui $2, 0
17# CHECK-NEXT: 10014: 8c 42 80 1c lw $2, -32740($2)
18
19# GOT: Relocations [
20# GOT-NEXT: ]
21
22# GOT: Primary GOT {
23# GOT-NEXT: Canonical gp value: 0x27FF0
24# GOT: Local entries [
25# GOT-NEXT: Entry {
26# GOT-NEXT: Address: 0x20008
27# GOT-NEXT: Access: -32744
28# GOT-NEXT: Initial: 0x10018
29# GOT-NEXT: }
30# GOT-NEXT: Entry {
31# GOT-NEXT: Address: 0x2000C
32# GOT-NEXT: Access: -32740
33# GOT-NEXT: Initial: 0x1001C
34# GOT-NEXT: }
35# GOT-NEXT: ]
36# GOT-NEXT: Global entries [
37# GOT-NEXT: Entry {
38# GOT-NEXT: Address: 0x20010
39# GOT-NEXT: Access: -32736
40# GOT-NEXT: Initial: 0x0
41# GOT-NEXT: Value: 0x0
42# GOT-NEXT: Type: None
43# GOT-NEXT: Section: Undefined
44# GOT-NEXT: Name: bar
45# GOT-NEXT: }
46# GOT-NEXT: ]
47# GOT-NEXT: Number of TLS and multi-GOT entries: 0
48# GOT-NEXT: }
49
50 .text
51 .global foo
52foo:
53 lui $2, %call_hi(bar)
54 lw $2, %call_lo(bar)($2)
55 lui $2, %call_hi(loc1)
56 lw $2, %call_lo(loc1)($2)
57 lui $2, %call_hi(loc2)
58 lw $2, %call_lo(loc2)($2)
59loc1:
60 nop
61loc2:
62 nop
deps/lld/test/ELF/mips-call16.s created+40
......@@ -0,0 +1,40 @@
1# Check R_MIPS_CALL16 relocation calculation.
2
3# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
4# RUN: ld.lld %t.o -shared -o %t.exe
5# RUN: llvm-objdump -d %t.exe | FileCheck %s
6# RUN: llvm-readobj -mips-plt-got -symbols %t.exe \
7# RUN: | FileCheck -check-prefix=GOT %s
8
9# REQUIRES: mips
10
11 .text
12 .globl __start
13__start:
14 lw $t0,%call16(g1)($gp)
15
16 .globl g1
17 .type g1,@function
18g1:
19 nop
20
21# CHECK: Disassembly of section .text:
22# CHECK-NEXT: __start:
23# CHECK-NEXT: 10000: 8f 88 80 18 lw $8, -32744
24
25# GOT: Name: g1
26# GOT-NEXT: Value: 0x[[ADDR:[0-9A-F]+]]
27
28# GOT: Local entries [
29# GOT-NEXT: ]
30# GOT-NEXT: Global entries [
31# GOT-NEXT: Entry {
32# GOT-NEXT: Address:
33# GOT-NEXT: Access: -32744
34# GOT-NEXT: Initial: 0x[[ADDR]]
35# GOT-NEXT: Value: 0x[[ADDR]]
36# GOT-NEXT: Type: Function
37# GOT-NEXT: Section: .text
38# GOT-NEXT: Name: g1
39# GOT-NEXT: }
40# GOT-NEXT: ]
deps/lld/test/ELF/mips-dynamic.s created+98
......@@ -0,0 +1,98 @@
1# Check MIPS specific .dynamic section entries.
2
3# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
4# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %p/Inputs/mips-dynamic.s -o %td.o
5# RUN: ld.lld -shared %td.o -o %td.so
6
7# RUN: ld.lld %t.o %td.so -o %t.exe
8# RUN: llvm-readobj -sections -dynamic-table %t.exe \
9# RUN: | FileCheck -check-prefix=EXE %s
10
11# RUN: ld.lld %t.o --image-base=0x123000 %td.so -o %t.exe
12# RUN: llvm-readobj -sections -dynamic-table %t.exe \
13# RUN: | FileCheck -check-prefix=IMAGE_BASE %s
14
15# RUN: ld.lld -shared %t.o %td.so -o %t.so
16# RUN: llvm-readobj -sections -dyn-symbols -dynamic-table %t.so \
17# RUN: | FileCheck -check-prefix=DSO %s
18
19# REQUIRES: mips
20
21# EXE: Sections [
22# EXE: Name: .dynamic
23# EXE-NEXT: Type: SHT_DYNAMIC
24# EXE-NEXT: Flags [
25# EXE-NEXT: SHF_ALLOC
26# EXE-NEXT: ]
27# EXE: Name: .rld_map
28# EXE-NEXT: Type: SHT_PROGBITS
29# EXE-NEXT: Flags [
30# EXE-NEXT: SHF_ALLOC
31# EXE-NEXT: SHF_WRITE
32# EXE-NEXT: ]
33# EXE-NEXT: Address: [[RLDMAPADDR:0x[0-9a-f]+]]
34# EXE-NEXT: Offset:
35# EXE-NEXT: Size: 4
36# EXE: Name: .got
37# EXE-NEXT: Type: SHT_PROGBITS
38# EXE-NEXT: Flags [ (0x10000003)
39# EXE-NEXT: SHF_ALLOC
40# EXE-NEXT: SHF_MIPS_GPREL
41# EXE-NEXT: SHF_WRITE
42# EXE-NEXT: ]
43# EXE-NEXT: Address: [[GOTADDR:0x[0-9a-f]+]]
44# EXE-NEXT: Offset:
45# EXE-NEXT: Size: 8
46# EXE: ]
47# EXE: DynamicSection [
48# EXE-NEXT: Tag Type Name/Value
49# EXE-DAG: 0x00000003 PLTGOT [[GOTADDR]]
50# EXE-DAG: 0x70000001 MIPS_RLD_VERSION 1
51# EXE-DAG: 0x70000005 MIPS_FLAGS NOTPOT
52# EXE-DAG: 0x70000006 MIPS_BASE_ADDRESS 0x10000
53# EXE-DAG: 0x7000000A MIPS_LOCAL_GOTNO 2
54# EXE-DAG: 0x70000011 MIPS_SYMTABNO 2
55# EXE-DAG: 0x70000013 MIPS_GOTSYM 0x2
56# EXE-DAG: 0x70000016 MIPS_RLD_MAP [[RLDMAPADDR]]
57# EXE: ]
58
59# IMAGE_BASE: 0x70000006 MIPS_BASE_ADDRESS 0x123000
60
61# DSO: Sections [
62# DSO: Name: .dynamic
63# DSO-NEXT: Type: SHT_DYNAMIC
64# DSO-NEXT: Flags [
65# DSO-NEXT: SHF_ALLOC
66# DSO-NEXT: ]
67# DSO: Name: .got
68# DSO-NEXT: Type: SHT_PROGBITS
69# DSO-NEXT: Flags [ (0x10000003)
70# DSO-NEXT: SHF_ALLOC
71# DSO-NEXT: SHF_MIPS_GPREL
72# DSO-NEXT: SHF_WRITE
73# DSO-NEXT: ]
74# DSO-NEXT: Address: [[GOTADDR:0x[0-9a-f]+]]
75# DSO-NEXT: Offset:
76# DSO-NEXT: Size: 8
77# DSO: ]
78# DSO: DynamicSymbols [
79# DSO: Name: @
80# DSO: Name: __start@
81# DSO: Name: _foo@
82# DSO: ]
83# DSO: DynamicSection [
84# DSO-NEXT: Tag Type Name/Value
85# DSO-DAG: 0x00000003 PLTGOT [[GOTADDR]]
86# DSO-DAG: 0x70000001 MIPS_RLD_VERSION 1
87# DSO-DAG: 0x70000005 MIPS_FLAGS NOTPOT
88# DSO-DAG: 0x70000006 MIPS_BASE_ADDRESS 0x0
89# DSO-DAG: 0x7000000A MIPS_LOCAL_GOTNO 2
90# DSO-DAG: 0x70000011 MIPS_SYMTABNO 3
91# DSO-DAG: 0x70000013 MIPS_GOTSYM 0x3
92# DSO: ]
93
94 .text
95 .globl __start,_foo
96 .type _foo,@function
97__start:
98 nop
deps/lld/test/ELF/mips-dynsym-sort.s created+43
......@@ -0,0 +1,43 @@
1# Check the order of dynamic symbols for the MIPS target.
2
3# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-be.o
4# RUN: ld.lld -shared %t-be.o -o %t-be.so
5# RUN: llvm-readobj -symbols -dyn-symbols %t-be.so | FileCheck %s
6
7# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %t-el.o
8# RUN: ld.lld -shared %t-el.o -o %t-el.so
9# RUN: llvm-readobj -symbols -dyn-symbols %t-el.so | FileCheck %s
10
11# REQUIRES: mips
12
13 .data
14 .globl v1,v2,v3
15v1:
16 .space 4
17v2:
18 .space 4
19v3:
20 .space 4
21
22 .text
23 .globl __start
24__start:
25 lui $2, %got(v3) # v3 will precede v1 in the GOT
26 lui $2, %got(v1)
27
28# Since all these symbols have global binding,
29# the Symbols section contains them in the original order.
30# CHECK: Symbols [
31# CHECK: Name: v1
32# CHECK: Name: v2
33# CHECK: Name: v3
34# CHECK: ]
35
36# The symbols in the DynamicSymbols section are sorted in compliance with
37# the MIPS rules. v2 comes first as it is not in the GOT.
38# v1 and v3 are sorted according to their order in the GOT.
39# CHECK: DynamicSymbols [
40# CHECK: Name: v2@
41# CHECK: Name: v3@
42# CHECK: Name: v1@
43# CHECK: ]
deps/lld/test/ELF/mips-elf-flags-err.s created+86
......@@ -0,0 +1,86 @@
1# Check MIPS ELF ISA flag calculation if input files have different ISAs.
2
3# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
4# RUN: -mcpu=mips32 %S/Inputs/mips-dynamic.s -o %t1.o
5# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
6# RUN: -mcpu=mips32r2 %s -o %t2.o
7# RUN: ld.lld %t1.o %t2.o -o %t.exe
8# RUN: llvm-readobj -h %t.exe | FileCheck -check-prefix=R1R2 %s
9
10# Check that lld does not allow to link incompatible ISAs.
11
12# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
13# RUN: -mcpu=mips3 %S/Inputs/mips-dynamic.s -o %t1.o
14# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
15# RUN: -mcpu=mips32 -mattr=+fp64 %s -o %t2.o
16# RUN: not ld.lld %t1.o %t2.o -o %t.exe 2>&1 | FileCheck -check-prefix=R3R32 %s
17
18# Check that lld does not allow to link incompatible ISAs.
19
20# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \
21# RUN: -mcpu=mips64r6 %S/Inputs/mips-dynamic.s -o %t1.o
22# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \
23# RUN: -position-independent -mcpu=octeon %s -o %t2.o
24# RUN: not ld.lld %t1.o %t2.o -o %t.exe 2>&1 \
25# RUN: | FileCheck -check-prefix=R6OCTEON %s
26
27# Check that lld does not allow to link incompatible floating point ABI.
28
29# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
30# RUN: -mcpu=mips32 %S/Inputs/mips-dynamic.s -o %t1.o
31# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
32# RUN: -mcpu=mips32 -mattr=+fp64 %s -o %t2.o
33# RUN: not ld.lld %t1.o %t2.o -o %t.exe 2>&1 | FileCheck -check-prefix=FPABI %s
34
35# Check that lld take in account EF_MIPS_MACH_XXX ISA flags
36
37# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \
38# RUN: -position-independent -mcpu=mips64 %S/Inputs/mips-dynamic.s -o %t1.o
39# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \
40# RUN: -position-independent -mcpu=octeon %s -o %t2.o
41# RUN: ld.lld %t1.o %t2.o -o %t.exe
42# RUN: llvm-readobj -h %t.exe | FileCheck -check-prefix=OCTEON %s
43
44# Check that lld does not allow to link incompatible ABIs.
45
46# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
47# RUN: -target-abi n32 %S/Inputs/mips-dynamic.s -o %t1.o
48# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
49# RUN: -target-abi o32 %s -o %t2.o
50# RUN: not ld.lld %t1.o %t2.o -o %t.exe 2>&1 | FileCheck -check-prefix=N32O32 %s
51
52# Check that lld does not allow to link modules with incompatible NAN flags.
53
54# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
55# RUN: -mattr=+nan2008 %S/Inputs/mips-dynamic.s -o %t1.o
56# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
57# RUN: %s -o %t2.o
58# RUN: not ld.lld %t1.o %t2.o -o %t.exe 2>&1 | FileCheck -check-prefix=NAN %s
59
60# REQUIRES: mips
61
62 .option pic0
63 .text
64 .global __start
65__start:
66 nop
67
68# R1R2: Flags [
69# R1R2-NEXT: EF_MIPS_ABI_O32
70# R1R2-NEXT: EF_MIPS_ARCH_32R2
71# R1R2-NEXT: EF_MIPS_CPIC
72# R1R2-NEXT: ]
73
74# R3R32: target ISA 'mips3' is incompatible with 'mips32': {{.*}}mips-elf-flags-err.s.tmp2.o
75# R6OCTEON: target ISA 'mips64r6' is incompatible with 'octeon': {{.*}}mips-elf-flags-err.s.tmp2.o
76# FPABI: target floating point ABI '-mdouble-float' is incompatible with '-mgp32 -mfp64': {{.*}}mips-elf-flags-err.s.tmp2.o
77
78# OCTEON: Flags [
79# OCTEON-NEXT: EF_MIPS_ARCH_64R2
80# OCTEON-NEXT: EF_MIPS_CPIC
81# OCTEON-NEXT: EF_MIPS_MACH_OCTEON
82# OCTEON: ]
83
84# N32O32: error: {{.*}}mips-elf-flags-err.s.tmp2.o is incompatible with {{.*}}mips-elf-flags-err.s.tmp1.o
85
86# NAN: target -mnan=2008 is incompatible with -mnan=legacy: {{.*}}mips-elf-flags-err.s.tmp2.o
deps/lld/test/ELF/mips-elf-flags.s created+172
......@@ -0,0 +1,172 @@
1# Check generation of MIPS specific ELF header flags.
2
3# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
4# RUN: %S/Inputs/mips-dynamic.s -o %t-so.o
5# RUN: ld.lld %t-so.o --gc-sections -shared -o %t.so
6# RUN: llvm-readobj -h -mips-abi-flags %t.so | FileCheck -check-prefix=SO %s
7
8# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
9# RUN: ld.lld %t.o -o %t.exe
10# RUN: llvm-readobj -h -mips-abi-flags %t.exe | FileCheck -check-prefix=EXE %s
11
12# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
13# RUN: -mcpu=mips32r2 %s -o %t-r2.o
14# RUN: ld.lld %t-r2.o -o %t-r2.exe
15# RUN: llvm-readobj -h -mips-abi-flags %t-r2.exe \
16# RUN: | FileCheck -check-prefix=EXE-R2 %s
17
18# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
19# RUN: -mcpu=mips32r2 %s -o %t-r2.o
20# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
21# RUN: -mcpu=mips32r5 %S/Inputs/mips-dynamic.s -o %t-r5.o
22# RUN: ld.lld %t-r2.o %t-r5.o -o %t-r5.exe
23# RUN: llvm-readobj -h -mips-abi-flags %t-r5.exe \
24# RUN: | FileCheck -check-prefix=EXE-R5 %s
25
26# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
27# RUN: -mcpu=mips32r6 %s -o %t-r6.o
28# RUN: ld.lld %t-r6.o -o %t-r6.exe
29# RUN: llvm-readobj -h -mips-abi-flags %t-r6.exe \
30# RUN: | FileCheck -check-prefix=EXE-R6 %s
31
32# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \
33# RUN: -position-independent -mcpu=octeon %s -o %t.o
34# RUN: ld.lld %t.o -o %t.exe
35# RUN: llvm-readobj -h -mips-abi-flags %t.exe \
36# RUN: | FileCheck -check-prefix=OCTEON %s
37
38# REQUIRES: mips
39
40 .text
41 .globl __start
42__start:
43 nop
44
45# SO: Flags [
46# SO-NEXT: EF_MIPS_ABI_O32
47# SO-NEXT: EF_MIPS_ARCH_32
48# SO-NEXT: EF_MIPS_CPIC
49# SO-NEXT: EF_MIPS_PIC
50# SO-NEXT: ]
51# SO: MIPS ABI Flags {
52# SO-NEXT: Version: 0
53# SO-NEXT: ISA: MIPS32
54# SO-NEXT: ISA Extension: None
55# SO-NEXT: ASEs [
56# SO-NEXT: ]
57# SO-NEXT: FP ABI: Hard float (double precision)
58# SO-NEXT: GPR size: 32
59# SO-NEXT: CPR1 size: 32
60# SO-NEXT: CPR2 size: 0
61# SO-NEXT: Flags 1 [
62# SO-NEXT: ODDSPREG
63# SO-NEXT: ]
64# SO-NEXT: Flags 2: 0x0
65# SO-NEXT: }
66
67# EXE: Flags [
68# EXE-NEXT: EF_MIPS_ABI_O32
69# EXE-NEXT: EF_MIPS_ARCH_32
70# EXE-NEXT: EF_MIPS_CPIC
71# EXE-NEXT: ]
72# EXE: MIPS ABI Flags {
73# EXE-NEXT: Version: 0
74# EXE-NEXT: ISA: MIPS32
75# EXE-NEXT: ISA Extension: None
76# EXE-NEXT: ASEs [
77# EXE-NEXT: ]
78# EXE-NEXT: FP ABI: Hard float (double precision)
79# EXE-NEXT: GPR size: 32
80# EXE-NEXT: CPR1 size: 32
81# EXE-NEXT: CPR2 size: 0
82# EXE-NEXT: Flags 1 [
83# EXE-NEXT: ODDSPREG
84# EXE-NEXT: ]
85# EXE-NEXT: Flags 2: 0x0
86# EXE-NEXT: }
87
88# EXE-R2: Flags [
89# EXE-R2-NEXT: EF_MIPS_ABI_O32
90# EXE-R2-NEXT: EF_MIPS_ARCH_32R2
91# EXE-R2-NEXT: EF_MIPS_CPIC
92# EXE-R2-NEXT: ]
93# EXE-R2: MIPS ABI Flags {
94# EXE-R2-NEXT: Version: 0
95# EXE-R2-NEXT: ISA: MIPS32r2
96# EXE-R2-NEXT: ISA Extension: None
97# EXE-R2-NEXT: ASEs [
98# EXE-R2-NEXT: ]
99# EXE-R2-NEXT: FP ABI: Hard float (double precision)
100# EXE-R2-NEXT: GPR size: 32
101# EXE-R2-NEXT: CPR1 size: 32
102# EXE-R2-NEXT: CPR2 size: 0
103# EXE-R2-NEXT: Flags 1 [
104# EXE-R2-NEXT: ODDSPREG
105# EXE-R2-NEXT: ]
106# EXE-R2-NEXT: Flags 2: 0x0
107# EXE-R2-NEXT: }
108
109# EXE-R5: Flags [
110# EXE-R5-NEXT: EF_MIPS_ABI_O32
111# EXE-R5-NEXT: EF_MIPS_ARCH_32R2
112# EXE-R5-NEXT: EF_MIPS_CPIC
113# EXE-R5-NEXT: ]
114# EXE-R5: MIPS ABI Flags {
115# EXE-R5-NEXT: Version: 0
116# EXE-R5-NEXT: ISA: MIPS32r5
117# EXE-R5-NEXT: ISA Extension: None
118# EXE-R5-NEXT: ASEs [
119# EXE-R5-NEXT: ]
120# EXE-R5-NEXT: FP ABI: Hard float (double precision)
121# EXE-R5-NEXT: GPR size: 32
122# EXE-R5-NEXT: CPR1 size: 32
123# EXE-R5-NEXT: CPR2 size: 0
124# EXE-R5-NEXT: Flags 1 [
125# EXE-R5-NEXT: ODDSPREG
126# EXE-R5-NEXT: ]
127# EXE-R5-NEXT: Flags 2: 0x0
128# EXE-R5-NEXT: }
129
130# EXE-R6: Flags [
131# EXE-R6-NEXT: EF_MIPS_ABI_O32
132# EXE-R6-NEXT: EF_MIPS_ARCH_32R6
133# EXE-R6-NEXT: EF_MIPS_CPIC
134# EXE-R6-NEXT: EF_MIPS_NAN2008
135# EXE-R6-NEXT: ]
136# EXE-R6: MIPS ABI Flags {
137# EXE-R6-NEXT: Version: 0
138# EXE-R6-NEXT: ISA: MIPS32
139# EXE-R6-NEXT: ISA Extension: None
140# EXE-R6-NEXT: ASEs [
141# EXE-R6-NEXT: ]
142# EXE-R6-NEXT: FP ABI: Hard float (32-bit CPU, 64-bit FPU)
143# EXE-R6-NEXT: GPR size: 32
144# EXE-R6-NEXT: CPR1 size: 64
145# EXE-R6-NEXT: CPR2 size: 0
146# EXE-R6-NEXT: Flags 1 [
147# EXE-R6-NEXT: ODDSPREG
148# EXE-R6-NEXT: ]
149# EXE-R6-NEXT: Flags 2: 0x0
150# EXE-R6-NEXT: }
151
152# OCTEON: Flags [
153# OCTEON-NEXT: EF_MIPS_ARCH_64R2
154# OCTEON-NEXT: EF_MIPS_CPIC
155# OCTEON-NEXT: EF_MIPS_MACH_OCTEON
156# OCTEON-NEXT: EF_MIPS_PIC
157# OCTEON-NEXT: ]
158# OCTEON: MIPS ABI Flags {
159# OCTEON-NEXT: Version: 0
160# OCTEON-NEXT: ISA: MIPS64r2
161# OCTEON-NEXT: ISA Extension: Cavium Networks Octeon
162# OCTEON-NEXT: ASEs [
163# OCTEON-NEXT: ]
164# OCTEON-NEXT: FP ABI: Hard float (double precision)
165# OCTEON-NEXT: GPR size: 64
166# OCTEON-NEXT: CPR1 size: 64
167# OCTEON-NEXT: CPR2 size: 0
168# OCTEON-NEXT: Flags 1 [
169# OCTEON-NEXT: ODDSPREG
170# OCTEON-NEXT: ]
171# OCTEON-NEXT: Flags 2: 0x0
172# OCTEON-NEXT: }
deps/lld/test/ELF/mips-gnu-hash.s created+15
......@@ -0,0 +1,15 @@
1# Shouldn't allow the GNU hash style to be selected with the MIPS target.
2
3# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-be.o
4# RUN: not ld.lld -shared -hash-style=gnu %t-be.o -o %t-be.so 2>&1 | FileCheck %s
5
6# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %t-el.o
7# RUN: not ld.lld -shared -hash-style=gnu %t-el.o -o %t-el.so 2>&1 | FileCheck %s
8
9# CHECK: the .gnu.hash section is not compatible with the MIPS target.
10
11# REQUIRES: mips
12
13 .globl __start
14__start:
15 nop
deps/lld/test/ELF/mips-got-and-copy.s created+57
......@@ -0,0 +1,57 @@
1# REQUIRES: mips
2
3# If there are two relocations such that the first one requires
4# dynamic COPY relocation, the second one requires GOT entry
5# creation, linker should create both - dynamic relocation
6# and GOT entry.
7
8# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
9# RUN: %S/Inputs/mips-dynamic.s -o %t.so.o
10# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
11# RUN: ld.lld %t.so.o -shared -o %t.so
12# RUN: ld.lld %t.o %t.so -o %t.exe
13# RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck %s
14
15# CHECK: Relocations [
16# CHECK-NEXT: Section (7) .rel.dyn {
17# CHECK-NEXT: 0x[[DATA0:[0-9A-F]+]] R_MIPS_COPY data0
18# CHECK-NEXT: 0x[[DATA1:[0-9A-F]+]] R_MIPS_COPY data1
19# CHECK-NEXT: }
20# CHECK-NEXT: ]
21# CHECK-NEXT: Primary GOT {
22# CHECK-NEXT: Canonical gp value:
23# CHECK-NEXT: Reserved entries [
24# CHECK: ]
25# CHECK-NEXT: Local entries [
26# CHECK-NEXT: Entry {
27# CHECK-NEXT: Address:
28# CHECK-NEXT: Access: -32744
29# CHECK-NEXT: Initial: 0x[[DATA0]]
30# CHECK-NEXT: }
31# CHECK-NEXT: ]
32# CHECK-NEXT: Global entries [
33# CHECK-NEXT: Entry {
34# CHECK-NEXT: Address:
35# CHECK-NEXT: Access: -32740
36# CHECK-NEXT: Initial: 0x[[DATA1]]
37# CHECK-NEXT: Value: 0x[[DATA1]]
38# CHECK-NEXT: Type: Object
39# CHECK-NEXT: Section: .bss
40# CHECK-NEXT: Name: data1@
41# CHECK-NEXT: }
42# CHECK-NEXT: ]
43# CHECK-NEXT: Number of TLS and multi-GOT entries: 0
44# CHECK-NEXT: }
45
46 .text
47 .global __start
48__start:
49 # Case A: 'got' relocation goes before 'copy' relocation
50 lui $t0,%hi(data0) # R_MIPS_HI16 - requires R_MISP_COPY relocation
51 addi $t0,$t0,%lo(data0)
52 lw $t0,%got(data0)($gp) # R_MIPS_GOT16 - requires GOT entry
53
54 # Case B: 'copy' relocation goes before 'got' relocation
55 lw $t0,%got(data1)($gp) # R_MIPS_GOT16 - requires GOT entry
56 lui $t0,%hi(data1) # R_MIPS_HI16 - requires R_MISP_COPY relocation
57 addi $t0,$t0,%lo(data1)
deps/lld/test/ELF/mips-got-extsym.s created+59
......@@ -0,0 +1,59 @@
1# Check creation of GOT entries for global symbols in case of executable
2# file linking. Symbols defined in DSO should get entries in the global part
3# of the GOT. Symbols defined in the executable itself should get local GOT
4# entries and does not need a row in .dynsym table.
5
6# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
7# RUN: %S/Inputs/mips-dynamic.s -o %t.so.o
8# RUN: ld.lld -shared %t.so.o -o %t.so
9# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
10# RUN: ld.lld %t.o %t.so -o %t.exe
11# RUN: llvm-readobj -dt -t -mips-plt-got %t.exe | FileCheck %s
12
13# REQUIRES: mips
14
15# CHECK: Symbols [
16# CHECK: Symbol {
17# CHECK: Name: _foo
18# CHECK-NEXT: Value: 0x0
19# CHECK-NEXT: Size: 0
20# CHECK-NEXT: Binding: Global
21
22# CHECK: Symbol {
23# CHECK: Name: bar
24# CHECK-NEXT: Value: 0x20008
25# CHECK-NEXT: Size: 0
26# CHECK-NEXT: Binding: Global
27
28# CHECK: DynamicSymbols [
29# CHECK-NOT: Name: bar
30
31# CHECK: Local entries [
32# CHECK-NEXT: Entry {
33# CHECK-NEXT: Address:
34# CHECK-NEXT: Access: -32744
35# CHECK-NEXT: Initial: 0x20008
36# ^-- bar
37# CHECK-NEXT: }
38# CHECK-NEXT: ]
39# CHECK-NEXT: Global entries [
40# CHECK-NEXT: Entry {
41# CHECK-NEXT: Address:
42# CHECK-NEXT: Access: -32740
43# CHECK-NEXT: Initial: 0x0
44# CHECK-NEXT: Value: 0x0
45# CHECK-NEXT: Type: None
46# CHECK-NEXT: Section: Undefined
47# CHECK-NEXT: Name: _foo@
48# CHECK-NEXT: }
49# CHECK-NEXT: ]
50
51 .text
52 .globl __start
53__start:
54 lw $t0,%got(bar)($gp)
55 lw $t0,%got(_foo)($gp)
56
57.global bar
58bar:
59 .word 0
deps/lld/test/ELF/mips-got-hilo.s created+64
......@@ -0,0 +1,64 @@
1# Check R_MIPS_GOT_HI16 / R_MIPS_GOT_LO16 relocations calculation.
2
3# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
4# RUN: ld.lld %t.o -shared -o %t.so
5# RUN: llvm-objdump -d %t.so | FileCheck %s
6# RUN: llvm-readobj -r -mips-plt-got %t.so | FileCheck -check-prefix=GOT %s
7
8# REQUIRES: mips
9
10# CHECK: Disassembly of section .text:
11# CHECK-NEXT: foo:
12# CHECK-NEXT: 10000: 3c 02 00 00 lui $2, 0
13# CHECK-NEXT: 10004: 8c 42 80 20 lw $2, -32736($2)
14# CHECK-NEXT: 10008: 3c 02 00 00 lui $2, 0
15# CHECK-NEXT: 1000c: 8c 42 80 18 lw $2, -32744($2)
16# CHECK-NEXT: 10010: 3c 02 00 00 lui $2, 0
17# CHECK-NEXT: 10014: 8c 42 80 1c lw $2, -32740($2)
18
19# GOT: Relocations [
20# GOT-NEXT: ]
21
22# GOT: Primary GOT {
23# GOT-NEXT: Canonical gp value:
24# GOT: Local entries [
25# GOT-NEXT: Entry {
26# GOT-NEXT: Address:
27# GOT-NEXT: Access: -32744
28# GOT-NEXT: Initial: 0x20000
29# GOT-NEXT: }
30# GOT-NEXT: Entry {
31# GOT-NEXT: Address:
32# GOT-NEXT: Access: -32740
33# GOT-NEXT: Initial: 0x20004
34# GOT-NEXT: }
35# GOT-NEXT: ]
36# GOT-NEXT: Global entries [
37# GOT-NEXT: Entry {
38# GOT-NEXT: Address:
39# GOT-NEXT: Access: -32736
40# GOT-NEXT: Initial: 0x0
41# GOT-NEXT: Value: 0x0
42# GOT-NEXT: Type: None
43# GOT-NEXT: Section: Undefined
44# GOT-NEXT: Name: bar
45# GOT-NEXT: }
46# GOT-NEXT: ]
47# GOT-NEXT: Number of TLS and multi-GOT entries: 0
48# GOT-NEXT: }
49
50 .text
51 .global foo
52foo:
53 lui $2, %got_hi(bar)
54 lw $2, %got_lo(bar)($2)
55 lui $2, %got_hi(loc1)
56 lw $2, %got_lo(loc1)($2)
57 lui $2, %got_hi(loc2)
58 lw $2, %got_lo(loc2)($2)
59
60 .data
61loc1:
62 .word 0
63loc2:
64 .word 0
deps/lld/test/ELF/mips-got-page.s created+40
......@@ -0,0 +1,40 @@
1# Check the case when small section (less that 0x10000 bytes) occupies
2# two adjacent 0xffff-bytes pages. We need to create two GOT entries
3# for R_MIPS_GOT_PAGE relocations.
4
5# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux -o %t.o %s
6# RUN: ld.lld --section-start .rodata=0x27FFC -shared -o %t.so %t.o
7# RUN: llvm-readobj -t -mips-plt-got %t.so | FileCheck %s
8
9# REQUIRES: mips
10
11# CHECK: Name: bar
12# CHECK-NEXT: Value: 0x28000
13# ^ page-address = (0x28000 + 0x8000) & ~0xffff = 0x30000
14
15# CHECK: Name: foo
16# CHECK-NEXT: Value: 0x27FFC
17# ^ page-address = (0x27ffc + 0x8000) & ~0xffff = 0x20000
18
19# CHECK: Local entries [
20# CHECK-NEXT: Entry {
21# CHECK-NEXT: Address:
22# CHECK-NEXT: Access: -32736
23# CHECK-NEXT: Initial: 0x20000
24# CHECK-NEXT: }
25# CHECK-NEXT: Entry {
26# CHECK-NEXT: Address:
27# CHECK-NEXT: Access: -32728
28# CHECK-NEXT: Initial: 0x30000
29# CHECK-NEXT: }
30# CHECK-NEXT: ]
31
32 .text
33 ld $v0,%got_page(foo)($gp)
34 ld $v0,%got_page(bar)($gp)
35
36 .rodata
37foo:
38 .word 0
39bar:
40 .word 0
deps/lld/test/ELF/mips-got-redundant.s created+64
......@@ -0,0 +1,64 @@
1# Check number of redundant entries in the local part of MIPS GOT.
2
3# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
4# RUN: ld.lld %t.o -shared -o %t.so
5# RUN: llvm-readobj -mips-plt-got %t.so | FileCheck %s
6
7# REQUIRES: mips
8
9# CHECK: Local entries [
10# CHECK-NEXT: Entry {
11# CHECK-NEXT: Address:
12# CHECK-NEXT: Access: -32744
13# CHECK-NEXT: Initial: 0x20000
14# ^-- loc1
15# CHECK-NEXT: }
16# CHECK-NEXT: Entry {
17# CHECK-NEXT: Address:
18# CHECK-NEXT: Access: -32740
19# CHECK-NEXT: Initial: 0x30000
20# ^-- loc2, loc3, loc4
21# CHECK-NEXT: }
22# CHECK-NEXT: Entry {
23# CHECK-NEXT: Address:
24# CHECK-NEXT: Access: -32736
25# CHECK-NEXT: Initial: 0x40000
26# ^-- redundant
27# CHECK-NEXT: }
28# CHECK-NEXT: Entry {
29# CHECK-NEXT: Address:
30# CHECK-NEXT: Access: -32732
31# CHECK-NEXT: Initial: 0x30008
32# ^-- glb1
33# CHECK-NEXT: }
34# CHECK-NEXT: ]
35
36 .text
37 .globl foo
38foo:
39 lw $t0, %got(loc1)($gp)
40 addi $t0, $t0, %lo(loc1)
41 lw $t0, %got(loc2)($gp)
42 addi $t0, $t0, %lo(loc2)
43 lw $t0, %got(loc3)($gp)
44 addi $t0, $t0, %lo(loc3)
45 lw $t0, %got(loc4)($gp)
46 addi $t0, $t0, %lo(loc4)
47 lw $t0, %got(glb1)($gp)
48 lw $t0, %got(glb1)($gp)
49
50 .section .data.1,"aw",%progbits
51loc1:
52 .space 0x10000
53loc2:
54 .word 0
55loc3:
56 .word 0
57 .global glb1
58 .hidden glb1
59glb1:
60 .word 0
61
62 .section .data.2,"aw",%progbits
63loc4:
64 .word 0
deps/lld/test/ELF/mips-got-relocs.s created+100
......@@ -0,0 +1,100 @@
1# Check R_MIPS_GOT16 relocation calculation.
2
3# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-be.o
4# RUN: ld.lld %t-be.o -o %t-be.exe
5# RUN: llvm-objdump -section-headers -t %t-be.exe | FileCheck -check-prefix=EXE_SYM %s
6# RUN: llvm-objdump -s -section=.got %t-be.exe | FileCheck -check-prefix=EXE_GOT_BE %s
7# RUN: llvm-objdump -d %t-be.exe | FileCheck -check-prefix=EXE_DIS_BE %s
8# RUN: llvm-readobj -relocations %t-be.exe | FileCheck -check-prefix=NORELOC %s
9# RUN: llvm-readobj -sections %t-be.exe | FileCheck -check-prefix=SHFLAGS %s
10
11# RUN: llvm-mc -filetype=obj -triple=mipsel-unknown-linux %s -o %t-el.o
12# RUN: ld.lld %t-el.o -o %t-el.exe
13# RUN: llvm-objdump -section-headers -t %t-el.exe | FileCheck -check-prefix=EXE_SYM %s
14# RUN: llvm-objdump -s -section=.got %t-el.exe | FileCheck -check-prefix=EXE_GOT_EL %s
15# RUN: llvm-objdump -d %t-el.exe | FileCheck -check-prefix=EXE_DIS_EL %s
16# RUN: llvm-readobj -relocations %t-el.exe | FileCheck -check-prefix=NORELOC %s
17# RUN: llvm-readobj -sections %t-el.exe | FileCheck -check-prefix=SHFLAGS %s
18
19# RUN: ld.lld -shared %t-be.o -o %t-be.so
20# RUN: llvm-objdump -section-headers -t %t-be.so | FileCheck -check-prefix=DSO_SYM %s
21# RUN: llvm-objdump -s -section=.got %t-be.so | FileCheck -check-prefix=DSO_GOT_BE %s
22# RUN: llvm-objdump -d %t-be.so | FileCheck -check-prefix=DSO_DIS_BE %s
23# RUN: llvm-readobj -relocations %t-be.so | FileCheck -check-prefix=NORELOC %s
24# RUN: llvm-readobj -sections %t-be.so | FileCheck -check-prefix=SHFLAGS %s
25
26# RUN: ld.lld -shared %t-el.o -o %t-el.so
27# RUN: llvm-objdump -section-headers -t %t-el.so | FileCheck -check-prefix=DSO_SYM %s
28# RUN: llvm-objdump -s -section=.got %t-el.so | FileCheck -check-prefix=DSO_GOT_EL %s
29# RUN: llvm-objdump -d %t-el.so | FileCheck -check-prefix=DSO_DIS_EL %s
30# RUN: llvm-readobj -relocations %t-el.so | FileCheck -check-prefix=NORELOC %s
31# RUN: llvm-readobj -sections %t-el.so | FileCheck -check-prefix=SHFLAGS %s
32
33# REQUIRES: mips
34
35 .text
36 .globl __start
37__start:
38 lui $2, %got(v1)
39
40 .data
41 .globl v1
42 .type v1,@object
43 .size v1,4
44v1:
45 .word 0
46
47# EXE_SYM: Sections:
48# EXE_SYM: .got 0000000c 0000000000030010 DATA
49# EXE_SYM: SYMBOL TABLE:
50# EXE_SYM: 00038000 *ABS* 00000000 .hidden _gp
51# ^-- .got + GP offset (0x7ff0)
52# EXE_SYM: 00030000 g .data 00000004 v1
53
54
55# EXE_GOT_BE: Contents of section .got:
56# EXE_GOT_BE: 30010 00000000 80000000 00030000
57# ^ ^ ^-- v1 (0x30000)
58# | +-- Module pointer (0x80000000)
59# +-- Lazy resolver (0x0)
60
61# EXE_GOT_EL: Contents of section .got:
62# EXE_GOT_EL: 30010 00000000 00000080 00000300
63# ^ ^ ^-- v1 (0x30000)
64# | +-- Module pointer (0x80000000)
65# +-- Lazy resolver (0x0)
66
67# v1GotAddr (0x3000c) - _gp (0x37ff4) = -0x7fe8 => 0x8018 = 32792
68# EXE_DIS_BE: 20000: 3c 02 80 18 lui $2, 32792
69# EXE_DIS_EL: 20000: 18 80 02 3c lui $2, 32792
70
71# DSO_SYM: Sections:
72# DSO_SYM: .got 0000000c 0000000000020010 DATA
73# DSO_SYM: SYMBOL TABLE:
74# DSO_SYM: 00028000 *ABS* 00000000 .hidden _gp
75# ^-- .got + GP offset (0x7ff0)
76# DSO_SYM: 00020000 g .data 00000004 v1
77
78# DSO_GOT_BE: Contents of section .got:
79# DSO_GOT_BE: 20010 00000000 80000000 00020000
80# ^ ^ ^-- v1 (0x20000)
81# | +-- Module pointer (0x80000000)
82# +-- Lazy resolver (0x0)
83
84# DSO_GOT_EL: Contents of section .got:
85# DSO_GOT_EL: 20010 00000000 00000080 00000200
86# ^ ^ ^-- v1 (0x20000)
87# | +-- Module pointer (0x80000000)
88# +-- Lazy resolver (0x0)
89
90# v1GotAddr (0x2000c) - _gp (0x27ff4) = -0x7fe8 => 0x8018 = 32792
91# DSO_DIS_BE: 10000: 3c 02 80 18 lui $2, 32792
92# DSO_DIS_EL: 10000: 18 80 02 3c lui $2, 32792
93
94# NORELOC: Relocations [
95# NORELOC-NEXT: ]
96
97# SHFLAGS: Name: .got
98# SHFLAGS-NEXT: Type: SHT_PROGBITS
99# SHFLAGS-NEXT: Flags [ (0x10000003)
100# ^-- SHF_MIPS_GPREL | SHF_ALLOC | SHF_WRITE
deps/lld/test/ELF/mips-got-string.s created+28
......@@ -0,0 +1,28 @@
1# Check R_MIPS_GOT16 relocation against merge section.
2
3# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux -o %t.o %s
4# RUN: ld.lld -shared -o %t.so %t.o
5# RUN: llvm-readobj -t -mips-plt-got %t.so | FileCheck %s
6
7# REQUIRES: mips
8
9# CHECK: Symbol {
10# CHECK: Name: $.str
11# CHECK-NEXT: Value: 0xF4
12# CHECK: }
13
14# CHECK: Local entries [
15# CHECK-NEXT: Entry {
16# CHECK-NEXT: Address:
17# CHECK-NEXT: Access: -32744
18# CHECK-NEXT: Initial: 0x0
19# CHECK: }
20# CHECK: ]
21
22 .text
23 lw $t9, %got($.str)($gp)
24 addiu $a0, $t9, %lo($.str)
25
26 .section .rodata.str,"aMS",@progbits,1
27$.str:
28 .asciz "foo"
deps/lld/test/ELF/mips-got-weak.s created+172
......@@ -0,0 +1,172 @@
1# Check R_MIPS_GOT16 relocation against weak symbols.
2
3# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
4# RUN: ld.lld %t.o -shared -o %t1.so
5# RUN: llvm-readobj -r -dt -dynamic-table -mips-plt-got %t1.so \
6# RUN: | FileCheck -check-prefix=NOSYM %s
7# RUN: ld.lld %t.o -shared -Bsymbolic -o %t2.so
8# RUN: llvm-readobj -r -dt -dynamic-table -mips-plt-got %t2.so \
9# RUN: | FileCheck -check-prefix=SYM %s
10
11# REQUIRES: mips
12
13# NOSYM: Relocations [
14# NOSYM-NEXT: ]
15
16# NOSYM: Symbol {
17# NOSYM: Name: foo
18# NOSYM-NEXT: Value: 0x20000
19# NOSYM-NEXT: Size: 0
20# NOSYM-NEXT: Binding: Weak
21# NOSYM-NEXT: Type: None
22# NOSYM-NEXT: Other: 0
23# NOSYM-NEXT: Section: .data
24# NOSYM-NEXT: }
25# NOSYM-NEXT: Symbol {
26# NOSYM-NEXT: Name: bar
27# NOSYM-NEXT: Value: 0x0
28# NOSYM-NEXT: Size: 0
29# NOSYM-NEXT: Binding: Weak
30# NOSYM-NEXT: Type: None
31# NOSYM-NEXT: Other: 0
32# NOSYM-NEXT: Section: Undefined
33# NOSYM-NEXT: }
34# NOSYM-NEXT: Symbol {
35# NOSYM-NEXT: Name: sym
36# NOSYM-NEXT: Value: 0x20004
37# NOSYM-NEXT: Size: 0
38# NOSYM-NEXT: Binding: Global
39# NOSYM-NEXT: Type: None
40# NOSYM-NEXT: Other: 0
41# NOSYM-NEXT: Section: .data
42# NOSYM-NEXT: }
43# NOSYM-NEXT: ]
44
45# NOSYM: 0x70000011 MIPS_SYMTABNO 4
46# NOSYM-NEXT: 0x7000000A MIPS_LOCAL_GOTNO 2
47# NOSYM-NEXT: 0x70000013 MIPS_GOTSYM 0x1
48
49# NOSYM: Primary GOT {
50# NOSYM-NEXT: Canonical gp value:
51# NOSYM-NEXT: Reserved entries [
52# NOSYM-NEXT: Entry {
53# NOSYM-NEXT: Address:
54# NOSYM-NEXT: Access: -32752
55# NOSYM-NEXT: Initial: 0x0
56# NOSYM-NEXT: Purpose: Lazy resolver
57# NOSYM-NEXT: }
58# NOSYM-NEXT: Entry {
59# NOSYM-NEXT: Address:
60# NOSYM-NEXT: Access: -32748
61# NOSYM-NEXT: Initial: 0x80000000
62# NOSYM-NEXT: Purpose: Module pointer (GNU extension)
63# NOSYM-NEXT: }
64# NOSYM-NEXT: ]
65# NOSYM-NEXT: Local entries [
66# NOSYM-NEXT: ]
67# NOSYM-NEXT: Global entries [
68# NOSYM-NEXT: Entry {
69# NOSYM-NEXT: Address:
70# NOSYM-NEXT: Access: -32744
71# NOSYM-NEXT: Initial: 0x20000
72# NOSYM-NEXT: Value: 0x20000
73# NOSYM-NEXT: Type: None
74# NOSYM-NEXT: Section: .data
75# NOSYM-NEXT: Name: foo
76# NOSYM-NEXT: }
77# NOSYM-NEXT: Entry {
78# NOSYM-NEXT: Address:
79# NOSYM-NEXT: Access: -32740
80# NOSYM-NEXT: Initial: 0x0
81# NOSYM-NEXT: Value: 0x0
82# NOSYM-NEXT: Type: None
83# NOSYM-NEXT: Section: Undefined
84# NOSYM-NEXT: Name: bar
85# NOSYM-NEXT: }
86# NOSYM-NEXT: Entry {
87# NOSYM-NEXT: Address:
88# NOSYM-NEXT: Access: -32736
89# NOSYM-NEXT: Initial: 0x20004
90# NOSYM-NEXT: Value: 0x20004
91# NOSYM-NEXT: Type: None
92# NOSYM-NEXT: Section: .data
93# NOSYM-NEXT: Name: sym
94# NOSYM-NEXT: }
95# NOSYM-NEXT: ]
96# NOSYM-NEXT: Number of TLS and multi-GOT entries: 0
97# NOSYM-NEXT: }
98
99# SYM: Relocations [
100# SYM-NEXT: ]
101
102# SYM: Symbol {
103# SYM: Name: bar
104# SYM-NEXT: Value: 0x0
105# SYM-NEXT: Size: 0
106# SYM-NEXT: Binding: Weak
107# SYM-NEXT: Type: None
108# SYM-NEXT: Other: 0
109# SYM-NEXT: Section: Undefined
110# SYM-NEXT: }
111# SYM-NEXT: ]
112
113# SYM: 0x70000011 MIPS_SYMTABNO 4
114# SYM-NEXT: 0x7000000A MIPS_LOCAL_GOTNO 4
115# SYM-NEXT: 0x70000013 MIPS_GOTSYM 0x3
116
117# SYM: Primary GOT {
118# SYM-NEXT: Canonical gp value:
119# SYM-NEXT: Reserved entries [
120# SYM-NEXT: Entry {
121# SYM-NEXT: Address:
122# SYM-NEXT: Access: -32752
123# SYM-NEXT: Initial: 0x0
124# SYM-NEXT: Purpose: Lazy resolver
125# SYM-NEXT: }
126# SYM-NEXT: Entry {
127# SYM-NEXT: Address:
128# SYM-NEXT: Access: -32748
129# SYM-NEXT: Initial: 0x80000000
130# SYM-NEXT: Purpose: Module pointer (GNU extension)
131# SYM-NEXT: }
132# SYM-NEXT: ]
133# SYM-NEXT: Local entries [
134# SYM-NEXT: Entry {
135# SYM-NEXT: Address:
136# SYM-NEXT: Access: -32744
137# SYM-NEXT: Initial: 0x20000
138# SYM-NEXT: }
139# SYM-NEXT: Entry {
140# SYM-NEXT: Address:
141# SYM-NEXT: Access: -32740
142# SYM-NEXT: Initial: 0x20004
143# SYM-NEXT: }
144# SYM-NEXT: ]
145# SYM-NEXT: Global entries [
146# SYM-NEXT: Entry {
147# SYM-NEXT: Address:
148# SYM-NEXT: Access: -32736
149# SYM-NEXT: Initial: 0x0
150# SYM-NEXT: Value: 0x0
151# SYM-NEXT: Type: None
152# SYM-NEXT: Section: Undefined
153# SYM-NEXT: Name: bar
154# SYM-NEXT: }
155# SYM-NEXT: ]
156# SYM-NEXT: Number of TLS and multi-GOT entries: 0
157# SYM-NEXT: }
158
159 .text
160 .global sym
161 .weak foo,bar
162func:
163 lw $t0,%got(foo)($gp)
164 lw $t0,%got(bar)($gp)
165 lw $t0,%got(sym)($gp)
166
167 .data
168 .weak foo
169foo:
170 .word 0
171sym:
172 .word 0
deps/lld/test/ELF/mips-got16-relocatable.s created+40
......@@ -0,0 +1,40 @@
1# Check writing updated addend for R_MIPS_GOT16 relocation,
2# when produce a relocatable output.
3
4# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux -o %t.o %s
5# RUN: ld.lld -r -o %t %t.o %t.o
6# RUN: llvm-objdump -d -r %t | FileCheck -check-prefix=OBJ %s
7# RUN: ld.lld -shared -o %t.so %t
8# RUN: llvm-objdump -d %t.so | FileCheck -check-prefix=SO %s
9
10# REQUIRES: mips
11
12# OBJ: Disassembly of section .text:
13# OBJ-NEXT: .text:
14# OBJ-NEXT: 0: 8f 99 00 00 lw $25, 0($gp)
15# OBJ-NEXT: 00000000: R_MIPS_GOT16 .data
16# OBJ-NEXT: 4: 27 24 00 00 addiu $4, $25, 0
17# OBJ-NEXT: 00000004: R_MIPS_LO16 .data
18# OBJ-NEXT: 8: ef ef ef ef <unknown>
19# OBJ-NEXT: c: ef ef ef ef <unknown>
20# OBJ-NEXT: 10: 8f 99 00 00 lw $25, 0($gp)
21# OBJ-NEXT: 00000010: R_MIPS_GOT16 .data
22# OBJ-NEXT: 14: 27 24 00 10 addiu $4, $25, 16
23# OBJ-NEXT: 00000014: R_MIPS_LO16 .data
24
25# SO: Disassembly of section .text:
26# SO-NEXT: .text:
27# SO-NEXT: 10000: 8f 99 80 18 lw $25, -32744($gp)
28# SO-NEXT: 10004: 27 24 00 00 addiu $4, $25, 0
29# SO-NEXT: 10008: ef ef ef ef <unknown>
30# SO-NEXT: 1000c: ef ef ef ef <unknown>
31# SO-NEXT: 10010: 8f 99 80 18 lw $25, -32744($gp)
32# SO-NEXT: 10014: 27 24 00 10 addiu $4, $25, 16
33
34 .text
35 lw $t9, %got(.data)($gp)
36 addiu $a0, $t9, %lo(.data)
37
38 .data
39data:
40 .word 0
deps/lld/test/ELF/mips-got16.s created+132
......@@ -0,0 +1,132 @@
1# Check R_MIPS_GOT16 relocation calculation.
2
3# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
4# RUN: ld.lld %t.o -shared -o %t.so
5# RUN: llvm-objdump -d -t %t.so | FileCheck %s
6# RUN: llvm-readobj -r -mips-plt-got %t.so | FileCheck -check-prefix=GOT %s
7
8# REQUIRES: mips
9
10# CHECK: Disassembly of section .text:
11# CHECK-NEXT: __start:
12# CHECK-NEXT: 10000: 8f 88 80 18 lw $8, -32744($gp)
13# CHECK-NEXT: 10004: 21 08 00 2c addi $8, $8, 44
14# CHECK-NEXT: 10008: 8f 88 80 24 lw $8, -32732($gp)
15# CHECK-NEXT: 1000c: 21 08 90 00 addi $8, $8, -28672
16# CHECK-NEXT: 10010: 8f 88 80 28 lw $8, -32728($gp)
17# CHECK-NEXT: 10014: 21 08 90 04 addi $8, $8, -28668
18# CHECK-NEXT: 10018: 8f 88 80 28 lw $8, -32728($gp)
19# CHECK-NEXT: 1001c: 21 08 10 04 addi $8, $8, 4100
20# CHECK-NEXT: 10020: 8f 88 80 30 lw $8, -32720($gp)
21# CHECK-NEXT: 10024: 21 08 10 08 addi $8, $8, 4104
22# CHECK-NEXT: 10028: 8f 88 80 34 lw $8, -32716($gp)
23#
24# CHECK: SYMBOL TABLE:
25# CHECK: 00041008 .data 00000000 .hidden bar
26# CHECK: 00000000 *UND* 00000000 foo
27
28# GOT: Relocations [
29# GOT-NEXT: ]
30
31# GOT: Primary GOT {
32# GOT-NEXT: Canonical gp value:
33# GOT-NEXT: Reserved entries [
34# GOT-NEXT: Entry {
35# GOT-NEXT: Address:
36# GOT-NEXT: Access: -32752
37# GOT-NEXT: Initial: 0x0
38# GOT-NEXT: Purpose: Lazy resolver
39# GOT-NEXT: }
40# GOT-NEXT: Entry {
41# GOT-NEXT: Address:
42# GOT-NEXT: Access: -32748
43# GOT-NEXT: Initial: 0x80000000
44# GOT-NEXT: Purpose: Module pointer (GNU extension)
45# GOT-NEXT: }
46# GOT-NEXT: ]
47# GOT-NEXT: Local entries [
48# GOT-NEXT: Entry {
49# GOT-NEXT: Address:
50# GOT-NEXT: Access: -32744
51# GOT-NEXT: Initial: 0x10000
52# ^-- (0x1002c + 0x8000) & ~0xffff
53# GOT-NEXT: }
54# GOT-NEXT: Entry {
55# GOT-NEXT: Address:
56# GOT-NEXT: Access: -32740
57# GOT-NEXT: Initial: 0x20000
58# ^-- redundant unused entry
59# GOT-NEXT: }
60# GOT-NEXT: Entry {
61# GOT-NEXT: Address:
62# GOT-NEXT: Access: -32736
63# GOT-NEXT: Initial: 0x20000
64# ^-- redundant unused entry
65# GOT-NEXT: }
66# GOT-NEXT: Entry {
67# GOT-NEXT: Address:
68# GOT-NEXT: Access: -32732
69# GOT-NEXT: Initial: 0x30000
70# ^-- (0x29000 + 0x8000) & ~0xffff
71# GOT-NEXT: }
72# GOT-NEXT: Entry {
73# GOT-NEXT: Address:
74# GOT-NEXT: Access: -32728
75# GOT-NEXT: Initial: 0x40000
76# ^-- (0x29000 + 0x10004 + 0x8000) & ~0xffff
77# ^-- (0x29000 + 0x18004 + 0x8000) & ~0xffff
78# GOT-NEXT: }
79# GOT-NEXT: Entry {
80# GOT-NEXT: Address:
81# GOT-NEXT: Access: -32724
82# GOT-NEXT: Initial: 0x50000
83# ^-- redundant unused entry
84# GOT-NEXT: }
85# GOT-NEXT: Entry {
86# GOT-NEXT: Address:
87# GOT-NEXT: Access: -32720
88# GOT-NEXT: Initial: 0x41008
89# ^-- 'bar' address
90# GOT-NEXT: }
91# GOT-NEXT: ]
92# GOT-NEXT: Global entries [
93# GOT-NEXT: Entry {
94# GOT-NEXT: Address:
95# GOT-NEXT: Access: -32716
96# GOT-NEXT: Initial: 0x0
97# GOT-NEXT: Value: 0x0
98# GOT-NEXT: Type: None
99# GOT-NEXT: Section: Undefined
100# GOT-NEXT: Name: foo@
101# GOT-NEXT: }
102# GOT-NEXT: ]
103# GOT-NEXT: Number of TLS and multi-GOT entries: 0
104# GOT-NEXT: }
105
106 .text
107 .globl __start
108__start:
109 lw $t0,%got($LC0)($gp)
110 addi $t0,$t0,%lo($LC0)
111 lw $t0,%got($LC1)($gp)
112 addi $t0,$t0,%lo($LC1)
113 lw $t0,%got($LC1+0x10004)($gp)
114 addi $t0,$t0,%lo($LC1+0x10004)
115 lw $t0,%got($LC1+0x18004)($gp)
116 addi $t0,$t0,%lo($LC1+0x18004)
117 lw $t0,%got(bar)($gp)
118 addi $t0,$t0,%lo(bar)
119 lw $t0,%got(foo)($gp)
120$LC0:
121 nop
122
123 .data
124 .space 0x9000
125$LC1:
126 .word 0
127 .space 0x18000
128 .word 0
129.global bar
130.hidden bar
131bar:
132 .word 0
deps/lld/test/ELF/mips-gp-disp.s created+37
......@@ -0,0 +1,37 @@
1# Check that even if _gp_disp symbol is defined in the shared library
2# we use our own value.
3
4# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
5# RUN: ld.lld -shared -o %t.so %t.o %S/Inputs/mips-gp-disp.so
6# RUN: llvm-readobj -symbols %t.so | FileCheck -check-prefix=INT-SO %s
7# RUN: llvm-readobj -symbols %S/Inputs/mips-gp-disp.so \
8# RUN: | FileCheck -check-prefix=EXT-SO %s
9# RUN: llvm-objdump -d -t %t.so | FileCheck -check-prefix=DIS %s
10# RUN: llvm-readobj -relocations %t.so | FileCheck -check-prefix=REL %s
11
12# REQUIRES: mips
13
14# INT-SO: Name: _gp_disp
15# INT-SO-NEXT: Value:
16# INT-SO-NEXT: Size:
17# INT-SO-NEXT: Binding: Local
18
19# EXT-SO: Name: _gp_disp
20# EXT-SO-NEXT: Value: 0x20000
21
22# DIS: Disassembly of section .text:
23# DIS-NEXT: __start:
24# DIS-NEXT: 10000: 3c 08 00 01 lui $8, 1
25# DIS-NEXT: 10004: 21 08 7f f0 addi $8, $8, 32752
26# ^-- 0x37ff0 & 0xffff
27# DIS: 00027ff0 *ABS* 00000000 .hidden _gp
28
29# REL: Relocations [
30# REL-NEXT: ]
31
32 .text
33 .globl __start
34__start:
35 lui $t0,%hi(_gp_disp)
36 addi $t0,$t0,%lo(_gp_disp)
37 lw $v0,%call16(_foo)($gp)
deps/lld/test/ELF/mips-gp-ext.s created+69
......@@ -0,0 +1,69 @@
1# Check that the linker use a value of _gp symbol defined
2# in a linker script to calculate GOT relocations.
3
4# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
5
6# RUN: echo "SECTIONS { \
7# RUN: .text : { *(.text) } \
8# RUN: _gp = ABSOLUTE(.) + 0x100; \
9# RUN: .got : { *(.got) } }" > %t.rel.script
10# RUN: ld.lld -shared -o %t.rel.so --script %t.rel.script %t.o
11# RUN: llvm-objdump -s -t %t.rel.so | FileCheck --check-prefix=REL %s
12
13# RUN: echo "SECTIONS { \
14# RUN: .text : { *(.text) } \
15# RUN: _gp = 0x200; \
16# RUN: .got : { *(.got) } }" > %t.abs.script
17# RUN: ld.lld -shared -o %t.abs.so --script %t.abs.script %t.o
18# RUN: llvm-objdump -s -t %t.abs.so | FileCheck --check-prefix=ABS %s
19
20# REQUIRES: mips
21
22# REL: Contents of section .text:
23# REL-NEXT: 0000 3c080000 2108010c 8f82fffc
24# ^-- %hi(_gp_disp)
25# ^-- %lo(_gp_disp)
26# ^-- 8 - (0x10c - 0x100)
27# G - (GP - .got)
28
29# REL: Contents of section .reginfo:
30# REL-NEXT: 0028 10000104 00000000 00000000 00000000
31# REL-NEXT: 0038 00000000 0000010c
32# ^-- _gp
33
34# REL: Contents of section .data:
35# REL-NEXT: 00f0 fffffef4
36# ^-- 0-0x10c
37
38# REL: 00000000 .text 00000000 foo
39# REL: 00000000 *ABS* 00000000 .hidden _gp_disp
40# REL: 0000010c *ABS* 00000000 .hidden _gp
41
42# ABS: Contents of section .text:
43# ABS-NEXT: 0000 3c080000 21080200 8f82ff08
44# ^-- %hi(_gp_disp)
45# ^-- %lo(_gp_disp)
46# ^-- 8 - (0x200 - 0x100)
47# G - (GP - .got)
48
49# ABS: Contents of section .reginfo:
50# ABS-NEXT: 0028 10000104 00000000 00000000 00000000
51# ABS-NEXT: 0038 00000000 00000200
52# ^-- _gp
53
54# ABS: Contents of section .data:
55# ABS-NEXT: 00f0 fffffe00
56# ^-- 0-0x200
57
58# ABS: 00000000 .text 00000000 foo
59# ABS: 00000000 *ABS* 00000000 .hidden _gp_disp
60# ABS: 00000200 *ABS* 00000000 .hidden _gp
61
62 .text
63foo:
64 lui $t0, %hi(_gp_disp)
65 addi $t0, $t0, %lo(_gp_disp)
66 lw $v0, %call16(bar)($gp)
67
68 .data
69 .gpword foo
deps/lld/test/ELF/mips-gp-local.s created+20
......@@ -0,0 +1,20 @@
1# Check handling of relocations against __gnu_local_gp symbol.
2
3# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
4# RUN: ld.lld -o %t.exe %t.o
5# RUN: llvm-objdump -d -t %t.exe | FileCheck %s
6
7# REQUIRES: mips
8
9# CHECK: Disassembly of section .text:
10# CHECK-NEXT: __start:
11# CHECK-NEXT: 20000: 3c 08 00 03 lui $8, 3
12# CHECK-NEXT: 20004: 21 08 7f f0 addi $8, $8, 32752
13
14# CHECK: 00037ff0 *ABS* 00000000 .hidden _gp
15
16 .text
17 .globl __start
18__start:
19 lui $t0,%hi(__gnu_local_gp)
20 addi $t0,$t0,%lo(__gnu_local_gp)
deps/lld/test/ELF/mips-gp-lowest.s created+44
......@@ -0,0 +1,44 @@
1# Check that default _gp value is calculated relative
2# to the GP-relative section with the lowest address.
3
4# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
5# RUN: echo "SECTIONS { \
6# RUN: .sdata : { *(.sdata) } \
7# RUN: .got : { *(.got) } }" > %t.rel.script
8# RUN: ld.lld %t.o --script %t.rel.script -shared -o %t.so
9# RUN: llvm-readobj -s -t %t.so | FileCheck %s
10
11# REQUIRES: mips
12
13 .text
14 .global foo
15foo:
16 lui $gp, %call16(foo)
17
18 .sdata
19 .word 0
20
21# CHECK: Section {
22# CHECK: Name: .sdata
23# CHECK-NEXT: Type: SHT_PROGBITS
24# CHECK-NEXT: Flags [
25# CHECK-NEXT: SHF_ALLOC
26# CHECK-NEXT: SHF_MIPS_GPREL
27# CHECK-NEXT: SHF_WRITE
28# CHECK-NEXT: ]
29# CHECK-NEXT: Address: 0xE0
30# CHECK: }
31# CHECK: Section {
32# CHECK: Name: .got
33# CHECK-NEXT: Type: SHT_PROGBITS
34# CHECK-NEXT: Flags [
35# CHECK-NEXT: SHF_ALLOC
36# CHECK-NEXT: SHF_MIPS_GPREL
37# CHECK-NEXT: SHF_WRITE
38# CHECK-NEXT: ]
39# CHECK-NEXT: Address: 0xF0
40# CHECK: }
41
42# CHECK: Name: _gp (5)
43# CHECK-NEXT: Value: 0x80D0
44# ^-- 0xE0 + 0x7ff0
deps/lld/test/ELF/mips-gprel-sec.s created+37
......@@ -0,0 +1,37 @@
1# Check order of gp-relative sections, i.e. sections with SHF_MIPS_GPREL flag.
2
3# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
4# RUN: ld.lld %t.o -shared -o %t.so
5# RUN: llvm-readobj -s %t.so | FileCheck %s
6
7# REQUIRES: mips
8
9 .text
10 nop
11
12 .sdata
13 .word 0
14
15# CHECK: Section {
16# CHECK: Name: .got
17# CHECK-NEXT: Type: SHT_PROGBITS
18# CHECK-NEXT: Flags [
19# CHECK-NEXT: SHF_ALLOC
20# CHECK-NEXT: SHF_MIPS_GPREL
21# CHECK-NEXT: SHF_WRITE
22# CHECK-NEXT: ]
23# CHECK-NEXT: Address: 0x20000
24# CHECK-NEXT: Offset: 0x20000
25# CHECK: }
26# CHECK: Section {
27# CHECK-NEXT: Index:
28# CHECK-NEXT: Name: .sdata
29# CHECK-NEXT: Type: SHT_PROGBITS
30# CHECK-NEXT: Flags [
31# CHECK-NEXT: SHF_ALLOC
32# CHECK-NEXT: SHF_MIPS_GPREL
33# CHECK-NEXT: SHF_WRITE
34# CHECK-NEXT: ]
35# CHECK-NEXT: Address: 0x20008
36# CHECK-NEXT: Offset: 0x20008
37# CHECK: }
deps/lld/test/ELF/mips-gprel32-relocs-gp0.s created+48
......@@ -0,0 +1,48 @@
1# Check that relocatable object produced by LLD has zero gp0 value.
2# Also check an error message if input object file has non-zero gp0 value
3# and the linker generates a relocatable object.
4# mips-gp0-non-zero.o is a relocatable object produced from the asm code
5# below and linked by GNU bfd linker.
6
7# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
8# RUN: ld.lld -r -o %t-rel.o %t.o
9# RUN: llvm-readobj -mips-reginfo %t-rel.o | FileCheck --check-prefix=REL %s
10
11# RUN: ld.lld -shared -o %t.so %S/Inputs/mips-gp0-non-zero.o
12# RUN: llvm-readobj -mips-reginfo %t.so | FileCheck --check-prefix=DSO %s
13# RUN: llvm-objdump -s -t %t.so | FileCheck --check-prefix=DUMP %s
14
15# RUN: not ld.lld -r -o %t-rel.o %S/Inputs/mips-gp0-non-zero.o 2>&1 \
16# RUN: | FileCheck --check-prefix=ERR %s
17
18# REQUIRES: mips
19
20# REL: GP: 0x0
21
22# DSO: GP: 0x27FF0
23
24# DUMP: Contents of section .rodata:
25# DUMP: 00f4 ffff0004 ffff0008
26# ^ 0x10004 + 0x7ff0 - 0x27ff0
27# ^ 0x10008 + 0x7ff0 - 0x27ff0
28
29# DUMP: SYMBOL TABLE:
30# DUMP: 00010008 .text 00000000 bar
31# DUMP: 00010004 .text 00000000 foo
32# DUMP: 00027ff0 *ABS* 00000000 .hidden _gp
33
34# ERR: error: {{.*}}mips-gp0-non-zero.o: unsupported non-zero ri_gp_value
35
36 .text
37 .global __start
38__start:
39 lw $t0,%call16(__start)($gp)
40foo:
41 nop
42bar:
43 nop
44
45 .section .rodata, "a"
46v:
47 .gpword foo
48 .gpword bar
deps/lld/test/ELF/mips-gprel32-relocs.s created+31
......@@ -0,0 +1,31 @@
1# Check R_MIPS_GPREL32 relocation calculation.
2
3# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
4# RUN: ld.lld -shared -o %t.so %t.o
5# RUN: llvm-objdump -s -section=.rodata -t %t.so | FileCheck %s
6
7# REQUIRES: mips
8
9 .text
10 .globl __start
11__start:
12 lw $t0,%call16(__start)($gp)
13foo:
14 nop
15bar:
16 nop
17
18 .section .rodata, "a"
19v1:
20 .gpword foo
21 .gpword bar
22
23# CHECK: Contents of section .rodata:
24# CHECK: 00f4 fffe8014 fffe8018
25# ^ 0x10004 - 0x27ff0
26# ^ 0x10008 - 0x27ff0
27
28# CHECK: SYMBOL TABLE:
29# CHECK: 00010008 .text 00000000 bar
30# CHECK: 00010004 .text 00000000 foo
31# CHECK: 00027ff0 *ABS* 00000000 .hidden _gp
deps/lld/test/ELF/mips-higher-highest.s created+21
......@@ -0,0 +1,21 @@
1# Check R_MIPS_HIGHER / R_MIPS_HIGHEST relocations calculation.
2
3# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t1.o
4# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \
5# RUN: %S/Inputs/mips-dynamic.s -o %t2.o
6# RUN: ld.lld %t1.o %t2.o -o %t.exe
7# RUN: llvm-objdump -d %t.exe | FileCheck %s
8
9# REQUIRES: mips
10
11 .global __start
12__start:
13 lui $6, %highest(_foo+0x300047FFF7FF7)
14 daddiu $6, $6, %higher(_foo+0x300047FFF7FF7)
15 lui $7, %highest(_foo+0x300047FFF7FF8)
16 ld $7, %higher (_foo+0x300047FFF7FF8)($7)
17
18# CHECK: 20000: 3c 06 00 03 lui $6, 3
19# CHECK-NEXT: 20004: 64 c6 00 05 daddiu $6, $6, 5
20# CHECK-NEXT: 20008: 3c 07 00 03 lui $7, 3
21# CHECK-NEXT: 2000c: dc e7 00 05 ld $7, 5($7)
deps/lld/test/ELF/mips-hilo-gp-disp.s created+55
......@@ -0,0 +1,55 @@
1# Check R_MIPS_HI16 / LO16 relocations calculation against _gp_disp.
2
3# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t1.o
4# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
5# RUN: %S/Inputs/mips-dynamic.s -o %t2.o
6# RUN: ld.lld %t1.o %t2.o -o %t.exe
7# RUN: llvm-objdump -d -t %t.exe | FileCheck -check-prefix=EXE %s
8# RUN: ld.lld %t1.o %t2.o -shared -o %t.so
9# RUN: llvm-objdump -d -t %t.so | FileCheck -check-prefix=SO %s
10
11# REQUIRES: mips
12
13 .text
14 .globl __start
15__start:
16 lui $t0,%hi(_gp_disp)
17 addi $t0,$t0,%lo(_gp_disp)
18 lw $v0,%call16(_foo)($gp)
19bar:
20 lui $t0,%hi(_gp_disp)
21 addi $t0,$t0,%lo(_gp_disp)
22
23# EXE: Disassembly of section .text:
24# EXE-NEXT: __start:
25# EXE-NEXT: 20000: 3c 08 00 02 lui $8, 2
26# ^-- %hi(0x47ff0-0x20000)
27# EXE-NEXT: 20004: 21 08 80 00 addi $8, $8, -32768
28# ^-- %lo(0x38000-0x20004+4)
29# EXE: bar:
30# EXE-NEXT: 2000c: 3c 08 00 01 lui $8, 1
31# ^-- %hi(0x38000-0x2000c)
32# EXE-NEXT: 20010: 21 08 7f f4 addi $8, $8, 32756
33# ^-- %lo(0x38000-0x20010+4)
34
35# EXE: SYMBOL TABLE:
36# EXE: 0002000c .text 00000000 bar
37# EXE: 00038000 *ABS* 00000000 .hidden _gp
38# EXE: 00020000 .text 00000000 __start
39
40# SO: Disassembly of section .text:
41# SO-NEXT: __start:
42# SO-NEXT: 10000: 3c 08 00 02 lui $8, 2
43# ^-- %hi(0x28000-0x10000)
44# SO-NEXT: 10004: 21 08 80 00 addi $8, $8, -32768
45# ^-- %lo(0x28000-0x10004+4)
46# SO: bar:
47# SO-NEXT: 1000c: 3c 08 00 01 lui $8, 1
48# ^-- %hi(0x28000-0x1000c)
49# SO-NEXT: 10010: 21 08 7f f4 addi $8, $8, 32756
50# ^-- %lo(0x28000-0x10010+4)
51
52# SO: SYMBOL TABLE:
53# SO: 0001000c .text 00000000 bar
54# SO: 00028000 *ABS* 00000000 .hidden _gp
55# SO: 00010000 .text 00000000 __start
deps/lld/test/ELF/mips-hilo-hi-only.s created+28
......@@ -0,0 +1,28 @@
1# Check warning on orphaned R_MIPS_HI16 relocations.
2
3# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
4# RUN: ld.lld %t.o -o %t.exe 2>&1 | FileCheck -check-prefix=WARN %s
5# RUN: llvm-objdump -d -t %t.exe | FileCheck %s
6
7# REQUIRES: mips
8
9 .text
10 .globl __start
11__start:
12 lui $t0,%hi(__start+0x10000)
13 addi $t0,$t0,%lo(_label)
14_label:
15 nop
16
17# WARN: can't find matching R_MIPS_LO16 relocation for R_MIPS_HI16
18
19# CHECK: Disassembly of section .text:
20# CHECK-NEXT: __start:
21# CHECK-NEXT: 20000: 3c 08 00 02 lui $8, 2
22# ^-- %hi(__start) w/o addend
23# CHECK-NEXT 20004: 21 08 00 08 addi $8, $8, 8
24# ^-- %lo(_label)
25
26# CHECK: SYMBOL TABLE:
27# CHECK: 00020008 .text 00000000 _label
28# CHECK: 00020000 .text 00000000 __start
deps/lld/test/ELF/mips-hilo.s created+53
......@@ -0,0 +1,53 @@
1# Check R_MIPS_HI16 / LO16 relocations calculation.
2
3# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
4# RUN: ld.lld %t.o -o %t.exe
5# RUN: llvm-objdump -d -t %t.exe | FileCheck %s
6
7# REQUIRES: mips
8
9 .text
10 .globl __start
11__start:
12 lui $t0,%hi(__start)
13 lui $t1,%hi(g1)
14 addi $t0,$t0,%lo(__start+4)
15 addi $t0,$t0,%lo(g1+8)
16
17 lui $t0,%hi(l1+0x10000)
18 lui $t1,%hi(l1+0x20000)
19 addi $t0,$t0,%lo(l1+(-4))
20
21 .data
22 .type l1,@object
23 .size l1,4
24l1:
25 .word 0
26
27 .globl g1
28 .type g1,@object
29 .size g1,4
30g1:
31 .word 0
32
33# CHECK: Disassembly of section .text:
34# CHECK-NEXT: __start:
35# CHECK-NEXT: 20000: 3c 08 00 02 lui $8, 2
36# ^-- %hi(__start+4)
37# CHECK-NEXT: 20004: 3c 09 00 03 lui $9, 3
38# ^-- %hi(g1+8)
39# CHECK-NEXT: 20008: 21 08 00 04 addi $8, $8, 4
40# ^-- %lo(__start+4)
41# CHECK-NEXT: 2000c: 21 08 00 0c addi $8, $8, 12
42# ^-- %lo(g1+8)
43# CHECK-NEXT: 20010: 3c 08 00 04 lui $8, 4
44# ^-- %hi(l1+0x10000-4)
45# CHECK-NEXT: 20014: 3c 09 00 05 lui $9, 5
46# ^-- %hi(l1+0x20000-4)
47# CHECK-NEXT: 20018: 21 08 ff fc addi $8, $8, -4
48# ^-- %lo(l1-4)
49
50# CHECK: SYMBOL TABLE:
51# CHECK: 0030000 l .data 00000004 l1
52# CHECK: 0020000 .text 00000000 __start
53# CHECK: 0030004 g .data 00000004 g1
deps/lld/test/ELF/mips-jalr.test created+52
......@@ -0,0 +1,52 @@
1# Check that lld ignores R_MIPS_JALR relocation for now.
2
3# RUN: yaml2obj %s -o %t.o
4# RUN: ld.lld %t.o -o %t.so -shared
5# RUN: llvm-objdump -d %t.so | FileCheck %s
6# RUN: llvm-readobj -relocations %t.so | FileCheck -check-prefix=REL %s
7
8# REQUIRES: mips
9
10# CHECK: 10000: 09 f8 20 03 jalr $25
11
12# REL: Relocations [
13# REL-NEXT: ]
14
15!ELF
16FileHeader:
17 Class: ELFCLASS32
18 Data: ELFDATA2LSB
19 Type: ET_REL
20 Machine: EM_MIPS
21 Flags: [EF_MIPS_PIC, EF_MIPS_CPIC, EF_MIPS_ABI_O32, EF_MIPS_ARCH_32]
22
23Sections:
24 - Name: .text
25 Type: SHT_PROGBITS
26 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
27 AddressAlign: 16
28 Content: "09f82003"
29# ^-- jalr T1
30
31 - Name: .rel.text
32 Type: SHT_REL
33 Link: .symtab
34 Info: .text
35 Relocations:
36 - Offset: 0
37 Symbol: T1
38 Type: R_MIPS_JALR
39
40Symbols:
41 Local:
42 - Name: T1
43 Type: STT_FUNC
44 Section: .text
45 Value: 0
46 Size: 4
47 Global:
48 - Name: __start
49 Type: STT_FUNC
50 Section: .text
51 Value: 0
52 Size: 4
deps/lld/test/ELF/mips-lo16-not-relative.s created+23
......@@ -0,0 +1,23 @@
1# Check that R_MIPS_LO16 relocation is handled as non-relative,
2# and if a target symbol is a DSO data symbol, LLD create a copy
3# relocation.
4
5# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
6# RUN: %S/Inputs/mips-dynamic.s -o %t.so.o
7# RUN: ld.lld %t.so.o -shared -o %t.so
8# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
9# RUN: ld.lld %t.o %t.so -o %t.exe
10# RUN: llvm-readobj -r %t.exe | FileCheck %s
11
12# REQUIRES: mips
13
14# CHECK: Relocations [
15# CHECK-NEXT: Section (7) .rel.dyn {
16# CHECK-NEXT: 0x{{[0-9A-F]+}} R_MIPS_COPY data0 0x0
17# CHECK-NEXT: }
18# CHECK-NEXT: ]
19
20 .text
21 .global __start
22__start:
23 addi $t0, $t0, %lo(data0)
deps/lld/test/ELF/mips-merge-abiflags.s created+63
......@@ -0,0 +1,63 @@
1# Test that lld handles input files with concatenated .MIPS.abiflags sections
2# This happens e.g. with the FreeBSD BFD (BFD 2.17.50 [FreeBSD] 2007-07-03)
3
4# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-freebsd %s -o %t.o
5# RUN: ld.lld %t.o %p/Inputs/mips-concatenated-abiflags.o -o %t.exe
6# RUN: llvm-readobj -sections -mips-abi-flags %t.exe | FileCheck %s
7# RUN: llvm-readobj -sections -mips-abi-flags \
8# RUN: %p/Inputs/mips-concatenated-abiflags.o | \
9# RUN: FileCheck --check-prefix=INPUT-OBJECT %s
10
11# REQUIRES: mips
12 .globl __start
13__start:
14 nop
15
16# CHECK: Section {
17# CHECK: Index: 1
18# CHECK-NEXT: Name: .MIPS.abiflags
19# CHECK-NEXT: Type: SHT_MIPS_ABIFLAGS
20# CHECK-NEXT: Flags [
21# CHECK-NEXT: SHF_ALLOC
22# CHECK-NEXT: ]
23# CHECK-NEXT: Address:
24# CHECK-NEXT: Offset:
25# CHECK-NEXT: Size: 24
26# CHECK-NEXT: Link: 0
27# CHECK-NEXT: Info: 0
28# CHECK-NEXT: AddressAlignment: 8
29# CHECK-NEXT: EntrySize: 24
30# CHECK-NEXT: }
31
32# CHECK: MIPS ABI Flags {
33# CHECK-NEXT: Version: 0
34# CHECK-NEXT: ISA: MIPS64
35# CHECK-NEXT: ISA Extension: None
36# CHECK-NEXT: ASEs [
37# CHECK-NEXT: ]
38# CHECK-NEXT: FP ABI: Hard float (double precision)
39# CHECK-NEXT: GPR size: 64
40# CHECK-NEXT: CPR1 size: 64
41# CHECK-NEXT: CPR2 size: 0
42# CHECK-NEXT: Flags 1 [
43# CHECK-NEXT: ODDSPREG
44# CHECK-NEXT: ]
45# CHECK-NEXT: Flags 2: 0x0
46# CHECK-NEXT: }
47
48# INPUT-OBJECT: Section {
49# INPUT-OBJECT: Index: 3
50# INPUT-OBJECT-NEXT: Name: .MIPS.abiflags
51# INPUT-OBJECT-NEXT: Type: SHT_MIPS_ABIFLAGS
52# INPUT-OBJECT-NEXT: Flags [
53# INPUT-OBJECT-NEXT: SHF_ALLOC
54# INPUT-OBJECT-NEXT: ]
55# INPUT-OBJECT-NEXT: Address:
56# INPUT-OBJECT-NEXT: Offset:
57# INPUT-OBJECT-NEXT: Size: 48
58# INPUT-OBJECT-NEXT: Link: 0
59# INPUT-OBJECT-NEXT: Info: 0
60# INPUT-OBJECT-NEXT: AddressAlignment: 8
61# INPUT-OBJECT-NEXT: EntrySize: 0
62# INPUT-OBJECT-NEXT: }
63# INPUT-OBJECT: The .MIPS.abiflags section has a wrong size.
deps/lld/test/ELF/mips-n32-emul.s created+14
......@@ -0,0 +1,14 @@
1# Check that LLD shows an error when N32 ABI emulation argument
2# is combined with non-N32 ABI object files.
3
4# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
5# RUN: not ld.lld -m elf32btsmipn32 %t.o -o %t.exe 2>&1 | FileCheck %s
6
7# REQUIRES: mips
8
9 .text
10 .global __start
11__start:
12 nop
13
14# CHECK: error: {{.*}}mips-n32-emul.s.tmp.o is incompatible with elf32btsmipn32
deps/lld/test/ELF/mips-n32-rels.s created+71
......@@ -0,0 +1,71 @@
1# Check handling of N32 ABI relocation records.
2
3# For now llvm-mc generates incorrect object files for N32 ABI.
4# We use the binary input file generated by GNU tool.
5# llvm-mc -filetype=obj -triple=mips64-unknown-linux \
6# -target-abi n32 %s -o %t.o
7# RUN: ld.lld %S/Inputs/mips-n32-rels.o -o %t.exe
8# RUN: llvm-objdump -t -d -s %t.exe | FileCheck %s
9# RUN: llvm-readobj -h %t.exe | FileCheck -check-prefix=ELF %s
10
11# REQUIRES: mips
12
13# .text
14# .type __start, @function
15# .global __start
16# __start:
17# lui $gp,%hi(%neg(%gp_rel(__start))) # R_MIPS_GPREL16
18# # R_MIPS_SUB
19# # R_MIPS_HI16
20# loc:
21# daddiu $gp,$gp,%lo(%neg(%gp_rel(__start))) # R_MIPS_GPREL16
22# # R_MIPS_SUB
23# # R_MIPS_LO16
24#
25# .section .rodata,"a",@progbits
26# .gpword(loc) # R_MIPS_32
27
28# CHECK: Disassembly of section .text:
29# CHECK-NEXT: __start:
30# CHECK-NEXT: 20000: 3c 1c 00 01 lui $gp, 1
31# ^-- 0x20000 - 0x37ff0
32# ^-- 0 - 0xfffe8010
33# ^-- %hi(0x17ff0)
34# CHECK: loc:
35# CHECK-NEXT: 20004: 67 9c 7f f0 daddiu $gp, $gp, 32752
36# ^-- 0x20000 - 0x37ff0
37# ^-- 0 - 0xfffe8010
38# ^-- %lo(0x17ff0)
39
40# CHECK: Contents of section .rodata:
41# CHECK-NEXT: 100d4 00020004
42# ^-- loc
43
44# CHECK: 00020004 .text 00000000 loc
45# CHECK: 00037ff0 *ABS* 00000000 .hidden _gp
46# CHECK: 00020000 g F .text 00000000 __start
47
48# ELF: Format: ELF32-mips
49# ELF-NEXT: Arch: mips
50# ELF-NEXT: AddressSize: 32bit
51# ELF-NEXT: LoadName:
52# ELF-NEXT: ElfHeader {
53# ELF-NEXT: Ident {
54# ELF-NEXT: Magic: (7F 45 4C 46)
55# ELF-NEXT: Class: 32-bit (0x1)
56# ELF-NEXT: DataEncoding: BigEndian (0x2)
57# ELF-NEXT: FileVersion: 1
58# ELF-NEXT: OS/ABI: SystemV (0x0)
59# ELF-NEXT: ABIVersion: 0
60# ELF-NEXT: Unused: (00 00 00 00 00 00 00)
61# ELF-NEXT: }
62# ELF-NEXT: Type: Executable (0x2)
63# ELF-NEXT: Machine: EM_MIPS (0x8)
64# ELF-NEXT: Version: 1
65# ELF-NEXT: Entry: 0x20000
66# ELF-NEXT: ProgramHeaderOffset:
67# ELF-NEXT: SectionHeaderOffset:
68# ELF-NEXT: Flags [
69# ELF-NEXT: EF_MIPS_ABI2
70# ELF-NEXT: EF_MIPS_ARCH_64R2
71# ELF-NEXT: ]
deps/lld/test/ELF/mips-no-objects.s created+5
......@@ -0,0 +1,5 @@
1# REQUIRES: mips
2# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
3# RUN: ld.lld %t.o -shared -o %t.so
4# RUN: ld.lld %t.so -shared -o %t2.so
5# RUN: llvm-readobj %t2.so > /dev/null 2>&1
deps/lld/test/ELF/mips-nonalloc.s created+21
......@@ -0,0 +1,21 @@
1# Check reading addends for relocations in non-allocatable sections.
2
3# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t1.o
4# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
5# RUN: %S/Inputs/mips-nonalloc.s -o %t2.o
6# RUN: ld.lld %t1.o %t2.o -o %t.exe
7# RUN: llvm-objdump -s %t.exe | FileCheck %s
8
9# REQUIRES: mips
10
11# CHECK: Contents of section .debug_info:
12# CHECK-NEXT: 0000 ffffffff 00020000 00020000
13# ^--------^-- __start
14
15 .global __start
16__start:
17 nop
18
19.section .debug_info
20 .word 0xffffffff
21 .word __start
deps/lld/test/ELF/mips-npic-call-pic-os.s created+138
......@@ -0,0 +1,138 @@
1# REQUIRES: mips
2# Check LA25 stubs creation with caller in different Output Section to callee.
3# This stub code is necessary when non-PIC code calls PIC function.
4
5# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
6# RUN: %p/Inputs/mips-fpic.s -o %t-fpic.o
7# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
8# RUN: %p/Inputs/mips-fnpic.s -o %t-fnpic.o
9# RUN: ld.lld -r %t-fpic.o %t-fnpic.o -o %t-sto-pic.o
10# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
11# RUN: %p/Inputs/mips-pic.s -o %t-pic.o
12# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-npic.o
13# RUN: ld.lld %t-npic.o %t-pic.o %t-sto-pic.o -o %t.exe
14# RUN: llvm-objdump -d %t.exe | FileCheck %s
15
16# CHECK: Disassembly of section .text:
17# CHECK-NEXT: __LA25Thunk_foo1a:
18# CHECK-NEXT: 20000: 3c 19 00 02 lui $25, 2
19# CHECK-NEXT: 20004: 08 00 80 08 j 131104 <foo1a>
20# CHECK-NEXT: 20008: 27 39 00 20 addiu $25, $25, 32
21# CHECK-NEXT: 2000c: 00 00 00 00 nop
22# CHECK: __LA25Thunk_foo1b:
23# CHECK-NEXT: 20010: 3c 19 00 02 lui $25, 2
24# CHECK-NEXT: 20014: 08 00 80 09 j 131108 <foo1b>
25# CHECK-NEXT: 20018: 27 39 00 24 addiu $25, $25, 36
26# CHECK-NEXT: 2001c: 00 00 00 00 nop
27# CHECK: foo1a:
28# CHECK-NEXT: 20020: 00 00 00 00 nop
29# CHECK: foo1b:
30# CHECK-NEXT: 20024: 00 00 00 00 nop
31# CHECK: __LA25Thunk_foo2:
32# CHECK-NEXT: 20028: 3c 19 00 02 lui $25, 2
33# CHECK-NEXT: 2002c: 08 00 80 10 j 131136 <foo2>
34# CHECK-NEXT: 20030: 27 39 00 40 addiu $25, $25, 64
35# CHECK-NEXT: 20034: 00 00 00 00 nop
36# CHECK-NEXT: 20038: ef ef ef ef <unknown>
37# CHECK-NEXT: 2003c: ef ef ef ef <unknown>
38# CHECK: foo2:
39# CHECK-NEXT: 20040: 00 00 00 00 nop
40# CHECK: __LA25Thunk_fpic:
41# CHECK-NEXT: 20044: 3c 19 00 02 lui $25, 2
42# CHECK-NEXT: 20048: 08 00 80 18 j 131168 <fpic>
43# CHECK-NEXT: 2004c: 27 39 00 60 addiu $25, $25, 96
44# CHECK-NEXT: 20050: 00 00 00 00 nop
45# CHECK-NEXT: 20054: ef ef ef ef <unknown>
46# CHECK-NEXT: 20058: ef ef ef ef <unknown>
47# CHECK-NEXT: 2005c: ef ef ef ef <unknown>
48# CHECK: fpic:
49# CHECK-NEXT: 20060: 00 00 00 00 nop
50# CHECK-NEXT: 20064: ef ef ef ef <unknown>
51# CHECK-NEXT: 20068: ef ef ef ef <unknown>
52# CHECK-NEXT: 2006c: ef ef ef ef <unknown>
53# CHECK: fnpic:
54# CHECK-NEXT: 20070: 00 00 00 00 nop
55# CHECK-NEXT: Disassembly of section differentos:
56# CHECK-NEXT: __start:
57# CHECK-NEXT: 20074: 0c 00 80 00 jal 131072 <__LA25Thunk_foo1a>
58# CHECK-NEXT: 20078: 00 00 00 00 nop
59# CHECK-NEXT: 2007c: 0c 00 80 0a jal 131112 <__LA25Thunk_foo2>
60# CHECK-NEXT: 20080: 00 00 00 00 nop
61# CHECK-NEXT: 20084: 0c 00 80 04 jal 131088 <__LA25Thunk_foo1b>
62# CHECK-NEXT: 20088: 00 00 00 00 nop
63# CHECK-NEXT: 2008c: 0c 00 80 0a jal 131112 <__LA25Thunk_foo2>
64# CHECK-NEXT: 20090: 00 00 00 00 nop
65# CHECK-NEXT: 20094: 0c 00 80 11 jal 131140 <__LA25Thunk_fpic>
66# CHECK-NEXT: 20098: 00 00 00 00 nop
67# CHECK-NEXT: 2009c: 0c 00 80 1c jal 131184 <fnpic>
68# CHECK-NEXT: 200a0: 00 00 00 00 nop
69
70# Make sure the thunks are created properly no matter how
71# objects are laid out.
72#
73# RUN: ld.lld %t-pic.o %t-npic.o %t-sto-pic.o -o %t.exe
74# RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=REVERSE %s
75
76# REVERSE: Disassembly of section .text:
77# REVERSE-NEXT: __LA25Thunk_foo1a:
78# REVERSE-NEXT: 20000: 3c 19 00 02 lui $25, 2
79# REVERSE-NEXT: 20004: 08 00 80 08 j 131104 <foo1a>
80# REVERSE-NEXT: 20008: 27 39 00 20 addiu $25, $25, 32
81# REVERSE-NEXT: 2000c: 00 00 00 00 nop
82# REVERSE: __LA25Thunk_foo1b:
83# REVERSE-NEXT: 20010: 3c 19 00 02 lui $25, 2
84# REVERSE-NEXT: 20014: 08 00 80 09 j 131108 <foo1b>
85# REVERSE-NEXT: 20018: 27 39 00 24 addiu $25, $25, 36
86# REVERSE-NEXT: 2001c: 00 00 00 00 nop
87# REVERSE: foo1a:
88# REVERSE-NEXT: 20020: 00 00 00 00 nop
89# REVERSE: foo1b:
90# REVERSE-NEXT: 20024: 00 00 00 00 nop
91# REVERSE: __LA25Thunk_foo2:
92# REVERSE-NEXT: 20028: 3c 19 00 02 lui $25, 2
93# REVERSE-NEXT: 2002c: 08 00 80 10 j 131136 <foo2>
94# REVERSE-NEXT: 20030: 27 39 00 40 addiu $25, $25, 64
95# REVERSE-NEXT: 20034: 00 00 00 00 nop
96# REVERSE-NEXT: 20038: ef ef ef ef <unknown>
97# REVERSE-NEXT: 2003c: ef ef ef ef <unknown>
98# REVERSE: foo2:
99# REVERSE-NEXT: 20040: 00 00 00 00 nop
100# REVERSE-NEXT: 20044: ef ef ef ef <unknown>
101# REVERSE-NEXT: 20048: ef ef ef ef <unknown>
102# REVERSE-NEXT: 2004c: ef ef ef ef <unknown>
103# REVERSE: __LA25Thunk_fpic:
104# REVERSE-NEXT: 20050: 3c 19 00 02 lui $25, 2
105# REVERSE-NEXT: 20054: 08 00 80 18 j 131168 <fpic>
106# REVERSE-NEXT: 20058: 27 39 00 60 addiu $25, $25, 96
107# REVERSE-NEXT: 2005c: 00 00 00 00 nop
108# REVERSE: fpic:
109# REVERSE-NEXT: 20060: 00 00 00 00 nop
110# REVERSE-NEXT: 20064: ef ef ef ef <unknown>
111# REVERSE-NEXT: 20068: ef ef ef ef <unknown>
112# REVERSE-NEXT: 2006c: ef ef ef ef <unknown>
113# REVERSE: fnpic:
114# REVERSE-NEXT: 20070: 00 00 00 00 nop
115# REVERSE-NEXT: Disassembly of section differentos:
116# REVERSE-NEXT: __start:
117# REVERSE-NEXT: 20074: 0c 00 80 00 jal 131072 <__LA25Thunk_foo1a>
118# REVERSE-NEXT: 20078: 00 00 00 00 nop
119# REVERSE-NEXT: 2007c: 0c 00 80 0a jal 131112 <__LA25Thunk_foo2>
120# REVERSE-NEXT: 20080: 00 00 00 00 nop
121# REVERSE-NEXT: 20084: 0c 00 80 04 jal 131088 <__LA25Thunk_foo1b>
122# REVERSE-NEXT: 20088: 00 00 00 00 nop
123# REVERSE-NEXT: 2008c: 0c 00 80 0a jal 131112 <__LA25Thunk_foo2>
124# REVERSE-NEXT: 20090: 00 00 00 00 nop
125# REVERSE-NEXT: 20094: 0c 00 80 14 jal 131152 <__LA25Thunk_fpic>
126# REVERSE-NEXT: 20098: 00 00 00 00 nop
127# REVERSE-NEXT: 2009c: 0c 00 80 1c jal 131184 <fnpic>
128# REVERSE-NEXT: 200a0: 00 00 00 00 nop
129
130 .section differentos, "ax", %progbits
131 .globl __start
132__start:
133 jal foo1a
134 jal foo2
135 jal foo1b
136 jal foo2
137 jal fpic
138 jal fnpic
deps/lld/test/ELF/mips-npic-call-pic-script.s created+255
......@@ -0,0 +1,255 @@
1# REQUIRES: mips
2# Check LA25 stubs creation. This stub code is necessary when
3# non-PIC code calls PIC function.
4# RUN: echo "SECTIONS { .out 0x20000 : { *(.text.*) . = . + 0x100 ; *(.text) } }" > %t1.script
5# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
6# RUN: %p/Inputs/mips-fpic.s -o %t-fpic.o
7# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
8# RUN: %p/Inputs/mips-fnpic.s -o %t-fnpic.o
9# RUN: ld.lld -r %t-fpic.o %t-fnpic.o -o %t-sto-pic.o
10# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
11# RUN: %p/Inputs/mips-pic.s -o %t-pic.o
12# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-npic.o
13# RUN: ld.lld --script %t1.script %t-npic.o %t-pic.o %t-sto-pic.o -o %t.exe
14# RUN: llvm-objdump -d %t.exe | FileCheck %s
15
16# CHECK: Disassembly of section .out:
17# CHECK-NEXT: __LA25Thunk_foo1a:
18# CHECK-NEXT: 20000: 3c 19 00 02 lui $25, 2
19# CHECK-NEXT: 20004: 08 00 80 08 j 131104 <foo1a>
20# CHECK-NEXT: 20008: 27 39 00 20 addiu $25, $25, 32
21# CHECK-NEXT: 2000c: 00 00 00 00 nop
22# CHECK: __LA25Thunk_foo1b:
23# CHECK-NEXT: 20010: 3c 19 00 02 lui $25, 2
24# CHECK-NEXT: 20014: 08 00 80 09 j 131108 <foo1b>
25# CHECK-NEXT: 20018: 27 39 00 24 addiu $25, $25, 36
26# CHECK-NEXT: 2001c: 00 00 00 00 nop
27# CHECK: foo1a:
28# CHECK-NEXT: 20020: 00 00 00 00 nop
29# CHECK: foo1b:
30# CHECK-NEXT: 20024: 00 00 00 00 nop
31# CHECK: __LA25Thunk_foo2:
32# CHECK-NEXT: 20028: 3c 19 00 02 lui $25, 2
33# CHECK-NEXT: 2002c: 08 00 80 10 j 131136 <foo2>
34# CHECK-NEXT: 20030: 27 39 00 40 addiu $25, $25, 64
35# CHECK-NEXT: 20034: 00 00 00 00 nop
36# CHECK-NEXT: 20038: ef ef ef ef <unknown>
37# CHECK-NEXT: 2003c: ef ef ef ef <unknown>
38# CHECK: foo2:
39# CHECK-NEXT: 20040: 00 00 00 00 nop
40# CHECK-NEXT: 20044: ef ef ef ef <unknown>
41# CHECK-NEXT: 20048: ef ef ef ef <unknown>
42# CHECK-NEXT: 2004c: ef ef ef ef <unknown>
43# CHECK-NEXT: 20050: ef ef ef ef <unknown>
44# CHECK-NEXT: 20054: ef ef ef ef <unknown>
45# CHECK-NEXT: 20058: ef ef ef ef <unknown>
46# CHECK-NEXT: 2005c: ef ef ef ef <unknown>
47# CHECK-NEXT: 20060: ef ef ef ef <unknown>
48# CHECK-NEXT: 20064: ef ef ef ef <unknown>
49# CHECK-NEXT: 20068: ef ef ef ef <unknown>
50# CHECK-NEXT: 2006c: ef ef ef ef <unknown>
51# CHECK-NEXT: 20070: ef ef ef ef <unknown>
52# CHECK-NEXT: 20074: ef ef ef ef <unknown>
53# CHECK-NEXT: 20078: ef ef ef ef <unknown>
54# CHECK-NEXT: 2007c: ef ef ef ef <unknown>
55# CHECK-NEXT: 20080: ef ef ef ef <unknown>
56# CHECK-NEXT: 20084: ef ef ef ef <unknown>
57# CHECK-NEXT: 20088: ef ef ef ef <unknown>
58# CHECK-NEXT: 2008c: ef ef ef ef <unknown>
59# CHECK-NEXT: 20090: ef ef ef ef <unknown>
60# CHECK-NEXT: 20094: ef ef ef ef <unknown>
61# CHECK-NEXT: 20098: ef ef ef ef <unknown>
62# CHECK-NEXT: 2009c: ef ef ef ef <unknown>
63# CHECK-NEXT: 200a0: ef ef ef ef <unknown>
64# CHECK-NEXT: 200a4: ef ef ef ef <unknown>
65# CHECK-NEXT: 200a8: ef ef ef ef <unknown>
66# CHECK-NEXT: 200ac: ef ef ef ef <unknown>
67# CHECK-NEXT: 200b0: ef ef ef ef <unknown>
68# CHECK-NEXT: 200b4: ef ef ef ef <unknown>
69# CHECK-NEXT: 200b8: ef ef ef ef <unknown>
70# CHECK-NEXT: 200bc: ef ef ef ef <unknown>
71# CHECK-NEXT: 200c0: ef ef ef ef <unknown>
72# CHECK-NEXT: 200c4: ef ef ef ef <unknown>
73# CHECK-NEXT: 200c8: ef ef ef ef <unknown>
74# CHECK-NEXT: 200cc: ef ef ef ef <unknown>
75# CHECK-NEXT: 200d0: ef ef ef ef <unknown>
76# CHECK-NEXT: 200d4: ef ef ef ef <unknown>
77# CHECK-NEXT: 200d8: ef ef ef ef <unknown>
78# CHECK-NEXT: 200dc: ef ef ef ef <unknown>
79# CHECK-NEXT: 200e0: ef ef ef ef <unknown>
80# CHECK-NEXT: 200e4: ef ef ef ef <unknown>
81# CHECK-NEXT: 200e8: ef ef ef ef <unknown>
82# CHECK-NEXT: 200ec: ef ef ef ef <unknown>
83# CHECK-NEXT: 200f0: ef ef ef ef <unknown>
84# CHECK-NEXT: 200f4: ef ef ef ef <unknown>
85# CHECK-NEXT: 200f8: ef ef ef ef <unknown>
86# CHECK-NEXT: 200fc: ef ef ef ef <unknown>
87# CHECK-NEXT: 20100: ef ef ef ef <unknown>
88# CHECK-NEXT: 20104: ef ef ef ef <unknown>
89# CHECK-NEXT: 20108: ef ef ef ef <unknown>
90# CHECK-NEXT: 2010c: ef ef ef ef <unknown>
91# CHECK-NEXT: 20110: ef ef ef ef <unknown>
92# CHECK-NEXT: 20114: ef ef ef ef <unknown>
93# CHECK-NEXT: 20118: ef ef ef ef <unknown>
94# CHECK-NEXT: 2011c: ef ef ef ef <unknown>
95# CHECK-NEXT: 20120: ef ef ef ef <unknown>
96# CHECK-NEXT: 20124: ef ef ef ef <unknown>
97# CHECK-NEXT: 20128: ef ef ef ef <unknown>
98# CHECK-NEXT: 2012c: ef ef ef ef <unknown>
99# CHECK-NEXT: 20130: ef ef ef ef <unknown>
100# CHECK-NEXT: 20134: ef ef ef ef <unknown>
101# CHECK-NEXT: 20138: ef ef ef ef <unknown>
102# CHECK-NEXT: 2013c: ef ef ef ef <unknown>
103# CHECK-NEXT: 20140: ef ef ef ef <unknown>
104# CHECK-NEXT: 20144: ef ef ef ef <unknown>
105# CHECK-NEXT: 20148: ef ef ef ef <unknown>
106# CHECK-NEXT: 2014c: ef ef ef ef <unknown>
107# CHECK: __start:
108# CHECK-NEXT: 20150: 0c 00 80 00 jal 131072 <__LA25Thunk_foo1a>
109# CHECK-NEXT: 20154: 00 00 00 00 nop
110# CHECK-NEXT: 20158: 0c 00 80 0a jal 131112 <__LA25Thunk_foo2>
111# CHECK-NEXT: 2015c: 00 00 00 00 nop
112# CHECK-NEXT: 20160: 0c 00 80 04 jal 131088 <__LA25Thunk_foo1b>
113# CHECK-NEXT: 20164: 00 00 00 00 nop
114# CHECK-NEXT: 20168: 0c 00 80 0a jal 131112 <__LA25Thunk_foo2>
115# CHECK-NEXT: 2016c: 00 00 00 00 nop
116# CHECK-NEXT: 20170: 0c 00 80 60 jal 131456 <__LA25Thunk_fpic>
117# CHECK-NEXT: 20174: 00 00 00 00 nop
118# CHECK-NEXT: 20178: 0c 00 80 68 jal 131488 <fnpic>
119# CHECK-NEXT: 2017c: 00 00 00 00 nop
120# CHECK: __LA25Thunk_fpic:
121# CHECK-NEXT: 20180: 3c 19 00 02 lui $25, 2
122# CHECK-NEXT: 20184: 08 00 80 64 j 131472 <fpic>
123# CHECK-NEXT: 20188: 27 39 01 90 addiu $25, $25, 400
124# CHECK-NEXT: 2018c: 00 00 00 00 nop
125# CHECK: fpic:
126# CHECK-NEXT: 20190: 00 00 00 00 nop
127# CHECK-NEXT: 20194: ef ef ef ef <unknown>
128# CHECK-NEXT: 20198: ef ef ef ef <unknown>
129# CHECK-NEXT: 2019c: ef ef ef ef <unknown>
130# CHECK: fnpic:
131# CHECK-NEXT: 201a0: 00 00 00 00 nop
132
133 .text
134 .globl __start
135__start:
136 jal foo1a
137 jal foo2
138 jal foo1b
139 jal foo2
140 jal fpic
141 jal fnpic
142
143# Test script with orphans added to existing OutputSection, the .text.1 and
144# .text.2 sections will be added to .text
145# RUN: echo "SECTIONS { .text 0x20000 : { *(.text) } }" > %t2.script
146# RUN: ld.lld --script %t2.script %t-npic.o %t-pic.o %t-sto-pic.o -o %t2.exe
147# RUN: llvm-objdump -d %t2.exe | FileCheck -check-prefix=ORPH1 %s
148# ORPH1: Disassembly of section .text:
149# ORPH1-NEXT: __start:
150# ORPH1-NEXT: 20000: 0c 00 80 15 jal 131156 <__LA25Thunk_foo1a>
151# ORPH1-NEXT: 20004: 00 00 00 00 nop
152# ORPH1-NEXT: 20008: 0c 00 80 22 jal 131208 <__LA25Thunk_foo2>
153# ORPH1-NEXT: 2000c: 00 00 00 00 nop
154# ORPH1-NEXT: 20010: 0c 00 80 19 jal 131172 <__LA25Thunk_foo1b>
155# ORPH1-NEXT: 20014: 00 00 00 00 nop
156# ORPH1-NEXT: 20018: 0c 00 80 22 jal 131208 <__LA25Thunk_foo2>
157# ORPH1-NEXT: 2001c: 00 00 00 00 nop
158# ORPH1-NEXT: 20020: 0c 00 80 0c jal 131120 <__LA25Thunk_fpic>
159# ORPH1-NEXT: 20024: 00 00 00 00 nop
160# ORPH1-NEXT: 20028: 0c 00 80 14 jal 131152 <fnpic>
161# ORPH1-NEXT: 2002c: 00 00 00 00 nop
162# ORPH1: __LA25Thunk_fpic:
163# ORPH1-NEXT: 20030: 3c 19 00 02 lui $25, 2
164# ORPH1-NEXT: 20034: 08 00 80 10 j 131136 <fpic>
165# ORPH1-NEXT: 20038: 27 39 00 40 addiu $25, $25, 64
166# ORPH1-NEXT: 2003c: 00 00 00 00 nop
167# ORPH1: fpic:
168# ORPH1-NEXT: 20040: 00 00 00 00 nop
169# ORPH1-NEXT: 20044: ef ef ef ef <unknown>
170# ORPH1-NEXT: 20048: ef ef ef ef <unknown>
171# ORPH1-NEXT: 2004c: ef ef ef ef <unknown>
172# ORPH1: fnpic:
173# ORPH1-NEXT: 20050: 00 00 00 00 nop
174# ORPH1: __LA25Thunk_foo1a:
175# ORPH1-NEXT: 20054: 3c 19 00 02 lui $25, 2
176# ORPH1-NEXT: 20058: 08 00 80 20 j 131200 <foo1a>
177# ORPH1-NEXT: 2005c: 27 39 00 80 addiu $25, $25, 128
178# ORPH1-NEXT: 20060: 00 00 00 00 nop
179# ORPH1: __LA25Thunk_foo1b:
180# ORPH1-NEXT: 20064: 3c 19 00 02 lui $25, 2
181# ORPH1-NEXT: 20068: 08 00 80 21 j 131204 <foo1b>
182# ORPH1-NEXT: 2006c: 27 39 00 84 addiu $25, $25, 132
183# ORPH1-NEXT: 20070: 00 00 00 00 nop
184# ORPH1-NEXT: 20074: ef ef ef ef <unknown>
185# ORPH1-NEXT: 20078: ef ef ef ef <unknown>
186# ORPH1-NEXT: 2007c: ef ef ef ef <unknown>
187# ORPH1: foo1a:
188# ORPH1-NEXT: 20080: 00 00 00 00 nop
189# ORPH1: foo1b:
190# ORPH1-NEXT: 20084: 00 00 00 00 nop
191# ORPH1: __LA25Thunk_foo2:
192# ORPH1-NEXT: 20088: 3c 19 00 02 lui $25, 2
193# ORPH1-NEXT: 2008c: 08 00 80 28 j 131232 <foo2>
194# ORPH1-NEXT: 20090: 27 39 00 a0 addiu $25, $25, 160
195# ORPH1-NEXT: 20094: 00 00 00 00 nop
196# ORPH1-NEXT: 20098: ef ef ef ef <unknown>
197# ORPH1-NEXT: 2009c: ef ef ef ef <unknown>
198# ORPH1: foo2:
199# ORPH1-NEXT: 200a0: 00 00 00 00 nop
200
201# Test script with orphans added to new OutputSection, the .text.1 and
202# .text.2 sections will form a new OutputSection .text
203# RUN: echo "SECTIONS { .out 0x20000 : { *(.text) } }" > %t3.script
204# RUN: ld.lld --script %t3.script %t-npic.o %t-pic.o %t-sto-pic.o -o %t3.exe
205# RUN: llvm-objdump -d %t3.exe | FileCheck -check-prefix=ORPH2 %s
206# ORPH2: Disassembly of section .out:
207# ORPH2-NEXT: __start:
208# ORPH2-NEXT: 20000: 0c 00 80 18 jal 131168 <__LA25Thunk_foo1a>
209# ORPH2-NEXT: 20004: 00 00 00 00 nop
210# ORPH2-NEXT: 20008: 0c 00 80 22 jal 131208 <__LA25Thunk_foo2>
211# ORPH2-NEXT: 2000c: 00 00 00 00 nop
212# ORPH2-NEXT: 20010: 0c 00 80 1c jal 131184 <__LA25Thunk_foo1b>
213# ORPH2-NEXT: 20014: 00 00 00 00 nop
214# ORPH2-NEXT: 20018: 0c 00 80 22 jal 131208 <__LA25Thunk_foo2>
215# ORPH2-NEXT: 2001c: 00 00 00 00 nop
216# ORPH2-NEXT: 20020: 0c 00 80 0c jal 131120 <__LA25Thunk_fpic>
217# ORPH2-NEXT: 20024: 00 00 00 00 nop
218# ORPH2-NEXT: 20028: 0c 00 80 14 jal 131152 <fnpic>
219# ORPH2-NEXT: 2002c: 00 00 00 00 nop
220# ORPH2: __LA25Thunk_fpic:
221# ORPH2-NEXT: 20030: 3c 19 00 02 lui $25, 2
222# ORPH2-NEXT: 20034: 08 00 80 10 j 131136 <fpic>
223# ORPH2-NEXT: 20038: 27 39 00 40 addiu $25, $25, 64
224# ORPH2-NEXT: 2003c: 00 00 00 00 nop
225# ORPH2: fpic:
226# ORPH2-NEXT: 20040: 00 00 00 00 nop
227# ORPH2-NEXT: 20044: ef ef ef ef <unknown>
228# ORPH2-NEXT: 20048: ef ef ef ef <unknown>
229# ORPH2-NEXT: 2004c: ef ef ef ef <unknown>
230# ORPH2: fnpic:
231# ORPH2-NEXT: 20050: 00 00 00 00 nop
232# ORPH2-NEXT: Disassembly of section .text:
233# ORPH2-NEXT: __LA25Thunk_foo1a:
234# ORPH2-NEXT: 20060: 3c 19 00 02 lui $25, 2
235# ORPH2-NEXT: 20064: 08 00 80 20 j 131200 <foo1a>
236# ORPH2-NEXT: 20068: 27 39 00 80 addiu $25, $25, 128
237# ORPH2-NEXT: 2006c: 00 00 00 00 nop
238# ORPH2: __LA25Thunk_foo1b:
239# ORPH2-NEXT: 20070: 3c 19 00 02 lui $25, 2
240# ORPH2-NEXT: 20074: 08 00 80 21 j 131204 <foo1b>
241# ORPH2-NEXT: 20078: 27 39 00 84 addiu $25, $25, 132
242# ORPH2-NEXT: 2007c: 00 00 00 00 nop
243# ORPH2: foo1a:
244# ORPH2-NEXT: 20080: 00 00 00 00 nop
245# ORPH2: foo1b:
246# ORPH2-NEXT: 20084: 00 00 00 00 nop
247# ORPH2: __LA25Thunk_foo2:
248# ORPH2-NEXT: 20088: 3c 19 00 02 lui $25, 2
249# ORPH2-NEXT: 2008c: 08 00 80 28 j 131232 <foo2>
250# ORPH2-NEXT: 20090: 27 39 00 a0 addiu $25, $25, 160
251# ORPH2-NEXT: 20094: 00 00 00 00 nop
252# ORPH2-NEXT: 20098: ef ef ef ef <unknown>
253# ORPH2-NEXT: 2009c: ef ef ef ef <unknown>
254# ORPH2: foo2:
255# ORPH2-NEXT: 200a0: 00 00 00 00 nop
deps/lld/test/ELF/mips-npic-call-pic.s created+145
......@@ -0,0 +1,145 @@
1# REQUIRES: mips
2# Check LA25 stubs creation. This stub code is necessary when
3# non-PIC code calls PIC function.
4
5# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
6# RUN: %p/Inputs/mips-fpic.s -o %t-fpic.o
7# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
8# RUN: %p/Inputs/mips-fnpic.s -o %t-fnpic.o
9# RUN: ld.lld -r %t-fpic.o %t-fnpic.o -o %t-sto-pic.o
10# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
11# RUN: %p/Inputs/mips-pic.s -o %t-pic.o
12# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-npic.o
13# RUN: ld.lld %t-npic.o %t-pic.o %t-sto-pic.o -o %t.exe
14# RUN: llvm-objdump -d %t.exe | FileCheck %s
15
16# CHECK: Disassembly of section .text:
17# CHECK-NEXT: __start:
18# CHECK-NEXT: 20000: 0c 00 80 0c jal 131120 <__LA25Thunk_foo1a>
19# CHECK-NEXT: 20004: 00 00 00 00 nop
20# CHECK-NEXT: 20008: 0c 00 80 16 jal 131160 <__LA25Thunk_foo2>
21# CHECK-NEXT: 2000c: 00 00 00 00 nop
22# CHECK-NEXT: 20010: 0c 00 80 10 jal 131136 <__LA25Thunk_foo1b>
23# CHECK-NEXT: 20014: 00 00 00 00 nop
24# CHECK-NEXT: 20018: 0c 00 80 16 jal 131160 <__LA25Thunk_foo2>
25# CHECK-NEXT: 2001c: 00 00 00 00 nop
26# CHECK-NEXT: 20020: 0c 00 80 1d jal 131188 <__LA25Thunk_fpic>
27# CHECK-NEXT: 20024: 00 00 00 00 nop
28# CHECK-NEXT: 20028: 0c 00 80 28 jal 131232 <fnpic>
29# CHECK-NEXT: 2002c: 00 00 00 00 nop
30#
31# CHECK: __LA25Thunk_foo1a:
32# CHECK-NEXT: 20030: 3c 19 00 02 lui $25, 2
33# CHECK-NEXT: 20034: 08 00 80 14 j 131152 <foo1a>
34# CHECK-NEXT: 20038: 27 39 00 50 addiu $25, $25, 80
35# CHECK-NEXT: 2003c: 00 00 00 00 nop
36
37# CHECK: __LA25Thunk_foo1b:
38# CHECK-NEXT: 20040: 3c 19 00 02 lui $25, 2
39# CHECK-NEXT: 20044: 08 00 80 15 j 131156 <foo1b>
40# CHECK-NEXT: 20048: 27 39 00 54 addiu $25, $25, 84
41# CHECK-NEXT: 2004c: 00 00 00 00 nop
42
43# CHECK: foo1a:
44# CHECK-NEXT: 20050: 00 00 00 00 nop
45
46# CHECK: foo1b:
47# CHECK-NEXT: 20054: 00 00 00 00 nop
48
49# CHECK: __LA25Thunk_foo2:
50# CHECK-NEXT: 20058: 3c 19 00 02 lui $25, 2
51# CHECK-NEXT: 2005c: 08 00 80 1c j 131184 <foo2>
52# CHECK-NEXT: 20060: 27 39 00 70 addiu $25, $25, 112
53# CHECK-NEXT: 20064: 00 00 00 00 nop
54# CHECK-NEXT: 20068: ef ef ef ef <unknown>
55# CHECK-NEXT: 2006c: ef ef ef ef <unknown>
56
57# CHECK: foo2:
58# CHECK-NEXT: 20070: 00 00 00 00 nop
59
60# CHECK: __LA25Thunk_fpic:
61# CHECK-NEXT: 20074: 3c 19 00 02 lui $25, 2
62# CHECK-NEXT: 20078: 08 00 80 24 j 131216 <fpic>
63# CHECK-NEXT: 2007c: 27 39 00 90 addiu $25, $25, 144
64# CHECK-NEXT: 20080: 00 00 00 00 nop
65# CHECK-NEXT: 20084: ef ef ef ef <unknown>
66# CHECK-NEXT: 20088: ef ef ef ef <unknown>
67# CHECK-NEXT: 2008c: ef ef ef ef <unknown>
68
69# CHECK: fpic:
70# CHECK-NEXT: 20090: 00 00 00 00 nop
71# CHECK-NEXT: 20094: ef ef ef ef <unknown>
72# CHECK-NEXT: 20098: ef ef ef ef <unknown>
73# CHECK-NEXT: 2009c: ef ef ef ef <unknown>
74
75# CHECK: fnpic:
76# CHECK-NEXT: 200a0: 00 00 00 00 nop
77
78# Make sure the thunks are created properly no matter how
79# objects are laid out.
80#
81# RUN: ld.lld %t-pic.o %t-npic.o %t-sto-pic.o -o %t.exe
82# RUN: llvm-objdump -d %t.exe | FileCheck -check-prefix=REVERSE %s
83
84# REVERSE: Disassembly of section .text:
85# REVERSE-NEXT: __LA25Thunk_foo1a:
86# REVERSE-NEXT: 20000: 3c 19 00 02 lui $25, 2
87# REVERSE-NEXT: 20004: 08 00 80 08 j 131104 <foo1a>
88# REVERSE-NEXT: 20008: 27 39 00 20 addiu $25, $25, 32
89# REVERSE-NEXT: 2000c: 00 00 00 00 nop
90# REVERSE: __LA25Thunk_foo1b:
91# REVERSE-NEXT: 20010: 3c 19 00 02 lui $25, 2
92# REVERSE-NEXT: 20014: 08 00 80 09 j 131108 <foo1b>
93# REVERSE-NEXT: 20018: 27 39 00 24 addiu $25, $25, 36
94# REVERSE-NEXT: 2001c: 00 00 00 00 nop
95# REVERSE: foo1a:
96# REVERSE-NEXT: 20020: 00 00 00 00 nop
97# REVERSE: foo1b:
98# REVERSE-NEXT: 20024: 00 00 00 00 nop
99# REVERSE: __LA25Thunk_foo2:
100# REVERSE-NEXT: 20028: 3c 19 00 02 lui $25, 2
101# REVERSE-NEXT: 2002c: 08 00 80 10 j 131136 <foo2>
102# REVERSE-NEXT: 20030: 27 39 00 40 addiu $25, $25, 64
103# REVERSE-NEXT: 20034: 00 00 00 00 nop
104# REVERSE-NEXT: 20038: ef ef ef ef <unknown>
105# REVERSE-NEXT: 2003c: ef ef ef ef <unknown>
106# REVERSE: foo2:
107# REVERSE-NEXT: 20040: 00 00 00 00 nop
108# REVERSE-NEXT: 20044: ef ef ef ef <unknown>
109# REVERSE-NEXT: 20048: ef ef ef ef <unknown>
110# REVERSE-NEXT: 2004c: ef ef ef ef <unknown>
111# REVERSE: __start:
112# REVERSE-NEXT: 20050: 0c 00 80 00 jal 131072 <__LA25Thunk_foo1a>
113# REVERSE-NEXT: 20054: 00 00 00 00 nop
114# REVERSE-NEXT: 20058: 0c 00 80 0a jal 131112 <__LA25Thunk_foo2>
115# REVERSE-NEXT: 2005c: 00 00 00 00 nop
116# REVERSE-NEXT: 20060: 0c 00 80 04 jal 131088 <__LA25Thunk_foo1b>
117# REVERSE-NEXT: 20064: 00 00 00 00 nop
118# REVERSE-NEXT: 20068: 0c 00 80 0a jal 131112 <__LA25Thunk_foo2>
119# REVERSE-NEXT: 2006c: 00 00 00 00 nop
120# REVERSE-NEXT: 20070: 0c 00 80 20 jal 131200 <__LA25Thunk_fpic>
121# REVERSE-NEXT: 20074: 00 00 00 00 nop
122# REVERSE-NEXT: 20078: 0c 00 80 28 jal 131232 <fnpic>
123# REVERSE-NEXT: 2007c: 00 00 00 00 nop
124# REVERSE: __LA25Thunk_fpic:
125# REVERSE-NEXT: 20080: 3c 19 00 02 lui $25, 2
126# REVERSE-NEXT: 20084: 08 00 80 24 j 131216 <fpic>
127# REVERSE-NEXT: 20088: 27 39 00 90 addiu $25, $25, 144
128# REVERSE-NEXT: 2008c: 00 00 00 00 nop
129# REVERSE: fpic:
130# REVERSE-NEXT: 20090: 00 00 00 00 nop
131# REVERSE-NEXT: 20094: ef ef ef ef <unknown>
132# REVERSE-NEXT: 20098: ef ef ef ef <unknown>
133# REVERSE-NEXT: 2009c: ef ef ef ef <unknown>
134# REVERSE: fnpic:
135# REVERSE-NEXT: 200a0: 00 00 00 00 nop
136
137 .text
138 .globl __start
139__start:
140 jal foo1a
141 jal foo2
142 jal foo1b
143 jal foo2
144 jal fpic
145 jal fnpic
deps/lld/test/ELF/mips-options-r.test created+18
......@@ -0,0 +1,18 @@
1# Check that if input file contains .MIPS.options section and symbol
2# points to the section and the linker generates a relocatable output,
3# LLD does not crash.
4#
5# PR 27878
6#
7# Input object file created using the following script:
8# % cat t.s
9# .text
10# nop
11# % as -mabi=64 -mips64r2 t.s
12
13# RUN: ld.lld -r %p/Inputs/mips-options.o -o %t.o
14# RUN: llvm-readobj -s %t.o | FileCheck %s
15
16# REQUIRES: mips
17
18# CHECK: Name: .MIPS.options
deps/lld/test/ELF/mips-options.s created+31
......@@ -0,0 +1,31 @@
1# Check MIPS .MIPS.options section generation.
2
3# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t1.o
4# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \
5# RUN: %S/Inputs/mips-dynamic.s -o %t2.o
6# RUN: echo "SECTIONS { \
7# RUN: . = 0x100000000; \
8# RUN: .got : { *(.got) } }" > %t.rel.script
9# RUN: ld.lld %t1.o %t2.o --gc-sections --script %t.rel.script -shared -o %t.so
10# RUN: llvm-readobj -symbols -mips-options %t.so | FileCheck %s
11
12# REQUIRES: mips
13
14 .text
15 .globl __start
16__start:
17 lui $gp, %hi(%neg(%gp_rel(g1)))
18
19# CHECK: Name: _gp
20# CHECK-NEXT: Value: 0x[[GP:[0-9A-F]+]]
21
22# CHECK: MIPS Options {
23# CHECK-NEXT: ODK_REGINFO {
24# CHECK-NEXT: GP: 0x[[GP]]
25# CHECK-NEXT: General Mask: 0x10000001
26# CHECK-NEXT: Co-Proc Mask0: 0x0
27# CHECK-NEXT: Co-Proc Mask1: 0x0
28# CHECK-NEXT: Co-Proc Mask2: 0x0
29# CHECK-NEXT: Co-Proc Mask3: 0x0
30# CHECK-NEXT: }
31# CHECK-NEXT: }
deps/lld/test/ELF/mips-pc-relocs.s created+45
......@@ -0,0 +1,45 @@
1# Check R_MIPS_PCxxx relocations calculation.
2
3# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
4# RUN: -mcpu=mips32r6 %s -o %t1.o
5# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
6# RUN: -mcpu=mips32r6 %S/Inputs/mips-dynamic.s -o %t2.o
7# RUN: ld.lld %t1.o %t2.o -o %t.exe
8# RUN: llvm-objdump -mcpu=mips32r6 -d -t -s %t.exe | FileCheck %s
9
10# REQUIRES: mips
11
12 .text
13 .globl __start
14__start:
15 lwpc $6, _foo # R_MIPS_PC19_S2
16 beqc $5, $6, _foo # R_MIPS_PC16
17 beqzc $9, _foo # R_MIPS_PC21_S2
18 bc _foo # R_MIPS_PC26_S2
19 aluipc $2, %pcrel_hi(_foo) # R_MIPS_PCHI16
20 addiu $2, $2, %pcrel_lo(_foo) # R_MIPS_PCLO16
21
22 .data
23 .word _foo+8-. # R_MIPS_PC32
24
25# CHECK: Disassembly of section .text:
26# CHECK-NEXT: __start:
27# CHECK-NEXT: 20000: ec c8 00 08 lwpc $6, 32
28# ^-- (0x20020-0x20000)>>2
29# CHECK-NEXT: 20004: 20 a6 00 06 beqc $5, $6, 28
30# ^-- (0x20020-4-0x20004)>>2
31# CHECK-NEXT: 20008: d9 20 00 05 beqzc $9, 24
32# ^-- (0x20020-4-0x20008)>>2
33# CHECK-NEXT: 2000c: c8 00 00 04 bc 20
34# ^-- (0x20020-4-0x2000c)>>2
35# CHECK-NEXT: 20010: ec 5f 00 00 aluipc $2, 0
36# ^-- %hi(0x20020-0x20010)
37# CHECK-NEXT: 20014: 24 42 00 0c addiu $2, $2, 12
38# ^-- %lo(0x20020-0x20014)
39
40# CHECK: Contents of section .data:
41# CHECK-NEXT: 30000 ffff0028 00000000 00000000 00000000
42# ^-- 0x20020 + 8 - 0x30000
43
44# CHECK: 00020000 .text 00000000 __start
45# CHECK: 00020020 .text 00000000 _foo
deps/lld/test/ELF/mips-plt-copy.s created+85
......@@ -0,0 +1,85 @@
1# Check creating of R_MIPS_COPY and R_MIPS_JUMP_SLOT dynamic relocations
2# and corresponding PLT entries.
3
4# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
5# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
6# RUN: %S/Inputs/mips-dynamic.s -o %t.so.o
7# RUN: ld.lld %t.so.o -shared -o %t.so
8# RUN: ld.lld %t.o %t.so -o %t.exe
9# RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck %s
10
11# REQUIRES: mips
12
13# CHECK: Relocations [
14# CHECK-NEXT: Section ({{.*}}) .rel.dyn {
15# CHECK-NEXT: 0x{{[0-9A-F]+}} R_MIPS_COPY data0 0x0
16# CHECK-NEXT: 0x{{[0-9A-F]+}} R_MIPS_COPY data1 0x0
17# CHECK-NEXT: }
18# CHECK-NEXT: Section ({{.*}}) .rel.plt {
19# CHECK-NEXT: 0x{{[0-9A-F]+}} R_MIPS_JUMP_SLOT foo0 0x0
20# CHECK-NEXT: 0x{{[0-9A-F]+}} R_MIPS_JUMP_SLOT foo1 0x0
21# CHECK-NEXT: }
22# CHECK-NEXT: ]
23
24# CHECK: Primary GOT {
25# CHECK: Local entries [
26# CHECK-NEXT: ]
27# CHECK-NEXT: Global entries [
28# CHECK-NEXT: ]
29# CHECK-NEXT: Number of TLS and multi-GOT entries: 0
30# CHECK-NEXT: }
31
32# CHECK: PLT GOT {
33# CHECK: Entries [
34# CHECK-NEXT: Entry {
35# CHECK-NEXT: Address: 0x{{[0-9A-F]+}}
36# CHECK-NEXT: Initial: 0x{{[0-9A-F]+}}
37# CHECK-NEXT: Value: 0x{{[0-9A-F]+}}
38# CHECK-NEXT: Type: Function
39# CHECK-NEXT: Section: Undefined
40# CHECK-NEXT: Name: foo0
41# CHECK-NEXT: }
42# CHECK-NEXT: Entry {
43# CHECK-NEXT: Address: 0x{{[0-9A-F]+}}
44# CHECK-NEXT: Initial: 0x{{[0-9A-F]+}}
45# CHECK-NEXT: Value: 0x{{[0-9A-F]+}}
46# CHECK-NEXT: Type: Function
47# CHECK-NEXT: Section: Undefined
48# CHECK-NEXT: Name: foo1
49# CHECK-NEXT: }
50# CHECK-NEXT: ]
51# CHECK-NEXT: }
52
53 .text
54 .globl __start
55__start:
56 lui $t0,%hi(foo0) # R_MIPS_HI16 requires JUMP_SLOT/PLT entry
57 # for DSO defined func.
58 addi $t0,$t0,%lo(foo0)
59 lui $t0,%hi(bar) # Does not require PLT for locally defined func.
60 addi $t0,$t0,%lo(bar)
61 lui $t0,%hi(loc) # Does not require PLT for local func.
62 addi $t0,$t0,%lo(loc)
63
64 lui $t0,%hi(data0) # R_MIPS_HI16 requires COPY rel for DSO defined data.
65 addi $t0,$t0,%lo(data0)
66 lui $t0,%hi(gd) # Does not require COPY rel for locally defined data.
67 addi $t0,$t0,%lo(gd)
68 lui $t0,%hi(ld) # Does not require COPY rel for local data.
69 addi $t0,$t0,%lo(ld)
70
71 .globl bar
72 .type bar, @function
73bar:
74 nop
75loc:
76 nop
77
78 .rodata
79 .globl gd
80gd:
81 .word 0
82ld:
83 .word data1+8 # R_MIPS_32 requires REL32 dnamic relocation
84 # for DSO defined data. For now we generate COPY one.
85 .word foo1+8 # R_MIPS_32 requires PLT entry for DSO defined func.
deps/lld/test/ELF/mips-plt-r6.s created+38
......@@ -0,0 +1,38 @@
1# Check PLT entries generation in case of R6 ABI version.
2
3# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
4# RUN: -mcpu=mips32r6 %s -o %t1.o
5# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
6# RUN: -mcpu=mips32r6 %S/Inputs/mips-dynamic.s -o %t2.o
7# RUN: ld.lld %t2.o -shared -o %t.so
8# RUN: ld.lld %t1.o %t.so -o %t.exe
9# RUN: llvm-objdump -d %t.exe | FileCheck %s
10
11# REQUIRES: mips
12
13# CHECK: Disassembly of section .text:
14# CHECK-NEXT: __start:
15# CHECK-NEXT: 20000: 0c 00 80 0c jal 131120
16# ^-- 0x20030 gotplt[foo0]
17# CHECK-NEXT: 20004: 00 00 00 00 nop
18#
19# CHECK-NEXT: Disassembly of section .plt:
20# CHECK-NEXT: .plt:
21# CHECK-NEXT: 20010: 3c 1c 00 03 aui $gp, $zero, 3
22# CHECK-NEXT: 20014: 8f 99 00 04 lw $25, 4($gp)
23# CHECK-NEXT: 20018: 27 9c 00 04 addiu $gp, $gp, 4
24# CHECK-NEXT: 2001c: 03 1c c0 23 subu $24, $24, $gp
25# CHECK-NEXT: 20020: 03 e0 78 25 move $15, $ra
26# CHECK-NEXT: 20024: 00 18 c0 82 srl $24, $24, 2
27# CHECK-NEXT: 20028: 03 20 f8 09 jalr $25
28# CHECK-NEXT: 2002c: 27 18 ff fe addiu $24, $24, -2
29
30# CHECK-NEXT: 20030: 3c 0f 00 03 aui $15, $zero, 3
31# CHECK-NEXT: 20034: 8d f9 00 0c lw $25, 12($15)
32# CHECK-NEXT: 20038: 03 20 00 09 jr $25
33# CHECK-NEXT: 2003c: 25 f8 00 0c addiu $24, $15, 12
34
35 .text
36 .global __start
37__start:
38 jal foo0 # R_MIPS_26 against 'foo0' from DSO
deps/lld/test/ELF/mips-reginfo.s created+26
......@@ -0,0 +1,26 @@
1# Check MIPS .reginfo section generation.
2
3# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t1.o
4# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
5# RUN: %S/Inputs/mips-dynamic.s -o %t2.o
6# RUN: ld.lld %t1.o %t2.o --gc-sections -shared -o %t.so
7# RUN: llvm-readobj -symbols -mips-reginfo %t.so | FileCheck %s
8
9# REQUIRES: mips
10
11 .text
12 .globl __start
13__start:
14 lw $t0,%call16(g1)($gp)
15
16# CHECK: Name: _gp
17# CHECK-NEXT: Value: 0x[[GP:[0-9A-F]+]]
18
19# CHECK: MIPS RegInfo {
20# CHECK-NEXT: GP: 0x[[GP]]
21# CHECK-NEXT: General Mask: 0x10000101
22# CHECK-NEXT: Co-Proc Mask0: 0x0
23# CHECK-NEXT: Co-Proc Mask1: 0x0
24# CHECK-NEXT: Co-Proc Mask2: 0x0
25# CHECK-NEXT: Co-Proc Mask3: 0x0
26# CHECK-NEXT: }
deps/lld/test/ELF/mips-relocatable.s created+21
......@@ -0,0 +1,21 @@
1# Check linking MIPS code in case of -r linker's option.
2
3# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
4# RUN: ld.lld -r -o %t-r.o %t.o
5# RUN: llvm-objdump -s -t %t-r.o | FileCheck %s
6
7# REQUIRES: mips
8
9 .text
10 .global __start
11__start:
12 lw $t0,%call16(__start)($gp)
13foo:
14 nop
15
16 .section .rodata, "a"
17v:
18 .gpword foo
19
20# CHECK-NOT: Contents of section .got:
21# CHECK-NOT: {{.*}} _gp
deps/lld/test/ELF/mips-sto-pic-flag.s created+58
......@@ -0,0 +1,58 @@
1# In case of linking PIC and non-PIC code together and generation
2# of a relocatable object, all PIC symbols should have STO_MIPS_PIC
3# flag in the symbol table of the ouput file.
4
5# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t-npic.o
6# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
7# RUN: %p/Inputs/mips-pic.s -o %t-pic.o
8# RUN: ld.lld -r %t-npic.o %t-pic.o -o %t-rel.o
9# RUN: llvm-readobj -t %t-rel.o | FileCheck %s
10
11# REQUIRES: mips
12
13# CHECK: Symbol {
14# CHECK: Name: main
15# CHECK-NEXT: Value:
16# CHECK-NEXT: Size:
17# CHECK-NEXT: Binding: Local
18# CHECK-NEXT: Type: None
19# CHECK-NEXT: Other: 0
20# CHECK-NEXT: Section: .text
21# CHECK-NEXT: }
22# CHECK: Symbol {
23# CHECK: Name: foo1a
24# CHECK-NEXT: Value:
25# CHECK-NEXT: Size:
26# CHECK-NEXT: Binding: Global
27# CHECK-NEXT: Type: Function
28# CHECK-NEXT: Other [
29# CHECK-NEXT: STO_MIPS_PIC
30# CHECK-NEXT: ]
31# CHECK-NEXT: Section: .text
32# CHECK-NEXT: }
33# CHECK-NEXT: Symbol {
34# CHECK-NEXT: Name: foo1b
35# CHECK-NEXT: Value:
36# CHECK-NEXT: Size:
37# CHECK-NEXT: Binding: Global
38# CHECK-NEXT: Type: Function
39# CHECK-NEXT: Other [
40# CHECK-NEXT: STO_MIPS_PIC
41# CHECK-NEXT: ]
42# CHECK-NEXT: Section: .text
43# CHECK-NEXT: }
44# CHECK-NEXT: Symbol {
45# CHECK-NEXT: Name: foo2
46# CHECK-NEXT: Value:
47# CHECK-NEXT: Size:
48# CHECK-NEXT: Binding: Global
49# CHECK-NEXT: Type: Function
50# CHECK-NEXT: Other [
51# CHECK-NEXT: STO_MIPS_PIC
52# CHECK-NEXT: ]
53# CHECK-NEXT: Section: .text
54# CHECK-NEXT: }
55
56 .text
57main:
58 nop
deps/lld/test/ELF/mips-sto-plt.s created+66
......@@ -0,0 +1,66 @@
1# Check assigning STO_MIPS_PLT flag to symbol needs a pointer equality.
2
3# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
4# RUN: %S/Inputs/mips-dynamic.s -o %t.so.o
5# RUN: ld.lld %t.so.o -shared -o %t.so
6# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
7# RUN: ld.lld %t.o %t.so -o %t.exe
8# RUN: llvm-readobj -dt -mips-plt-got %t.exe | FileCheck %s
9
10# REQUIRES: mips
11
12# CHECK: Symbol {
13# CHECK: Name: foo0@
14# CHECK-NEXT: Value: 0x0
15# CHECK-NEXT: Size: 0
16# CHECK-NEXT: Binding: Global
17# CHECK-NEXT: Type: Function
18# CHECK-NEXT: Other: 0
19# CHECK-NEXT: Section: Undefined
20# CHECK-NEXT: }
21# CHECK: Symbol {
22# CHECK: Name: foo1@
23# CHECK-NEXT: Value: 0x20050
24# CHECK-NEXT: Size: 0
25# CHECK-NEXT: Binding: Global
26# CHECK-NEXT: Type: Function
27# CHECK-NEXT: Other [ (0x8)
28# CHECK-NEXT: STO_MIPS_PLT
29# CHECK-NEXT: ]
30# CHECK-NEXT: Section: Undefined
31# CHECK-NEXT: }
32
33# CHECK: Primary GOT {
34# CHECK: Local entries [
35# CHECK-NEXT: ]
36# CHECK-NEXT: Global entries [
37# CHECK-NEXT: ]
38# CHECK: PLT GOT {
39# CHECK: Entries [
40# CHECK-NEXT: Entry {
41# CHECK-NEXT: Address:
42# CHECK-NEXT: Initial:
43# CHECK-NEXT: Value: 0x0
44# CHECK-NEXT: Type: Function
45# CHECK-NEXT: Section: Undefined
46# CHECK-NEXT: Name: foo0
47# CHECK-NEXT: }
48# CHECK-NEXT: Entry {
49# CHECK-NEXT: Address:
50# CHECK-NEXT: Initial:
51# CHECK-NEXT: Value: 0x20050
52# CHECK-NEXT: Type: Function
53# CHECK-NEXT: Section: Undefined
54# CHECK-NEXT: Name: foo1
55# CHECK-NEXT: }
56# CHECK-NEXT: ]
57
58 .text
59 .globl __start
60__start:
61 jal foo0 # R_MIPS_26 against 'foo0' from DSO
62 lui $t0,%hi(foo1) # R_MIPS_HI16/LO16 against 'foo1' from DSO
63 addi $t0,$t0,%lo(foo1)
64
65loc:
66 nop
deps/lld/test/ELF/mips-tls-64.s created+111
......@@ -0,0 +1,111 @@
1# Check MIPS TLS 64-bit relocations handling.
2
3# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux \
4# RUN: %p/Inputs/mips-tls.s -o %t.so.o
5# RUN: ld.lld -shared %t.so.o -o %t.so
6# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t.o
7
8# RUN: ld.lld %t.o %t.so -o %t.exe
9# RUN: llvm-objdump -d -s -t %t.exe | FileCheck -check-prefix=DIS %s
10# RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck %s
11
12# RUN: ld.lld -shared %t.o %t.so -o %t-out.so
13# RUN: llvm-objdump -d -s -t %t-out.so | FileCheck -check-prefix=DIS-SO %s
14# RUN: llvm-readobj -r -mips-plt-got %t-out.so | FileCheck -check-prefix=SO %s
15
16# REQUIRES: mips
17
18# DIS: __start:
19# DIS-NEXT: 20000: 24 62 80 20 addiu $2, $3, -32736
20# DIS-NEXT: 20004: 24 62 80 30 addiu $2, $3, -32720
21# DIS-NEXT: 20008: 24 62 80 38 addiu $2, $3, -32712
22# DIS-NEXT: 2000c: 24 62 80 48 addiu $2, $3, -32696
23# DIS-NEXT: 20010: 24 62 80 58 addiu $2, $3, -32680
24
25# DIS: Contents of section .got:
26# DIS-NEXT: 30010 00000000 00000000 80000000 00000000
27# DIS-NEXT: 30020 00000000 00000000 00000000 00000000
28# DIS-NEXT: 30030 00000000 00000000 00000000 00000001
29# DIS-NEXT: 30040 00000000 00000000 00000000 00000001
30# DIS-NEXT: 30050 ffffffff ffff8004 ffffffff ffff9004
31
32# DIS: 0000000000000000 l .tdata 00000000 loc
33# DIS: 0000000000000004 g .tdata 00000000 bar
34# DIS: 0000000000000000 g *UND* 00000000 foo
35
36# CHECK: Relocations [
37# CHECK-NEXT: Section (7) .rela.dyn {
38# CHECK-NEXT: 0x30020 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE foo 0x0
39# CHECK-NEXT: 0x30028 R_MIPS_TLS_DTPREL64/R_MIPS_NONE/R_MIPS_NONE foo 0x0
40# CHECK-NEXT: 0x30030 R_MIPS_TLS_TPREL64/R_MIPS_NONE/R_MIPS_NONE foo 0x0
41# CHECK-NEXT: }
42# CHECK-NEXT: ]
43# CHECK-NEXT: Primary GOT {
44# CHECK-NEXT: Canonical gp value: 0x38000
45# CHECK-NEXT: Reserved entries [
46# CHECK: ]
47# CHECK-NEXT: Local entries [
48# CHECK-NEXT: ]
49# CHECK-NEXT: Global entries [
50# CHECK-NEXT: ]
51# CHECK-NEXT: Number of TLS and multi-GOT entries: 8
52# ^-- -32736 R_MIPS_TLS_GD R_MIPS_TLS_DTPMOD64 foo
53# ^-- -32728 R_MIPS_TLS_DTPREL64 foo
54# ^-- -32720 R_MIPS_TLS_GOTTPREL R_MIPS_TLS_TPREL64 foo
55# ^-- -32712 R_MIPS_TLS_LDM 1 loc
56# ^-- -32704 0 loc
57# ^-- -32696 R_MIPS_TLS_GD 1 bar
58# ^-- -32688 VA - 0x8000 bar
59# ^-- -32680 R_MIPS_TLS_GOTTPREL VA - 0x7000 bar
60
61# DIS-SO: Contents of section .got:
62# DIS-SO-NEXT: 20000 00000000 00000000 80000000 00000000
63# DIS-SO-NEXT: 20010 00000000 00000000 00000000 00000000
64# DIS-SO-NEXT: 20020 00000000 00000000 00000000 00000000
65# DIS-SO-NEXT: 20030 00000000 00000000 00000000 00000000
66# DIS-SO-NEXT: 20040 00000000 00000000 00000000 00000000
67
68# SO: Relocations [
69# SO-NEXT: Section (7) .rela.dyn {
70# SO-NEXT: 0x20028 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE - 0x0
71# SO-NEXT: 0x20038 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE bar 0x0
72# SO-NEXT: 0x20040 R_MIPS_TLS_DTPREL64/R_MIPS_NONE/R_MIPS_NONE bar 0x0
73# SO-NEXT: 0x20048 R_MIPS_TLS_TPREL64/R_MIPS_NONE/R_MIPS_NONE bar 0x0
74# SO-NEXT: 0x20010 R_MIPS_TLS_DTPMOD64/R_MIPS_NONE/R_MIPS_NONE foo 0x0
75# SO-NEXT: 0x20018 R_MIPS_TLS_DTPREL64/R_MIPS_NONE/R_MIPS_NONE foo 0x0
76# SO-NEXT: 0x20020 R_MIPS_TLS_TPREL64/R_MIPS_NONE/R_MIPS_NONE foo 0x0
77# SO-NEXT: }
78# SO-NEXT: ]
79# SO-NEXT: Primary GOT {
80# SO-NEXT: Canonical gp value: 0x27FF0
81# SO-NEXT: Reserved entries [
82# SO: ]
83# SO-NEXT: Local entries [
84# SO-NEXT: ]
85# SO-NEXT: Global entries [
86# SO-NEXT: ]
87# SO-NEXT: Number of TLS and multi-GOT entries: 8
88# ^-- -32736 R_MIPS_TLS_GD R_MIPS_TLS_DTPMOD64 foo
89# ^-- -32728 R_MIPS_TLS_DTPREL64 foo
90# ^-- -32720 R_MIPS_TLS_GOTTPREL R_MIPS_TLS_TPREL64 foo
91# ^-- -32712 R_MIPS_TLS_LDM R_MIPS_TLS_DTPMOD64 loc
92# ^-- -32704 0 loc
93# ^-- -32696 R_MIPS_TLS_GD R_MIPS_TLS_DTPMOD64 bar
94# ^-- -32688 R_MIPS_TLS_DTPREL64 bar
95# ^-- -32680 R_MIPS_TLS_GOTTPREL R_MIPS_TLS_TPREL64 bar
96
97 .text
98 .global __start
99__start:
100 addiu $2, $3, %tlsgd(foo) # R_MIPS_TLS_GD
101 addiu $2, $3, %gottprel(foo) # R_MIPS_TLS_GOTTPREL
102 addiu $2, $3, %tlsldm(loc) # R_MIPS_TLS_LDM
103 addiu $2, $3, %tlsgd(bar) # R_MIPS_TLS_GD
104 addiu $2, $3, %gottprel(bar) # R_MIPS_TLS_GOTTPREL
105
106 .section .tdata,"awT",%progbits
107 .global bar
108loc:
109 .word 0
110bar:
111 .word 0
deps/lld/test/ELF/mips-tls-hilo.s created+51
......@@ -0,0 +1,51 @@
1# Check MIPS R_MIPS_TLS_DTPREL_HI16/LO16 and R_MIPS_TLS_TPREL_HI16/LO16
2# relocations handling.
3
4# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
5# RUN: ld.lld %t.o -o %t.exe
6# RUN: llvm-objdump -d -t %t.exe | FileCheck -check-prefix=DIS %s
7# RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck %s
8
9# RUN: ld.lld %t.o -shared -o %t.so
10# RUN: llvm-readobj -r -mips-plt-got %t.so | FileCheck -check-prefix=SO %s
11
12# REQUIRES: mips
13
14# DIS: __start:
15# DIS-NEXT: 20000: 24 62 00 00 addiu $2, $3, 0
16# %hi(loc0 - .tdata - 0x8000) --^
17# DIS-NEXT: 20004: 24 62 80 00 addiu $2, $3, -32768
18# %lo(loc0 - .tdata - 0x8000) --^
19# DIS-NEXT: 20008: 24 62 00 00 addiu $2, $3, 0
20# %hi(loc0 - .tdata - 0x7000) --^
21# DIS-NEXT: 2000c: 24 62 90 00 addiu $2, $3, -28672
22# %lo(loc0 - .tdata - 0x7000) --^
23
24# DIS: 00000000 l .tdata 00000000 loc0
25
26# CHECK: Relocations [
27# CHECK-NEXT: ]
28# CHECK-NOT: Primary GOT
29
30# SO: Relocations [
31# SO-NEXT: ]
32# SO: Primary GOT {
33# SO: Local entries [
34# SO-NEXT: ]
35# SO-NEXT: Global entries [
36# SO-NEXT: ]
37# SO-NEXT: Number of TLS and multi-GOT entries: 0
38# SO-NEXT: }
39
40 .text
41 .globl __start
42 .type __start,@function
43__start:
44 addiu $2, $3, %dtprel_hi(loc0) # R_MIPS_TLS_DTPREL_HI16
45 addiu $2, $3, %dtprel_lo(loc0) # R_MIPS_TLS_DTPREL_LO16
46 addiu $2, $3, %tprel_hi(loc0) # R_MIPS_TLS_TPREL_HI16
47 addiu $2, $3, %tprel_lo(loc0) # R_MIPS_TLS_TPREL_LO16
48
49 .section .tdata,"awT",%progbits
50loc0:
51 .word 0
deps/lld/test/ELF/mips-tls-static-64.s created+37
......@@ -0,0 +1,37 @@
1# Check handling TLS related relocations and symbols when linking
2# a 64-bit static executable.
3
4# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-linux %s -o %t
5# RUN: ld.lld -static %t -o %t.exe
6# RUN: llvm-objdump -s -t %t.exe | FileCheck %s
7
8# REQUIRES: mips
9
10# CHECK: Contents of section .data:
11# CHECK-NEXT: 30000 00020004 ffffffff ffff8004 ffffffff
12# CHECK-NEXT: 30010 ffff9004
13#
14# CHECK: SYMBOL TABLE:
15# CHECK: 0000000000020004 .text 00000000 __tls_get_addr
16# CHECK: 0000000000000000 g .tdata 00000000 tls1
17
18 .text
19 .global __start
20__start:
21 nop
22
23 .global __tls_get_addr
24__tls_get_addr:
25 nop
26
27 .data
28loc:
29 .word __tls_get_addr
30 .dtpreldword tls1+4 # R_MIPS_TLS_DTPREL64
31 .tpreldword tls1+4 # R_MIPS_TLS_TPREL64
32
33 .section .tdata,"awT",%progbits
34 .global tls1
35tls1:
36 .word __tls_get_addr
37 .word 0
deps/lld/test/ELF/mips-tls-static.s created+42
......@@ -0,0 +1,42 @@
1# Check handling TLS related relocations and symbols when linking
2# a static executable.
3
4# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t
5# RUN: ld.lld -static %t -o %t.exe
6# RUN: llvm-objdump -s -t %t.exe | FileCheck %s
7
8# REQUIRES: mips
9
10# CHECK: Contents of section .data:
11# CHECK-NEXT: 30000 0002000c ffff8004 ffff9004
12# CHECK: Contents of section .got:
13# CHECK-NEXT: 30010 00000000 80000000 00000001 ffff8000
14# CHECK-NEXT: 30020 00000001 00000000 ffff9000
15#
16# CHECK: SYMBOL TABLE:
17# CHECK: 0002000c .text 00000000 __tls_get_addr
18# CHECK: 00000000 g .tdata 00000000 tls1
19
20 .text
21 .global __start
22__start:
23 addiu $2, $3, %tlsgd(tls1) # R_MIPS_TLS_GD
24 addiu $2, $3, %tlsldm(tls2) # R_MIPS_TLS_LDM
25 addiu $2, $3, %gottprel(tls1) # R_MIPS_TLS_GOTTPREL
26
27 .global __tls_get_addr
28__tls_get_addr:
29 nop
30
31 .data
32loc:
33 .word __tls_get_addr
34 .dtprelword tls1+4 # R_MIPS_TLS_DTPREL32
35 .tprelword tls1+4 # R_MIPS_TLS_TPREL32
36
37 .section .tdata,"awT",%progbits
38 .global tls1
39tls1:
40 .word __tls_get_addr
41tls2:
42 .word 0
deps/lld/test/ELF/mips-tls.s created+107
......@@ -0,0 +1,107 @@
1# Check MIPS TLS relocations handling.
2
3# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux \
4# RUN: %p/Inputs/mips-tls.s -o %t.so.o
5# RUN: ld.lld -shared %t.so.o -o %t.so
6# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
7
8# RUN: ld.lld %t.o %t.so -o %t.exe
9# RUN: llvm-objdump -d -s -t %t.exe | FileCheck -check-prefix=DIS %s
10# RUN: llvm-readobj -r -mips-plt-got %t.exe | FileCheck %s
11
12# RUN: ld.lld -shared %t.o %t.so -o %t-out.so
13# RUN: llvm-objdump -d -s -t %t-out.so | FileCheck -check-prefix=DIS-SO %s
14# RUN: llvm-readobj -r -mips-plt-got %t-out.so | FileCheck -check-prefix=SO %s
15
16# REQUIRES: mips
17
18# DIS: __start:
19# DIS-NEXT: 20000: 24 62 80 18 addiu $2, $3, -32744
20# DIS-NEXT: 20004: 24 62 80 20 addiu $2, $3, -32736
21# DIS-NEXT: 20008: 24 62 80 24 addiu $2, $3, -32732
22# DIS-NEXT: 2000c: 24 62 80 2c addiu $2, $3, -32724
23# DIS-NEXT: 20010: 24 62 80 34 addiu $2, $3, -32716
24
25# DIS: Contents of section .got:
26# DIS-NEXT: 30010 00000000 80000000 00000000 00000000
27# DIS-NEXT: 30020 00000000 00000001 00000000 00000001
28# DIS-NEXT: 30030 ffff8004 ffff9004
29
30# DIS: 00000000 l .tdata 00000000 loc
31# DIS: 00000004 g .tdata 00000000 bar
32# DIS: 00000000 g *UND* 00000000 foo
33
34# CHECK: Relocations [
35# CHECK-NEXT: Section (7) .rel.dyn {
36# CHECK-NEXT: 0x30018 R_MIPS_TLS_DTPMOD32 foo 0x0
37# CHECK-NEXT: 0x3001C R_MIPS_TLS_DTPREL32 foo 0x0
38# CHECK-NEXT: 0x30020 R_MIPS_TLS_TPREL32 foo 0x0
39# CHECK-NEXT: }
40# CHECK-NEXT: ]
41# CHECK-NEXT: Primary GOT {
42# CHECK-NEXT: Canonical gp value: 0x38000
43# CHECK-NEXT: Reserved entries [
44# CHECK: ]
45# CHECK-NEXT: Local entries [
46# CHECK-NEXT: ]
47# CHECK-NEXT: Global entries [
48# CHECK-NEXT: ]
49# CHECK-NEXT: Number of TLS and multi-GOT entries: 8
50# ^-- -32744 R_MIPS_TLS_GD R_MIPS_TLS_DTPMOD32 foo
51# ^-- -32740 R_MIPS_TLS_DTPREL32 foo
52# ^-- -32736 R_MIPS_TLS_GOTTPREL R_MIPS_TLS_TPREL32 foo
53# ^-- -32732 R_MIPS_TLS_LDM 1 loc
54# ^-- -32728 0 loc
55# ^-- -32724 R_MIPS_TLS_GD 1 bar
56# ^-- -32720 VA - 0x8000 bar
57# ^-- -32716 R_MIPS_TLS_GOTTPREL VA - 0x7000 bar
58
59# DIS-SO: Contents of section .got:
60# DIS-SO-NEXT: 20000 00000000 80000000 00000000 00000000
61# DIS-SO-NEXT: 20010 00000000 00000000 00000000 00000000
62# DIS-SO-NEXT: 20020 00000000 00000000
63
64# SO: Relocations [
65# SO-NEXT: Section (7) .rel.dyn {
66# SO-NEXT: 0x20014 R_MIPS_TLS_DTPMOD32 - 0x0
67# SO-NEXT: 0x2001C R_MIPS_TLS_DTPMOD32 bar 0x0
68# SO-NEXT: 0x20020 R_MIPS_TLS_DTPREL32 bar 0x0
69# SO-NEXT: 0x20024 R_MIPS_TLS_TPREL32 bar 0x0
70# SO-NEXT: 0x20008 R_MIPS_TLS_DTPMOD32 foo 0x0
71# SO-NEXT: 0x2000C R_MIPS_TLS_DTPREL32 foo 0x0
72# SO-NEXT: 0x20010 R_MIPS_TLS_TPREL32 foo 0x0
73# SO-NEXT: }
74# SO-NEXT: ]
75# SO-NEXT: Primary GOT {
76# SO-NEXT: Canonical gp value: 0x27FF0
77# SO-NEXT: Reserved entries [
78# SO: ]
79# SO-NEXT: Local entries [
80# SO-NEXT: ]
81# SO-NEXT: Global entries [
82# SO-NEXT: ]
83# SO-NEXT: Number of TLS and multi-GOT entries: 8
84# ^-- -32744 R_MIPS_TLS_GD R_MIPS_TLS_DTPMOD32 foo
85# ^-- -32740 R_MIPS_TLS_DTPREL32 foo
86# ^-- -32736 R_MIPS_TLS_GOTTPREL R_MIPS_TLS_TPREL32 foo
87# ^-- -32732 R_MIPS_TLS_LDM R_MIPS_TLS_DTPMOD32 loc
88# ^-- -32728 0 loc
89# ^-- -32724 R_MIPS_TLS_GD R_MIPS_TLS_DTPMOD32 bar
90# ^-- -32720 R_MIPS_TLS_DTPREL32 bar
91# ^-- -32716 R_MIPS_TLS_GOTTPREL R_MIPS_TLS_TPREL32 bar
92
93 .text
94 .global __start
95__start:
96 addiu $2, $3, %tlsgd(foo) # R_MIPS_TLS_GD
97 addiu $2, $3, %gottprel(foo) # R_MIPS_TLS_GOTTPREL
98 addiu $2, $3, %tlsldm(loc) # R_MIPS_TLS_LDM
99 addiu $2, $3, %tlsgd(bar) # R_MIPS_TLS_GD
100 addiu $2, $3, %gottprel(bar) # R_MIPS_TLS_GOTTPREL
101
102 .section .tdata,"awT",%progbits
103 .global bar
104loc:
105 .word 0
106bar:
107 .word 0
deps/lld/test/ELF/mips-xgot-order.s created+49
......@@ -0,0 +1,49 @@
1# Check that GOT entries accessed via 16-bit indexing are allocated
2# in the beginning of the GOT.
3
4# RUN: llvm-mc -filetype=obj -triple=mips-unknown-linux %s -o %t.o
5# RUN: ld.lld %t.o -o %t.exe
6# RUN: llvm-objdump -d -s -t %t.exe | FileCheck %s
7
8# REQUIRES: mips
9
10# CHECK: Disassembly of section .text:
11# CHECK-NEXT: __start:
12# CHECK-NEXT: 20000: 3c 02 00 00 lui $2, 0
13# CHECK-NEXT: 20004: 8c 42 80 24 lw $2, -32732($2)
14# CHECK-NEXT: 20008: 3c 02 00 00 lui $2, 0
15# CHECK-NEXT: 2000c: 8c 42 80 28 lw $2, -32728($2)
16#
17# CHECK: bar:
18# CHECK-NEXT: 20010: 8c 42 80 20 lw $2, -32736($2)
19# CHECK-NEXT: 20014: 8c 42 80 18 lw $2, -32744($2)
20# CHECK-NEXT: 20018: 20 42 00 00 addi $2, $2, 0
21
22# CHECK: Contents of section .got:
23# CHECK-NEXT: 30010 00000000 80000000 00030000 00040000
24# ^ %hi(loc)
25# ^ redundant entry
26# CHECK-NEXT: 30020 00020010 00020000 00030000
27# ^ %got(bar)
28# ^ %got_hi/lo(start)
29# ^ %got_hi/lo(loc)
30
31# CHECK: 00030000 .data 00000000 loc
32# CHECK: 00020000 .text 00000000 __start
33# CHECK: 00020010 .text 00000000 bar
34
35 .text
36 .global __start, bar
37__start:
38 lui $2, %got_hi(__start)
39 lw $2, %got_lo(__start)($2)
40 lui $2, %got_hi(loc)
41 lw $2, %got_lo(loc)($2)
42bar:
43 lw $2, %got(bar)($2)
44 lw $2, %got(loc)($2)
45 addi $2, $2, %lo(loc)
46
47 .data
48loc:
49 .word 0
deps/lld/test/ELF/mips64-eh-abs-reloc.s created+38
......@@ -0,0 +1,38 @@
1# Having an R_MIPS_64 relocation in eh_frame would previously crash LLD
2# REQUIRES: mips
3# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-freebsd %s -o %t.o
4# RUN: llvm-readobj -r %t.o | FileCheck %s -check-prefix OBJ
5# RUN: ld.lld --eh-frame-hdr -shared -z notext -o %t.so %t.o
6# RUN: llvm-readobj -r %t.so | FileCheck %s -check-prefix PIC-RELOCS
7
8# Linking this as a PIE executable would also previously crash
9# RUN: llvm-mc -filetype=obj -triple=mips64-unknown-freebsd %S/Inputs/archive2.s -o %t-foo.o
10# -pie needs -z notext because of the R_MIPS_64 relocation
11# RUN: ld.lld --eh-frame-hdr -Bdynamic -pie -z notext -o %t-pie-dynamic.exe %t.o %t-foo.o
12# RUN: llvm-readobj -r %t-pie-dynamic.exe | FileCheck %s -check-prefix PIC-RELOCS
13
14
15# OBJ: Section ({{.*}}) .rela.text {
16# OBJ-NEXT: 0x0 R_MIPS_GPREL16/R_MIPS_SUB/R_MIPS_HI16 foo 0x0
17# OBJ-NEXT: }
18# OBJ-NEXT: Section ({{.*}}) .rela.eh_frame {
19# OBJ-NEXT: 0x1C R_MIPS_64/R_MIPS_NONE/R_MIPS_NONE .text 0x0
20# OBJ-NEXT: }
21
22# PIC-RELOCS: Relocations [
23# PIC-RELOCS-NEXT: Section (7) .rela.dyn {
24# PIC-RELOCS-NEXT: {{0x.+}} R_MIPS_REL32/R_MIPS_64/R_MIPS_NONE - 0x10000
25# PIC-RELOCS-NEXT: }
26# PIC-RELOCS-NEXT:]
27
28
29.globl foo
30
31bar:
32.cfi_startproc
33lui $11, %hi(%neg(%gp_rel(foo)))
34.cfi_endproc
35
36.globl __start
37__start:
38b bar
deps/lld/test/ELF/new-dtags.test created+16
......@@ -0,0 +1,16 @@
1# REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: ld.lld %t.o -rpath=/somepath -shared --disable-new-dtags -o %t
4// RUN: ld.lld %t.o -rpath=/somepath -shared --enable-new-dtags -o %t2
5// RUN: llvm-readobj --dynamic-table %t | FileCheck --check-prefix=DISABLE %s
6// RUN: llvm-readobj --dynamic-table %t2 | FileCheck --check-prefix=ENABLE %s
7
8// DISABLE: DynamicSection [
9// DISABLE: 0x000000000000000F RPATH /somepath
10// DISABLE-NOT: RUNPATH
11// DISABLE: ]
12
13// ENABLE: DynamicSection [
14// ENABLE: 0x000000000000001D RUNPATH /somepath
15// ENABLE-NOT: RPATH
16// ENABLE: ]
deps/lld/test/ELF/no-augmentation.s created+19
......@@ -0,0 +1,19 @@
1// RUN: llvm-mc -filetype=obj -triple=mips64-unknown-freebsd %s -o %t.o
2// RUN: ld.lld --eh-frame-hdr %t.o -o %t | FileCheck -allow-empty %s
3
4// REQUIRES: mips
5
6// CHECK-NOT: corrupted or unsupported CIE information
7// CHECK-NOT: corrupted CIE
8
9.global __start
10__start:
11
12.section .eh_frame,"aw",@progbits
13 .4byte 9
14 .4byte 0x0
15 .byte 0x1
16 .string ""
17 .uleb128 0x1
18 .sleb128 -4
19 .byte 0x1f
deps/lld/test/ELF/no-dynamic-linker.s created+12
......@@ -0,0 +1,12 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/shared.s -o %tso.o
3# RUN: ld.lld -shared %tso.o -o %t.so
4# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
5
6# RUN: ld.lld -dynamic-linker foo --no-dynamic-linker %t.o %t.so -o %t
7# RUN: llvm-readobj --program-headers %t | FileCheck %s --check-prefix=NODL
8# NODL-NOT: PT_INTERP
9
10# RUN: ld.lld --no-dynamic-linker -dynamic-linker foo %t.o %t.so -o %t
11# RUN: llvm-readobj --program-headers %t | FileCheck %s --check-prefix=WITHDL
12# WITHDL: PT_INTERP
deps/lld/test/ELF/no-inhibit-exec.s created+15
......@@ -0,0 +1,15 @@
1# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
2# RUN: not ld.lld %t -o %t2
3# RUN: ld.lld %t --noinhibit-exec -o %t2
4# RUN: llvm-objdump -d %t2 | FileCheck %s
5# REQUIRES: x86
6
7# CHECK: Disassembly of section .text:
8# CHECK-NEXT: _start
9# CHECK-NEXT: 201000: {{.*}} callq -2101253
10
11# next code will not link without noinhibit-exec flag
12# because of undefined symbol _bar
13.globl _start
14_start:
15 call _bar
deps/lld/test/ELF/no-merge.s created+19
......@@ -0,0 +1,19 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: echo "SECTIONS { .rodata : {*(.rodata.*)} }" > %t0.script
4# RUN: ld.lld %t.o -o %t0.out --script %t0.script
5# RUN: llvm-objdump -s %t0.out | FileCheck %s
6
7# RUN: ld.lld -O0 %t.o -o %t1.out --script %t0.script
8# RUN: llvm-objdump -s %t1.out | FileCheck %s
9# CHECK: Contents of section .rodata:
10# CHECK-NEXT: 0000 01610003
11
12.section .rodata.a,"a",@progbits
13.byte 1
14
15.section .rodata.ams,"aMS",@progbits,1
16.asciz "a"
17
18.section .rodata.am,"aM",@progbits,1
19.byte 3
deps/lld/test/ELF/no-obj.s created+9
......@@ -0,0 +1,9 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: llvm-ar rcs %t.a %t.o
4// RUN: not ld.lld -o %t2 -u _start %t.a 2>&1 | FileCheck %s
5
6// CHECK: target emulation unknown: -m or at least one .o file required
7
8.global _start
9_start:
deps/lld/test/ELF/no-plt-shared.s created+17
......@@ -0,0 +1,17 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/shared.s -o %t.o
3// RUN: ld.lld %t.o -o %t.so -shared
4
5// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t2.o
6// RUN: ld.lld %t2.o %t.so -o %t2.so -shared
7// RUN: llvm-readobj -r %t2.so | FileCheck %s
8
9 .data
10fp:
11 .quad bar
12
13// CHECK: Relocations [
14// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
15// CHECK-NEXT: R_X86_64_64 bar 0x0
16// CHECK-NEXT: }
17// CHECK-NEXT: ]
deps/lld/test/ELF/no-soname.s created+32
......@@ -0,0 +1,32 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: mkdir -p %T/no-soname
4// RUN: ld.lld %t.o -shared -o %T/no-soname/libfoo.so
5
6// RUN: ld.lld %t.o %T/no-soname/libfoo.so -o %t
7// RUN: llvm-readobj --dynamic-table %t | FileCheck %s
8
9// CHECK: 0x0000000000000001 NEEDED Shared library: [{{.*}}/no-soname/libfoo.so]
10// CHECK-NOT: NEEDED
11
12// RUN: ld.lld %t.o %T/no-soname/../no-soname/libfoo.so -o %t
13// RUN: llvm-readobj --dynamic-table %t | FileCheck %s --check-prefix=CHECK2
14
15// CHECK2: 0x0000000000000001 NEEDED Shared library: [{{.*}}/no-soname/../no-soname/libfoo.so]
16// CHECK2-NOT: NEEDED
17
18// RUN: ld.lld %t.o -L%T/no-soname/../no-soname -lfoo -o %t
19// RUN: llvm-readobj --dynamic-table %t | FileCheck %s --check-prefix=CHECK3
20
21// CHECK3: 0x0000000000000001 NEEDED Shared library: [libfoo.so]
22// CHECK3-NOT: NEEDED
23
24// RUN: ld.lld %t.o -shared -soname libbar.so -o %T/no-soname/libbar.so
25// RUN: ld.lld %t.o %T/no-soname/libbar.so -o %t
26// RUN: llvm-readobj --dynamic-table %t | FileCheck %s --check-prefix=CHECK4
27
28// CHECK4: 0x0000000000000001 NEEDED Shared library: [libbar.so]
29// CHECK4-NOT: NEEDED
30
31.global _start
32_start:
deps/lld/test/ELF/no-symtab.s created+5
......@@ -0,0 +1,5 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: ld.lld %t.o %p/Inputs/no-symtab.o -o %t
4.global _start
5_start:
deps/lld/test/ELF/no-undefined.s created+8
......@@ -0,0 +1,8 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: not ld.lld --no-undefined -shared %t -o %t.so
4# RUN: ld.lld -shared %t -o %t1.so
5
6.globl _shared
7_shared:
8 callq _unresolved@PLT
deps/lld/test/ELF/non-abs-reloc.s created+11
......@@ -0,0 +1,11 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s
4// CHECK: {{.*}}:(.dummy+0x0): has non-ABS reloc
5
6.globl _start
7_start:
8 nop
9
10.section .dummy
11 .long foo@gotpcrel
deps/lld/test/ELF/noplt-pie.s created+21
......@@ -0,0 +1,21 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o
4# RUN: ld.lld -shared %t2.o -o %t2.so
5# RUN: ld.lld %t1.o %t2.so -o %t.out
6# RUN: llvm-readobj -s -r %t.out | FileCheck %s
7
8# CHECK: Section {
9# CHECK-NOT: Name: .plt
10
11# CHECK: Relocations [
12# CHECK-NEXT: Section ({{.*}}) .rela.dyn {
13# CHECK-NEXT: 0x2020B0 R_X86_64_GLOB_DAT bar 0x0
14# CHECK-NEXT: 0x2020B8 R_X86_64_GLOB_DAT zed 0x0
15# CHECK-NEXT: }
16# CHECK-NEXT: ]
17
18.global _start
19_start:
20 movq bar@GOTPCREL(%rip), %rcx
21 movq zed@GOTPCREL(%rip), %rcx
deps/lld/test/ELF/note-contiguous.s created+24
......@@ -0,0 +1,24 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: echo "SECTIONS { \
4// RUN: .note : { *(.note.a) *(.note.b) } \
5// RUN: }" > %t.script
6// RUN: ld.lld %t.o --script %t.script -o %t
7// RUN: llvm-readobj -program-headers %t | FileCheck %s
8
9// CHECK: Type: PT_NOTE
10// CHECK-NEXT: Offset: 0x1000
11// CHECK-NEXT: VirtualAddress: 0x0
12// CHECK-NEXT: PhysicalAddress: 0x0
13// CHECK-NEXT: FileSize: 16
14// CHECK-NEXT: MemSize: 16
15// CHECK-NEXT: Flags [
16// CHECK-NEXT: PF_R
17// CHECK-NEXT: ]
18// CHECK-NEXT: Alignment: 1
19
20.section .note.a, "a", @note
21.quad 0
22
23.section .note.b, "a", @note
24.quad 0
deps/lld/test/ELF/note-loadaddr.c created+35
......@@ -0,0 +1,35 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: echo "SECTIONS { \
4// RUN: .note.a : AT(0x1000) { *(.note.a) } \
5// RUN: .note.b : AT(0x2000) { *(.note.b) } \
6// RUN: }" > %t.script
7// RUN: ld.lld %t.o --script %t.script -o %t
8// RUN: llvm-readobj -program-headers %t | FileCheck %s
9
10// CHECK: Type: PT_NOTE
11// CHECK-NEXT: Offset: 0x1000
12// CHECK-NEXT: VirtualAddress: 0x0
13// CHECK-NEXT: PhysicalAddress: 0x1000
14// CHECK-NEXT: FileSize: 8
15// CHECK-NEXT: MemSize: 8
16// CHECK-NEXT: Flags [
17// CHECK-NEXT: PF_R
18// CHECK-NEXT: ]
19// CHECK-NEXT: Alignment: 1
20// CHECK: Type: PT_NOTE
21// CHECK-NEXT: Offset: 0x1008
22// CHECK-NEXT: VirtualAddress: 0x8
23// CHECK-NEXT: PhysicalAddress: 0x2000
24// CHECK-NEXT: FileSize: 8
25// CHECK-NEXT: MemSize: 8
26// CHECK-NEXT: Flags [
27// CHECK-NEXT: PF_R
28// CHECK-NEXT: ]
29// CHECK-NEXT: Alignment: 1
30
31.section .note.a, "a", @note
32.quad 0
33
34.section .note.b, "a", @note
35.quad 0
deps/lld/test/ELF/note-multiple.s created+43
......@@ -0,0 +1,43 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: echo "SECTIONS { \
4// RUN: .note.a : { *(.note.a) } \
5// RUN: .b : { *(.b) } \
6// RUN: .c : { *(.c) } \
7// RUN: .note.d : { *(.note.d) } \
8// RUN: }" > %t.script
9// RUN: ld.lld %t.o --script %t.script -o %t
10// RUN: llvm-readobj -program-headers %t | FileCheck %s
11
12// CHECK: Type: PT_NOTE
13// CHECK-NEXT: Offset: 0x1000
14// CHECK-NEXT: VirtualAddress: 0x0
15// CHECK-NEXT: PhysicalAddress: 0x0
16// CHECK-NEXT: FileSize: 8
17// CHECK-NEXT: MemSize: 8
18// CHECK-NEXT: Flags [
19// CHECK-NEXT: PF_R
20// CHECK-NEXT: ]
21// CHECK-NEXT: Alignment: 1
22// CHECK: Type: PT_NOTE
23// CHECK-NEXT: Offset: 0x1018
24// CHECK-NEXT: VirtualAddress: 0x18
25// CHECK-NEXT: PhysicalAddress: 0x18
26// CHECK-NEXT: FileSize: 8
27// CHECK-NEXT: MemSize: 8
28// CHECK-NEXT: Flags [
29// CHECK-NEXT: PF_R
30// CHECK-NEXT: ]
31// CHECK-NEXT: Alignment: 1
32
33.section .note.a, "a", @note
34.quad 0
35
36.section .b, "a"
37.quad 0
38
39.section .c, "a"
40.quad 0
41
42.section .note.d, "a", @note
43.quad 0
deps/lld/test/ELF/note.s created+18
......@@ -0,0 +1,18 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: ld.lld %t.o -o %t -shared
4// RUN: llvm-readobj -program-headers %t | FileCheck %s
5
6// CHECK: Type: PT_NOTE
7// CHECK-NEXT: Offset:
8// CHECK-NEXT: VirtualAddress:
9// CHECK-NEXT: PhysicalAddress:
10// CHECK-NEXT: FileSize: 8
11// CHECK-NEXT: MemSize: 8
12// CHECK-NEXT: Flags [
13// CHECK-NEXT: PF_R
14// CHECK-NEXT: ]
15// CHECK-NEXT: Alignment: 1
16
17 .section .note.test,"a",@note
18 .quad 42
deps/lld/test/ELF/oformat-binary-ttext.s created+18
......@@ -0,0 +1,18 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4# RUN: ld.lld -N -Ttext 0x100 -o %t.out %t --oformat binary
5# RUN: od -t x1 -v %t.out | FileCheck %s --check-prefix=BIN
6
7# BIN: 0000000 90 00 00 00 00 00 00 00
8# BIN-NEXT: 0000010
9# BIN-NOT: 0000020
10
11## The same but without OMAGIC.
12# RUN: ld.lld -Ttext 0x100 -o %t.out %t --oformat binary
13# RUN: od -t x1 -v %t.out | FileCheck %s --check-prefix=BIN
14
15.text
16.globl _start
17_start:
18 nop
deps/lld/test/ELF/oformat-binary.s created+32
......@@ -0,0 +1,32 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4# RUN: ld.lld -o %t.out %t --oformat binary
5# RUN: od -t x1 -v %t.out | FileCheck %s
6# CHECK: 000000 90 11 22 00 00 00 00 00
7# CHECK-NOT: 00000010
8
9## Check case when linkerscript is used.
10# RUN: echo "SECTIONS { . = 0x1000; }" > %t.script
11# RUN: ld.lld -o %t2.out --script %t.script %t --oformat binary
12# RUN: od -t x1 -v %t2.out | FileCheck %s
13
14# RUN: echo "SECTIONS { }" > %t.script
15# RUN: ld.lld -o %t2.out --script %t.script %t --oformat binary
16# RUN: od -t x1 -v %t2.out | FileCheck %s
17
18# RUN: not ld.lld -o %t3.out %t --oformat foo 2>&1 \
19# RUN: | FileCheck %s --check-prefix ERR
20# ERR: unknown --oformat value: foo
21
22.text
23.align 4
24.globl _start
25_start:
26 nop
27
28.section .mysec.1,"ax"
29.byte 0x11
30
31.section .mysec.2,"ax"
32.byte 0x22
deps/lld/test/ELF/openbsd-randomize.s created+20
......@@ -0,0 +1,20 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
3# RUN: ld.lld %t -o %t.out
4# RUN: llvm-readobj --program-headers %t.out | FileCheck %s
5
6# CHECK: ProgramHeader {
7# CHECK: Type: PT_OPENBSD_RANDOMIZE (0x65A3DBE6)
8# CHECK-NEXT: Offset:
9# CHECK-NEXT: VirtualAddress:
10# CHECK-NEXT: PhysicalAddress:
11# CHECK-NEXT: FileSize: 8
12# CHECK-NEXT: MemSize: 8
13# CHECK-NEXT: Flags [
14# CHECK-NEXT: PF_R (0x4)
15# CHECK-NEXT: ]
16# CHECK-NEXT: Alignment: 1
17# CHECK-NEXT: }
18
19.section .openbsd.randomdata, "a"
20.quad 0
deps/lld/test/ELF/openbsd-wxneeded.s created+17
......@@ -0,0 +1,17 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
3# RUN: ld.lld -z wxneeded %t -o %t.out
4# RUN: llvm-readobj --program-headers %t.out | FileCheck %s
5
6# CHECK: ProgramHeader {
7# CHECK: Type: PT_OPENBSD_WXNEEDED (0x65A3DBE7)
8# CHECK-NEXT: Offset: 0x0
9# CHECK-NEXT: VirtualAddress: 0x0
10# CHECK-NEXT: PhysicalAddress: 0x0
11# CHECK-NEXT: FileSize: 0
12# CHECK-NEXT: MemSize: 0
13# CHECK-NEXT: Flags [
14# CHECK-NEXT: PF_X
15# CHECK-NEXT: ]
16# CHECK-NEXT: Alignment: 0
17# CHECK-NEXT: }
deps/lld/test/ELF/output-section.s created+34
......@@ -0,0 +1,34 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
2// RUN: ld.lld %t -o %t2
3// RUN: llvm-readobj -t %t2 | FileCheck %s
4// REQUIRES: x86
5
6// CHECK: Symbol {
7// CHECK: Name: bar_sym
8// CHECK-NEXT: Value:
9// CHECK-NEXT: Size:
10// CHECK-NEXT: Binding:
11// CHECK-NEXT: Type:
12// CHECK-NEXT: Other:
13// CHECK-NEXT: Section: bar
14// CHECK-NEXT: }
15// CHECK-NEXT: Symbol {
16// CHECK-NEXT: Name: foo_sym
17// CHECK-NEXT: Value:
18// CHECK-NEXT: Size:
19// CHECK-NEXT: Binding:
20// CHECK-NEXT: Type:
21// CHECK-NEXT: Other:
22// CHECK-NEXT: Section: foo
23// CHECK-NEXT: }
24
25.section foo
26.global foo_sym
27foo_sym:
28
29.section bar, "a"
30.global bar_sym
31bar_sym:
32
33.global _start
34_start:
deps/lld/test/ELF/phdr-align.s created+83
......@@ -0,0 +1,83 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3
4# RUN: echo "SECTIONS { \
5# RUN: . = SIZEOF_HEADERS; \
6# RUN: .bss : { *(.bss) } \
7# RUN: .data : { *(.data) } \
8# RUN: .text : { *(.text) } }" > %t.script
9# RUN: ld.lld %t.o --script %t.script -o %t
10# RUN: llvm-readobj -sections -symbols %t | FileCheck %s
11
12# CHECK: Sections [
13# CHECK-NEXT: Section {
14# CHECK-NEXT: Index: 0
15# CHECK-NEXT: Name: (0)
16# CHECK-NEXT: Type: SHT_NULL
17# CHECK-NEXT: Flags [
18# CHECK-NEXT: ]
19# CHECK-NEXT: Address: 0x0
20# CHECK-NEXT: Offset: 0x0
21# CHECK-NEXT: Size: 0
22# CHECK-NEXT: Link: 0
23# CHECK-NEXT: Info: 0
24# CHECK-NEXT: AddressAlignment: 0
25# CHECK-NEXT: EntrySize: 0
26# CHECK-NEXT: }
27# CHECK-NEXT: Section {
28# CHECK-NEXT: Index: 1
29# CHECK-NEXT: Name: .bss
30# CHECK-NEXT: Type: SHT_NOBITS
31# CHECK-NEXT: Flags [
32# CHECK-NEXT: SHF_ALLOC
33# CHECK-NEXT: SHF_WRITE
34# CHECK-NEXT: ]
35# CHECK-NEXT: Address: 0x158
36# CHECK-NEXT: Offset: 0x158
37# CHECK-NEXT: Size: 6
38# CHECK-NEXT: Link: 0
39# CHECK-NEXT: Info: 0
40# CHECK-NEXT: AddressAlignment: 1
41# CHECK-NEXT: EntrySize: 0
42# CHECK-NEXT: }
43# CHECK-NEXT: Section {
44# CHECK-NEXT: Index: 2
45# CHECK-NEXT: Name: .data
46# CHECK-NEXT: Type: SHT_PROGBITS
47# CHECK-NEXT: Flags [
48# CHECK-NEXT: SHF_ALLOC
49# CHECK-NEXT: SHF_WRITE
50# CHECK-NEXT: ]
51# CHECK-NEXT: Address: 0x15E
52# CHECK-NEXT: Offset: 0x15E
53# CHECK-NEXT: Size: 2
54# CHECK-NEXT: Link: 0
55# CHECK-NEXT: Info: 0
56# CHECK-NEXT: AddressAlignment: 1
57# CHECK-NEXT: EntrySize: 0
58# CHECK-NEXT: }
59# CHECK-NEXT: Section {
60# CHECK-NEXT: Index: 3
61# CHECK-NEXT: Name: .text
62# CHECK-NEXT: Type: SHT_PROGBITS
63# CHECK-NEXT: Flags [
64# CHECK-NEXT: SHF_ALLOC
65# CHECK-NEXT: SHF_EXECINSTR
66# CHECK-NEXT: ]
67# CHECK-NEXT: Address: 0x160
68# CHECK-NEXT: Offset: 0x160
69# CHECK-NEXT: Size: 1
70# CHECK-NEXT: Link: 0
71# CHECK-NEXT: Info: 0
72# CHECK-NEXT: AddressAlignment: 4
73# CHECK-NEXT: EntrySize: 0
74# CHECK-NEXT: }
75
76.global _start
77.text
78_start:
79 nop
80.data
81 .word 1
82.bss
83 .space 6
deps/lld/test/ELF/pie-weak.s created+17
......@@ -0,0 +1,17 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -relax-relocations=false -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: ld.lld -pie %t.o -o %t
4# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELOCS %s
5# RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
6
7# RELOCS: Relocations [
8# RELOCS-NEXT: ]
9
10.weak foo
11
12.globl _start
13_start:
14# DISASM: _start:
15# DISASM-NEXT: 1000: 48 8b 05 69 10 00 00 movq 4201(%rip), %rax
16# ^ .got - (.text + 7)
17mov foo@gotpcrel(%rip), %rax
deps/lld/test/ELF/pie.s created+56
......@@ -0,0 +1,56 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
3
4## Default is no PIE.
5# RUN: ld.lld %t1.o -o %t
6# RUN: llvm-readobj -file-headers -sections -program-headers -symbols -r %t \
7# RUN: | FileCheck %s --check-prefix=NOPIE
8
9## Check -pie.
10# RUN: ld.lld -pie %t1.o -o %t
11# RUN: llvm-readobj -file-headers -sections -program-headers -symbols -r %t | FileCheck %s
12
13## Test --pic-executable alias
14# RUN: ld.lld --pic-executable %t1.o -o %t
15# RUN: llvm-readobj -file-headers -sections -program-headers -symbols -r %t | FileCheck %s
16
17# CHECK: ElfHeader {
18# CHECK-NEXT: Ident {
19# CHECK-NEXT: Magic: (7F 45 4C 46)
20# CHECK-NEXT: Class: 64-bit
21# CHECK-NEXT: DataEncoding: LittleEndian
22# CHECK-NEXT: FileVersion: 1
23# CHECK-NEXT: OS/ABI: SystemV
24# CHECK-NEXT: ABIVersion: 0
25# CHECK-NEXT: Unused: (00 00 00 00 00 00 00)
26# CHECK-NEXT: }
27# CHECK-NEXT: Type: SharedObject
28
29# CHECK: ProgramHeaders [
30# CHECK-NEXT: ProgramHeader {
31# CHECK-NEXT: Type: PT_PHDR
32# CHECK-NEXT: Offset: 0x40
33# CHECK-NEXT: VirtualAddress: 0x40
34# CHECK-NEXT: PhysicalAddress: 0x40
35# CHECK-NEXT: FileSize:
36# CHECK-NEXT: MemSize:
37# CHECK-NEXT: Flags [
38# CHECK-NEXT: PF_R
39# CHECK-NEXT: ]
40# CHECK-NEXT: Alignment: 8
41# CHECK-NEXT: }
42# CHECK-NEXT: ProgramHeader {
43# CHECK-NEXT: Type: PT_LOAD
44# CHECK-NEXT: Offset: 0x0
45# CHECK-NEXT: VirtualAddress: 0x0
46# CHECK-NEXT: PhysicalAddress: 0x0
47
48# CHECK: Type: PT_DYNAMIC
49
50## Check -nopie
51# RUN: ld.lld -nopie %t1.o -o %t2
52# RUN: llvm-readobj -file-headers -r %t2 | FileCheck %s --check-prefix=NOPIE
53# NOPIE-NOT: Type: SharedObject
54
55.globl _start
56_start:
deps/lld/test/ELF/plt-aarch64.s created+203
......@@ -0,0 +1,203 @@
1// RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %s -o %t.o
2// RUN: llvm-mc -filetype=obj -triple=aarch64-pc-freebsd %p/Inputs/plt-aarch64.s -o %t2.o
3// RUN: ld.lld -shared %t2.o -o %t2.so
4// RUN: ld.lld -shared %t.o %t2.so -o %t.so
5// RUN: ld.lld %t.o %t2.so -o %t.exe
6// RUN: llvm-readobj -s -r %t.so | FileCheck --check-prefix=CHECKDSO %s
7// RUN: llvm-objdump -s -section=.got.plt %t.so | FileCheck --check-prefix=DUMPDSO %s
8// RUN: llvm-objdump -d %t.so | FileCheck --check-prefix=DISASMDSO %s
9// RUN: llvm-readobj -s -r %t.exe | FileCheck --check-prefix=CHECKEXE %s
10// RUN: llvm-objdump -s -section=.got.plt %t.exe | FileCheck --check-prefix=DUMPEXE %s
11// RUN: llvm-objdump -d %t.exe | FileCheck --check-prefix=DISASMEXE %s
12
13// REQUIRES: aarch64
14
15// CHECKDSO: Name: .plt
16// CHECKDSO-NEXT: Type: SHT_PROGBITS
17// CHECKDSO-NEXT: Flags [
18// CHECKDSO-NEXT: SHF_ALLOC
19// CHECKDSO-NEXT: SHF_EXECINSTR
20// CHECKDSO-NEXT: ]
21// CHECKDSO-NEXT: Address: 0x10010
22// CHECKDSO-NEXT: Offset:
23// CHECKDSO-NEXT: Size: 80
24// CHECKDSO-NEXT: Link:
25// CHECKDSO-NEXT: Info:
26// CHECKDSO-NEXT: AddressAlignment: 16
27
28// CHECKDSO: Name: .got.plt
29// CHECKDSO-NEXT: Type: SHT_PROGBITS
30// CHECKDSO-NEXT: Flags [
31// CHECKDSO-NEXT: SHF_ALLOC
32// CHECKDSO-NEXT: SHF_WRITE
33// CHECKDSO-NEXT: ]
34// CHECKDSO-NEXT: Address: 0x20000
35// CHECKDSO-NEXT: Offset:
36// CHECKDSO-NEXT: Size: 48
37// CHECKDSO-NEXT: Link:
38// CHECKDSO-NEXT: Info:
39// CHECKDSO-NEXT: AddressAlignment: 8
40
41// CHECKDSO: Relocations [
42// CHECKDSO-NEXT: Section ({{.*}}) .rela.plt {
43
44// &(.got.plt[3]) = 0x20000 + 3 * 8 = 0x30018
45// CHECKDSO-NEXT: 0x20018 R_AARCH64_JUMP_SLOT foo
46
47// &(.got.plt[4]) = 0x20000 + 4 * 8 = 0x30020
48// CHECKDSO-NEXT: 0x20020 R_AARCH64_JUMP_SLOT bar
49
50// &(.got.plt[5]) = 0x20000 + 5 * 8 = 0x30028
51// CHECKDSO-NEXT: 0x20028 R_AARCH64_JUMP_SLOT weak
52// CHECKDSO-NEXT: }
53// CHECKDSO-NEXT: ]
54
55// DUMPDSO: Contents of section .got.plt:
56// .got.plt[0..2] = 0 (reserved)
57// .got.plt[3..5] = .plt = 0x10010
58// DUMPDSO-NEXT: 20000 00000000 00000000 00000000 00000000 ................
59// DUMPDSO-NEXT: 20010 00000000 00000000 10000100 00000000 ................
60// DUMPDSO-NEXT: 20020 10000100 00000000 10000100 00000000 ................
61
62// DISASMDSO: _start:
63// 0x10030 - 0x10000 = 0x30 = 48
64// DISASMDSO-NEXT: 10000: 0c 00 00 14 b #48
65// 0x10040 - 0x10004 = 0x3c = 60
66// DISASMDSO-NEXT: 10004: 0f 00 00 14 b #60
67// 0x10050 - 0x10008 = 0x48 = 72
68// DISASMDSO-NEXT: 10008: 12 00 00 14 b #72
69
70// DISASMDSO: foo:
71// DISASMDSO-NEXT: 1000c: 1f 20 03 d5 nop
72
73// DISASMDSO: Disassembly of section .plt:
74// DISASMDSO-NEXT: .plt:
75// DISASMDSO-NEXT: 10010: f0 7b bf a9 stp x16, x30, [sp, #-16]!
76// &(.got.plt[2]) = 0x3000 + 2 * 8 = 0x3010
77// Page(0x20010) - Page(0x10014) = 0x20000 - 0x10000 = 0x10000 = 65536
78// DISASMDSO-NEXT: 10014: 90 00 00 90 adrp x16, #65536
79// 0x3010 & 0xFFF = 0x10 = 16
80// DISASMDSO-NEXT: 10018: 11 0a 40 f9 ldr x17, [x16, #16]
81// DISASMDSO-NEXT: 1001c: 10 42 00 91 add x16, x16, #16
82// DISASMDSO-NEXT: 10020: 20 02 1f d6 br x17
83// DISASMDSO-NEXT: 10024: 1f 20 03 d5 nop
84// DISASMDSO-NEXT: 10028: 1f 20 03 d5 nop
85// DISASMDSO-NEXT: 1002c: 1f 20 03 d5 nop
86
87// foo@plt
88// Page(0x30018) - Page(0x10030) = 0x20000 - 0x10000 = 0x10000 = 65536
89// DISASMDSO-NEXT: 10030: 90 00 00 90 adrp x16, #65536
90// 0x3018 & 0xFFF = 0x18 = 24
91// DISASMDSO-NEXT: 10034: 11 0e 40 f9 ldr x17, [x16, #24]
92// DISASMDSO-NEXT: 10038: 10 62 00 91 add x16, x16, #24
93// DISASMDSO-NEXT: 1003c: 20 02 1f d6 br x17
94
95// bar@plt
96// Page(0x30020) - Page(0x10040) = 0x20000 - 0x10000 = 0x10000 = 65536
97// DISASMDSO-NEXT: 10040: 90 00 00 90 adrp x16, #65536
98// 0x3020 & 0xFFF = 0x20 = 32
99// DISASMDSO-NEXT: 10044: 11 12 40 f9 ldr x17, [x16, #32]
100// DISASMDSO-NEXT: 10048: 10 82 00 91 add x16, x16, #32
101// DISASMDSO-NEXT: 1004c: 20 02 1f d6 br x17
102
103// weak@plt
104// Page(0x30028) - Page(0x10050) = 0x20000 - 0x10000 = 0x10000 = 65536
105// DISASMDSO-NEXT: 10050: 90 00 00 90 adrp x16, #65536
106// 0x3028 & 0xFFF = 0x28 = 40
107// DISASMDSO-NEXT: 10054: 11 16 40 f9 ldr x17, [x16, #40]
108// DISASMDSO-NEXT: 10058: 10 a2 00 91 add x16, x16, #40
109// DISASMDSO-NEXT: 1005c: 20 02 1f d6 br x17
110
111// CHECKEXE: Name: .plt
112// CHECKEXE-NEXT: Type: SHT_PROGBITS
113// CHECKEXE-NEXT: Flags [
114// CHECKEXE-NEXT: SHF_ALLOC
115// CHECKEXE-NEXT: SHF_EXECINSTR
116// CHECKEXE-NEXT: ]
117// CHECKEXE-NEXT: Address: 0x20010
118// CHECKEXE-NEXT: Offset:
119// CHECKEXE-NEXT: Size: 64
120// CHECKEXE-NEXT: Link:
121// CHECKEXE-NEXT: Info:
122// CHECKEXE-NEXT: AddressAlignment: 16
123
124// CHECKEXE: Name: .got.plt
125// CHECKEXE-NEXT: Type: SHT_PROGBITS
126// CHECKEXE-NEXT: Flags [
127// CHECKEXE-NEXT: SHF_ALLOC
128// CHECKEXE-NEXT: SHF_WRITE
129// CHECKEXE-NEXT: ]
130// CHECKEXE-NEXT: Address: 0x30000
131// CHECKEXE-NEXT: Offset:
132// CHECKEXE-NEXT: Size: 40
133// CHECKEXE-NEXT: Link:
134// CHECKEXE-NEXT: Info:
135// CHECKEXE-NEXT: AddressAlignment: 8
136
137// CHECKEXE: Relocations [
138// CHECKEXE-NEXT: Section ({{.*}}) .rela.plt {
139
140// &(.got.plt[3]) = 0x30000 + 3 * 8 = 0x30018
141// CHECKEXE-NEXT: 0x30018 R_AARCH64_JUMP_SLOT bar 0x0
142
143// &(.got.plt[4]) = 0x30000 + 4 * 8 = 0x30020
144// CHECKEXE-NEXT: 0x30020 R_AARCH64_JUMP_SLOT weak 0x0
145// CHECKEXE-NEXT: }
146// CHECKEXE-NEXT: ]
147
148// DUMPEXE: Contents of section .got.plt:
149// .got.plt[0..2] = 0 (reserved)
150// .got.plt[3..4] = .plt = 0x40010
151// DUMPEXE-NEXT: 30000 00000000 00000000 00000000 00000000 ................
152// DUMPEXE-NEXT: 30010 00000000 00000000 10000200 00000000 ................
153// DUMPEXE-NEXT: 30020 10000200 00000000 ........
154
155// DISASMEXE: _start:
156// 0x2000c - 0x20000 = 0xc = 12
157// DISASMEXE-NEXT: 20000: 03 00 00 14 b #12
158// 0x20030 - 0x20004 = 0x2c = 44
159// DISASMEXE-NEXT: 20004: 0b 00 00 14 b #44
160// 0x20040 - 0x20008 = 0x38 = 56
161// DISASMEXE-NEXT: 20008: 0e 00 00 14 b #56
162
163// DISASMEXE: foo:
164// DISASMEXE-NEXT: 2000c: 1f 20 03 d5 nop
165
166// DISASMEXE: Disassembly of section .plt:
167// DISASMEXE-NEXT: .plt:
168// DISASMEXE-NEXT: 20010: f0 7b bf a9 stp x16, x30, [sp, #-16]!
169// &(.got.plt[2]) = 0x300B0 + 2 * 8 = 0x300C0
170// Page(0x30010) - Page(0x20014) = 0x30000 - 0x20000 = 0x10000 = 65536
171// DISASMEXE-NEXT: 20014: 90 00 00 90 adrp x16, #65536
172// 0x120c0 & 0xFFF = 0xC0 = 192
173// DISASMEXE-NEXT: 20018: 11 0a 40 f9 ldr x17, [x16, #16]
174// DISASMEXE-NEXT: 2001c: 10 42 00 91 add x16, x16, #16
175// DISASMEXE-NEXT: 20020: 20 02 1f d6 br x17
176// DISASMEXE-NEXT: 20024: 1f 20 03 d5 nop
177// DISASMEXE-NEXT: 20028: 1f 20 03 d5 nop
178// DISASMEXE-NEXT: 2002c: 1f 20 03 d5 nop
179
180// bar@plt
181// Page(0x40018) - Page(0x20030) = 0x30000 - 0x20000 = 0x10000 = 65536
182// DISASMEXE-NEXT: 20030: 90 00 00 90 adrp x16, #65536
183// DISASMEXE-NEXT: 20034: 11 0e 40 f9 ldr x17, [x16, #24]
184// DISASMEXE-NEXT: 20038: 10 62 00 91 add x16, x16, #24
185// DISASMEXE-NEXT: 2003c: 20 02 1f d6 br x17
186
187// weak@plt
188// Page(0x40020) - Page(0x20040) = 0x30000 - 0x20000 = 0x10000 = 65536
189// DISASMEXE-NEXT: 20040: 90 00 00 90 adrp x16, #65536
190// DISASMEXE-NEXT: 20044: 11 12 40 f9 ldr x17, [x16, #32]
191// DISASMEXE-NEXT: 20048: 10 82 00 91 add x16, x16, #32
192// DISASMEXE-NEXT: 2004c: 20 02 1f d6 br x17
193
194.global _start,foo,bar
195.weak weak
196_start:
197 b foo
198 b bar
199 b weak
200
201.section .text2,"ax",@progbits
202foo:
203 nop
deps/lld/test/ELF/plt-i686.s created+174
......@@ -0,0 +1,174 @@
1// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o
2// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/shared.s -o %t2.o
3// RUN: ld.lld -shared %t2.o -o %t2.so
4// RUN: ld.lld %t.o %t2.so -o %t
5// RUN: llvm-readobj -s -r %t | FileCheck %s
6// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
7// RUN: ld.lld -shared %t.o %t2.so -o %t
8// RUN: llvm-readobj -s -r %t | FileCheck --check-prefix=CHECKSHARED %s
9// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASMSHARED %s
10// RUN: ld.lld -pie %t.o %t2.so -o %t
11// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASMPIE %s
12// REQUIRES: x86
13
14// CHECK: Name: .plt
15// CHECK-NEXT: Type: SHT_PROGBITS
16// CHECK-NEXT: Flags [
17// CHECK-NEXT: SHF_ALLOC
18// CHECK-NEXT: SHF_EXECINSTR
19// CHECK-NEXT: ]
20// CHECK-NEXT: Address: 0x11020
21// CHECK-NEXT: Offset:
22// CHECK-NEXT: Size: 48
23// CHECK-NEXT: Link: 0
24// CHECK-NEXT: Info: 0
25// CHECK-NEXT: AddressAlignment: 16
26
27// CHECK: Name: .got.plt
28// CHECK-NEXT: Type: SHT_PROGBITS
29// CHECK-NEXT: Flags [
30// CHECK-NEXT: SHF_ALLOC
31// CHECK-NEXT: SHF_WRITE
32// CHECK-NEXT: ]
33// CHECK-NEXT: Address: 0x12000
34// CHECK-NEXT: Offset: 0x2000
35// CHECK-NEXT: Size: 20
36// CHECK-NEXT: Link: 0
37// CHECK-NEXT: Info: 0
38// CHECK-NEXT: AddressAlignment: 4
39// CHECK-NEXT: EntrySize: 0
40
41// 0x12000 + got.plt.reserved(12) = 0x1200C
42// 0x12000 + got.plt.reserved(12) + 4 = 0x12010
43// CHECK: Relocations [
44// CHECK-NEXT: Section ({{.*}}) .rel.plt {
45// CHECK-NEXT: 0x1200C R_386_JUMP_SLOT bar 0x0
46// CHECK-NEXT: 0x12010 R_386_JUMP_SLOT zed 0x0
47// CHECK-NEXT: }
48// CHECK-NEXT: ]
49
50// Unfortunately FileCheck can't do math, so we have to check for explicit
51// values:
52
53// 16 is the size of PLT[0]
54// (0x11010 + 16) - (0x11000 + 1) - 4 = 27
55// (0x11010 + 16) - (0x11005 + 1) - 4 = 22
56// (0x11020 + 16) - (0x1100a + 1) - 4 = 33
57
58// DISASM: local:
59// DISASM-NEXT: 11000: {{.*}}
60// DISASM-NEXT: 11002: {{.*}}
61// DISASM: _start:
62// 0x11013 + 5 - 24 = 0x11000
63// DISASM-NEXT: 11004: e9 27 00 00 00 jmp 39
64// DISASM-NEXT: 11009: e9 22 00 00 00 jmp 34
65// DISASM-NEXT: 1100e: e9 2d 00 00 00 jmp 45
66// DISASM-NEXT: 11013: e9 e8 ff ff ff jmp -24
67
68// 0x11010 - 0x1102b - 5 = -32
69// 0x11010 - 0x1103b - 5 = -48
70// 77828 = 0x13004 = .got.plt (0x13000) + 4
71// 77832 = 0x13008 = .got.plt (0x13000) + 8
72// 77836 = 0x1300C = .got.plt (0x13000) + got.plt.reserved(12)
73// 77840 = 0x13010 = .got.plt (0x13000) + got.plt.reserved(12) + 4
74// DISASM: Disassembly of section .plt:
75// DISASM-NEXT: .plt:
76// DISASM-NEXT: 11020: ff 35 04 20 01 00 pushl 73732
77// DISASM-NEXT: 11026: ff 25 08 20 01 00 jmpl *73736
78// DISASM-NEXT: 1102c: 90 nop
79// DISASM-NEXT: 1102d: 90 nop
80// DISASM-NEXT: 1102e: 90 nop
81// DISASM-NEXT: 1102f: 90 nop
82// DISASM-NEXT: 11030: ff 25 0c 20 01 00 jmpl *73740
83// DISASM-NEXT: 11036: 68 00 00 00 00 pushl $0
84// DISASM-NEXT: 1103b: e9 e0 ff ff ff jmp -32 <.plt>
85// DISASM-NEXT: 11040: ff 25 10 20 01 00 jmpl *73744
86// DISASM-NEXT: 11046: 68 08 00 00 00 pushl $8
87// DISASM-NEXT: 1104b: e9 d0 ff ff ff jmp -48 <.plt>
88
89// CHECKSHARED: Name: .plt
90// CHECKSHARED-NEXT: Type: SHT_PROGBITS
91// CHECKSHARED-NEXT: Flags [
92// CHECKSHARED-NEXT: SHF_ALLOC
93// CHECKSHARED-NEXT: SHF_EXECINSTR
94// CHECKSHARED-NEXT: ]
95// CHECKSHARED-NEXT: Address: 0x1020
96// CHECKSHARED-NEXT: Offset: 0x1020
97// CHECKSHARED-NEXT: Size: 48
98// CHECKSHARED-NEXT: Link: 0
99// CHECKSHARED-NEXT: Info: 0
100// CHECKSHARED-NEXT: AddressAlignment: 16
101// CHECKSHARED-NEXT: EntrySize: 0
102// CHECKSHARED-NEXT: }
103// CHECKSHARED: Name: .got.plt
104// CHECKSHARED-NEXT: Type: SHT_PROGBITS
105// CHECKSHARED-NEXT: Flags [
106// CHECKSHARED-NEXT: SHF_ALLOC
107// CHECKSHARED-NEXT: SHF_WRITE
108// CHECKSHARED-NEXT: ]
109// CHECKSHARED-NEXT: Address: 0x2000
110// CHECKSHARED-NEXT: Offset: 0x2000
111// CHECKSHARED-NEXT: Size: 20
112// CHECKSHARED-NEXT: Link: 0
113// CHECKSHARED-NEXT: Info: 0
114// CHECKSHARED-NEXT: AddressAlignment: 4
115// CHECKSHARED-NEXT: EntrySize: 0
116// CHECKSHARED-NEXT: }
117
118// 0x2000 + got.plt.reserved(12) = 0x200C
119// 0x2000 + got.plt.reserved(12) + 4 = 0x2010
120// CHECKSHARED: Relocations [
121// CHECKSHARED-NEXT: Section ({{.*}}) .rel.plt {
122// CHECKSHARED-NEXT: 0x200C R_386_JUMP_SLOT bar 0x0
123// CHECKSHARED-NEXT: 0x2010 R_386_JUMP_SLOT zed 0x0
124// CHECKSHARED-NEXT: }
125// CHECKSHARED-NEXT: ]
126
127// DISASMSHARED: local:
128// DISASMSHARED-NEXT: 1000: {{.*}}
129// DISASMSHARED-NEXT: 1002: {{.*}}
130// DISASMSHARED: _start:
131// 0x1013 + 5 - 24 = 0x1000
132// DISASMSHARED-NEXT: 1004: e9 27 00 00 00 jmp 39
133// DISASMSHARED-NEXT: 1009: e9 22 00 00 00 jmp 34
134// DISASMSHARED-NEXT: 100e: e9 2d 00 00 00 jmp 45
135// DISASMSHARED-NEXT: 1013: e9 e8 ff ff ff jmp -24
136// DISASMSHARED-NEXT: Disassembly of section .plt:
137// DISASMSHARED-NEXT: .plt:
138// DISASMSHARED-NEXT: 1020: ff b3 04 20 00 00 pushl 8196(%ebx)
139// DISASMSHARED-NEXT: 1026: ff a3 08 20 00 00 jmpl *8200(%ebx)
140// DISASMSHARED-NEXT: 102c: 90 nop
141// DISASMSHARED-NEXT: 102d: 90 nop
142// DISASMSHARED-NEXT: 102e: 90 nop
143// DISASMSHARED-NEXT: 102f: 90 nop
144// DISASMSHARED-NEXT: 1030: ff a3 0c 20 00 00 jmpl *8204(%ebx)
145// DISASMSHARED-NEXT: 1036: 68 00 00 00 00 pushl $0
146// DISASMSHARED-NEXT: 103b: e9 e0 ff ff ff jmp -32 <.plt>
147// DISASMSHARED-NEXT: 1040: ff a3 10 20 00 00 jmpl *8208(%ebx)
148// DISASMSHARED-NEXT: 1046: 68 08 00 00 00 pushl $8
149// DISASMSHARED-NEXT: 104b: e9 d0 ff ff ff jmp -48 <.plt>
150
151// DISASMPIE: Disassembly of section .plt:
152// DISASMPIE-NEXT: .plt:
153// DISASMPIE-NEXT: 1020: ff b3 04 20 00 00 pushl 8196(%ebx)
154// DISASMPIE-NEXT: 1026: ff a3 08 20 00 00 jmpl *8200(%ebx)
155// DISASMPIE-NEXT: 102c: 90 nop
156// DISASMPIE-NEXT: 102d: 90 nop
157// DISASMPIE-NEXT: 102e: 90 nop
158// DISASMPIE-NEXT: 102f: 90 nop
159// DISASMPIE-NEXT: 1030: ff a3 0c 20 00 00 jmpl *8204(%ebx)
160// DISASMPIE-NEXT: 1036: 68 00 00 00 00 pushl $0
161// DISASMPIE-NEXT: 103b: e9 e0 ff ff ff jmp -32 <.plt>
162// DISASMPIE-NEXT: 1040: ff a3 10 20 00 00 jmpl *8208(%ebx)
163// DISASMPIE-NEXT: 1046: 68 08 00 00 00 pushl $8
164// DISASMPIE-NEXT: 104b: e9 d0 ff ff ff jmp -48 <.plt>
165
166local:
167.long 0
168
169.global _start
170_start:
171 jmp bar@PLT
172 jmp bar@PLT
173 jmp zed@PLT
174 jmp local@plt
deps/lld/test/ELF/plt.s created+119
......@@ -0,0 +1,119 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o
3// RUN: ld.lld -shared %t2.o -o %t2.so
4// RUN: ld.lld -shared %t.o %t2.so -o %t
5// RUN: ld.lld %t.o %t2.so -o %t3
6// RUN: llvm-readobj -s -r %t | FileCheck %s
7// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
8// RUN: llvm-readobj -s -r %t3 | FileCheck --check-prefix=CHECK2 %s
9// RUN: llvm-objdump -d %t3 | FileCheck --check-prefix=DISASM2 %s
10
11// REQUIRES: x86
12
13// CHECK: Name: .plt
14// CHECK-NEXT: Type: SHT_PROGBITS
15// CHECK-NEXT: Flags [
16// CHECK-NEXT: SHF_ALLOC
17// CHECK-NEXT: SHF_EXECINSTR
18// CHECK-NEXT: ]
19// CHECK-NEXT: Address: 0x1020
20// CHECK-NEXT: Offset:
21// CHECK-NEXT: Size: 64
22// CHECK-NEXT: Link: 0
23// CHECK-NEXT: Info: 0
24// CHECK-NEXT: AddressAlignment: 16
25
26// CHECK: Relocations [
27// CHECK-NEXT: Section ({{.*}}) .rela.plt {
28// CHECK-NEXT: 0x2018 R_X86_64_JUMP_SLOT bar 0x0
29// CHECK-NEXT: 0x2020 R_X86_64_JUMP_SLOT zed 0x0
30// CHECK-NEXT: 0x2028 R_X86_64_JUMP_SLOT _start 0x0
31// CHECK-NEXT: }
32// CHECK-NEXT: ]
33
34// CHECK2: Name: .plt
35// CHECK2-NEXT: Type: SHT_PROGBITS
36// CHECK2-NEXT: Flags [
37// CHECK2-NEXT: SHF_ALLOC
38// CHECK2-NEXT: SHF_EXECINSTR
39// CHECK2-NEXT: ]
40// CHECK2-NEXT: Address: 0x201020
41// CHECK2-NEXT: Offset:
42// CHECK2-NEXT: Size: 48
43// CHECK2-NEXT: Link: 0
44// CHECK2-NEXT: Info: 0
45// CHECK2-NEXT: AddressAlignment: 16
46
47// CHECK2: Relocations [
48// CHECK2-NEXT: Section ({{.*}}) .rela.plt {
49// CHECK2-NEXT: 0x202018 R_X86_64_JUMP_SLOT bar 0x0
50// CHECK2-NEXT: 0x202020 R_X86_64_JUMP_SLOT zed 0x0
51// CHECK2-NEXT: }
52// CHECK2-NEXT: ]
53
54// Unfortunately FileCheck can't do math, so we have to check for explicit
55// values:
56
57// 0x1030 - (0x1000 + 5) = 43
58// 0x1030 - (0x1005 + 5) = 38
59// 0x1040 - (0x100a + 5) = 49
60// 0x1048 - (0x100a + 5) = 60
61
62// DISASM: _start:
63// DISASM-NEXT: 1000: e9 {{.*}} jmp 43
64// DISASM-NEXT: 1005: e9 {{.*}} jmp 38
65// DISASM-NEXT: 100a: e9 {{.*}} jmp 49
66// DISASM-NEXT: 100f: e9 {{.*}} jmp 60
67
68// 0x2018 - 0x1036 = 4066
69// 0x2020 - 0x1046 = 4058
70// 0x2028 - 0x1056 = 4050
71
72// DISASM: Disassembly of section .plt:
73// DISASM-NEXT: .plt:
74// DISASM-NEXT: 1020: ff 35 e2 0f 00 00 pushq 4066(%rip)
75// DISASM-NEXT: 1026: ff 25 e4 0f 00 00 jmpq *4068(%rip)
76// DISASM-NEXT: 102c: 0f 1f 40 00 nopl (%rax)
77// DISASM-NEXT: 1030: ff 25 e2 0f 00 00 jmpq *4066(%rip)
78// DISASM-NEXT: 1036: 68 00 00 00 00 pushq $0
79// DISASM-NEXT: 103b: e9 e0 ff ff ff jmp -32 <.plt>
80// DISASM-NEXT: 1040: ff 25 da 0f 00 00 jmpq *4058(%rip)
81// DISASM-NEXT: 1046: 68 01 00 00 00 pushq $1
82// DISASM-NEXT: 104b: e9 d0 ff ff ff jmp -48 <.plt>
83// DISASM-NEXT: 1050: ff 25 d2 0f 00 00 jmpq *4050(%rip)
84// DISASM-NEXT: 1056: 68 02 00 00 00 pushq $2
85// DISASM-NEXT: 105b: e9 c0 ff ff ff jmp -64 <.plt>
86
87// 0x201030 - (0x201000 + 1) - 4 = 43
88// 0x201030 - (0x201005 + 1) - 4 = 38
89// 0x201040 - (0x20100a + 1) - 4 = 49
90// 0x201000 - (0x20100f + 1) - 4 = -20
91
92// DISASM2: _start:
93// DISASM2-NEXT: 201000: e9 {{.*}} jmp 43
94// DISASM2-NEXT: 201005: e9 {{.*}} jmp 38
95// DISASM2-NEXT: 20100a: e9 {{.*}} jmp 49
96// DISASM2-NEXT: 20100f: e9 {{.*}} jmp -20
97
98// 0x202018 - 0x201036 = 4066
99// 0x202020 - 0x201046 = 4058
100
101// DISASM2: Disassembly of section .plt:
102// DISASM2-NEXT: .plt:
103// DISASM2-NEXT: 201020: ff 35 e2 0f 00 00 pushq 4066(%rip)
104// DISASM2-NEXT: 201026: ff 25 e4 0f 00 00 jmpq *4068(%rip)
105// DISASM2-NEXT: 20102c: 0f 1f 40 00 nopl (%rax)
106// DISASM2-NEXT: 201030: ff 25 e2 0f 00 00 jmpq *4066(%rip)
107// DISASM2-NEXT: 201036: 68 00 00 00 00 pushq $0
108// DISASM2-NEXT: 20103b: e9 e0 ff ff ff jmp -32 <.plt>
109// DISASM2-NEXT: 201040: ff 25 da 0f 00 00 jmpq *4058(%rip)
110// DISASM2-NEXT: 201046: 68 01 00 00 00 pushq $1
111// DISASM2-NEXT: 20104b: e9 d0 ff ff ff jmp -48 <.plt>
112// DISASM2-NOT: 2010C0
113
114.global _start
115_start:
116 jmp bar@PLT
117 jmp bar@PLT
118 jmp zed@PLT
119 jmp _start@plt
deps/lld/test/ELF/ppc-relocs.s created+64
......@@ -0,0 +1,64 @@
1# RUN: llvm-mc -filetype=obj -triple=powerpc-unknown-freebsd %s -o %t
2# RUN: ld.lld %t -o %t2
3# RUN: llvm-objdump -d %t2 | FileCheck %s
4# REQUIRES: ppc
5
6.section .R_PPC_ADDR16_HA,"ax",@progbits
7.globl _start
8_start:
9 lis 4, msg@ha
10msg:
11 .string "foo"
12 len = . - msg
13
14# CHECK: Disassembly of section .R_PPC_ADDR16_HA:
15# CHECK: _start:
16# CHECK: 11000: 3c 80 00 01 lis 4, 1
17# CHECK: msg:
18# CHECK: 11004: 66 6f 6f 00 oris 15, 19, 28416
19
20.section .R_PPC_ADDR16_LO,"ax",@progbits
21 addi 4, 4, msg@l
22mystr:
23 .asciz "blah"
24 len = . - mystr
25
26# CHECK: Disassembly of section .R_PPC_ADDR16_LO:
27# CHECK: .R_PPC_ADDR16_LO:
28# CHECK: 11008: 38 84 10 04 addi 4, 4, 4100
29# CHECK: mystr:
30# CHECK: 1100c: 62 6c 61 68 ori 12, 19, 24936
31
32.align 2
33.section .R_PPC_REL24,"ax",@progbits
34.globl .FR_PPC_REL24
35.FR_PPC_REL24:
36 b .Lfoox
37.section .R_PPC_REL24_2,"ax",@progbits
38.Lfoox:
39
40# CHECK: Disassembly of section .R_PPC_REL24:
41# CHECK: .FR_PPC_REL24:
42# CHECK: 11014: 48 00 00 04 b .+4
43
44.section .R_PPC_REL32,"ax",@progbits
45.globl .FR_PPC_REL32
46.FR_PPC_REL32:
47 .long .Lfoox3 - .
48.section .R_PPC_REL32_2,"ax",@progbits
49.Lfoox3:
50
51# CHECK: Disassembly of section .R_PPC_REL32:
52# CHECK: .FR_PPC_REL32:
53# CHECK: 11018: 00 00 00 04
54
55.section .R_PPC_ADDR32,"ax",@progbits
56.globl .FR_PPC_ADDR32
57.FR_PPC_ADDR32:
58 .long .Lfoox2
59.section .R_PPC_ADDR32_2,"ax",@progbits
60.Lfoox2:
61
62# CHECK: Disassembly of section .R_PPC_ADDR32:
63# CHECK: .FR_PPC_ADDR32:
64# CHECK: 1101c: 00 01 10 20
deps/lld/test/ELF/ppc64-addr16-error.s created+8
......@@ -0,0 +1,8 @@
1// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t
2// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/ppc64-addr16-error.s -o %t2
3// RUN: not ld.lld -shared %t %t2 -o %t3 2>&1 | FileCheck %s
4// REQUIRES: ppc
5
6.short sym+65539
7
8// CHECK: relocation R_PPC64_ADDR16 out of range
deps/lld/test/ELF/ppc64-rel-calls.s created+42
......@@ -0,0 +1,42 @@
1# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t
2# RUN: ld.lld %t -o %t2
3# RUN: llvm-objdump -d %t2 | FileCheck %s
4# REQUIRES: ppc
5
6# CHECK: Disassembly of section .text:
7
8.section ".opd","aw"
9.global _start
10_start:
11.quad .Lfoo,.TOC.@tocbase,0
12
13.text
14.Lfoo:
15 li 0,1
16 li 3,42
17 sc
18
19# CHECK: 10010000: 38 00 00 01 li 0, 1
20# CHECK: 10010004: 38 60 00 2a li 3, 42
21# CHECK: 10010008: 44 00 00 02 sc
22
23.section ".opd","aw"
24.global bar
25bar:
26.quad .Lbar,.TOC.@tocbase,0
27
28.text
29.Lbar:
30 bl _start
31 nop
32 bl .Lfoo
33 nop
34 blr
35
36# FIXME: The printing here is misleading, the branch offset here is negative.
37# CHECK: 1001000c: 4b ff ff f5 bl .+67108852
38# CHECK: 10010010: 60 00 00 00 nop
39# CHECK: 10010014: 4b ff ff ed bl .+67108844
40# CHECK: 10010018: 60 00 00 00 nop
41# CHECK: 1001001c: 4e 80 00 20 blr
42
deps/lld/test/ELF/ppc64-relocs.s created+130
......@@ -0,0 +1,130 @@
1# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t
2# RUN: ld.lld %t -o %t2
3# RUN: llvm-objdump -d %t2 | FileCheck %s
4# REQUIRES: ppc
5
6.section ".opd","aw"
7.global _start
8_start:
9.quad .Lfoo,.TOC.@tocbase,0
10
11.text
12.Lfoo:
13 li 0,1
14 li 3,42
15 sc
16
17.section ".toc","aw"
18.L1:
19.quad 22, 37, 89, 47
20
21.section .R_PPC64_TOC16_LO_DS,"ax",@progbits
22.globl .FR_PPC64_TOC16_LO_DS
23.FR_PPC64_TOC16_LO_DS:
24 ld 1, .L1@toc@l(2)
25
26# CHECK: Disassembly of section .R_PPC64_TOC16_LO_DS:
27# CHECK: .FR_PPC64_TOC16_LO_DS:
28# CHECK: 1001000c: e8 22 80 00 ld 1, -32768(2)
29
30.section .R_PPC64_TOC16_LO,"ax",@progbits
31.globl .FR_PPC64_TOC16_LO
32.FR_PPC64_TOC16_LO:
33 addi 1, 2, .L1@toc@l
34
35# CHECK: Disassembly of section .R_PPC64_TOC16_LO:
36# CHECK: .FR_PPC64_TOC16_LO:
37# CHECK: 10010010: 38 22 80 00 addi 1, 2, -32768
38
39.section .R_PPC64_TOC16_HI,"ax",@progbits
40.globl .FR_PPC64_TOC16_HI
41.FR_PPC64_TOC16_HI:
42 addis 1, 2, .L1@toc@h
43
44# CHECK: Disassembly of section .R_PPC64_TOC16_HI:
45# CHECK: .FR_PPC64_TOC16_HI:
46# CHECK: 10010014: 3c 22 ff fe addis 1, 2, -2
47
48.section .R_PPC64_TOC16_HA,"ax",@progbits
49.globl .FR_PPC64_TOC16_HA
50.FR_PPC64_TOC16_HA:
51 addis 1, 2, .L1@toc@ha
52
53# CHECK: Disassembly of section .R_PPC64_TOC16_HA:
54# CHECK: .FR_PPC64_TOC16_HA:
55# CHECK: 10010018: 3c 22 ff ff addis 1, 2, -1
56
57.section .R_PPC64_REL24,"ax",@progbits
58.globl .FR_PPC64_REL24
59.FR_PPC64_REL24:
60 b .Lfoox
61.section .R_PPC64_REL24_2,"ax",@progbits
62.Lfoox:
63
64# CHECK: Disassembly of section .R_PPC64_REL24:
65# CHECK: .FR_PPC64_REL24:
66# CHECK: 1001001c: 48 00 00 04 b .+4
67
68.section .R_PPC64_ADDR16_LO,"ax",@progbits
69.globl .FR_PPC64_ADDR16_LO
70.FR_PPC64_ADDR16_LO:
71 li 1, .Lfoo@l
72
73# CHECK: Disassembly of section .R_PPC64_ADDR16_LO:
74# CHECK: .FR_PPC64_ADDR16_LO:
75# CHECK: 10010020: 38 20 00 00 li 1, 0
76
77.section .R_PPC64_ADDR16_HI,"ax",@progbits
78.globl .FR_PPC64_ADDR16_HI
79.FR_PPC64_ADDR16_HI:
80 li 1, .Lfoo@h
81
82# CHECK: Disassembly of section .R_PPC64_ADDR16_HI:
83# CHECK: .FR_PPC64_ADDR16_HI:
84# CHECK: 10010024: 38 20 10 01 li 1, 4097
85
86.section .R_PPC64_ADDR16_HA,"ax",@progbits
87.globl .FR_PPC64_ADDR16_HA
88.FR_PPC64_ADDR16_HA:
89 li 1, .Lfoo@ha
90
91# CHECK: Disassembly of section .R_PPC64_ADDR16_HA:
92# CHECK: .FR_PPC64_ADDR16_HA:
93# CHECK: 10010028: 38 20 10 01 li 1, 4097
94
95.section .R_PPC64_ADDR16_HIGHER,"ax",@progbits
96.globl .FR_PPC64_ADDR16_HIGHER
97.FR_PPC64_ADDR16_HIGHER:
98 li 1, .Lfoo@higher
99
100# CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHER:
101# CHECK: .FR_PPC64_ADDR16_HIGHER:
102# CHECK: 1001002c: 38 20 00 00 li 1, 0
103
104.section .R_PPC64_ADDR16_HIGHERA,"ax",@progbits
105.globl .FR_PPC64_ADDR16_HIGHERA
106.FR_PPC64_ADDR16_HIGHERA:
107 li 1, .Lfoo@highera
108
109# CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHERA:
110# CHECK: .FR_PPC64_ADDR16_HIGHERA:
111# CHECK: 10010030: 38 20 00 00 li 1, 0
112
113.section .R_PPC64_ADDR16_HIGHEST,"ax",@progbits
114.globl .FR_PPC64_ADDR16_HIGHEST
115.FR_PPC64_ADDR16_HIGHEST:
116 li 1, .Lfoo@highest
117
118# CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHEST:
119# CHECK: .FR_PPC64_ADDR16_HIGHEST:
120# CHECK: 10010034: 38 20 00 00 li 1, 0
121
122.section .R_PPC64_ADDR16_HIGHESTA,"ax",@progbits
123.globl .FR_PPC64_ADDR16_HIGHESTA
124.FR_PPC64_ADDR16_HIGHESTA:
125 li 1, .Lfoo@highesta
126
127# CHECK: Disassembly of section .R_PPC64_ADDR16_HIGHESTA:
128# CHECK: .FR_PPC64_ADDR16_HIGHESTA:
129# CHECK: 10010038: 38 20 00 00 li 1, 0
130
deps/lld/test/ELF/ppc64-shared-rel-toc.s created+27
......@@ -0,0 +1,27 @@
1// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
2// RUN: ld.lld -shared %t.o -o %t.so
3// RUN: llvm-readobj -t -r -dyn-symbols %t.so | FileCheck %s
4// REQUIRES: ppc
5
6// When we create the TOC reference in the shared library, make sure that the
7// R_PPC64_RELATIVE relocation uses the correct (non-zero) offset.
8
9 .globl foo
10 .align 2
11 .type foo,@function
12 .section .opd,"aw",@progbits
13foo: # @foo
14 .align 3
15 .quad .Lfunc_begin0
16 .quad .TOC.@tocbase
17 .quad 0
18 .text
19.Lfunc_begin0:
20 blr
21
22// CHECK: 0x20000 R_PPC64_RELATIVE - 0x10000
23// CHECK: 0x20008 R_PPC64_RELATIVE - 0x8000
24
25// CHECK: Name: foo
26// CHECK-NEXT: Value: 0x20000
27
deps/lld/test/ELF/ppc64-toc-restore.s created+62
......@@ -0,0 +1,62 @@
1// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
2// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared-ppc64.s -o %t2.o
3// RUN: ld.lld -shared %t2.o -o %t2.so
4// RUN: ld.lld %t.o %t2.so -o %t
5// RUN: llvm-objdump -d %t | FileCheck %s
6// REQUIRES: ppc
7
8// CHECK: Disassembly of section .text:
9
10.global _start
11_start:
12 bl bar
13 nop
14
15// CHECK: _start:
16// CHECK: 10010000: 48 00 00 21 bl .+32
17// CHECK-NOT: 10010004: 60 00 00 00 nop
18// CHECK: 10010004: e8 41 00 28 ld 2, 40(1)
19
20.global noret
21noret:
22 bl bar
23 li 5, 7
24
25// CHECK: noret:
26// CHECK: 10010008: 48 00 00 19 bl .+24
27// CHECK: 1001000c: 38 a0 00 07 li 5, 7
28
29.global noretend
30noretend:
31 bl bar
32
33// CHECK: noretend:
34// CHECK: 10010010: 48 00 00 11 bl .+16
35
36.global noretb
37noretb:
38 b bar
39
40// CHECK: noretb:
41// CHECK: 10010014: 48 00 00 0c b .+12
42
43// This should come last to check the end-of-buffer condition.
44.global last
45last:
46 bl bar
47 nop
48
49// CHECK: last:
50// CHECK: 10010018: 48 00 00 09 bl .+8
51// CHECK: 1001001c: e8 41 00 28 ld 2, 40(1)
52
53// CHECK: Disassembly of section .plt:
54// CHECK: .plt:
55// CHECK: 10010020: f8 41 00 28 std 2, 40(1)
56// CHECK: 10010024: 3d 62 10 02 addis 11, 2, 4098
57// CHECK: 10010028: e9 8b 80 18 ld 12, -32744(11)
58// CHECK: 1001002c: e9 6c 00 00 ld 11, 0(12)
59// CHECK: 10010030: 7d 69 03 a6 mtctr 11
60// CHECK: 10010034: e8 4c 00 08 ld 2, 8(12)
61// CHECK: 10010038: e9 6c 00 10 ld 11, 16(12)
62// CHECK: 1001003c: 4e 80 04 20 bctr
deps/lld/test/ELF/ppc64-weak-undef-call-shared.s created+16
......@@ -0,0 +1,16 @@
1# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
2# RUN: ld.lld -shared %t.o -o %t.so
3# RUN: llvm-readobj -t -r -dyn-symbols %t.so | FileCheck %s
4# REQUIRES: ppc
5
6.section ".toc","aw"
7.quad weakfunc
8// CHECK-NOT: R_PPC64_RELATIVE
9
10.text
11.Lfoo:
12 bl weakfunc
13// CHECK-NOT: R_PPC64_REL24
14
15.weak weakfunc
16
deps/lld/test/ELF/ppc64-weak-undef-call.s created+27
......@@ -0,0 +1,27 @@
1# RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t
2# RUN: ld.lld %t -o %t2
3# RUN: llvm-objdump -d %t2 | FileCheck %s
4# REQUIRES: ppc
5
6# CHECK: Disassembly of section .text:
7
8.section ".opd","aw"
9.global _start
10_start:
11.quad .Lfoo,.TOC.@tocbase,0
12
13.text
14.Lfoo:
15 bl weakfunc
16 nop
17 blr
18
19.weak weakfunc
20
21# It does not really matter how we fixup the bl, if at all, because it needs to
22# be unreachable. But, we should link successfully. We should not, however,
23# generate a .plt entry (this would be wasted space). For now, we do nothing
24# (leaving the zero relative offset present in the input).
25# CHECK: 10010000: 48 00 00 01 bl .+0
26# CHECK: 10010004: 60 00 00 00 nop
27# CHECK: 10010008: 4e 80 00 20 blr
deps/lld/test/ELF/pre_init_fini_array.s created+152
......@@ -0,0 +1,152 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2
3// RUN: ld.lld %t2 -o %t2.so -shared
4// RUN: ld.lld %t %t2.so -o %t2
5// RUN: llvm-readobj -r -symbols -sections -dynamic-table %t2 | FileCheck %s
6// RUN: llvm-objdump -d %t2 | FileCheck --check-prefix=DISASM %s
7// REQUIRES: x86
8
9.globl _start
10_start:
11 call __preinit_array_start
12 call __preinit_array_end
13 call __init_array_start
14 call __init_array_end
15 call __fini_array_start
16 call __fini_array_end
17
18
19.section .init_array,"aw",@init_array
20 .quad 0
21
22.section .preinit_array,"aw",@preinit_array
23 .quad 0
24 .byte 0
25
26.section .fini_array,"aw",@fini_array
27 .quad 0
28 .short 0
29
30// CHECK: Name: .init_array
31// CHECK-NEXT: Type: SHT_INIT_ARRAY
32// CHECK-NEXT: Flags [
33// CHECK-NEXT: SHF_ALLOC
34// CHECK-NEXT: SHF_WRITE
35// CHECK-NEXT: ]
36// CHECK-NEXT: Address: [[INIT_ADDR:.*]]
37// CHECK-NEXT: Offset:
38// CHECK-NEXT: Size: [[INIT_SIZE:.*]]
39
40
41// CHECK: Name: .preinit_array
42// CHECK-NEXT: Type: SHT_PREINIT_ARRAY
43// CHECK-NEXT: Flags [
44// CHECK-NEXT: SHF_ALLOC
45// CHECK-NEXT: SHF_WRITE
46// CHECK-NEXT: ]
47// CHECK-NEXT: Address: [[PREINIT_ADDR:.*]]
48// CHECK-NEXT: Offset:
49// CHECK-NEXT: Size: [[PREINIT_SIZE:.*]]
50
51
52// CHECK: Name: .fini_array
53// CHECK-NEXT: Type: SHT_FINI_ARRAY
54// CHECK-NEXT: Flags [
55// CHECK-NEXT: SHF_ALLOC
56// CHECK-NEXT: SHF_WRITE
57// CHECK-NEXT: ]
58// CHECK-NEXT: Address: [[FINI_ADDR:.*]]
59// CHECK-NEXT: Offset:
60// CHECK-NEXT: Size: [[FINI_SIZE:.*]]
61
62// CHECK: Relocations [
63// CHECK-NEXT: ]
64
65// CHECK: Name: __fini_array_end
66// CHECK-NEXT: Value: 0x20201B
67// CHECK-NEXT: Size: 0
68// CHECK-NEXT: Binding: Local
69// CHECK-NEXT: Type: None
70// CHECK-NEXT: Other [
71// CHECK-NEXT: STV_HIDDEN
72// CHECK-NEXT: ]
73// CHECK-NEXT: Section: .fini_array
74// CHECK-NEXT: }
75// CHECK-NEXT: Symbol {
76// CHECK-NEXT: Name: __fini_array_start
77// CHECK-NEXT: Value: [[FINI_ADDR]]
78// CHECK-NEXT: Size: 0
79// CHECK-NEXT: Binding: Local
80// CHECK-NEXT: Type: None
81// CHECK-NEXT: Other [
82// CHECK-NEXT: STV_HIDDEN
83// CHECK-NEXT: ]
84// CHECK-NEXT: Section: .fini_array
85// CHECK-NEXT: }
86// CHECK-NEXT: Symbol {
87// CHECK-NEXT: Name: __init_array_end
88// CHECK-NEXT: Value: 0x202008
89// CHECK-NEXT: Size: 0
90// CHECK-NEXT: Binding: Local
91// CHECK-NEXT: Type: None
92// CHECK-NEXT: Other [
93// CHECK-NEXT: STV_HIDDEN
94// CHECK-NEXT: ]
95// CHECK-NEXT: Section: .init_array
96// CHECK-NEXT: }
97// CHECK-NEXT: Symbol {
98// CHECK-NEXT: Name: __init_array_start
99// CHECK-NEXT: Value: [[INIT_ADDR]]
100// CHECK-NEXT: Size: 0
101// CHECK-NEXT: Binding: Local
102// CHECK-NEXT: Type: None
103// CHECK-NEXT: Other [
104// CHECK-NEXT: STV_HIDDEN
105// CHECK-NEXT: ]
106// CHECK-NEXT: Section: .init_array
107// CHECK-NEXT: }
108// CHECK-NEXT: Symbol {
109// CHECK-NEXT: Name: __preinit_array_end
110// CHECK-NEXT: Value: 0x202011
111// CHECK-NEXT: Size: 0
112// CHECK-NEXT: Binding: Local
113// CHECK-NEXT: Type: None
114// CHECK-NEXT: Other [
115// CHECK-NEXT: STV_HIDDEN
116// CHECK-NEXT: ]
117// CHECK-NEXT: Section: .preinit_array
118// CHECK-NEXT: }
119// CHECK-NEXT: Symbol {
120// CHECK-NEXT: Name: __preinit_array_start
121// CHECK-NEXT: Value: [[PREINIT_ADDR]]
122// CHECK-NEXT: Size: 0
123// CHECK-NEXT: Binding: Local
124// CHECK-NEXT: Type: None
125// CHECK-NEXT: Other [
126// CHECK-NEXT: STV_HIDDEN
127// CHECK-NEXT: ]
128// CHECK-NEXT: Section: .preinit_array
129// CHECK-NEXT: }
130
131// CHECK: DynamicSection
132// CHECK: PREINIT_ARRAY [[PREINIT_ADDR]]
133// CHECK: PREINIT_ARRAYSZ [[PREINIT_SIZE]] (bytes)
134// CHECK: INIT_ARRAY [[INIT_ADDR]]
135// CHECK: INIT_ARRAYSZ [[INIT_SIZE]] (bytes)
136// CHECK: FINI_ARRAY [[FINI_ADDR]]
137// CHECK: FINI_ARRAYSZ [[FINI_SIZE]] (bytes)
138
139
140// 0x202008 - (0x201000 + 5) = 4099
141// 0x202011 - (0x201005 + 5) = 4103
142// 0x202000 - (0x20100a + 5) = 4081
143// 0x202008 - (0x20100f + 5) = 4084
144// 0x202011 - (0x201014 + 5) = 4088
145// 0x20201B - (0x201019 + 5) = 4093
146// DISASM: _start:
147// DISASM-NEXT: 201000: e8 {{.*}} callq 4099
148// DISASM-NEXT: 201005: e8 {{.*}} callq 4103
149// DISASM-NEXT: 20100a: e8 {{.*}} callq 4081
150// DISASM-NEXT: 20100f: e8 {{.*}} callq 4084
151// DISASM-NEXT: 201014: e8 {{.*}} callq 4088
152// DISASM-NEXT: 201019: e8 {{.*}} callq 4093
deps/lld/test/ELF/pre_init_fini_array_missing.s created+43
......@@ -0,0 +1,43 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
2// RUN: ld.lld %t -o %t2
3// RUN: llvm-objdump -d %t2 | FileCheck %s
4// RUN: ld.lld -pie %t -o %t3
5// RUN: llvm-objdump -d %t3 | FileCheck --check-prefix=PIE %s
6// REQUIRES: x86
7
8.globl _start
9_start:
10 call __preinit_array_start
11 call __preinit_array_end
12 call __init_array_start
13 call __init_array_end
14 call __fini_array_start
15 call __fini_array_end
16
17// With no .init_array section the symbols resolve to 0
18// 0 - (0x201000 + 5) = -2101253
19// 0 - (0x201005 + 5) = -2101258
20// 0 - (0x20100a + 5) = -2101263
21// 0 - (0x20100f + 5) = -2101268
22// 0 - (0x201014 + 5) = -2101273
23// 0 - (0x201019 + 5) = -2101278
24
25// CHECK: Disassembly of section .text:
26// CHECK-NEXT: _start:
27// CHECK-NEXT: 201000: e8 fb ef df ff callq -2101253
28// CHECK-NEXT: 201005: e8 f6 ef df ff callq -2101258
29// CHECK-NEXT: 20100a: e8 f1 ef df ff callq -2101263
30// CHECK-NEXT: 20100f: e8 ec ef df ff callq -2101268
31// CHECK-NEXT: 201014: e8 e7 ef df ff callq -2101273
32// CHECK-NEXT: 201019: e8 e2 ef df ff callq -2101278
33
34// In position-independent binaries, they resolve to the image base.
35
36// PIE: Disassembly of section .text:
37// PIE-NEXT: _start:
38// PIE-NEXT: 1000: e8 fb ef ff ff callq -4101
39// PIE-NEXT: 1005: e8 f6 ef ff ff callq -4106
40// PIE-NEXT: 100a: e8 f1 ef ff ff callq -4111
41// PIE-NEXT: 100f: e8 ec ef ff ff callq -4116
42// PIE-NEXT: 1014: e8 e7 ef ff ff callq -4121
43// PIE-NEXT: 1019: e8 e2 ef ff ff callq -4126
deps/lld/test/ELF/progname.s created+32
......@@ -0,0 +1,32 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: echo .global __progname > %t2.s
4// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %t2.s -o %t2.o
5// RUN: ld.lld -shared %t2.o -o %t2.so
6// RUN: ld.lld -o %t %t.o %t2.so
7// RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
8
9// RUN: echo "VER_1 { global: bar; };" > %t.script
10// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux \
11// RUN: %p/Inputs/progname-ver.s -o %t-ver.o
12// RUN: ld.lld -shared -o %t.so -version-script %t.script %t-ver.o
13// RUN: ld.lld -o %t %t.o %t.so
14// RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
15
16// RUN: echo "{ _start; };" > %t.dynlist
17// RUN: ld.lld -dynamic-list %t.dynlist -o %t %t.o %t.so
18// RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
19
20// CHECK: Name: __progname@
21// CHECK-NEXT: Value: 0x201000
22// CHECK-NEXT: Size: 0
23// CHECK-NEXT: Binding: Global (0x1)
24// CHECK-NEXT: Type: None (0x0)
25// CHECK-NEXT: Other: 0
26// CHECK-NEXT: Section: .text
27// CHECK-NEXT: }
28
29.global _start, __progname
30_start:
31__progname:
32 nop
deps/lld/test/ELF/program-header-layout.s created+85
......@@ -0,0 +1,85 @@
1# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
2# RUN: ld.lld %t -o %t2
3# RUN: llvm-readobj -sections -program-headers %t2 | FileCheck %s
4# REQUIRES: x86
5
6# Check that different output sections with the same flags are merged into a
7# single Read/Write PT_LOAD.
8
9.section .r,"a"
10.globl _start
11_start:
12.quad 0
13
14.section .a,"aw"
15.quad 1
16
17.section .b,"aw"
18.quad 2
19
20# CHECK: Name: .r
21# CHECK-NEXT: Type: SHT_PROGBITS
22# CHECK-NEXT: Flags [
23# CHECK-NEXT: SHF_ALLOC
24# CHECK-NEXT: ]
25# CHECK-NEXT: Address:
26# CHECK-NEXT: Offset: 0x158
27# CHECK-NEXT: Size:
28# CHECK-NEXT: Link:
29# CHECK-NEXT: Info:
30# CHECK-NEXT: AddressAlignment:
31# CHECK-NEXT: EntrySize:
32# CHECK-NEXT: }
33
34# CHECK: ProgramHeaders [
35# CHECK-NEXT: ProgramHeader {
36# CHECK-NEXT: Type: PT_PHDR (0x6)
37# CHECK-NEXT: Offset: 0x40
38# CHECK-NEXT: VirtualAddress: 0x200040
39# CHECK-NEXT: PhysicalAddress: 0x200040
40# CHECK-NEXT: FileSize: 280
41# CHECK-NEXT: MemSize: 280
42# CHECK-NEXT: Flags [ (0x4)
43# CHECK-NEXT: PF_R (0x4)
44# CHECK-NEXT: ]
45# CHECK-NEXT: Alignment: 8
46# CHECK-NEXT: }
47# CHECK-NEXT: ProgramHeader {
48# CHECK-NEXT: Type: PT_LOAD
49# CHECK-NEXT: Offset: 0x0
50# CHECK-NEXT: VirtualAddress:
51# CHECK-NEXT: PhysicalAddress:
52# CHECK-NEXT: FileSize: 352
53# CHECK-NEXT: MemSize: 352
54# CHECK-NEXT: Flags [
55# CHECK-NEXT: PF_R
56# CHECK-NEXT: ]
57# CHECK-NEXT: Alignment:
58# CHECK-NEXT: }
59# CHECK-NEXT: ProgramHeader {
60# CHECK-NEXT: Type: PT_LOAD
61# CHECK-NEXT: Offset:
62# CHECK-NEXT: VirtualAddress:
63# CHECK-NEXT: PhysicalAddress:
64# CHECK-NEXT: FileSize: 16
65# CHECK-NEXT: MemSize: 16
66# CHECK-NEXT: Flags [
67# CHECK-NEXT: PF_R
68# CHECK-NEXT: PF_W
69# CHECK-NEXT: ]
70# CHECK-NEXT: Alignment:
71# CHECK-NEXT: }
72# CHECK-NEXT: ProgramHeader {
73# CHECK-NEXT: Type: PT_GNU_STACK
74# CHECK-NEXT: Offset: 0x0
75# CHECK-NEXT: VirtualAddress: 0x0
76# CHECK-NEXT: PhysicalAddress: 0x0
77# CHECK-NEXT: FileSize: 0
78# CHECK-NEXT: MemSize: 0
79# CHECK-NEXT: Flags [
80# CHECK-NEXT: PF_R
81# CHECK-NEXT: PF_W
82# CHECK-NEXT: ]
83# CHECK-NEXT: Alignment: 0
84# CHECK-NEXT: }
85# CHECK-NEXT: ]
deps/lld/test/ELF/protected-shared.s created+52
......@@ -0,0 +1,52 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/protected-shared.s -o %t2.o
4// RUN: ld.lld -shared %t2.o -o %t2.so
5// RUN: ld.lld %t.o %t2.so -o %t
6// RUN: llvm-readobj -t --dyn-symbols %t | FileCheck %s
7
8 .global _start
9_start:
10
11 .global bar
12bar:
13
14 .data
15 .quad foo
16
17// CHECK: Name: bar
18// CHECK-NEXT: Value:
19// CHECK-NEXT: Size: 0
20// CHECK-NEXT: Binding: Global
21// CHECK-NEXT: Type: None
22// CHECK-NEXT: Other: 0
23// CHECK-NEXT: Section: .text
24
25// CHECK: Name: foo
26// CHECK-NEXT: Value: 0x0
27// CHECK-NEXT: Size: 0
28// CHECK-NEXT: Binding: Global
29// CHECK-NEXT: Type: None
30// CHECK-NEXT: Other: 0
31// CHECK-NEXT: Section: Undefined
32
33// CHECK: DynamicSymbols [
34// CHECK-NEXT: Symbol {
35// CHECK-NEXT: Name: @
36// CHECK-NEXT: Value: 0x0
37// CHECK-NEXT: Size: 0
38// CHECK-NEXT: Binding: Local (0x0)
39// CHECK-NEXT: Type: None (0x0)
40// CHECK-NEXT: Other: 0
41// CHECK-NEXT: Section: Undefined (0x0)
42// CHECK-NEXT: }
43// CHECK-NEXT: Symbol {
44// CHECK-NEXT: Name: foo@
45// CHECK-NEXT: Value: 0x0
46// CHECK-NEXT: Size: 0
47// CHECK-NEXT: Binding: Global
48// CHECK-NEXT: Type: None
49// CHECK-NEXT: Other: 0
50// CHECK-NEXT: Section: Undefined
51// CHECK-NEXT: }
52// CHECK-NEXT: ]
deps/lld/test/ELF/rel-offset.s created+15
......@@ -0,0 +1,15 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: ld.lld %t.o -o %t -shared
4// RUN: llvm-readobj -r %t | FileCheck %s
5
6 .section .data.foo,"aw",@progbits
7 .quad foo
8
9 .section .data.zed,"aw",@progbits
10 .quad foo
11
12// CHECK: Section ({{.*}}) .rela.dyn {
13// CHECK-NEXT: 0x1000 R_X86_64_64 foo 0x0
14// CHECK-NEXT: 0x1008 R_X86_64_64 foo 0x0
15// CHECK-NEXT: }
deps/lld/test/ELF/relative-dynamic-reloc-pie.s created+27
......@@ -0,0 +1,27 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: ld.lld -pie %t.o -o %t.pie
4# RUN: llvm-readobj -r -dyn-symbols %t.pie | FileCheck %s
5
6## Test that we create R_X86_64_RELATIVE relocations with -pie.
7# CHECK: Relocations [
8# CHECK-NEXT: Section ({{.*}}) .rela.dyn {
9# CHECK-NEXT: 0x2000 R_X86_64_RELATIVE - 0x2000
10# CHECK-NEXT: 0x2008 R_X86_64_RELATIVE - 0x2008
11# CHECK-NEXT: 0x2010 R_X86_64_RELATIVE - 0x2009
12# CHECK-NEXT: }
13# CHECK-NEXT: ]
14
15.globl _start
16_start:
17nop
18
19 .data
20foo:
21 .quad foo
22
23.hidden bar
24.global bar
25bar:
26 .quad bar
27 .quad bar + 1
deps/lld/test/ELF/relative-dynamic-reloc-ppc64.s created+67
......@@ -0,0 +1,67 @@
1// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
2// RUN: ld.lld -shared %t.o -o %t.so
3// RUN: llvm-readobj -t -r -dyn-symbols %t.so | FileCheck %s
4// REQUIRES: ppc
5
6// Test that we create R_PPC64_RELATIVE relocations but don't put any
7// symbols in the dynamic symbol table.
8
9// CHECK: Relocations [
10// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
11// CHECK-NEXT: 0x[[FOO_ADDR:.*]] R_PPC64_RELATIVE - 0x[[FOO_ADDR]]
12// CHECK-NEXT: 0x[[BAR_ADDR:.*]] R_PPC64_RELATIVE - 0x[[BAR_ADDR]]
13// CHECK-NEXT: 0x10010 R_PPC64_RELATIVE - 0x10009
14// CHECK-NEXT: 0x{{.*}} R_PPC64_RELATIVE - 0x[[ZED_ADDR:.*]]
15// CHECK-NEXT: 0x{{.*}} R_PPC64_RELATIVE - 0x[[FOO_ADDR]]
16// CHECK-NEXT: 0x10028 R_PPC64_ADDR64 external 0x0
17// CHECK-NEXT: }
18// CHECK-NEXT: ]
19
20// CHECK: Symbols [
21// CHECK: Name: foo
22// CHECK-NEXT: Value: 0x[[FOO_ADDR]]
23// CHECK: Name: bar
24// CHECK-NEXT: Value: 0x[[BAR_ADDR]]
25// CHECK: Name: zed
26// CHECK-NEXT: Value: 0x[[ZED_ADDR]]
27// CHECK: ]
28
29// CHECK: DynamicSymbols [
30// CHECK-NEXT: Symbol {
31// CHECK-NEXT: Name: @
32// CHECK-NEXT: Value: 0x0
33// CHECK-NEXT: Size: 0
34// CHECK-NEXT: Binding: Local
35// CHECK-NEXT: Type: None
36// CHECK-NEXT: Other: 0
37// CHECK-NEXT: Section: Undefined
38// CHECK-NEXT: }
39// CHECK-NEXT: Symbol {
40// CHECK-NEXT: Name: external@
41// CHECK-NEXT: Value: 0x0
42// CHECK-NEXT: Size: 0
43// CHECK-NEXT: Binding: Global
44// CHECK-NEXT: Type: None
45// CHECK-NEXT: Other: 0
46// CHECK-NEXT: Section: Undefined
47// CHECK-NEXT: }
48// CHECK-NEXT: ]
49
50 .data
51foo:
52 .quad foo
53
54 .hidden bar
55 .global bar
56bar:
57 .quad bar
58 .quad bar + 1
59
60 .hidden zed
61 .comm zed,1
62 .quad zed
63
64 .section abc,"aw"
65 .quad foo
66
67 .quad external
deps/lld/test/ELF/relative-dynamic-reloc.s created+71
......@@ -0,0 +1,71 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3// RUN: ld.lld -shared %t.o -o %t.so
4// RUN: llvm-readobj -t -r -dyn-symbols %t.so | FileCheck %s
5
6// Test that we create R_X86_64_RELATIVE relocations but don't put any
7// symbols in the dynamic symbol table.
8
9// CHECK: Relocations [
10// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
11// CHECK-NEXT: 0x[[FOO_ADDR:.*]] R_X86_64_RELATIVE - 0x[[FOO_ADDR]]
12// CHECK-NEXT: 0x[[BAR_ADDR:.*]] R_X86_64_RELATIVE - 0x[[BAR_ADDR]]
13// CHECK-NEXT: 0x1010 R_X86_64_RELATIVE - 0x1009
14// CHECK-NEXT: 0x{{.*}} R_X86_64_RELATIVE - 0x[[ZED_ADDR:.*]]
15// CHECK-NEXT: 0x{{.*}} R_X86_64_RELATIVE - 0x[[FOO_ADDR]]
16// CHECK-NEXT: 0x1028 R_X86_64_64 external 0x0
17// CHECK-NEXT: }
18// CHECK-NEXT: ]
19
20// CHECK: Symbols [
21// CHECK: Name: foo
22// CHECK-NEXT: Value: 0x[[FOO_ADDR]]
23// CHECK: Name: bar
24// CHECK-NEXT: Value: 0x[[BAR_ADDR]]
25// CHECK: Name: zed
26// CHECK-NEXT: Value: 0x[[ZED_ADDR]]
27// CHECK: ]
28
29// CHECK: DynamicSymbols [
30// CHECK-NEXT: Symbol {
31// CHECK-NEXT: Name: @
32// CHECK-NEXT: Value: 0x0
33// CHECK-NEXT: Size: 0
34// CHECK-NEXT: Binding: Local
35// CHECK-NEXT: Type: None
36// CHECK-NEXT: Other: 0
37// CHECK-NEXT: Section: Undefined
38// CHECK-NEXT: }
39// CHECK-NEXT: Symbol {
40// CHECK-NEXT: Name: external@
41// CHECK-NEXT: Value: 0x0
42// CHECK-NEXT: Size: 0
43// CHECK-NEXT: Binding: Global
44// CHECK-NEXT: Type: None
45// CHECK-NEXT: Other: 0
46// CHECK-NEXT: Section: Undefined
47// CHECK-NEXT: }
48// CHECK-NEXT: ]
49
50 .data
51foo:
52 .quad foo
53
54 .hidden bar
55 .global bar
56bar:
57 .quad bar
58 .quad bar + 1
59
60 .hidden zed
61 .comm zed,1
62 .quad zed
63
64 .section abc,"aw"
65 .quad foo
66
67 .quad external
68
69// This doesn't need a relocation.
70 callq localfunc@PLT
71localfunc:
deps/lld/test/ELF/relocatable-bss.s created+40
......@@ -0,0 +1,40 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
3# RUN: ld.lld -r %t1.o -o %t
4# RUN: llvm-readobj -file-headers -sections -program-headers -symbols -r %t | FileCheck %s
5
6## We check here that .bss does not occupy the space in file.
7## If it would, the SectionHeaderOffset would have offset about 5 megabytes.
8# CHECK: ElfHeader {
9# CHECK-NEXT: Ident {
10# CHECK-NEXT: Magic: (7F 45 4C 46)
11# CHECK-NEXT: Class: 64-bit
12# CHECK-NEXT: DataEncoding: LittleEndian
13# CHECK-NEXT: FileVersion: 1
14# CHECK-NEXT: OS/ABI: SystemV
15# CHECK-NEXT: ABIVersion: 0
16# CHECK-NEXT: Unused: (00 00 00 00 00 00 00)
17# CHECK-NEXT: }
18# CHECK-NEXT: Type: Relocatable
19# CHECK-NEXT: Machine: EM_X86_64
20# CHECK-NEXT: Version:
21# CHECK-NEXT: Entry:
22# CHECK-NEXT: ProgramHeaderOffset:
23# CHECK-NEXT: SectionHeaderOffset: 0xD8
24# CHECK-NEXT: Flags [
25# CHECK-NEXT: ]
26# CHECK-NEXT: HeaderSize:
27# CHECK-NEXT: ProgramHeaderEntrySize:
28# CHECK-NEXT: ProgramHeaderCount:
29# CHECK-NEXT: SectionHeaderEntrySize:
30# CHECK-NEXT: SectionHeaderCount:
31# CHECK-NEXT: StringTableSectionIndex:
32# CHECK-NEXT: }
33
34.text
35.globl _start
36_start:
37 nop
38
39.bss
40 .space 5242880
deps/lld/test/ELF/relocatable-comdat-multiple.s created+31
......@@ -0,0 +1,31 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/relocatable-comdat-multiple.s -o %t2.o
4# RUN: ld.lld -r %t.o %t2.o -o %t
5# RUN: llvm-readobj -elf-section-groups %t | FileCheck %s
6
7# CHECK: Groups {
8# CHECK-NEXT: Group {
9# CHECK-NEXT: Name: .group
10# CHECK-NEXT: Index: 2
11# CHECK-NEXT: Type: COMDAT
12# CHECK-NEXT: Signature: aaa
13# CHECK-NEXT: Section(s) in group [
14# CHECK-NEXT: .text.a
15# CHECK-NEXT: .text.b
16# CHECK-NEXT: ]
17# CHECK-NEXT: }
18# CHECK-NEXT: Group {
19# CHECK-NEXT: Name: .group
20# CHECK-NEXT: Index: 5
21# CHECK-NEXT: Type: COMDAT
22# CHECK-NEXT: Signature: bbb
23# CHECK-NEXT: Section(s) in group [
24# CHECK-NEXT: .text.c
25# CHECK-NEXT: .text.d
26# CHECK-NEXT: ]
27# CHECK-NEXT: }
28# CHECK-NEXT: }
29
30.section .text.a,"axG",@progbits,aaa,comdat
31.section .text.b,"axG",@progbits,aaa,comdat
deps/lld/test/ELF/relocatable-comdat.s created+45
......@@ -0,0 +1,45 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: ld.lld -r %t.o %t.o -o %t
4# RUN: llvm-readobj -elf-section-groups -sections %t | FileCheck %s
5
6# CHECK: Name: .text.bar
7# CHECK-NEXT: Type: SHT_PROGBITS
8# CHECK-NEXT: Flags [
9# CHECK-NEXT: SHF_ALLOC
10# CHECK-NEXT: SHF_EXECINSTR
11# CHECK-NEXT: SHF_GROUP
12# CHECK-NEXT: ]
13# CHECK-NEXT: Address:
14# CHECK-NEXT: Offset:
15# CHECK-NEXT: Size: 8
16# CHECK: Section {
17# CHECK-NEXT: Index: 4
18# CHECK-NEXT: Name: .text.foo
19# CHECK-NEXT: Type: SHT_PROGBITS
20# CHECK-NEXT: Flags [
21# CHECK-NEXT: SHF_ALLOC
22# CHECK-NEXT: SHF_EXECINSTR
23# CHECK-NEXT: SHF_GROUP
24# CHECK-NEXT: ]
25# CHECK-NEXT: Address:
26# CHECK-NEXT: Offset:
27# CHECK-NEXT: Size: 4
28
29# CHECK: Groups {
30# CHECK-NEXT: Group {
31# CHECK-NEXT: Name: .group
32# CHECK-NEXT: Index: 2
33# CHECK-NEXT: Type: COMDAT
34# CHECK-NEXT: Signature: abc
35# CHECK-NEXT: Section(s) in group [
36# CHECK-NEXT: .text.bar
37# CHECK-NEXT: .text.foo
38# CHECK-NEXT: ]
39# CHECK-NEXT: }
40# CHECK-NEXT: }
41
42.section .text.bar,"axG",@progbits,abc,comdat
43.quad 42
44.section .text.foo,"axG",@progbits,abc,comdat
45.long 42
deps/lld/test/ELF/relocatable-comment.s created+27
......@@ -0,0 +1,27 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
3# RUN: ld.lld -r %t1.o -o %t
4# RUN: llvm-readobj -s -section-data %t | FileCheck %s
5
6# CHECK: Name: .comment
7# CHECK-NEXT: Type: SHT_PROGBITS
8# CHECK-NEXT: Flags [
9# CHECK-NEXT: SHF_MERGE
10# CHECK-NEXT: SHF_STRINGS
11# CHECK-NEXT: ]
12# CHECK-NEXT: Address:
13# CHECK-NEXT: Offset:
14# CHECK-NEXT: Size: 7
15# CHECK-NEXT: Link:
16# CHECK-NEXT: Info:
17# CHECK-NEXT: AddressAlignment: 1
18# CHECK-NEXT: EntrySize: 1
19# CHECK-NEXT: SectionData (
20# CHECK-NEXT: 0000: 666F6F62 617200 |foobar.|
21# CHECK-NEXT: )
22
23
24# We used to crash creating a merge and non merge .comment sections.
25
26 .section .comment,"MS",@progbits,1
27 .asciz "foobar"
deps/lld/test/ELF/relocatable-common.s created+36
......@@ -0,0 +1,36 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
3# RUN: ld.lld -r %t1.o -o %t
4# RUN: llvm-readobj -symbols -r %t | FileCheck %s
5# RUN: ld.lld -r --no-define-common %t1.o -o %t
6# RUN: llvm-readobj -symbols -r %t | FileCheck %s
7# RUN: ld.lld -r --define-common %t1.o -o %t
8# RUN: llvm-readobj -symbols -r %t | FileCheck -check-prefix=DEFCOMM %s
9# RUN: ld.lld -r -d %t1.o -o %t
10# RUN: llvm-readobj -symbols -r %t | FileCheck -check-prefix=DEFCOMM %s
11# RUN: ld.lld -r -dc %t1.o -o %t
12# RUN: llvm-readobj -symbols -r %t | FileCheck -check-prefix=DEFCOMM %s
13# RUN: ld.lld -r -dp %t1.o -o %t
14# RUN: llvm-readobj -symbols -r %t | FileCheck -check-prefix=DEFCOMM %s
15
16# CHECK: Symbol {
17# CHECK: Name: common
18# CHECK-NEXT: Value: 0x4
19# CHECK-NEXT: Size: 4
20# CHECK-NEXT: Binding: Global
21# CHECK-NEXT: Type: Object
22# CHECK-NEXT: Other: 0
23# CHECK-NEXT: Section: Common (0xFFF2)
24# CHECK-NEXT: }
25
26# DEFCOMM: Symbol {
27# DEFCOMM: Name: common
28# DEFCOMM-NEXT: Value: 0x0
29# DEFCOMM-NEXT: Size: 4
30# DEFCOMM-NEXT: Binding: Global
31# DEFCOMM-NEXT: Type: Object
32# DEFCOMM-NEXT: Other: 0
33# DEFCOMM-NEXT: Section: COMMON (0x2)
34# DEFCOMM-NEXT: }
35
36.comm common,4,4
deps/lld/test/ELF/relocatable-compressed-input.s created+45
......@@ -0,0 +1,45 @@
1# REQUIRES: x86, zlib
2
3# RUN: llvm-mc -compress-debug-sections=zlib-gnu -filetype=obj -triple=x86_64-unknown-linux %s -o %t1
4# RUN: llvm-readobj -sections %t1 | FileCheck -check-prefix=GNU %s
5# GNU: Name: .zdebug_str
6
7# RUN: ld.lld %t1 -o %t2 -r
8# RUN: llvm-readobj -sections -section-data %t2 | FileCheck %s
9
10## Check we decompress section and remove ".z" prefix specific for zlib-gnu compression.
11# CHECK: Section {
12# CHECK: Index:
13# CHECK: Name: .debug_str
14# CHECK-NEXT: Type: SHT_PROGBITS
15# CHECK-NEXT: Flags [
16# CHECK-NEXT: SHF_MERGE
17# CHECK-NEXT: SHF_STRINGS
18# CHECK-NEXT: ]
19# CHECK-NEXT: Address:
20# CHECK-NEXT: Offset:
21# CHECK-NEXT: Size:
22# CHECK-NEXT: Link:
23# CHECK-NEXT: Info:
24# CHECK-NEXT: AddressAlignment: 1
25# CHECK-NEXT: EntrySize: 1
26# CHECK-NEXT: SectionData (
27# CHECK-NEXT: 0000: {{.*}} |short unsigned i|
28# CHECK-NEXT: 0010: {{.*}} |nt.unsigned int.|
29# CHECK-NEXT: 0020: {{.*}} |long unsigned in|
30# CHECK-NEXT: 0030: {{.*}} |t.char.unsigned |
31# CHECK-NEXT: 0040: {{.*}} |char.|
32# CHECK-NEXT: )
33# CHECK-NEXT: }
34
35.section .debug_str,"MS",@progbits,1
36.LASF2:
37 .string "short unsigned int"
38.LASF3:
39 .string "unsigned int"
40.LASF0:
41 .string "long unsigned int"
42.LASF8:
43 .string "char"
44.LASF1:
45 .string "unsigned char"
deps/lld/test/ELF/relocatable-eh-frame-hdr.s created+11
......@@ -0,0 +1,11 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: ld.lld --eh-frame-hdr -r %t.o -o %t
4# RUN: llvm-readobj -s %t | FileCheck %s
5
6# CHECK: Sections [
7# CHECK-NOT: Name: .eh_frame_hdr
8
9.section .foo,"ax",@progbits
10.cfi_startproc
11.cfi_endproc
deps/lld/test/ELF/relocatable-eh-frame.s created+19
......@@ -0,0 +1,19 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: ld.lld -r %t.o %t.o -o %t
4# RUN: llvm-readobj -r %t | FileCheck %s
5# RUN: ld.lld %t -o %t.so -shared
6# RUN: llvm-objdump -h %t.so | FileCheck --check-prefix=DSO %s
7
8# DSO: .eh_frame 00000030
9
10# CHECK: Relocations [
11# CHECK-NEXT: Section ({{.*}}) .rela.eh_frame {
12# CHECK-NEXT: 0x20 R_X86_64_PC32 .foo 0x0
13# CHECK-NEXT: 0x50 R_X86_64_NONE - 0x0
14# CHECK-NEXT: }
15# CHECK-NEXT: ]
16
17.section .foo,"aG",@progbits,bar,comdat
18.cfi_startproc
19.cfi_endproc
deps/lld/test/ELF/relocatable-ehframe.s created+51
......@@ -0,0 +1,51 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/relocatable-ehframe.s -o %t2.o
4# RUN: ld.lld -r %t1.o %t2.o -o %t
5# RUN: llvm-readobj -r -s -section-data %t | FileCheck %s
6
7# CHECK: Name: .strtab
8# CHECK-NEXT: Type: SHT_STRTAB
9# CHECK-NEXT: Flags [
10# CHECK-NEXT: ]
11# CHECK-NEXT: Address:
12# CHECK-NEXT: Offset
13# CHECK-NEXT: Size: 8
14# CHECK-NEXT: Link: 0
15# CHECK-NEXT: Info: 0
16# CHECK-NEXT: AddressAlignment: 1
17# CHECK-NEXT: EntrySize: 0
18# CHECK-NEXT: SectionData (
19# CHECK-NEXT: 0000: 005F7374 61727400 |._start.|
20# CHECK-NEXT: )
21
22# CHECK: Relocations [
23# CHECK-NEXT: Section {{.*}} .rela.eh_frame {
24# CHECK-NEXT: 0x20 R_X86_64_PC32 foo 0x0
25# CHECK-NEXT: 0x34 R_X86_64_PC32 bar 0x0
26# CHECK-NEXT: 0x48 R_X86_64_PC32 dah 0x0
27# CHECK-NEXT: 0x78 R_X86_64_PC32 foo1 0x0
28# CHECK-NEXT: 0x8C R_X86_64_PC32 bar1 0x0
29# CHECK-NEXT: 0xA0 R_X86_64_PC32 dah1 0x0
30# CHECK-NEXT: }
31# CHECK-NEXT: ]
32
33.section foo,"ax",@progbits
34.cfi_startproc
35 nop
36.cfi_endproc
37
38.section bar,"ax",@progbits
39.cfi_startproc
40 nop
41.cfi_endproc
42
43.section dah,"ax",@progbits
44.cfi_startproc
45 nop
46.cfi_endproc
47
48.text
49.globl _start
50_start:
51 nop
deps/lld/test/ELF/relocatable-empty-archive.s created+10
......@@ -0,0 +1,10 @@
1# REQUIRES: x86
2# RUN: rm -f %t.a
3# RUN: llvm-ar rc %t.a
4# RUN: ld.lld -m elf_x86_64 %t.a -o %t -r
5# RUN: llvm-readobj -file-headers %t | FileCheck %s
6
7# CHECK: Format: ELF64-x86-64
8# CHECK: Arch: x86_64
9# CHECK: AddressSize: 64bit
10# CHECK: Type: Relocatable
deps/lld/test/ELF/relocatable-local-sym.s created+16
......@@ -0,0 +1,16 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
3# RUN: ld.lld -r %t1.o -o %t2.o
4# RUN: llvm-readobj -r %t2.o | FileCheck %s
5
6# CHECK: Relocations [
7# CHECK-NEXT: Section ({{.*}}) .rela.text {
8# CHECK-NEXT: 0x3 R_X86_64_PC32 .Lstr 0xFFFFFFFFFFFFFFFC
9# CHECK-NEXT: }
10# CHECK-NEXT: ]
11
12 leaq .Lstr(%rip), %rdi
13
14 .section .rodata.str1.1,"aMS",@progbits,1
15 .Lstr:
16 .asciz "abc\n"
deps/lld/test/ELF/relocatable-non-alloc.s created+10
......@@ -0,0 +1,10 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/relocatable-non-alloc.s -o %t2.o
4# RUN: ld.lld %t2.o %t2.o -r -o %t3.o
5# RUN: ld.lld %t1.o %t3.o -o %t.o | FileCheck -allow-empty %s
6
7# CHECK-NOT: has non-ABS reloc
8
9.globl _start
10_start:
deps/lld/test/ELF/relocatable-reloc.s created+15
......@@ -0,0 +1,15 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj %s -o %t.o -triple=x86_64-pc-linux
3// RUN: ld.lld %t.o %t.o -r -o %t2.o
4// RUN: llvm-readobj -r %t2.o | FileCheck %s
5
6.weak foo
7foo:
8.quad foo
9
10// CHECK: Relocations [
11// CHECK-NEXT: Section ({{.*}}) .rela.text {
12// CHECK-NEXT: 0x0 R_X86_64_64 foo 0x0
13// CHECK-NEXT: 0x8 R_X86_64_64 foo 0x0
14// CHECK-NEXT: }
15// CHECK-NEXT: ]
deps/lld/test/ELF/relocatable-script.s created+7
......@@ -0,0 +1,7 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux -o %t1.o %s
3# RUN: echo "SECTIONS { .foo : { BYTE(0x0) } }" > %t.script
4# RUN: ld.lld -r %t1.o -script %t.script -o %t2.o
5# RUN: llvm-readobj -sections %t2.o | FileCheck %s
6
7# CHECK: Name: .foo
deps/lld/test/ELF/relocatable-section-symbol.s created+50
......@@ -0,0 +1,50 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: ld.lld -r -o %t %t.o %t.o
4# RUN: llvm-readobj -r %t | FileCheck --check-prefix=RELA %s
5
6# RELA: Relocations [
7# RELA-NEXT: Section ({{.*}}) .rela.data {
8# RELA-NEXT: 0x0 R_X86_64_32 .text 0x1
9# RELA-NEXT: 0x4 R_X86_64_32 .text 0x5
10# RELA-NEXT: }
11# RELA-NEXT: ]
12
13
14# RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
15# RUN: ld.lld -r -o %t %t.o %t.o
16# RUN: llvm-readobj -r -s -section-data %t | FileCheck --check-prefix=REL %s
17
18
19# REL: Section {
20# REL: Index:
21# REL: Name: .data
22# REL-NEXT: Type: SHT_PROGBITS
23# REL-NEXT: Flags [
24# REL-NEXT: SHF_ALLOC
25# REL-NEXT: SHF_WRITE
26# REL-NEXT: ]
27# REL-NEXT: Address:
28# REL-NEXT: Offset:
29# REL-NEXT: Size:
30# REL-NEXT: Link:
31# REL-NEXT: Info:
32# REL-NEXT: AddressAlignment:
33# REL-NEXT: EntrySize:
34# REL-NEXT: SectionData (
35# REL-NEXT: 0000: 01000000 05000000 |
36# REL-NEXT: )
37# REL-NEXT: }
38
39
40# REL: Relocations [
41# REL-NEXT: Section ({{.*}}) .rel.data {
42# REL-NEXT: 0x0 R_386_32 .text 0x0
43# REL-NEXT: 0x4 R_386_32 .text 0x0
44# REL-NEXT: }
45# REL-NEXT: ]
46
47
48.long 42
49.data
50.long .text + 1
deps/lld/test/ELF/relocatable-sections.s created+31
......@@ -0,0 +1,31 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
3# RUN: ld.lld -r %t1.o -o %t
4# RUN: llvm-objdump -section-headers %t | FileCheck %s
5
6# CHECK: .text
7# CHECK-NEXT: .rela.text
8# CHECK: .text._init
9# CHECK-NEXT: .rela.text._init
10# CHECK: .text._fini
11# CHECK-NEXT: .rela.text._fini
12
13.globl _start
14_start:
15 call foo
16 nop
17
18.section .xxx,"a"
19 .quad 0
20
21.section .text._init,"ax"
22 .quad .xxx
23foo:
24 call bar
25 nop
26
27
28.section .text._fini,"ax"
29 .quad .xxx
30bar:
31 nop
deps/lld/test/ELF/relocatable-symbol-name.s created+28
......@@ -0,0 +1,28 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: ld.lld -r %t.o -o %t
4# RUN: llvm-readobj -t %t | FileCheck %s
5
6# Test that the section symbol has st_name equal to zero. GNU objdump
7# requires this to print relocations against the section.
8
9# CHECK: Symbols [
10# CHECK-NEXT: Symbol {
11# CHECK-NEXT: Name:
12# CHECK-NEXT: Value:
13# CHECK-NEXT: Size:
14# CHECK-NEXT: Binding:
15# CHECK-NEXT: Type:
16# CHECK-NEXT: Other:
17# CHECK-NEXT: Section:
18# CHECK-NEXT: }
19# CHECK-NEXT: Symbol {
20# CHECK-NEXT: Name: (0)
21# CHECK-NEXT: Value:
22# CHECK-NEXT: Size:
23# CHECK-NEXT: Binding:
24# CHECK-NEXT: Type: Section
25# CHECK-NEXT: Other:
26# CHECK-NEXT: Section: .text
27# CHECK-NEXT: }
28# CHECK-NEXT: ]
deps/lld/test/ELF/relocatable-symbols.s created+201
......@@ -0,0 +1,201 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: ld.lld -r %t -o %tout
4# RUN: llvm-objdump -d %tout | FileCheck -check-prefix=DISASM %s
5# RUN: llvm-readobj -r %t | FileCheck -check-prefix=RELOC %s
6# RUN: llvm-readobj -symbols -r %tout | FileCheck -check-prefix=SYMBOL %s
7
8# DISASM: _start:
9# DISASM-NEXT: 0: {{.*}} callq 0
10# DISASM-NEXT: 5: {{.*}} callq 0
11# DISASM-NEXT: a: {{.*}} callq 0
12# DISASM-NEXT: f: {{.*}} callq 0
13# DISASM-NEXT: 14: {{.*}} callq 0
14# DISASM-NEXT: 19: {{.*}} callq 0
15# DISASM-NEXT: 1e: {{.*}} callq 0
16# DISASM-NEXT: 23: {{.*}} callq 0
17# DISASM-NEXT: 28: {{.*}} callq 0
18# DISASM-NEXT: 2d: {{.*}} callq 0
19# DISASM-NEXT: 32: {{.*}} callq 0
20# DISASM-NEXT: 37: {{.*}} callq 0
21# DISASM-NEXT: Disassembly of section foo:
22# DISASM-NEXT: foo:
23# DISASM-NEXT: 0: 90 nop
24# DISASM-NEXT: 1: 90 nop
25# DISASM-NEXT: 2: 90 nop
26# DISASM-NEXT: Disassembly of section bar:
27# DISASM-NEXT: bar:
28# DISASM-NEXT: 0: 90 nop
29# DISASM-NEXT: 1: 90 nop
30# DISASM-NEXT: 2: 90 nop
31
32# RELOC: Relocations [
33# RELOC-NEXT: Section ({{.*}}) .rela.text {
34# RELOC-NEXT: 0x1 R_X86_64_PC32 __start_foo 0xFFFFFFFFFFFFFFFC
35# RELOC-NEXT: 0x6 R_X86_64_PC32 __stop_foo 0xFFFFFFFFFFFFFFFC
36# RELOC-NEXT: 0xB R_X86_64_PC32 __start_bar 0xFFFFFFFFFFFFFFFC
37# RELOC-NEXT: 0x10 R_X86_64_PC32 __stop_bar 0xFFFFFFFFFFFFFFFC
38# RELOC-NEXT: 0x15 R_X86_64_PC32 __start_doo 0xFFFFFFFFFFFFFFFC
39# RELOC-NEXT: 0x1A R_X86_64_PC32 __stop_doo 0xFFFFFFFFFFFFFFFC
40# RELOC-NEXT: 0x1F R_X86_64_PC32 __preinit_array_start 0xFFFFFFFFFFFFFFFC
41# RELOC-NEXT: 0x24 R_X86_64_PC32 __preinit_array_end 0xFFFFFFFFFFFFFFFC
42# RELOC-NEXT: 0x29 R_X86_64_PC32 __init_array_start 0xFFFFFFFFFFFFFFFC
43# RELOC-NEXT: 0x2E R_X86_64_PC32 __init_array_end 0xFFFFFFFFFFFFFFFC
44# RELOC-NEXT: 0x33 R_X86_64_PC32 __fini_array_start 0xFFFFFFFFFFFFFFFC
45# RELOC-NEXT: 0x38 R_X86_64_PC32 __fini_array_end 0xFFFFFFFFFFFFFFFC
46# RELOC-NEXT: }
47# RELOC-NEXT: ]
48
49# SYMBOL: Relocations [
50# SYMBOL-NEXT: Section ({{.*}}) .rela.text {
51# SYMBOL-NEXT: 0x1 R_X86_64_PC32 __start_foo 0xFFFFFFFFFFFFFFFC
52# SYMBOL-NEXT: 0x6 R_X86_64_PC32 __stop_foo 0xFFFFFFFFFFFFFFFC
53# SYMBOL-NEXT: 0xB R_X86_64_PC32 __start_bar 0xFFFFFFFFFFFFFFFC
54# SYMBOL-NEXT: 0x10 R_X86_64_PC32 __stop_bar 0xFFFFFFFFFFFFFFFC
55# SYMBOL-NEXT: 0x15 R_X86_64_PC32 __start_doo 0xFFFFFFFFFFFFFFFC
56# SYMBOL-NEXT: 0x1A R_X86_64_PC32 __stop_doo 0xFFFFFFFFFFFFFFFC
57# SYMBOL-NEXT: 0x1F R_X86_64_PC32 __preinit_array_start 0xFFFFFFFFFFFFFFFC
58# SYMBOL-NEXT: 0x24 R_X86_64_PC32 __preinit_array_end 0xFFFFFFFFFFFFFFFC
59# SYMBOL-NEXT: 0x29 R_X86_64_PC32 __init_array_start 0xFFFFFFFFFFFFFFFC
60# SYMBOL-NEXT: 0x2E R_X86_64_PC32 __init_array_end 0xFFFFFFFFFFFFFFFC
61# SYMBOL-NEXT: 0x33 R_X86_64_PC32 __fini_array_start 0xFFFFFFFFFFFFFFFC
62# SYMBOL-NEXT: 0x38 R_X86_64_PC32 __fini_array_end 0xFFFFFFFFFFFFFFFC
63# SYMBOL-NEXT: }
64# SYMBOL-NEXT: ]
65# SYMBOL: Symbol {
66# SYMBOL: Name: __fini_array_end
67# SYMBOL-NEXT: Value: 0x0
68# SYMBOL-NEXT: Size: 0
69# SYMBOL-NEXT: Binding: Global
70# SYMBOL-NEXT: Type: None
71# SYMBOL-NEXT: Other: 0
72# SYMBOL-NEXT: Section: Undefined
73# SYMBOL-NEXT: }
74# SYMBOL-NEXT: Symbol {
75# SYMBOL-NEXT: Name: __fini_array_start
76# SYMBOL-NEXT: Value: 0x0
77# SYMBOL-NEXT: Size: 0
78# SYMBOL-NEXT: Binding: Global
79# SYMBOL-NEXT: Type: None
80# SYMBOL-NEXT: Other: 0
81# SYMBOL-NEXT: Section: Undefined
82# SYMBOL-NEXT: }
83# SYMBOL-NEXT: Symbol {
84# SYMBOL-NEXT: Name: __init_array_end
85# SYMBOL-NEXT: Value: 0x0
86# SYMBOL-NEXT: Size: 0
87# SYMBOL-NEXT: Binding: Global
88# SYMBOL-NEXT: Type: None
89# SYMBOL-NEXT: Other: 0
90# SYMBOL-NEXT: Section: Undefined
91# SYMBOL-NEXT: }
92# SYMBOL-NEXT: Symbol {
93# SYMBOL-NEXT: Name: __init_array_start
94# SYMBOL-NEXT: Value: 0x0
95# SYMBOL-NEXT: Size: 0
96# SYMBOL-NEXT: Binding: Global
97# SYMBOL-NEXT: Type: None
98# SYMBOL-NEXT: Other: 0
99# SYMBOL-NEXT: Section: Undefined
100# SYMBOL-NEXT: }
101# SYMBOL-NEXT: Symbol {
102# SYMBOL-NEXT: Name: __preinit_array_end
103# SYMBOL-NEXT: Value: 0x0
104# SYMBOL-NEXT: Size: 0
105# SYMBOL-NEXT: Binding: Global
106# SYMBOL-NEXT: Type: None
107# SYMBOL-NEXT: Other: 0
108# SYMBOL-NEXT: Section: Undefined
109# SYMBOL-NEXT: }
110# SYMBOL-NEXT: Symbol {
111# SYMBOL-NEXT: Name: __preinit_array_start
112# SYMBOL-NEXT: Value: 0x0
113# SYMBOL-NEXT: Size: 0
114# SYMBOL-NEXT: Binding: Global
115# SYMBOL-NEXT: Type: None
116# SYMBOL-NEXT: Other: 0
117# SYMBOL-NEXT: Section: Undefined
118# SYMBOL-NEXT: }
119# SYMBOL-NEXT: Symbol {
120# SYMBOL-NEXT: Name: __start_bar
121# SYMBOL-NEXT: Value: 0x0
122# SYMBOL-NEXT: Size: 0
123# SYMBOL-NEXT: Binding: Global
124# SYMBOL-NEXT: Type: None
125# SYMBOL-NEXT: Other: 0
126# SYMBOL-NEXT: Section: Undefined
127# SYMBOL-NEXT: }
128# SYMBOL-NEXT: Symbol {
129# SYMBOL-NEXT: Name: __start_doo
130# SYMBOL-NEXT: Value: 0x0
131# SYMBOL-NEXT: Size: 0
132# SYMBOL-NEXT: Binding: Global
133# SYMBOL-NEXT: Type: None
134# SYMBOL-NEXT: Other: 0
135# SYMBOL-NEXT: Section: Undefined
136# SYMBOL-NEXT: }
137# SYMBOL-NEXT: Symbol {
138# SYMBOL-NEXT: Name: __start_foo
139# SYMBOL-NEXT: Value: 0x0
140# SYMBOL-NEXT: Size: 0
141# SYMBOL-NEXT: Binding: Global
142# SYMBOL-NEXT: Type: None
143# SYMBOL-NEXT: Other: 0
144# SYMBOL-NEXT: Section: Undefined
145# SYMBOL-NEXT: }
146# SYMBOL-NEXT: Symbol {
147# SYMBOL-NEXT: Name: __stop_bar
148# SYMBOL-NEXT: Value: 0x0
149# SYMBOL-NEXT: Size: 0
150# SYMBOL-NEXT: Binding: Global
151# SYMBOL-NEXT: Type: None
152# SYMBOL-NEXT: Other: 0
153# SYMBOL-NEXT: Section: Undefined
154# SYMBOL-NEXT: }
155# SYMBOL-NEXT: Symbol {
156# SYMBOL-NEXT: Name: __stop_doo
157# SYMBOL-NEXT: Value: 0x0
158# SYMBOL-NEXT: Size: 0
159# SYMBOL-NEXT: Binding: Global
160# SYMBOL-NEXT: Type: None
161# SYMBOL-NEXT: Other: 0
162# SYMBOL-NEXT: Section: Undefined
163# SYMBOL-NEXT: }
164# SYMBOL-NEXT: Symbol {
165# SYMBOL-NEXT: Name: __stop_foo
166# SYMBOL-NEXT: Value: 0x0
167# SYMBOL-NEXT: Size: 0
168# SYMBOL-NEXT: Binding: Global
169# SYMBOL-NEXT: Type: None
170# SYMBOL-NEXT: Other: 0
171# SYMBOL-NEXT: Section: Undefined
172# SYMBOL-NEXT: }
173
174.global _start
175.text
176_start:
177 call __start_foo
178 call __stop_foo
179
180 call __start_bar
181 call __stop_bar
182
183 call __start_doo
184 call __stop_doo
185
186 call __preinit_array_start
187 call __preinit_array_end
188 call __init_array_start
189 call __init_array_end
190 call __fini_array_start
191 call __fini_array_end
192
193.section foo,"ax"
194 nop
195 nop
196 nop
197
198.section bar,"ax"
199 nop
200 nop
201 nop
deps/lld/test/ELF/relocatable-tls.s created+16
......@@ -0,0 +1,16 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
4# RUN: %S/Inputs/relocatable-tls.s -o %t2.o
5
6# RUN: ld.lld -r %t2.o -o %t3.r
7# RUN: llvm-objdump -t %t3.r | FileCheck --check-prefix=RELOCATABLE %s
8# RELOCATABLE: SYMBOL TABLE:
9# RELOCATABLE: 0000000000000000 *UND* 00000000 __tls_get_addr
10
11# RUN: ld.lld -shared %t2.o %t3.r -o %t4.out
12# RUN: llvm-objdump -t %t4.out | FileCheck --check-prefix=DSO %s
13# DSO: SYMBOL TABLE:
14# DSO: 0000000000000000 *UND* 00000000 __tls_get_addr
15
16callq __tls_get_addr@PLT
deps/lld/test/ELF/relocatable-visibility.s created+19
......@@ -0,0 +1,19 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: ld.lld -r %t.o -o %t1
4# RUN: llvm-readobj -t %t1 | FileCheck --check-prefix=RELOCATABLE %s
5
6# RELOCATABLE: Name: foo
7# RELOCATABLE-NEXT: Value: 0x0
8# RELOCATABLE-NEXT: Size: 0
9# RELOCATABLE-NEXT: Binding: Global
10# RELOCATABLE-NEXT: Type: None
11# RELOCATABLE-NEXT: Other [
12# RELOCATABLE-NEXT: STV_HIDDEN
13# RELOCATABLE-NEXT: ]
14# RELOCATABLE-NEXT: Section: Undefined
15
16.global _start
17_start:
18 callq foo
19 .hidden foo
deps/lld/test/ELF/relocatable.s created+120
......@@ -0,0 +1,120 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/relocatable.s -o %t2.o
4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/relocatable2.s -o %t3.o
5# RUN: ld.lld -r %t1.o %t2.o %t3.o -o %t
6# RUN: llvm-readobj -file-headers -sections -program-headers -symbols -r %t | FileCheck %s
7# RUN: llvm-objdump -s -d %t | FileCheck -check-prefix=CHECKTEXT %s
8
9## Test --relocatable alias
10# RUN: ld.lld --relocatable %t1.o %t2.o %t3.o -o %t
11# RUN: llvm-readobj -file-headers -sections -program-headers -symbols -r %t | FileCheck %s
12# RUN: llvm-objdump -s -d %t | FileCheck -check-prefix=CHECKTEXT %s
13
14## Verify that we can use our relocation output as input to produce executable
15# RUN: ld.lld -e main %t -o %texec
16# RUN: llvm-readobj -file-headers %texec | FileCheck -check-prefix=CHECKEXE %s
17
18# CHECK: ElfHeader {
19# CHECK-NEXT: Ident {
20# CHECK-NEXT: Magic: (7F 45 4C 46)
21# CHECK-NEXT: Class: 64-bit
22# CHECK-NEXT: DataEncoding: LittleEndian
23# CHECK-NEXT: FileVersion: 1
24# CHECK-NEXT: OS/ABI: SystemV
25# CHECK-NEXT: ABIVersion: 0
26# CHECK-NEXT: Unused: (00 00 00 00 00 00 00)
27# CHECK-NEXT: }
28# CHECK-NEXT: Type: Relocatable
29# CHECK-NEXT: Machine: EM_X86_64
30# CHECK-NEXT: Version: 1
31# CHECK-NEXT: Entry: 0x0
32# CHECK-NEXT: ProgramHeaderOffset: 0x0
33# CHECK-NEXT: SectionHeaderOffset:
34# CHECK-NEXT: Flags [
35# CHECK-NEXT: ]
36# CHECK-NEXT: HeaderSize: 64
37# CHECK-NEXT: ProgramHeaderEntrySize: 0
38# CHECK-NEXT: ProgramHeaderCount: 0
39# CHECK-NEXT: SectionHeaderEntrySize: 64
40# CHECK-NEXT: SectionHeaderCount: 7
41# CHECK-NEXT: StringTableSectionIndex: 5
42# CHECK-NEXT: }
43
44# CHECK: Relocations [
45# CHECK-NEXT: Section ({{.*}}) .rela.text {
46# CHECK-NEXT: 0x3 R_X86_64_32S x 0x0
47# CHECK-NEXT: 0xE R_X86_64_32S y 0x0
48# CHECK-NEXT: 0x23 R_X86_64_32S xx 0x0
49# CHECK-NEXT: 0x2E R_X86_64_32S yy 0x0
50# CHECK-NEXT: 0x43 R_X86_64_32S xxx 0x0
51# CHECK-NEXT: 0x4E R_X86_64_32S yyy 0x0
52# CHECK-NEXT: }
53
54# CHECKTEXT: Disassembly of section .text:
55# CHECKTEXT-NEXT: main:
56# CHECKTEXT-NEXT: 0: c7 04 25 00 00 00 00 05 00 00 00 movl $5, 0
57# CHECKTEXT-NEXT: b: c7 04 25 00 00 00 00 07 00 00 00 movl $7, 0
58# CHECKTEXT: foo:
59# CHECKTEXT-NEXT: 20: c7 04 25 00 00 00 00 01 00 00 00 movl $1, 0
60# CHECKTEXT-NEXT: 2b: c7 04 25 00 00 00 00 02 00 00 00 movl $2, 0
61# CHECKTEXT: bar:
62# CHECKTEXT-NEXT: 40: c7 04 25 00 00 00 00 08 00 00 00 movl $8, 0
63# CHECKTEXT-NEXT: 4b: c7 04 25 00 00 00 00 09 00 00 00 movl $9, 0
64
65# CHECKEXE: Format: ELF64-x86-64
66# CHECKEXE-NEXT: Arch: x86_64
67# CHECKEXE-NEXT: AddressSize: 64bit
68# CHECKEXE-NEXT: LoadName:
69# CHECKEXE-NEXT: ElfHeader {
70# CHECKEXE-NEXT: Ident {
71# CHECKEXE-NEXT: Magic: (7F 45 4C 46)
72# CHECKEXE-NEXT: Class: 64-bit
73# CHECKEXE-NEXT: DataEncoding: LittleEndian
74# CHECKEXE-NEXT: FileVersion: 1
75# CHECKEXE-NEXT: OS/ABI: SystemV (0x0)
76# CHECKEXE-NEXT: ABIVersion: 0
77# CHECKEXE-NEXT: Unused: (00 00 00 00 00 00 00)
78# CHECKEXE-NEXT: }
79# CHECKEXE-NEXT: Type: Executable
80# CHECKEXE-NEXT: Machine: EM_X86_64
81# CHECKEXE-NEXT: Version: 1
82# CHECKEXE-NEXT: Entry: 0x201000
83# CHECKEXE-NEXT: ProgramHeaderOffset: 0x40
84# CHECKEXE-NEXT: SectionHeaderOffset: 0x11F8
85# CHECKEXE-NEXT: Flags [
86# CHECKEXE-NEXT: ]
87# CHECKEXE-NEXT: HeaderSize: 64
88# CHECKEXE-NEXT: ProgramHeaderEntrySize: 56
89# CHECKEXE-NEXT: ProgramHeaderCount: 5
90# CHECKEXE-NEXT: SectionHeaderEntrySize: 64
91# CHECKEXE-NEXT: SectionHeaderCount: 7
92# CHECKEXE-NEXT: StringTableSectionIndex: 5
93# CHECKEXE-NEXT: }
94
95.text
96.type x,@object
97.bss
98.globl x
99.align 4
100x:
101.long 0
102.size x, 4
103.type y,@object
104.globl y
105.align 4
106y:
107.long 0
108.size y, 4
109
110.text
111.globl main
112.align 16, 0x90
113.type main,@function
114main:
115movl $5, x
116movl $7, y
117
118blah:
119goo:
120abs = 42
deps/lld/test/ELF/relocation-absolute.s created+12
......@@ -0,0 +1,12 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/abs.s -o %tabs
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
3// RUN: ld.lld %tabs %t -o %tout
4// RUN: llvm-objdump -d %tout | FileCheck %s
5// REQUIRES: x86
6
7.global _start
8_start:
9 movl $abs, %edx
10
11//CHECK: start:
12//CHECK-NEXT: movl $66, %edx
deps/lld/test/ELF/relocation-common.s created+14
......@@ -0,0 +1,14 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
2// RUN: ld.lld %t -o %tout
3// RUN: llvm-objdump -t -d %tout | FileCheck %s
4// REQUIRES: x86
5
6.global _start
7_start:
8 movl $1, sym1(%rip)
9
10.global sym1
11.comm sym1,4,4
12
13// CHECK: 201000: {{.*}} movl $1, 4086(%rip)
14// CHECK: 0000000000202000 g .bss 00000004 sym1
deps/lld/test/ELF/relocation-copy-alias.s created+67
......@@ -0,0 +1,67 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/relocation-copy-alias.s -o %t2.o
4// RUN: ld.lld -shared %t2.o -o %t.so
5// RUN: ld.lld %t.o %t.so -o %t3
6// RUN: llvm-readobj --dyn-symbols -r --expand-relocs %t3 | FileCheck %s
7
8.global _start
9_start:
10movl $5, a1
11movl $5, b1
12movl $5, b2
13
14// CHECK: .rela.dyn {
15// CHECK-NEXT: Relocation {
16// CHECK-NEXT: Offset:
17// CHECK-NEXT: Type: R_X86_64_COPY
18// CHECK-NEXT: Symbol: a1
19// CHECK-NEXT: Addend: 0x0
20// CHECK-NEXT: }
21// CHECK-NEXT: Relocation {
22// CHECK-NEXT: Offset:
23// CHECK-NEXT: Type: R_X86_64_COPY
24// CHECK-NEXT: Symbol: b1
25// CHECK-NEXT: Addend: 0x0
26// CHECK-NEXT: }
27// CHECK-NEXT: }
28
29// CHECK: Name: a1
30// CHECK-NEXT: Value: [[A:.*]]
31// CHECK-NEXT: Size: 1
32// CHECK-NEXT: Binding: Global (0x1)
33// CHECK-NEXT: Type: Object (0x1)
34// CHECK-NEXT: Other: 0
35// CHECK-NEXT: Section: .bss (0x7)
36
37// CHECK: Name: b1
38// CHECK-NEXT: Value: [[B:.*]]
39// CHECK-NEXT: Size: 1
40// CHECK-NEXT: Binding: Global
41// CHECK-NEXT: Type: Object (0x1)
42// CHECK-NEXT: Other: 0
43// CHECK-NEXT: Section: .bss
44
45// CHECK: Name: b2
46// CHECK-NEXT: Value: [[B]]
47// CHECK-NEXT: Size: 1
48// CHECK-NEXT: Binding: Global
49// CHECK-NEXT: Type: Object (0x1)
50// CHECK-NEXT: Other: 0
51// CHECK-NEXT: Section: .bss
52
53// CHECK: Name: a2
54// CHECK-NEXT: Value: [[A]]
55// CHECK-NEXT: Size: 1
56// CHECK-NEXT: Binding: Weak
57// CHECK-NEXT: Type: Object (0x1)
58// CHECK-NEXT: Other: 0
59// CHECK-NEXT: Section: .bss
60
61// CHECK: Name: b3
62// CHECK-NEXT: Value: [[B]]
63// CHECK-NEXT: Size: 1
64// CHECK-NEXT: Binding: Weak
65// CHECK-NEXT: Type: Object (0x1)
66// CHECK-NEXT: Other: 0
67// CHECK-NEXT: Section: .bss
deps/lld/test/ELF/relocation-copy-align-common.s created+40
......@@ -0,0 +1,40 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux \
4# RUN: %p/Inputs/relocation-copy-align-common.s -o %t2.o
5# RUN: ld.lld -shared %t2.o -o %t.so
6# RUN: ld.lld %t.o %t.so -o %t3
7# RUN: llvm-readobj -s -r --expand-relocs %t3 | FileCheck %s
8
9# CHECK: Section {
10# CHECK: Index:
11# CHECK: Name: .bss
12# CHECK-NEXT: Type: SHT_NOBITS
13# CHECK-NEXT: Flags [
14# CHECK-NEXT: SHF_ALLOC
15# CHECK-NEXT: SHF_WRITE
16# CHECK-NEXT: ]
17# CHECK-NEXT: Address: 0x203000
18# CHECK-NEXT: Offset: 0x20B0
19# CHECK-NEXT: Size: 16
20# CHECK-NEXT: Link: 0
21# CHECK-NEXT: Info: 0
22# CHECK-NEXT: AddressAlignment: 8
23# CHECK-NEXT: EntrySize: 0
24# CHECK-NEXT: }
25
26# CHECK: Relocations [
27# CHECK-NEXT: Section {{.*}} .rela.dyn {
28# CHECK-NEXT: Relocation {
29# CHECK-NEXT: Offset: 0x203008
30# CHECK-NEXT: Type: R_X86_64_COPY
31# CHECK-NEXT: Symbol: foo
32# CHECK-NEXT: Addend: 0x0
33# CHECK-NEXT: }
34# CHECK-NEXT: }
35# CHECK-NEXT: ]
36
37.global _start
38_start:
39.comm sym1,4,4
40movl $5, foo
deps/lld/test/ELF/relocation-copy-align.s created+31
......@@ -0,0 +1,31 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/relocation-copy-align.s -o %t2.o
4// RUN: ld.lld -shared %t2.o -o %t.so
5// RUN: ld.lld %t.o %t.so -o %t3
6// RUN: llvm-readobj -s -r --expand-relocs %t3 | FileCheck %s
7
8.global _start
9_start:
10movl $5, x
11
12// CHECK: Name: .bss
13// CHECK-NEXT: Type: SHT_NOBITS
14// CHECK-NEXT: Flags [
15// CHECK-NEXT: SHF_ALLOC
16// CHECK-NEXT: SHF_WRITE
17// CHECK-NEXT: ]
18// CHECK-NEXT: Address:
19// CHECK-NEXT: Offset:
20// CHECK-NEXT: Size: 4
21// CHECK-NEXT: Link:
22// CHECK-NEXT: Info:
23// CHECK-NEXT: AddressAlignment: 4
24// CHECK-NEXT: EntrySize:
25
26// CHECK: Relocation {
27// CHECK-NEXT: Offset:
28// CHECK-NEXT: Type: R_X86_64_COPY
29// CHECK-NEXT: Symbol: x
30// CHECK-NEXT: Addend: 0x0
31// CHECK-NEXT: }
deps/lld/test/ELF/relocation-copy-flags.s created+73
......@@ -0,0 +1,73 @@
1// REQUIRES: x86
2
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
4// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/relocation-copy.s -o %t2.o
5// RUN: ld.lld %t2.o -o %t2.so -shared
6// RUN: ld.lld %t.o %t2.so -o %t.exe
7// RUN: llvm-readobj -s -section-data -r %t.exe | FileCheck %s
8
9 .global _start
10_start:
11 .quad x
12
13 .section foo
14 .quad y
15
16 .section bar, "aw"
17 .quad z
18
19// CHECK: Name: .text
20// CHECK-NEXT: Type: SHT_PROGBITS
21// CHECK-NEXT: Flags [
22// CHECK-NEXT: SHF_ALLOC
23// CHECK-NEXT: SHF_EXECINSTR
24// CHECK-NEXT: ]
25// CHECK-NEXT: Address: 0x201000
26// CHECK-NEXT: Offset: 0x1000
27// CHECK-NEXT: Size: 8
28// CHECK-NEXT: Link: 0
29// CHECK-NEXT: Info: 0
30// CHECK-NEXT: AddressAlignment: 4
31// CHECK-NEXT: EntrySize: 0
32// CHECK-NEXT: SectionData (
33// CHECK-NEXT: 0000: 00402000
34// CHECK-NEXT: )
35
36// CHECK: Name: bar
37// CHECK-NEXT: Type: SHT_PROGBITS
38// CHECK-NEXT: Flags [
39// CHECK-NEXT: SHF_ALLOC
40// CHECK-NEXT: SHF_WRITE
41// CHECK-NEXT: ]
42// CHECK-NEXT: Address: 0x202000
43// CHECK-NEXT: Offset: 0x2000
44// CHECK-NEXT: Size: 8
45// CHECK-NEXT: Link: 0
46// CHECK-NEXT: Info: 0
47// CHECK-NEXT: AddressAlignment: 1
48// CHECK-NEXT: EntrySize: 0
49// CHECK-NEXT: SectionData (
50// CHECK-NEXT: 0000: 00000000
51// CHECK-NEXT: )
52
53// CHECK: Name: foo
54// CHECK-NEXT: Type: SHT_PROGBITS
55// CHECK-NEXT: Flags [
56// CHECK-NEXT: ]
57// CHECK-NEXT: Address: 0x0
58// CHECK-NEXT: Offset: 0x30B0
59// CHECK-NEXT: Size: 8
60// CHECK-NEXT: Link: 0
61// CHECK-NEXT: Info: 0
62// CHECK-NEXT: AddressAlignment: 1
63// CHECK-NEXT: EntrySize: 0
64// CHECK-NEXT: SectionData (
65// CHECK-NEXT: 0000: 00000000
66// CHECK-NEXT: )
67
68// CHECK: Relocations [
69// CHECK-NEXT: Section (4) .rela.dyn {
70// CHECK-NEXT: 0x204000 R_X86_64_COPY x 0x0
71// CHECK-NEXT: 0x202000 R_X86_64_64 z 0x0
72// CHECK-NEXT: }
73// CHECK-NEXT: ]
deps/lld/test/ELF/relocation-copy-i686.s created+63
......@@ -0,0 +1,63 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
3// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %p/Inputs/relocation-copy.s -o %t2.o
4// RUN: ld.lld -shared %t2.o -o %t.so
5// RUN: ld.lld -e main %t.o %t.so -o %t3
6// RUN: llvm-readobj -s -r --expand-relocs %t3 | FileCheck %s
7// RUN: llvm-objdump -d %t3 | FileCheck -check-prefix=CODE %s
8
9.text
10.globl main
11.align 16, 0x90
12.type main,@function
13main:
14movl $5, x
15movl $7, y
16movl $9, z
17
18// CHECK: Name: .bss
19// CHECK-NEXT: Type: SHT_NOBITS
20// CHECK-NEXT: Flags [
21// CHECK-NEXT: SHF_ALLOC
22// CHECK-NEXT: SHF_WRITE
23// CHECK-NEXT: ]
24// CHECK-NEXT: Address: 0x13000
25// CHECK-NEXT: Offset:
26// CHECK-NEXT: Size: 24
27// CHECK-NEXT: Link: 0
28// CHECK-NEXT: Info: 0
29// CHECK-NEXT: AddressAlignment: 16
30// CHECK-NEXT: EntrySize: 0
31
32// CHECK: Relocations [
33// CHECK-NEXT: Section ({{.*}}) .rel.dyn {
34// CHECK-NEXT: Relocation {
35// CHECK-NEXT: Offset:
36// CHECK-NEXT: Type: R_386_COPY
37// CHECK-NEXT: Symbol: x
38// CHECK-NEXT: Addend: 0x0
39// CHECK-NEXT: }
40// CHECK-NEXT: Relocation {
41// CHECK-NEXT: Offset:
42// CHECK-NEXT: Type: R_386_COPY
43// CHECK-NEXT: Symbol: y
44// CHECK-NEXT: Addend: 0x0
45// CHECK-NEXT: }
46// CHECK-NEXT: Relocation {
47// CHECK-NEXT: Offset:
48// CHECK-NEXT: Type: R_386_COPY
49// CHECK-NEXT: Symbol: z
50// CHECK-NEXT: Addend: 0x0
51// CHECK-NEXT: }
52// CHECK-NEXT: }
53// CHECK-NEXT: ]
54
55// 77824 = 0x13000
56// 16 is alignment here
57// 77840 = 0x13000 + 16
58// 77844 = 0x13000 + 16 + 4
59// CODE: Disassembly of section .text:
60// CODE-NEXT: main:
61// CODE-NEXT: 11000: c7 05 00 30 01 00 05 00 00 00 movl $5, 77824
62// CODE-NEXT: 1100a: c7 05 10 30 01 00 07 00 00 00 movl $7, 77840
63// CODE-NEXT: 11014: c7 05 14 30 01 00 09 00 00 00 movl $9, 77844
deps/lld/test/ELF/relocation-copy-relro.s created+32
......@@ -0,0 +1,32 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/relocation-copy-relro.s -o %t2.o
4// RUN: ld.lld -shared %t2.o -o %t.so
5// RUN: ld.lld %t.o %t.so -o %t3
6// RUN: llvm-readobj -program-headers -s -r %t3 | FileCheck %s
7
8// CHECK: Name: .bss.rel.ro (48)
9// CHECK-NEXT: Type: SHT_NOBITS (0x8)
10// CHECK-NEXT: Flags [ (0x3)
11// CHECK-NEXT: SHF_ALLOC (0x2)
12// CHECK-NEXT: SHF_WRITE (0x1)
13// CHECK-NEXT: ]
14// CHECK-NEXT: Address: 0x2020B0
15// CHECK-NEXT: Offset: 0x20B0
16// CHECK-NEXT: Size: 8
17
18// CHECK: 0x2020B0 R_X86_64_COPY a 0x0
19// CHECK: 0x2020B4 R_X86_64_COPY b 0x0
20
21// CHECK: Type: PT_GNU_RELRO (0x6474E552)
22// CHECK-NEXT: Offset: 0x2000
23// CHECK-NEXT: VirtualAddress: 0x202000
24// CHECK-NEXT: PhysicalAddress: 0x202000
25// CHECK-NEXT: FileSize: 176
26// CHECK-NEXT: MemSize: 4096
27
28.text
29.global _start
30_start:
31movl $1, a
32movl $2, b
deps/lld/test/ELF/relocation-copy.s created+67
......@@ -0,0 +1,67 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/relocation-copy.s -o %t2.o
4// RUN: ld.lld -shared %t2.o -o %t.so
5// RUN: ld.lld %t.o %t.so -o %t3
6// RUN: llvm-readobj -s -r --expand-relocs %t3 | FileCheck %s
7// RUN: llvm-objdump -d %t3 | FileCheck -check-prefix=CODE %s
8
9.text
10.global _start
11_start:
12movl $5, x
13movl $7, y
14movl $9, z
15movl $x, %edx
16movl $y, %edx
17movl $z, %edx
18
19// CHECK: Name: .bss
20// CHECK-NEXT: Type: SHT_NOBITS (0x8)
21// CHECK-NEXT: Flags [ (0x3)
22// CHECK-NEXT: SHF_ALLOC (0x2)
23// CHECK-NEXT: SHF_WRITE (0x1)
24// CHECK-NEXT: ]
25// CHECK-NEXT: Address: 0x203000
26// CHECK-NEXT: Offset:
27// CHECK-NEXT: Size: 24
28// CHECK-NEXT: Link: 0
29// CHECK-NEXT: Info: 0
30// CHECK-NEXT: AddressAlignment: 16
31// CHECK-NEXT: EntrySize: 0
32
33// CHECK: Relocations [
34// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
35// CHECK-NEXT: Relocation {
36// CHECK-NEXT: Offset:
37// CHECK-NEXT: Type: R_X86_64_COPY
38// CHECK-NEXT: Symbol: x
39// CHECK-NEXT: Addend: 0x0
40// CHECK-NEXT: }
41// CHECK-NEXT: Relocation {
42// CHECK-NEXT: Offset:
43// CHECK-NEXT: Type: R_X86_64_COPY
44// CHECK-NEXT: Symbol: y
45// CHECK-NEXT: Addend: 0x0
46// CHECK-NEXT: }
47// CHECK-NEXT: Relocation {
48// CHECK-NEXT: Offset:
49// CHECK-NEXT: Type: R_X86_64_COPY
50// CHECK-NEXT: Symbol: z
51// CHECK-NEXT: Addend: 0x0
52// CHECK-NEXT: }
53// CHECK-NEXT: }
54// CHECK-NEXT: ]
55
56// 2109440 = 0x203000
57// 16 is alignment here
58// 2109456 = 0x203000 + 16
59// 2109460 = 0x203000 + 16 + 4
60// CODE: Disassembly of section .text:
61// CODE-NEXT: _start:
62// CODE-NEXT: 201000: {{.*}} movl $5, 2109440
63// CODE-NEXT: 20100b: {{.*}} movl $7, 2109456
64// CODE-NEXT: 201016: {{.*}} movl $9, 2109460
65// CODE-NEXT: 201021: {{.*}} movl $2109440, %edx
66// CODE-NEXT: 201026: {{.*}} movl $2109456, %edx
67// CODE-NEXT: 20102b: {{.*}} movl $2109460, %edx
deps/lld/test/ELF/relocation-dtrace.test created+24
......@@ -0,0 +1,24 @@
1# RUN: yaml2obj %s -o %t.o
2# RUN: ld.lld -shared %t.o -o %t.so
3
4# Test that we can handle R_X86_64_NONE as produced by dtrace.
5
6!ELF
7FileHeader:
8 Class: ELFCLASS64
9 Data: ELFDATA2LSB
10 OSABI: ELFOSABI_FREEBSD
11 Type: ET_REL
12 Machine: EM_X86_64
13Sections:
14 - Name: .text
15 Type: SHT_PROGBITS
16 Flags: [ SHF_ALLOC ]
17 - Name: .rela.text
18 Type: SHT_RELA
19 Link: .symtab
20 Info: .text
21 Relocations:
22 - Offset: 0x0000000000000000
23 Symbol: ''
24 Type: R_X86_64_NONE
deps/lld/test/ELF/relocation-group.test created+43
......@@ -0,0 +1,43 @@
1# RUN: yaml2obj %s -o %t.o
2# RUN: ld.lld %t.o %t.o -o %t -r
3# RUN: llvm-readobj -s %t | FileCheck %s
4
5# CHECK: Name: .text.foo
6# CHECK: Name: .rela.text.foo
7
8## YAML below corresponds to following asm code:
9## .section .text,"axG",@progbits,foo,comdat
10## .quad bar
11## gas 2.27 does not include .rela.text to group in that case:
12## COMDAT group section [ 1] `.group' [foo] contains 1 sections:
13## [Index] Name
14## [ 5] .text
15--- !ELF
16FileHeader:
17 Class: ELFCLASS64
18 Data: ELFDATA2LSB
19 Type: ET_REL
20 Machine: EM_X86_64
21Sections:
22 - Name: .group
23 Type: SHT_GROUP
24 Link: .symtab
25 Info: foo
26 Members:
27 - SectionOrType: GRP_COMDAT
28 - SectionOrType: .text.foo
29 - Name: .text.foo
30 Type: SHT_PROGBITS
31 Flags: [ SHF_ALLOC, SHF_EXECINSTR, SHF_GROUP ]
32 - Name: .rela.text.foo
33 Type: SHT_RELA
34 Flags: [ SHF_INFO_LINK ]
35 Link: .symtab
36 Info: .text.foo
37 Relocations:
38 - Offset: 0x0000000000000000
39 Symbol: foo
40 Type: R_X86_64_64
41Symbols:
42 Global:
43 - Name: foo
deps/lld/test/ELF/relocation-i686.s created+96
......@@ -0,0 +1,96 @@
1// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t
2// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/shared.s -o %t2.o
3// RUN: ld.lld -shared %t2.o -o %t2.so
4// RUN: ld.lld %t %t2.so -o %t2
5// RUN: llvm-readobj -s %t2 | FileCheck --check-prefix=ADDR %s
6// RUN: llvm-objdump -d %t2 | FileCheck %s
7// REQUIRES: x86
8
9.global _start
10_start:
11
12.section .R_386_32,"ax",@progbits
13.global R_386_32
14R_386_32:
15 movl $R_386_32 + 1, %edx
16
17
18.section .R_386_PC32,"ax",@progbits,unique,1
19.global R_386_PC32
20R_386_PC32:
21 call R_386_PC32_2
22
23.section .R_386_PC32,"ax",@progbits,unique,2
24.zero 4
25R_386_PC32_2:
26 nop
27
28// CHECK: Disassembly of section .R_386_32:
29// CHECK-NEXT: R_386_32:
30// CHECK-NEXT: 11000: {{.*}} movl $69633, %edx
31
32// CHECK: Disassembly of section .R_386_PC32:
33// CHECK-NEXT: R_386_PC32:
34// CHECK-NEXT: 11005: e8 04 00 00 00 calll 4
35
36// CHECK: R_386_PC32_2:
37// CHECK-NEXT: 1100e: 90 nop
38
39// Create a .got
40movl bar@GOT, %eax
41
42// ADDR: Name: .plt
43// ADDR-NEXT: Type: SHT_PROGBITS
44// ADDR-NEXT: Flags [
45// ADDR-NEXT: SHF_ALLOC
46// ADDR-NEXT: SHF_EXECINSTR
47// ADDR-NEXT: ]
48// ADDR-NEXT: Address: 0x11040
49// ADDR-NEXT: Offset: 0x1040
50// ADDR-NEXT: Size: 32
51
52// ADDR: Name: .got (
53// ADDR-NEXT: Type: SHT_PROGBITS
54// ADDR-NEXT: Flags [
55// ADDR-NEXT: SHF_ALLOC
56// ADDR-NEXT: SHF_WRITE
57// ADDR-NEXT: ]
58// ADDR-NEXT: Address: 0x13078
59// ADDR-NEXT: Offset:
60// ADDR-NEXT: Size: 8
61
62.section .R_386_GOTPC,"ax",@progbits
63R_386_GOTPC:
64 movl $_GLOBAL_OFFSET_TABLE_, %eax
65
66// 0x12078 + 8 - 0x11014 = 4204
67
68// CHECK: Disassembly of section .R_386_GOTPC:
69// CHECK-NEXT: R_386_GOTPC:
70// CHECK-NEXT: 11014: {{.*}} movl $8300, %eax
71
72.section .dynamic_reloc, "ax",@progbits
73 call bar
74// addr(.plt) + 16 - (0x11019 + 5) = 50
75// CHECK: Disassembly of section .dynamic_reloc:
76// CHECK-NEXT: .dynamic_reloc:
77// CHECK-NEXT: 11019: e8 32 00 00 00 calll 50
78
79.section .R_386_GOT32,"ax",@progbits
80.global R_386_GOT32
81R_386_GOT32:
82 movl bar@GOT, %eax
83 movl zed@GOT, %eax
84 movl bar+8@GOT, %eax
85 movl zed+4@GOT, %eax
86
87// 4294967288 = 0xFFFFFFF8 = got[0](0x12070) - .got(0x12070) - sizeof(.got)(8)
88// 4294967292 = 0xFFFFFFFC = got[1](0x12074) - .got(0x12070) - sizeof(.got)(8)
89// 0xFFFFFFF8 + 8 = 0
90// 0xFFFFFFFC + 4 = 0
91// CHECK: Disassembly of section .R_386_GOT32:
92// CHECK-NEXT: R_386_GOT32:
93// CHECK-NEXT: 1101e: a1 f8 ff ff ff movl 4294967288, %eax
94// CHECK-NEXT: 11023: a1 fc ff ff ff movl 4294967292, %eax
95// CHECK-NEXT: 11028: a1 00 00 00 00 movl 0, %eax
96// CHECK-NEXT: 1102d: a1 00 00 00 00 movl 0, %eax
deps/lld/test/ELF/relocation-in-merge.s created+12
......@@ -0,0 +1,12 @@
1// REQUIRES: x86
2// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
3// RUN: ld.lld %t.o -o %t -shared
4// RUN: llvm-objdump -section-headers %t | FileCheck %s
5
6// Test that we accept this by just not merging the section.
7// CHECK: .foo 00000008
8
9bar:
10 .section .foo,"aM",@progbits,8
11 .long bar - .
12 .long bar - .
deps/lld/test/ELF/relocation-local.s created+38
......@@ -0,0 +1,38 @@
1// Test that relocation of local symbols is working.
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
3// RUN: ld.lld %t -o %t2
4// RUN: llvm-objdump -s -d %t2 | FileCheck %s
5// REQUIRES: x86
6
7
8.global _start
9_start:
10 call lulz
11
12.zero 4
13lulz:
14
15.section .text2,"ax",@progbits
16R_X86_64_32:
17 movl $R_X86_64_32, %edx
18
19// FIXME: this would be far more self evident if llvm-objdump printed
20// constants in hex.
21// CHECK: Disassembly of section .text2:
22// CHECK-NEXT: R_X86_64_32:
23// CHECK-NEXT: 201009: {{.*}} movl $2101257, %edx
24
25.section .R_X86_64_32S,"ax",@progbits
26R_X86_64_32S:
27 movq lulz - 0x100000, %rdx
28
29// CHECK: Disassembly of section .R_X86_64_32S:
30// CHECK-NEXT: R_X86_64_32S:
31// CHECK-NEXT: {{.*}}: {{.*}} movq 1052681, %rdx
32
33.section .R_X86_64_64,"a",@progbits
34R_X86_64_64:
35 .quad R_X86_64_64
36
37// CHECK: Contents of section .R_X86_64_64:
38// CHECK-NEXT: 200120 20012000 00000000
deps/lld/test/ELF/relocation-nocopy.s created+19
......@@ -0,0 +1,19 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/relocation-copy.s -o %t2.o
4// RUN: ld.lld -shared %t2.o -o %t.so
5// RUN: not ld.lld -z nocopyreloc %t.o %t.so -o %t3 2>&1 | FileCheck %s
6
7// CHECK: unresolvable relocation R_X86_64_32S against symbol 'x'
8// CHECK: unresolvable relocation R_X86_64_32S against symbol 'y'
9// CHECK: unresolvable relocation R_X86_64_32S against symbol 'z'
10
11.text
12.global _start
13_start:
14movl $5, x
15movl $7, y
16movl $9, z
17movl $x, %edx
18movl $y, %edx
19movl $z, %edx
deps/lld/test/ELF/relocation-non-alloc.s created+60
......@@ -0,0 +1,60 @@
1// REQUIRES: x86
2
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
4// RUN: ld.lld %t -o %t2 -shared
5// RUN: llvm-readobj -s -section-data -r %t2 | FileCheck %s
6
7// CHECK: Name: .data
8// CHECK-NEXT: Type: SHT_PROGBITS
9// CHECK-NEXT: Flags [
10// CHECK-NEXT: SHF_ALLOC
11// CHECK-NEXT: SHF_WRITE
12// CHECK-NEXT: ]
13// CHECK-NEXT: Address: 0x1000
14// CHECK-NEXT: Offset: 0x1000
15// CHECK-NEXT: Size: 16
16// CHECK-NEXT: Link: 0
17// CHECK-NEXT: Info: 0
18// CHECK-NEXT: AddressAlignment: 1
19// CHECK-NEXT: EntrySize: 0
20// CHECK-NEXT: SectionData (
21// CHECK-NEXT: 0000: 00000000 00000000 00000000 00000000
22// CHECK-NEXT: )
23
24// CHECK: Name: foo
25// CHECK-NEXT: Type: SHT_PROGBITS
26// CHECK-NEXT: Flags [
27// CHECK-NEXT: ]
28// CHECK-NEXT: Address: 0x0
29// CHECK-NEXT: Offset:
30// CHECK-NEXT: Size: 32
31// CHECK-NEXT: Link: 0
32// CHECK-NEXT: Info: 0
33// CHECK-NEXT: AddressAlignment: 1
34// CHECK-NEXT: EntrySize: 0
35// CHECK-NEXT: SectionData (
36// CHECK-NEXT: 0000: 00100000 00000000 00100000 00000000
37// CHECK-NEXT: 0010: 00100000 00000000 00100000 00000000
38// CHECK-NEXT: )
39
40// CHECK: Relocations [
41// CHECK-NEXT: Section ({{.}}) .rela.dyn {
42// CHECK-NEXT: 0x1000 R_X86_64_RELATIVE - 0x1000
43// CHECK-NEXT: 0x1008 R_X86_64_64 zed 0x0
44// CHECK-NEXT: }
45// CHECK-NEXT: ]
46
47.data
48 .global zed
49zed:
50bar:
51 .quad bar
52 .quad zed
53
54 .section foo
55 .quad bar
56 .quad zed
57
58 .section foo
59 .quad bar
60 .quad zed
deps/lld/test/ELF/relocation-none-aarch64.test created+24
......@@ -0,0 +1,24 @@
1# REQUIRES: aarch64
2
3# RUN: yaml2obj %s -o %t.o
4# RUN: ld.lld %t.o -o %t.out
5
6!ELF
7FileHeader:
8 Class: ELFCLASS64
9 Data: ELFDATA2LSB
10 Type: ET_REL
11 Machine: EM_AARCH64
12Sections:
13 - Type: SHT_PROGBITS
14 Name: .text
15 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
16 Content: "00000000"
17 - Type: SHT_RELA
18 Name: .rela.text
19 Link: .symtab
20 Info: .text
21 Relocations:
22 - Offset: 0
23 Symbol: ''
24 Type: R_AARCH64_NONE
deps/lld/test/ELF/relocation-none-i686.test created+23
......@@ -0,0 +1,23 @@
1# RUN: yaml2obj %s -o %t.o
2# RUN: ld.lld %t.o -o %t.out
3
4# Test that we can handle R_386_NONE.
5
6!ELF
7FileHeader:
8 Class: ELFCLASS32
9 Data: ELFDATA2LSB
10 Type: ET_REL
11 Machine: EM_386
12Sections:
13 - Name: .text
14 Type: SHT_PROGBITS
15 Flags: [ SHF_ALLOC ]
16 - Name: .rel.text
17 Type: SHT_RELA
18 Link: .symtab
19 Info: .text
20 Relocations:
21 - Offset: 0x0000000000000000
22 Symbol: ''
23 Type: R_386_NONE
deps/lld/test/ELF/relocation-past-merge-end.s created+9
......@@ -0,0 +1,9 @@
1// REQUIRES: x86
2// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
3// RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s
4// CHECK: relocation-past-merge-end.s.tmp.o:(.foo): entry is past the end of the section
5
6.data
7.long .foo + 10
8.section .foo,"aM",@progbits,4
9.quad 0
deps/lld/test/ELF/relocation-relative-absolute.s created+14
......@@ -0,0 +1,14 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %tinput1.o
3# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux \
4# RUN: %S/Inputs/relocation-relative-absolute.s -o %tinput2.o
5# RUN: not ld.lld %tinput1.o %tinput2.o -o %t -pie 2>&1 | FileCheck %s
6
7.globl _start
8_start:
9
10# CHECK: error: relocation R_X86_64_PLT32 cannot refer to absolute symbol: answer
11# CHECK-NEXT: >>> defined in {{.*}}input2.o
12# CHECK-NEXT: >>> referenced by {{.*}}o:(.text+0x1)
13
14call answer@PLT
deps/lld/test/ELF/relocation-relative-synthetic.s created+11
......@@ -0,0 +1,11 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: ld.lld %t.o -o %t -pie
4# RUN: llvm-readobj -dyn-relocations %t | FileCheck %s
5
6# CHECK: Dynamic Relocations {
7# CHECK-NEXT: }
8
9.globl _start
10_start:
11call __init_array_start@PLT
deps/lld/test/ELF/relocation-relative-weak.s created+14
......@@ -0,0 +1,14 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: ld.lld %t.o -o %t -pie
4# RUN: llvm-readobj -dyn-relocations %t | FileCheck %s
5
6# CHECK: Dynamic Relocations {
7# CHECK-NEXT: }
8
9.globl _start
10_start:
11
12.globl w
13.weak w
14call w@PLT
deps/lld/test/ELF/relocation-shared.s created+36
......@@ -0,0 +1,36 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: ld.lld %t.o -shared -o %t.so
4// RUN: llvm-readobj -r -s -section-data %t.so | FileCheck %s
5
6// CHECK: Name: foo
7// CHECK-NEXT: Type: SHT_PROGBITS
8// CHECK-NEXT: Flags [
9// CHECK-NEXT: SHF_ALLOC
10// CHECK-NEXT: ]
11// CHECK-NEXT: Address: 0x1C8
12// CHECK-NEXT: Offset:
13// CHECK-NEXT: Size: 8
14// CHECK-NEXT: Link: 0
15// CHECK-NEXT: Info: 0
16// CHECK-NEXT: AddressAlignment: 1
17// CHECK-NEXT: EntrySize: 0
18// CHECK-NEXT: SectionData (
19// CHECK-NEXT: 0000: 380E0000 00000000
20// 0x1000 - 0x1C8 = 0xE38
21// CHECK-NEXT: )
22
23// CHECK: Name: .text
24// CHECK-NEXT: Type: SHT_PROGBITS
25// CHECK-NEXT: Flags [
26// CHECK-NEXT: SHF_ALLOC
27// CHECK-NEXT: SHF_EXECINSTR
28// CHECK-NEXT: ]
29// CHECK-NEXT: Address: 0x1000
30
31// CHECK: Relocations [
32// CHECK-NEXT: ]
33
34bar:
35 .section foo,"a",@progbits
36 .quad bar - .
deps/lld/test/ELF/relocation-size-shared.s created+78
......@@ -0,0 +1,78 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/relocation-size-shared.s -o %tso.o
3// RUN: ld.lld -shared %tso.o -o %tso
4// RUN: ld.lld %t.o %tso -o %t1
5// RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=RELOCSHARED %s
6// RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s
7
8// RELOCSHARED: Relocations [
9// RELOCSHARED-NEXT: Section ({{.*}}) .rela.dyn {
10// RELOCSHARED-NEXT: 0x201018 R_X86_64_SIZE64 fooshared 0xFFFFFFFFFFFFFFFF
11// RELOCSHARED-NEXT: 0x201020 R_X86_64_SIZE64 fooshared 0x0
12// RELOCSHARED-NEXT: 0x201028 R_X86_64_SIZE64 fooshared 0x1
13// RELOCSHARED-NEXT: 0x201048 R_X86_64_SIZE32 fooshared 0xFFFFFFFFFFFFFFFF
14// RELOCSHARED-NEXT: 0x20104F R_X86_64_SIZE32 fooshared 0x0
15// RELOCSHARED-NEXT: 0x201056 R_X86_64_SIZE32 fooshared 0x1
16// RELOCSHARED-NEXT: }
17// RELOCSHARED-NEXT:]
18
19// DISASM: Disassembly of section test
20// DISASM: _data:
21// DISASM-NEXT: 201000: 19 00
22// DISASM-NEXT: 201002: 00 00
23// DISASM-NEXT: 201004: 00 00
24// DISASM-NEXT: 201006: 00 00
25// DISASM-NEXT: 201008: 1a 00
26// DISASM-NEXT: 20100a: 00 00
27// DISASM-NEXT: 20100c: 00 00
28// DISASM-NEXT: 20100e: 00 00
29// DISASM-NEXT: 201010: 1b 00
30// DISASM-NEXT: 201012: 00 00
31// DISASM-NEXT: 201014: 00 00
32// DISASM-NEXT: 201016: 00 00
33// DISASM-NEXT: 201018: 00 00
34// DISASM-NEXT: 20101a: 00 00
35// DISASM-NEXT: 20101c: 00 00
36// DISASM-NEXT: 20101e: 00 00
37// DISASM-NEXT: 201020: 00 00
38// DISASM-NEXT: 201022: 00 00
39// DISASM-NEXT: 201024: 00 00
40// DISASM-NEXT: 201026: 00 00
41// DISASM-NEXT: 201028: 00 00
42// DISASM-NEXT: 20102a: 00 00
43// DISASM-NEXT: 20102c: 00 00
44// DISASM-NEXT: 20102e: 00 00
45// DISASM: _start:
46// DISASM-NEXT: 201030: 8b 04 25 19 00 00 00 movl 25, %eax
47// DISASM-NEXT: 201037: 8b 04 25 1a 00 00 00 movl 26, %eax
48// DISASM-NEXT: 20103e: 8b 04 25 1b 00 00 00 movl 27, %eax
49// DISASM-NEXT: 201045: 8b 04 25 00 00 00 00 movl 0, %eax
50// DISASM-NEXT: 20104c: 8b 04 25 00 00 00 00 movl 0, %eax
51// DISASM-NEXT: 201053: 8b 04 25 00 00 00 00 movl 0, %eax
52
53.data
54.global foo
55.type foo,%object
56.size foo,26
57foo:
58.zero 26
59
60.section test, "awx"
61_data:
62 // R_X86_64_SIZE64:
63 .quad foo@SIZE-1
64 .quad foo@SIZE
65 .quad foo@SIZE+1
66 .quad fooshared@SIZE-1
67 .quad fooshared@SIZE
68 .quad fooshared@SIZE+1
69
70.globl _start
71_start:
72 // R_X86_64_SIZE32:
73 movl foo@SIZE-1,%eax
74 movl foo@SIZE,%eax
75 movl foo@SIZE+1,%eax
76 movl fooshared@SIZE-1,%eax
77 movl fooshared@SIZE,%eax
78 movl fooshared@SIZE+1,%eax
deps/lld/test/ELF/relocation-size.s created+123
......@@ -0,0 +1,123 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
2// RUN: ld.lld %t.o -o %t1
3// RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=NORELOC %s
4// RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s
5// RUN: ld.lld -shared %t.o -o %t1
6// RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=RELOCSHARED %s
7// RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASMSHARED %s
8
9// NORELOC: Relocations [
10// NORELOC-NEXT: ]
11
12// DISASM: Disassembly of section test:
13// DISASM-NEXT: _data:
14// DISASM-NEXT: 201000: 19 00
15// DISASM-NEXT: 201002: 00 00
16// DISASM-NEXT: 201004: 00 00
17// DISASM-NEXT: 201006: 00 00
18// DISASM-NEXT: 201008: 1a 00
19// DISASM-NEXT: 20100a: 00 00
20// DISASM-NEXT: 20100c: 00 00
21// DISASM-NEXT: 20100e: 00 00
22// DISASM-NEXT: 201010: 1b 00
23// DISASM-NEXT: 201012: 00 00
24// DISASM-NEXT: 201014: 00 00
25// DISASM-NEXT: 201016: 00 00
26// DISASM-NEXT: 201018: 19 00
27// DISASM-NEXT: 20101a: 00 00
28// DISASM-NEXT: 20101c: 00 00
29// DISASM-NEXT: 20101e: 00 00
30// DISASM-NEXT: 201020: 1a 00
31// DISASM-NEXT: 201022: 00 00
32// DISASM-NEXT: 201024: 00 00
33// DISASM-NEXT: 201026: 00 00
34// DISASM-NEXT: 201028: 1b 00
35// DISASM-NEXT: 20102a: 00 00
36// DISASM-NEXT: 20102c: 00 00
37// DISASM-NEXT: 20102e: 00 00
38// DISASM: _start:
39// DISASM-NEXT: 201030: 8b 04 25 19 00 00 00 movl 25, %eax
40// DISASM-NEXT: 201037: 8b 04 25 1a 00 00 00 movl 26, %eax
41// DISASM-NEXT: 20103e: 8b 04 25 1b 00 00 00 movl 27, %eax
42// DISASM-NEXT: 201045: 8b 04 25 19 00 00 00 movl 25, %eax
43// DISASM-NEXT: 20104c: 8b 04 25 1a 00 00 00 movl 26, %eax
44// DISASM-NEXT: 201053: 8b 04 25 1b 00 00 00 movl 27, %eax
45
46// RELOCSHARED: Relocations [
47// RELOCSHARED-NEXT: Section ({{.*}}) .rela.dyn {
48// RELOCSHARED-NEXT: 0x1000 R_X86_64_SIZE64 foo 0xFFFFFFFFFFFFFFFF
49// RELOCSHARED-NEXT: 0x1008 R_X86_64_SIZE64 foo 0x0
50// RELOCSHARED-NEXT: 0x1010 R_X86_64_SIZE64 foo 0x1
51// RELOCSHARED-NEXT: 0x1033 R_X86_64_SIZE32 foo 0xFFFFFFFFFFFFFFFF
52// RELOCSHARED-NEXT: 0x103A R_X86_64_SIZE32 foo 0x0
53// RELOCSHARED-NEXT: 0x1041 R_X86_64_SIZE32 foo 0x1
54// RELOCSHARED-NEXT: }
55// RELOCSHARED-NEXT: ]
56
57// DISASMSHARED: Disassembly of section test:
58// DISASMSHARED-NEXT: _data:
59// DISASMSHARED-NEXT: 1000: 00 00
60// DISASMSHARED-NEXT: 1002: 00 00
61// DISASMSHARED-NEXT: 1004: 00 00
62// DISASMSHARED-NEXT: 1006: 00 00
63// DISASMSHARED-NEXT: 1008: 00 00
64// DISASMSHARED-NEXT: 100a: 00 00
65// DISASMSHARED-NEXT: 100c: 00 00
66// DISASMSHARED-NEXT: 100e: 00 00
67// DISASMSHARED-NEXT: 1010: 00 00
68// DISASMSHARED-NEXT: 1012: 00 00
69// DISASMSHARED-NEXT: 1014: 00 00
70// DISASMSHARED-NEXT: 1016: 00 00
71// DISASMSHARED-NEXT: 1018: 19 00
72// DISASMSHARED-NEXT: 101a: 00 00
73// DISASMSHARED-NEXT: 101c: 00 00
74// DISASMSHARED-NEXT: 101e: 00 00
75// DISASMSHARED-NEXT: 1020: 1a 00
76// DISASMSHARED-NEXT: 1022: 00 00
77// DISASMSHARED-NEXT: 1024: 00 00
78// DISASMSHARED-NEXT: 1026: 00 00
79// DISASMSHARED-NEXT: 1028: 1b 00
80// DISASMSHARED-NEXT: 102a: 00 00
81// DISASMSHARED-NEXT: 102c: 00 00
82// DISASMSHARED-NEXT: 102e: 00 00
83// DISASMSHARED: _start:
84// DISASMSHARED-NEXT: 1030: 8b 04 25 00 00 00 00 movl 0, %eax
85// DISASMSHARED-NEXT: 1037: 8b 04 25 00 00 00 00 movl 0, %eax
86// DISASMSHARED-NEXT: 103e: 8b 04 25 00 00 00 00 movl 0, %eax
87// DISASMSHARED-NEXT: 1045: 8b 04 25 19 00 00 00 movl 25, %eax
88// DISASMSHARED-NEXT: 104c: 8b 04 25 1a 00 00 00 movl 26, %eax
89// DISASMSHARED-NEXT: 1053: 8b 04 25 1b 00 00 00 movl 27, %eax
90
91.data
92.global foo
93.type foo,%object
94.size foo,26
95foo:
96.zero 26
97
98.data
99.global foohidden
100.hidden foohidden
101.type foohidden,%object
102.size foohidden,26
103foohidden:
104.zero 26
105
106.section test,"axw"
107_data:
108 // R_X86_64_SIZE64:
109 .quad foo@SIZE-1
110 .quad foo@SIZE
111 .quad foo@SIZE+1
112 .quad foohidden@SIZE-1
113 .quad foohidden@SIZE
114 .quad foohidden@SIZE+1
115.globl _start
116_start:
117 // R_X86_64_SIZE32:
118 movl foo@SIZE-1,%eax
119 movl foo@SIZE,%eax
120 movl foo@SIZE+1,%eax
121 movl foohidden@SIZE-1,%eax
122 movl foohidden@SIZE,%eax
123 movl foohidden@SIZE+1,%eax
deps/lld/test/ELF/relocation-undefined-weak.s created+27
......@@ -0,0 +1,27 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
2// RUN: ld.lld %t -o %tout
3// RUN: llvm-readobj -sections %tout | FileCheck %s
4// RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix DISASM
5// REQUIRES: x86
6
7// Check that undefined weak symbols are treated as having a VA of 0.
8
9.global _start
10_start:
11 movl $1, sym1(%rip)
12
13.weak sym1
14
15// CHECK: Name: .text
16// CHECK-NEXT: Type: SHT_PROGBITS
17// CHECK-NEXT: Flags [
18// CHECK-NEXT: SHF_ALLOC
19// CHECK-NEXT: SHF_EXECINSTR
20// CHECK-NEXT: ]
21// CHECK-NEXT: Address: 0x201000
22
23// Unfortunately FileCheck can't do math, so we have to check for explicit
24// values:
25// R_86_64_PC32 = 0 + (-8 - (0x201000 + 2)) = -2101258
26
27// DISASM: movl $1, -2101258(%rip)
deps/lld/test/ELF/relocation.s created+142
......@@ -0,0 +1,142 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/shared.s -o %t2
3// RUN: ld.lld %t2 -o %t2.so -shared
4// RUN: ld.lld %t %t2.so -o %t3
5// RUN: llvm-readobj -s %t3 | FileCheck --check-prefix=SEC %s
6// RUN: llvm-objdump -s -d %t3 | FileCheck %s
7// REQUIRES: x86
8
9// SEC: Name: .plt
10// SEC-NEXT: Type: SHT_PROGBITS
11// SEC-NEXT: Flags [
12// SEC-NEXT: SHF_ALLOC
13// SEC-NEXT: SHF_EXECINSTR
14// SEC-NEXT: ]
15// SEC-NEXT: Address: 0x201030
16// SEC-NEXT: Offset: 0x1030
17// SEC-NEXT: Size: 48
18
19// SEC: Name: .got.plt
20// SEC-NEXT: Type: SHT_PROGBITS
21// SEC-NEXT: Flags [
22// SEC-NEXT: SHF_ALLOC
23// SEC-NEXT: SHF_WRITE
24// SEC-NEXT: ]
25// SEC-NEXT: Address: 0x202000
26// SEC-NEXT: Offset: 0x2000
27// SEC-NEXT: Size: 40
28// SEC-NEXT: Link: 0
29// SEC-NEXT: Info: 0
30// SEC-NEXT: AddressAlignment: 8
31// SEC-NEXT: EntrySize: 0
32// SEC-NEXT: }
33
34// SEC: Name: .got
35// SEC-NEXT: Type: SHT_PROGBITS
36// SEC-NEXT: Flags [
37// SEC-NEXT: SHF_ALLOC
38// SEC-NEXT: SHF_WRITE
39// SEC-NEXT: ]
40// SEC-NEXT: Address: 0x2030F0
41// SEC-NEXT: Offset:
42// SEC-NEXT: Size: 8
43// SEC-NEXT: Link: 0
44// SEC-NEXT: Info: 0
45// SEC-NEXT: AddressAlignment: 8
46// SEC-NEXT: EntrySize: 0
47// SEC-NEXT: }
48
49.section .text,"ax",@progbits,unique,1
50.global _start
51_start:
52 call lulz
53
54.section .text,"ax",@progbits,unique,2
55.zero 4
56.global lulz
57lulz:
58 nop
59
60// CHECK: Disassembly of section .text:
61// CHECK-NEXT: _start:
62// CHECK-NEXT: 201000: e8 04 00 00 00 callq 4
63// CHECK-NEXT: 201005:
64
65// CHECK: lulz:
66// CHECK-NEXT: 201009: 90 nop
67
68
69.section .text2,"ax",@progbits
70.global R_X86_64_32
71R_X86_64_32:
72 movl $R_X86_64_32, %edx
73
74// FIXME: this would be far more self evident if llvm-objdump printed
75// constants in hex.
76// CHECK: Disassembly of section .text2:
77// CHECK-NEXT: R_X86_64_32:
78// CHECK-NEXT: 20100a: {{.*}} movl $2101258, %edx
79
80.section .R_X86_64_32S,"ax",@progbits
81.global R_X86_64_32S
82R_X86_64_32S:
83 movq lulz - 0x100000, %rdx
84
85// CHECK: Disassembly of section .R_X86_64_32S:
86// CHECK-NEXT: R_X86_64_32S:
87// CHECK-NEXT: {{.*}}: {{.*}} movq 1052681, %rdx
88
89.section .R_X86_64_PC32,"ax",@progbits
90.global R_X86_64_PC32
91R_X86_64_PC32:
92 call bar
93 movl $bar, %eax
94//16 is a size of PLT[0]
95// 0x201030 + 16 - (0x201017 + 5) = 20
96// CHECK: Disassembly of section .R_X86_64_PC32:
97// CHECK-NEXT: R_X86_64_PC32:
98// CHECK-NEXT: 201017: {{.*}} callq 36
99// CHECK-NEXT: 20101c: {{.*}} movl $2101312, %eax
100
101.section .R_X86_64_32S_2,"ax",@progbits
102.global R_X86_64_32S_2
103R_X86_64_32S_2:
104 mov bar2, %eax
105// plt is at 0x201030. The second plt entry is at 0x201050 == 69712
106// CHECK: Disassembly of section .R_X86_64_32S_2:
107// CHECK-NEXT: R_X86_64_32S_2:
108// CHECK-NEXT: 201021: {{.*}} movl 2101328, %eax
109
110.section .R_X86_64_64,"a",@progbits
111.global R_X86_64_64
112R_X86_64_64:
113 .quad R_X86_64_64
114
115// CHECK: Contents of section .R_X86_64_64:
116// CHECK-NEXT: 2001c8 c8012000 00000000
117
118.section .R_X86_64_GOTPCREL,"a",@progbits
119.global R_X86_64_GOTPCREL
120R_X86_64_GOTPCREL:
121 .long zed@gotpcrel
122
123// 0x2020F8 - 0x2001D8 = 7952
124// 7952 = 0x101f0000 in little endian
125// CHECK: Contents of section .R_X86_64_GOTPCREL
126// CHECK-NEXT: 2001d0 202f0000
127
128.section .R_X86_64_GOT32,"a",@progbits
129.global R_X86_64_GOT32
130R_X86_64_GOT32:
131 .long zed@got
132
133// CHECK: Contents of section .R_X86_64_GOT32:
134// CHECK-NEXT: f8ffffff
135
136
137// CHECK: Contents of section .R_X86_64_GOT64:
138// CHECK-NEXT: f8ffffff ffffffff
139.section .R_X86_64_GOT64,"a",@progbits
140.global R_X86_64_GOT64
141R_X86_64_GOT64:
142 .quad zed@got
deps/lld/test/ELF/relro-omagic.s created+34
......@@ -0,0 +1,34 @@
1# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o
3# RUN: ld.lld -shared %t2.o -o %t2.so -soname relro-omagic.s.tmp2.so
4# RUN: ld.lld -N %t.o %t2.so -o %t
5# RUN: llvm-objdump -section-headers %t | FileCheck --check-prefix=NORELRO %s
6# RUN: llvm-readobj --program-headers %t | FileCheck --check-prefix=NOPHDRS %s
7
8# NORELRO: Sections:
9# NORELRO-NEXT: Idx Name Size Address Type
10# NORELRO-NEXT: 0 00000000 0000000000000000
11# NORELRO-NEXT: 1 .dynsym 00000048 0000000000200120
12# NORELRO-NEXT: 2 .hash 00000020 0000000000200168
13# NORELRO-NEXT: 3 .dynstr 00000021 0000000000200188
14# NORELRO-NEXT: 4 .rela.dyn 00000018 00000000002001b0
15# NORELRO-NEXT: 5 .rela.plt 00000018 00000000002001c8
16# NORELRO-NEXT: 6 .text 0000000a 00000000002001e0 TEXT DATA
17# NORELRO-NEXT: 7 .plt 00000020 00000000002001f0 TEXT DATA
18# NORELRO-NEXT: 8 .data 00000008 0000000000200210 DATA
19# NORELRO-NEXT: 9 .foo 00000004 0000000000200218 DATA
20# NORELRO-NEXT: 10 .dynamic 000000f0 0000000000200220
21# NORELRO-NEXT: 11 .got 00000008 0000000000200310 DATA
22# NORELRO-NEXT: 12 .got.plt 00000020 0000000000200318 DATA
23
24# NOPHDRS: ProgramHeaders [
25# NOPHDRS-NOT: PT_GNU_RELRO
26
27.long bar
28jmp *bar2@GOTPCREL(%rip)
29
30.section .data,"aw"
31.quad 0
32
33.section .foo,"aw"
34.zero 4
deps/lld/test/ELF/relro-tls.s created+23
......@@ -0,0 +1,23 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3// RUN: ld.lld %t -o %tout
4// RUN: llvm-readobj -program-headers %tout | FileCheck %s
5
6// CHECK: Type: PT_GNU_RELRO
7// CHECK-NEXT: Offset:
8// CHECK-NEXT: VirtualAddress:
9// CHECK-NEXT: PhysicalAddress:
10// CHECK-NEXT: FileSize: 4
11// CHECK-NEXT: MemSize: 4
12// CHECK-NEXT: Flags [
13// CHECK-NEXT: PF_R
14// CHECK-NEXT: ]
15// CHECK-NEXT: Alignment: 1
16
17.global _start
18_start:
19
20.global d
21.section .foo,"awT",@progbits
22d:
23.long 2
deps/lld/test/ELF/relro.s created+41
......@@ -0,0 +1,41 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o
3// RUN: ld.lld -shared %t2.o -o %t2.so
4// RUN: ld.lld %t.o %t2.so -z now -z relro -o %t
5// RUN: llvm-readobj -l --elf-output-style=GNU %t | FileCheck --check-prefix=CHECK --check-prefix=FULLRELRO %s
6// RUN: ld.lld %t.o %t2.so -z relro -o %t
7// RUN: llvm-readobj -l --elf-output-style=GNU %t | FileCheck --check-prefix=CHECK --check-prefix=PARTRELRO %s
8// RUN: ld.lld %t.o %t2.so -z norelro -o %t
9// RUN: llvm-readobj -l --elf-output-style=GNU %t | FileCheck --check-prefix=NORELRO %s
10// REQUIRES: x86
11
12// CHECK: Program Headers:
13// CHECK-NEXT: Type
14// CHECK-NEXT: PHDR
15// CHECK-NEXT: LOAD
16// CHECK-NEXT: LOAD
17// CHECK-NEXT: LOAD
18// CHECK-NEXT: DYNAMIC
19// CHECK-NEXT: GNU_RELRO
20// CHECK: Section to Segment mapping:
21
22// FULLRELRO: 05 .openbsd.randomdata .dynamic .got .got.plt {{$}}
23// PARTRELRO: 05 .openbsd.randomdata .dynamic .got {{$}}
24
25
26// NORELRO-NOT: GNU_RELRO
27
28.global _start
29_start:
30 .long bar
31 jmp *bar2@GOTPCREL(%rip)
32
33.section .data,"aw"
34.quad 0
35
36.zero 4
37.section .foo,"aw"
38.section .bss,"",@nobits
39
40.section .openbsd.randomdata, "aw"
41.quad 0
deps/lld/test/ELF/reproduce-backslash.s created+9
......@@ -0,0 +1,9 @@
1# REQUIRES: x86, shell
2
3# Test that we don't erroneously replace \ with / on UNIX, as it's
4# legal for a filename to contain backslashes.
5# RUN: llvm-mc %s -o foo\\.o -filetype=obj -triple=x86_64-pc-linux
6# RUN: ld.lld foo\\.o --reproduce repro.tar
7# RUN: tar tf repro.tar | FileCheck %s
8
9# CHECK: repro/{{.*}}/foo\\.o
deps/lld/test/ELF/reproduce-error.s created+14
......@@ -0,0 +1,14 @@
1# Extracting the tar archive can get over the path limit on windows.
2# REQUIRES: shell
3
4# RUN: rm -rf %t.dir
5# RUN: mkdir -p %t.dir
6# RUN: cd %t.dir
7
8# RUN: not ld.lld --reproduce repro.tar abc -o t 2>&1 | FileCheck %s
9# CHECK: cannot open abc: {{N|n}}o such file or directory
10
11# RUN: tar xf repro.tar
12# RUN: FileCheck --check-prefix=RSP %s < repro/response.txt
13# RSP: abc
14# RSP: -o t
deps/lld/test/ELF/reproduce-linkerscript.s created+20
......@@ -0,0 +1,20 @@
1# REQUIRES: x86, shell
2
3# RUN: rm -rf %t.dir
4# RUN: mkdir -p %t.dir/build
5# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.dir/build/foo.o
6# RUN: echo "INPUT(\"%t.dir/build/foo.o\")" > %t.dir/build/foo.script
7# RUN: echo "INCLUDE \"%t.dir/build/bar.script\"" >> %t.dir/build/foo.script
8# RUN: echo "/* empty */" > %t.dir/build/bar.script
9# RUN: cd %t.dir
10# RUN: ld.lld build/foo.script -o bar --reproduce repro.tar
11# RUN: tar xf repro.tar
12# RUN: diff build/foo.script repro/%:t.dir/build/foo.script
13# RUN: diff build/bar.script repro/%:t.dir/build/bar.script
14# RUN: diff build/foo.o repro/%:t.dir/build/foo.o
15
16.globl _start
17_start:
18 mov $60, %rax
19 mov $42, %rdi
20 syscall
deps/lld/test/ELF/reproduce-thin-archive.s created+15
......@@ -0,0 +1,15 @@
1# REQUIRES: x86, shell
2
3# RUN: rm -rf %t.dir
4# RUN: mkdir -p %t.dir
5# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.dir/foo.o
6# RUN: cd %t.dir
7# RUN: llvm-ar --format=gnu rcT foo.a foo.o
8# RUN: ld.lld -m elf_x86_64 foo.a -o bar --reproduce repro.tar
9# RUN: tar xf repro.tar
10# RUN: diff foo.a repro/%:t.dir/foo.a
11# RUN: diff foo.o repro/%:t.dir/foo.o
12
13.globl _start
14_start:
15 nop
deps/lld/test/ELF/reproduce-windows.s created+12
......@@ -0,0 +1,12 @@
1# REQUIRES: x86
2
3# Test that a repro archive always uses / instead of \.
4# RUN: rm -rf %t.dir
5# RUN: mkdir -p %t.dir/build
6# RUN: llvm-mc %s -o %t.dir/build/foo.o -filetype=obj -triple=x86_64-pc-linux
7# RUN: cd %t.dir
8# RUN: ld.lld build/foo.o --reproduce repro.tar
9# RUN: tar tf repro.tar | FileCheck %s
10
11# CHECK: repro/response.txt
12# CHECK: repro/{{.*}}/build/foo.o
deps/lld/test/ELF/reproduce-windows2.s created+10
......@@ -0,0 +1,10 @@
1# REQUIRES: system-windows, x86
2
3# Test that a response.txt file always uses / instead of \.
4# RUN: rm -rf %t.dir
5# RUN: mkdir -p %t.dir/build
6# RUN: llvm-mc %s -o %t.dir/build/foo.o -filetype=obj -triple=x86_64-pc-linux
7# RUN: cd %t.dir
8# RUN: ld.lld build/foo.o --reproduce repro.tar
9# RUN: tar -O -x -f repro.tar repro/response.txt | FileCheck %s
10# CHECK: {{.*}}/build/foo.o
deps/lld/test/ELF/reproduce.s created+75
......@@ -0,0 +1,75 @@
1# REQUIRES: x86
2
3# Extracting the tar archive can get over the path limit on windows.
4# REQUIRES: shell
5
6# RUN: rm -rf %t.dir
7# RUN: mkdir -p %t.dir/build1
8# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.dir/build1/foo.o
9# RUN: cd %t.dir
10# RUN: ld.lld --hash-style=gnu build1/foo.o -o bar -shared --as-needed --reproduce repro.tar
11# RUN: tar xf repro.tar
12# RUN: diff build1/foo.o repro/%:t.dir/build1/foo.o
13
14# RUN: FileCheck %s --check-prefix=RSP < repro/response.txt
15# RSP: {{^}}--hash-style gnu{{$}}
16# RSP-NOT: repro{{[/\\]}}
17# RSP-NEXT: {{[/\\]}}foo.o
18# RSP-NEXT: -o bar
19# RSP-NEXT: -shared
20# RSP-NEXT: --as-needed
21
22# RUN: FileCheck %s --check-prefix=VERSION < repro/version.txt
23# VERSION: LLD
24
25# RUN: mkdir -p %t.dir/build2/a/b/c
26# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.dir/build2/foo.o
27# RUN: cd %t.dir/build2/a/b/c
28# RUN: env LLD_REPRODUCE=repro.tar ld.lld ./../../../foo.o -o bar -shared --as-needed
29# RUN: tar xf repro.tar
30# RUN: diff %t.dir/build2/foo.o repro/%:t.dir/build2/foo.o
31
32# RUN: echo "{ local: *; };" > ver
33# RUN: echo "{};" > dyn
34# RUN: echo > file
35# RUN: echo > file2
36# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o 'foo bar'
37# RUN: ld.lld --reproduce repro2.tar 'foo bar' -L"foo bar" -Lfile -Tfile2 \
38# RUN: --dynamic-list dyn -rpath file --script=file --version-script ver \
39# RUN: --dynamic-linker "some unusual/path" -soname 'foo bar' -soname='foo bar'
40# RUN: tar xf repro2.tar
41# RUN: FileCheck %s --check-prefix=RSP2 < repro2/response.txt
42# RSP2: "{{.*}}foo bar"
43# RSP2-NEXT: -L "{{.*}}foo bar"
44# RSP2-NEXT: -L {{.+}}file
45# RSP2-NEXT: --script {{.+}}file2
46# RSP2-NEXT: --dynamic-list {{.+}}dyn
47# RSP2-NEXT: -rpath {{.+}}file
48# RSP2-NEXT: --script {{.+}}file
49# RSP2-NEXT: --version-script [[PATH:.*]]ver
50# RSP2-NEXT: --dynamic-linker "some unusual/path"
51# RSP2-NEXT: -soname="foo bar"
52# RSP2-NEXT: -soname="foo bar"
53
54# RUN: tar tf repro2.tar | FileCheck %s
55# CHECK: repro2/response.txt
56# CHECK-NEXT: repro2/version.txt
57# CHECK-NEXT: repro2/{{.*}}/dyn
58# CHECK-NEXT: repro2/{{.*}}/ver
59# CHECK-NEXT: repro2/{{.*}}/foo bar
60# CHECK-NEXT: repro2/{{.*}}/file2
61# CHECK-NEXT: repro2/{{.*}}/file
62
63## Check that directory path is stripped from -o <file-path>
64# RUN: mkdir -p %t.dir/build3/a/b/c
65# RUN: cd %t.dir
66# RUN: ld.lld build1/foo.o -o build3/a/b/c/bar -shared --as-needed --reproduce=repro3.tar
67# RUN: tar xf repro3.tar
68# RUN: FileCheck %s --check-prefix=RSP3 < repro3/response.txt
69# RSP3: -o bar
70
71.globl _start
72_start:
73 mov $60, %rax
74 mov $42, %rdi
75 syscall
deps/lld/test/ELF/resolution-end.s created+38
......@@ -0,0 +1,38 @@
1# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/resolution-end.s -o %t2.o
3# RUN: ld.lld -shared -o %t2.so %t2.o
4# RUN: ld.lld %t1.o %t2.so -o %t
5# RUN: llvm-readobj -t -s -section-data %t | FileCheck %s
6# REQUIRES: x86
7
8# Test that we resolve _end to the this executable.
9
10# CHECK: Name: .text
11# CHECK-NEXT: Type: SHT_PROGBITS
12# CHECK-NEXT: Flags [
13# CHECK-NEXT: SHF_ALLOC
14# CHECK-NEXT: SHF_EXECINSTR
15# CHECK-NEXT: ]
16# CHECK-NEXT: Address:
17# CHECK-NEXT: Offset:
18# CHECK-NEXT: Size:
19# CHECK-NEXT: Link:
20# CHECK-NEXT: Info:
21# CHECK-NEXT: AddressAlignment:
22# CHECK-NEXT: EntrySize:
23# CHECK-NEXT: SectionData (
24# CHECK-NEXT: 0000: 80202000 00000000 80202000 00000000
25# CHECK-NEXT: )
26
27# CHECK: Symbol {
28# CHECK: Name: _end
29# CHECK-NEXT: Value: 0x202080
30
31# CHECK: Symbol {
32# CHECK: Name: end
33# CHECK-NEXT: Value: 0x202080
34
35.global _start
36_start:
37.quad _end
38.quad end
deps/lld/test/ELF/resolution-shared.s created+15
......@@ -0,0 +1,15 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/resolution-shared.s -o %t2.o
3// RUN: ld.lld %t2.o -o %t2.so -shared
4// RUN: ld.lld %t.o %t2.so -o %t3 -shared
5// RUN: llvm-readobj -t %t3 | FileCheck %s
6// REQUIRES: x86
7
8 .weak foo
9foo:
10
11// CHECK: Symbol {
12// CHECK: Name: foo
13// CHECK-NEXT: Value:
14// CHECK-NEXT: Size:
15// CHECK-NEXT: Binding: Weak
deps/lld/test/ELF/resolution.s created+430
......@@ -0,0 +1,430 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/resolution.s -o %t2
3// RUN: ld.lld -discard-all %t %t2 -o %t3
4// RUN: llvm-readobj -t %t3 | FileCheck %s
5// REQUIRES: x86
6
7// This is an exhaustive test for checking which symbol is kept when two
8// have the same name. Each symbol has a different size which is used
9// to see which one was chosen.
10
11// CHECK: Symbols [
12// CHECK-NEXT: Symbol {
13// CHECK-NEXT: Name: (0)
14// CHECK-NEXT: Value: 0x0
15// CHECK-NEXT: Size: 0
16// CHECK-NEXT: Binding: Local (0x0)
17// CHECK-NEXT: Type: None (0x0)
18// CHECK-NEXT: Other: 0
19// CHECK-NEXT: Section: Undefined (0x0)
20// CHECK-NEXT: }
21// CHECK-NEXT: Symbol {
22// CHECK-NEXT: Name: CommonStrong_with_CommonStrong
23// CHECK-NEXT: Value:
24// CHECK-NEXT: Size: 63
25// CHECK-NEXT: Binding: Global
26// CHECK-NEXT: Type: Object
27// CHECK-NEXT: Other: 0
28// CHECK-NEXT: Section:
29// CHECK-NEXT: }
30// CHECK-NEXT: Symbol {
31// CHECK-NEXT: Name: CommonStrong_with_CommonWeak
32// CHECK-NEXT: Value:
33// CHECK-NEXT: Size: 30
34// CHECK-NEXT: Binding: Global
35// CHECK-NEXT: Type: Object
36// CHECK-NEXT: Other: 0
37// CHECK-NEXT: Section:
38// CHECK-NEXT: }
39// CHECK-NEXT: Symbol {
40// CHECK-NEXT: Name: CommonStrong_with_RegularStrong
41// CHECK-NEXT: Value:
42// CHECK-NEXT: Size: 55
43// CHECK-NEXT: Binding: Global
44// CHECK-NEXT: Type: None
45// CHECK-NEXT: Other: 0
46// CHECK-NEXT: Section: .text
47// CHECK-NEXT: }
48// CHECK-NEXT: Symbol {
49// CHECK-NEXT: Name: CommonStrong_with_RegularWeak
50// CHECK-NEXT: Value:
51// CHECK-NEXT: Size: 22
52// CHECK-NEXT: Binding: Global
53// CHECK-NEXT: Type: Object
54// CHECK-NEXT: Other: 0
55// CHECK-NEXT: Section:
56// CHECK-NEXT: }
57// CHECK-NEXT: Symbol {
58// CHECK-NEXT: Name: CommonStrong_with_UndefStrong
59// CHECK-NEXT: Value:
60// CHECK-NEXT: Size: 27
61// CHECK-NEXT: Binding: Global
62// CHECK-NEXT: Type: Object
63// CHECK-NEXT: Other: 0
64// CHECK-NEXT: Section:
65// CHECK-NEXT: }
66// CHECK-NEXT: Symbol {
67// CHECK-NEXT: Name: CommonStrong_with_UndefWeak
68// CHECK-NEXT: Value:
69// CHECK-NEXT: Size: 26
70// CHECK-NEXT: Binding: Global
71// CHECK-NEXT: Type: Object
72// CHECK-NEXT: Other: 0
73// CHECK-NEXT: Section:
74// CHECK-NEXT: }
75// CHECK-NEXT: Symbol {
76// CHECK-NEXT: Name: CommonWeak_with_CommonStrong
77// CHECK-NEXT: Value:
78// CHECK-NEXT: Size: 61
79// CHECK-NEXT: Binding: Global
80// CHECK-NEXT: Type: Object
81// CHECK-NEXT: Other: 0
82// CHECK-NEXT: Section:
83// CHECK-NEXT: }
84// CHECK-NEXT: Symbol {
85// CHECK-NEXT: Name: CommonWeak_with_CommonWeak
86// CHECK-NEXT: Value:
87// CHECK-NEXT: Size: 28
88// CHECK-NEXT: Binding: Weak
89// CHECK-NEXT: Type: Object
90// CHECK-NEXT: Other: 0
91// CHECK-NEXT: Section:
92// CHECK-NEXT: }
93// CHECK-NEXT: Symbol {
94// CHECK-NEXT: Name: CommonWeak_with_RegularStrong
95// CHECK-NEXT: Value:
96// CHECK-NEXT: Size: 53
97// CHECK-NEXT: Binding: Global
98// CHECK-NEXT: Type: None
99// CHECK-NEXT: Other: 0
100// CHECK-NEXT: Section: .text
101// CHECK-NEXT: }
102// CHECK-NEXT: Symbol {
103// CHECK-NEXT: Name: CommonWeak_with_RegularWeak
104// CHECK-NEXT: Value:
105// CHECK-NEXT: Size: 20
106// CHECK-NEXT: Binding: Weak
107// CHECK-NEXT: Type: Object
108// CHECK-NEXT: Other: 0
109// CHECK-NEXT: Section:
110// CHECK-NEXT: }
111// CHECK-NEXT: Symbol {
112// CHECK-NEXT: Name: CommonWeak_with_UndefStrong
113// CHECK-NEXT: Value:
114// CHECK-NEXT: Size: 25
115// CHECK-NEXT: Binding: Weak
116// CHECK-NEXT: Type: Object
117// CHECK-NEXT: Other: 0
118// CHECK-NEXT: Section:
119// CHECK-NEXT: }
120// CHECK-NEXT: Symbol {
121// CHECK-NEXT: Name: CommonWeak_with_UndefWeak
122// CHECK-NEXT: Value:
123// CHECK-NEXT: Size: 24
124// CHECK-NEXT: Binding: Weak
125// CHECK-NEXT: Type: Object
126// CHECK-NEXT: Other: 0
127// CHECK-NEXT: Section:
128// CHECK-NEXT: }
129// CHECK-NEXT: Symbol {
130// CHECK-NEXT: Name: RegularStrong_with_CommonStrong
131// CHECK-NEXT: Value:
132// CHECK-NEXT: Size: 10
133// CHECK-NEXT: Binding: Global
134// CHECK-NEXT: Type: None
135// CHECK-NEXT: Other: 0
136// CHECK-NEXT: Section: .text
137// CHECK-NEXT: }
138// CHECK-NEXT: Symbol {
139// CHECK-NEXT: Name: RegularStrong_with_CommonWeak
140// CHECK-NEXT: Value:
141// CHECK-NEXT: Size: 9
142// CHECK-NEXT: Binding: Global
143// CHECK-NEXT: Type: None
144// CHECK-NEXT: Other: 0
145// CHECK-NEXT: Section: .text
146// CHECK-NEXT: }
147// CHECK-NEXT: Symbol {
148// CHECK-NEXT: Name: RegularStrong_with_RegularWeak
149// CHECK-NEXT: Value:
150// CHECK-NEXT: Size: 2
151// CHECK-NEXT: Binding: Global
152// CHECK-NEXT: Type: None
153// CHECK-NEXT: Other: 0
154// CHECK-NEXT: Section: .text
155// CHECK-NEXT: }
156// CHECK-NEXT: Symbol {
157// CHECK-NEXT: Name: RegularStrong_with_UndefStrong
158// CHECK-NEXT: Value:
159// CHECK-NEXT: Size: 6
160// CHECK-NEXT: Binding: Global
161// CHECK-NEXT: Type: None
162// CHECK-NEXT: Other: 0
163// CHECK-NEXT: Section: .text
164// CHECK-NEXT: }
165// CHECK-NEXT: Symbol {
166// CHECK-NEXT: Name: RegularStrong_with_UndefWeak
167// CHECK-NEXT: Value:
168// CHECK-NEXT: Size: 5
169// CHECK-NEXT: Binding: Global
170// CHECK-NEXT: Type: None
171// CHECK-NEXT: Other: 0
172// CHECK-NEXT: Section: .text
173// CHECK-NEXT: }
174// CHECK-NEXT: Symbol {
175// CHECK-NEXT: Name: RegularWeak_with_CommonStrong
176// CHECK-NEXT: Value:
177// CHECK-NEXT: Size: 40
178// CHECK-NEXT: Binding: Global
179// CHECK-NEXT: Type: Object
180// CHECK-NEXT: Other: 0
181// CHECK-NEXT: Section:
182// CHECK-NEXT: }
183// CHECK-NEXT: Symbol {
184// CHECK-NEXT: Name: RegularWeak_with_CommonWeak
185// CHECK-NEXT: Value:
186// CHECK-NEXT: Size: 7
187// CHECK-NEXT: Binding: Weak
188// CHECK-NEXT: Type: None
189// CHECK-NEXT: Other: 0
190// CHECK-NEXT: Section: .text
191// CHECK-NEXT: }
192// CHECK-NEXT: Symbol {
193// CHECK-NEXT: Name: RegularWeak_with_RegularStrong
194// CHECK-NEXT: Value:
195// CHECK-NEXT: Size: 33
196// CHECK-NEXT: Binding: Global
197// CHECK-NEXT: Type: None
198// CHECK-NEXT: Other: 0
199// CHECK-NEXT: Section: .text
200// CHECK-NEXT: }
201// CHECK-NEXT: Symbol {
202// CHECK-NEXT: Name: RegularWeak_with_RegularWeak
203// CHECK-NEXT: Value:
204// CHECK-NEXT: Size: 0
205// CHECK-NEXT: Binding: Weak
206// CHECK-NEXT: Type: None
207// CHECK-NEXT: Other: 0
208// CHECK-NEXT: Section: .text
209// CHECK-NEXT: }
210// CHECK-NEXT: Symbol {
211// CHECK-NEXT: Name: RegularWeak_with_UndefStrong
212// CHECK-NEXT: Value:
213// CHECK-NEXT: Size: 4
214// CHECK-NEXT: Binding: Weak
215// CHECK-NEXT: Type: None
216// CHECK-NEXT: Other: 0
217// CHECK-NEXT: Section: .text
218// CHECK-NEXT: }
219// CHECK-NEXT: Symbol {
220// CHECK-NEXT: Name: RegularWeak_with_UndefWeak
221// CHECK-NEXT: Value:
222// CHECK-NEXT: Size: 3
223// CHECK-NEXT: Binding: Weak
224// CHECK-NEXT: Type: None
225// CHECK-NEXT: Other: 0
226// CHECK-NEXT: Section: .text
227// CHECK-NEXT: }
228// CHECK-NEXT: Symbol {
229// CHECK-NEXT: Name: UndefStrong_with_CommonStrong
230// CHECK-NEXT: Value:
231// CHECK-NEXT: Size: 51
232// CHECK-NEXT: Binding: Global
233// CHECK-NEXT: Type: Object
234// CHECK-NEXT: Other: 0
235// CHECK-NEXT: Section:
236// CHECK-NEXT: }
237// CHECK-NEXT: Symbol {
238// CHECK-NEXT: Name: UndefStrong_with_CommonWeak
239// CHECK-NEXT: Value:
240// CHECK-NEXT: Size: 50
241// CHECK-NEXT: Binding: Weak
242// CHECK-NEXT: Type: Object
243// CHECK-NEXT: Other: 0
244// CHECK-NEXT: Section:
245// CHECK-NEXT: }
246// CHECK-NEXT: Symbol {
247// CHECK-NEXT: Name: UndefStrong_with_RegularStrong
248// CHECK-NEXT: Value:
249// CHECK-NEXT: Size: 46
250// CHECK-NEXT: Binding: Global
251// CHECK-NEXT: Type: None
252// CHECK-NEXT: Other: 0
253// CHECK-NEXT: Section: .text
254// CHECK-NEXT: }
255// CHECK-NEXT: Symbol {
256// CHECK-NEXT: Name: UndefStrong_with_RegularWeak
257// CHECK-NEXT: Value:
258// CHECK-NEXT: Size: 45
259// CHECK-NEXT: Binding: Weak
260// CHECK-NEXT: Type: None
261// CHECK-NEXT: Other: 0
262// CHECK-NEXT: Section: .text
263// CHECK-NEXT: }
264// CHECK-NEXT: Symbol {
265// CHECK-NEXT: Name: UndefWeak_with_CommonStrong
266// CHECK-NEXT: Value:
267// CHECK-NEXT: Size: 49
268// CHECK-NEXT: Binding: Global
269// CHECK-NEXT: Type: Object
270// CHECK-NEXT: Other: 0
271// CHECK-NEXT: Section:
272// CHECK-NEXT: }
273// CHECK-NEXT: Symbol {
274// CHECK-NEXT: Name: UndefWeak_with_CommonWeak
275// CHECK-NEXT: Value:
276// CHECK-NEXT: Size: 48
277// CHECK-NEXT: Binding: Weak
278// CHECK-NEXT: Type: Object
279// CHECK-NEXT: Other: 0
280// CHECK-NEXT: Section:
281// CHECK-NEXT: }
282// CHECK-NEXT: Symbol {
283// CHECK-NEXT: Name: UndefWeak_with_RegularStrong
284// CHECK-NEXT: Value:
285// CHECK-NEXT: Size: 44
286// CHECK-NEXT: Binding: Global
287// CHECK-NEXT: Type: None
288// CHECK-NEXT: Other: 0
289// CHECK-NEXT: Section: .text
290// CHECK-NEXT: }
291// CHECK-NEXT: Symbol {
292// CHECK-NEXT: Name: UndefWeak_with_RegularWeak
293// CHECK-NEXT: Value:
294// CHECK-NEXT: Size: 43
295// CHECK-NEXT: Binding: Weak
296// CHECK-NEXT: Type: None
297// CHECK-NEXT: Other: 0
298// CHECK-NEXT: Section: .text
299// CHECK-NEXT: }
300// CHECK-NEXT: Symbol {
301// CHECK-NEXT: Name: UndefWeak_with_UndefWeak
302// CHECK-NEXT: Value: 0x0
303// CHECK-NEXT: Size: 0
304// CHECK-NEXT: Binding: Weak
305// CHECK-NEXT: Type: None
306// CHECK-NEXT: Other: 0
307// CHECK-NEXT: Section: Undefined
308// CHECK-NEXT: }
309// CHECK-NEXT: Symbol {
310// CHECK-NEXT: Name: _start
311// CHECK-NEXT: Value: 0x201000
312// CHECK-NEXT: Size: 0
313// CHECK-NEXT: Binding: Global (0x1)
314// CHECK-NEXT: Type: None (0x0)
315// CHECK-NEXT: Other: 0
316// CHECK-NEXT: Section: .text (0x1)
317// CHECK-NEXT: }
318// CHECK-NEXT: ]
319
320.globl _start
321_start:
322 nop
323
324local:
325
326.weak RegularWeak_with_RegularWeak
327.size RegularWeak_with_RegularWeak, 0
328RegularWeak_with_RegularWeak:
329
330.weak RegularWeak_with_RegularStrong
331.size RegularWeak_with_RegularStrong, 1
332RegularWeak_with_RegularStrong:
333
334.global RegularStrong_with_RegularWeak
335.size RegularStrong_with_RegularWeak, 2
336RegularStrong_with_RegularWeak:
337
338.weak RegularWeak_with_UndefWeak
339.size RegularWeak_with_UndefWeak, 3
340RegularWeak_with_UndefWeak:
341
342.weak RegularWeak_with_UndefStrong
343.size RegularWeak_with_UndefStrong, 4
344RegularWeak_with_UndefStrong:
345
346.global RegularStrong_with_UndefWeak
347.size RegularStrong_with_UndefWeak, 5
348RegularStrong_with_UndefWeak:
349
350.global RegularStrong_with_UndefStrong
351.size RegularStrong_with_UndefStrong, 6
352RegularStrong_with_UndefStrong:
353
354.weak RegularWeak_with_CommonWeak
355.size RegularWeak_with_CommonWeak, 7
356RegularWeak_with_CommonWeak:
357
358.weak RegularWeak_with_CommonStrong
359.size RegularWeak_with_CommonStrong, 8
360RegularWeak_with_CommonStrong:
361
362.global RegularStrong_with_CommonWeak
363.size RegularStrong_with_CommonWeak, 9
364RegularStrong_with_CommonWeak:
365
366.global RegularStrong_with_CommonStrong
367.size RegularStrong_with_CommonStrong, 10
368RegularStrong_with_CommonStrong:
369
370.weak UndefWeak_with_RegularWeak
371.size UndefWeak_with_RegularWeak, 11
372.quad UndefWeak_with_RegularWeak
373
374.weak UndefWeak_with_RegularStrong
375.size UndefWeak_with_RegularStrong, 12
376.quad UndefWeak_with_RegularStrong
377
378.size UndefStrong_with_RegularWeak, 13
379.quad UndefStrong_with_RegularWeak
380
381.size UndefStrong_with_RegularStrong, 14
382.quad UndefStrong_with_RegularStrong
383
384.weak UndefWeak_with_UndefWeak
385.size UndefWeak_with_UndefWeak, 15
386.quad UndefWeak_with_UndefWeak
387
388.weak UndefWeak_with_CommonWeak
389.size UndefWeak_with_CommonWeak, 16
390.quad UndefWeak_with_CommonWeak
391
392.weak UndefWeak_with_CommonStrong
393.size UndefWeak_with_CommonStrong, 17
394.quad UndefWeak_with_CommonStrong
395
396.size UndefStrong_with_CommonWeak, 18
397.quad UndefStrong_with_CommonWeak
398
399.size UndefStrong_with_CommonStrong, 19
400.quad UndefStrong_with_CommonStrong
401
402.weak CommonWeak_with_RegularWeak
403.comm CommonWeak_with_RegularWeak,20,4
404
405.weak CommonWeak_with_RegularStrong
406.comm CommonWeak_with_RegularStrong,21,4
407
408.comm CommonStrong_with_RegularWeak,22,4
409
410.comm CommonStrong_with_RegularStrong,23,4
411
412.weak CommonWeak_with_UndefWeak
413.comm CommonWeak_with_UndefWeak,24,4
414
415.weak CommonWeak_with_UndefStrong
416.comm CommonWeak_with_UndefStrong,25,4
417
418.comm CommonStrong_with_UndefWeak,26,4
419
420.comm CommonStrong_with_UndefStrong,27,4
421
422.weak CommonWeak_with_CommonWeak
423.comm CommonWeak_with_CommonWeak,28,4
424
425.weak CommonWeak_with_CommonStrong
426.comm CommonWeak_with_CommonStrong,29,4
427
428.comm CommonStrong_with_CommonWeak,30,4
429
430.comm CommonStrong_with_CommonStrong,31,4
deps/lld/test/ELF/retain-symbols-file.s created+74
......@@ -0,0 +1,74 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
3# RUN: echo "bar" > %t_retain.txt
4# RUN: echo "foo" >> %t_retain.txt
5# RUN: ld.lld -shared --retain-symbols-file=%t_retain.txt %t -o %t2
6# RUN: llvm-readobj --dyn-symbols %t2 | FileCheck %s
7
8## Check separate form.
9# RUN: ld.lld -shared --retain-symbols-file %t_retain.txt %t -o %t2
10# RUN: llvm-readobj --dyn-symbols %t2 | FileCheck %s
11
12# CHECK: DynamicSymbols [
13# CHECK-NEXT: Symbol {
14# CHECK-NEXT: Name: @
15# CHECK-NEXT: Value:
16# CHECK-NEXT: Size:
17# CHECK-NEXT: Binding:
18# CHECK-NEXT: Type:
19# CHECK-NEXT: Other:
20# CHECK-NEXT: Section:
21# CHECK-NEXT: }
22# CHECK-NEXT: Symbol {
23# CHECK-NEXT: Name: bar
24# CHECK-NEXT: Value:
25# CHECK-NEXT: Size:
26# CHECK-NEXT: Binding: Global
27# CHECK-NEXT: Type:
28# CHECK-NEXT: Other:
29# CHECK-NEXT: Section: .text
30# CHECK-NEXT: }
31# CHECK-NEXT: Symbol {
32# CHECK-NEXT: Name: foo
33# CHECK-NEXT: Value:
34# CHECK-NEXT: Size:
35# CHECK-NEXT: Binding: Global
36# CHECK-NEXT: Type:
37# CHECK-NEXT: Other:
38# CHECK-NEXT: Section: .text
39# CHECK-NEXT: }
40# CHECK-NEXT: Symbol {
41# CHECK-NEXT: Name: und
42# CHECK-NEXT: Value:
43# CHECK-NEXT: Size:
44# CHECK-NEXT: Binding: Global
45# CHECK-NEXT: Type:
46# CHECK-NEXT: Other:
47# CHECK-NEXT: Section: Undefined
48# CHECK-NEXT: }
49# CHECK-NEXT: ]
50
51.text
52.globl _start
53_start:
54call zed@PLT
55call und@PLT
56
57.globl foo
58.type foo,@function
59foo:
60retq
61
62.globl bar
63.type bar,@function
64bar:
65retq
66
67.globl zed
68.type zed,@function
69zed:
70retq
71
72.type loc,@function
73loc:
74retq
deps/lld/test/ELF/retain-und.s created+18
......@@ -0,0 +1,18 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: echo > %t.retain
4# RUN: echo "{ local: *; }; " > %t.script
5# RUN: ld.lld -shared --version-script %t.script %t.o -o %t1.so
6# RUN: ld.lld -shared --retain-symbols-file %t.retain %t.o -o %t2.so
7# RUN: llvm-readobj -r %t1.so | FileCheck %s
8# RUN: llvm-readobj -r %t2.so | FileCheck %s
9
10# CHECK: Relocations [
11# CHECK-NEXT: Section ({{.*}}) .rela.dyn {
12# CHECK-NEXT: 0x{{.*}} R_X86_64_64 foo 0x0
13# CHECK-NEXT: }
14# CHECK-NEXT: ]
15
16.data
17.quad foo
18.weak foo
deps/lld/test/ELF/rodynamic.s created+35
......@@ -0,0 +1,35 @@
1# RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
2# RUN: llvm-mc %p/Inputs/rodynamic.s -o %t.so.o -filetype=obj -triple=x86_64-pc-linux
3
4# RUN: ld.lld -shared %t.so.o -o %t.so
5# RUN: ld.lld %t.o %t.so -o %t.exe
6# RUN: llvm-readobj -dynamic-table %t.exe | FileCheck -check-prefix=DEFDEBUG %s
7# RUN: llvm-readobj -sections %t.exe | FileCheck -check-prefix=DEFSEC %s
8
9# RUN: ld.lld -shared -z rodynamic %t.so.o -o %t.so
10# RUN: ld.lld -z rodynamic %t.o %t.so -o %t.exe
11# RUN: llvm-readobj -dynamic-table %t.exe | FileCheck -check-prefix=RODEBUG %s
12# RUN: llvm-readobj -sections %t.exe | FileCheck -check-prefix=ROSEC %s
13
14.globl _start
15_start:
16 call foo
17
18# DEFDEBUG: DEBUG
19
20# DEFSEC: Section {
21# DEFSEC: Name: .dynamic
22# DEFSEC-NEXT: Type: SHT_DYNAMIC
23# DEFSEC-NEXT: Flags [
24# DEFSEC-NEXT: SHF_ALLOC
25# DEFSEC-NEXT: SHF_WRITE
26# DEFSEC-NEXT: ]
27
28# RODEBUG-NOT: DEBUG
29
30# ROSEC: Section {
31# ROSEC: Name: .dynamic
32# ROSEC-NEXT: Type: SHT_DYNAMIC
33# ROSEC-NEXT: Flags [
34# ROSEC-NEXT: SHF_ALLOC
35# ROSEC-NEXT: ]
deps/lld/test/ELF/section-align-0.test created+20
......@@ -0,0 +1,20 @@
1# RUN: yaml2obj %s -o %t
2# RUN: ld.lld %t -o %tout
3
4# Verify that lld can handle sections with an alignment of zero.
5
6!ELF
7FileHeader:
8 Class: ELFCLASS64
9 Data: ELFDATA2LSB
10 Type: ET_REL
11 Machine: EM_X86_64
12Sections:
13 - Name: .text
14 Type: SHT_PROGBITS
15 AddressAlign: 0
16
17Symbols:
18 Global:
19 - Name: _start
20 Section: .text
deps/lld/test/ELF/section-layout.s created+59
......@@ -0,0 +1,59 @@
1# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
2# RUN: ld.lld %t -o %tout
3# RUN: llvm-readobj -sections %tout | FileCheck %s
4# REQUIRES: x86
5
6# Check that sections are laid out in the correct order.
7
8.global _start
9.text
10_start:
11
12.section t,"x",@nobits
13.section s,"x"
14.section r,"w",@nobits
15.section q,"w"
16.section p,"wx",@nobits
17.section o,"wx"
18.section n,"",@nobits
19.section m,""
20
21.section l,"awx",@nobits
22.section k,"awx"
23.section j,"aw",@nobits
24.section i,"aw"
25.section g,"awT",@nobits
26.section e,"awT"
27.section d,"ax",@nobits
28.section c,"ax"
29.section b,"a",@nobits
30.section a,"a"
31
32// CHECK: Name: a
33// CHECK: Name: b
34// CHECK: Name: c
35// CHECK: Name: d
36
37// Sections that are both writable and executable appear before
38// sections that are only writable.
39// CHECK: Name: k
40// CHECK: Name: l
41
42// Writable sections appear before TLS and other relro sections.
43// CHECK: Name: i
44
45// TLS sections are only sorted on NOBITS.
46// CHECK: Name: e
47// CHECK: Name: g
48
49// CHECK: Name: j
50
51// Non allocated sections are in input order.
52// CHECK: Name: t
53// CHECK: Name: s
54// CHECK: Name: r
55// CHECK: Name: q
56// CHECK: Name: p
57// CHECK: Name: o
58// CHECK: Name: n
59// CHECK: Name: m
deps/lld/test/ELF/section-metadata-err.s created+15
......@@ -0,0 +1,15 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
4# RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s
5
6# CHECK: error: Merge and .eh_frame sections are not supported with SHF_LINK_ORDER {{.*}}section-metadata-err.s.tmp.o:(.foo)
7
8.global _start
9_start:
10.quad .foo
11
12.section .foo,"aM",@progbits,8
13.quad 0
14
15.section bar,"ao",@progbits,.foo
deps/lld/test/ELF/section-name.s created+58
......@@ -0,0 +1,58 @@
1# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
2# RUN: ld.lld %t -o %tout
3# RUN: llvm-objdump --section-headers %tout | FileCheck %s
4# REQUIRES: x86
5
6.global _start
7.text
8_start:
9
10.section .text.a,"ax"
11.byte 0
12.section .text.,"ax"
13.byte 0
14.section .rodata.a,"a"
15.byte 0
16.section .rodata,"a"
17.byte 0
18.section .data.a,"aw"
19.byte 0
20.section .data,"aw"
21.byte 0
22.section .bss.a,"aw",@nobits
23.byte 0
24.section .bss,"aw",@nobits
25.byte 0
26.section .foo.a,"aw"
27.byte 0
28.section .foo,"aw"
29.byte 0
30.section .data.rel.ro,"aw",%progbits
31.byte 0
32.section .data.rel.ro.a,"aw",%progbits
33.byte 0
34.section .data.rel.ro.local,"aw",%progbits
35.byte 0
36.section .data.rel.ro.local.a,"aw",%progbits
37.byte 0
38.section .tbss.foo,"aGwT",@nobits,foo,comdat
39.byte 0
40.section .gcc_except_table.foo,"aG",@progbits,foo,comdat
41.byte 0
42.section .tdata.foo,"aGwT",@progbits,foo,comdat
43.byte 0
44
45// CHECK: 1 .rodata 00000002
46// CHECK: 2 .gcc_except_table 00000001
47// CHECK: 3 .text 00000002
48// CHECK: 4 .data 00000002
49// CHECK: 5 .foo.a 00000001
50// CHECK: 6 .foo 00000001
51// CHECK: 7 .tdata 00000001
52// CHECK: 8 .tbss 00000001
53// CHECK: 9 .data.rel.ro 00000004
54// CHECK: 10 .bss 00000002
55// CHECK: 11 .comment 00000008
56// CHECK: 12 .symtab 00000030
57// CHECK: 13 .shstrtab 00000075
58// CHECK: 14 .strtab 00000008
deps/lld/test/ELF/section-symbol.s created+40
......@@ -0,0 +1,40 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
2// RUN: ld.lld %t -o %t.so -shared -discard-none
3// RUN: llvm-readobj -t %t.so | FileCheck %s
4
5// Test that we don't include the section symbols from the .o in the .so
6
7// CHECK: Symbols [
8// CHECK-NEXT: Symbol {
9// CHECK-NEXT: Name: (0)
10// CHECK-NEXT: Value: 0x0
11// CHECK-NEXT: Size: 0
12// CHECK-NEXT: Binding: Local
13// CHECK-NEXT: Type: None
14// CHECK-NEXT: Other: 0
15// CHECK-NEXT: Section: Undefined
16// CHECK-NEXT: }
17// CHECK-NEXT: Symbol {
18// CHECK-NEXT: Name: foo
19// CHECK-NEXT: Value:
20// CHECK-NEXT: Size: 0
21// CHECK-NEXT: Binding: Local
22// CHECK-NEXT: Type: None
23// CHECK-NEXT: Other: 0
24// CHECK-NEXT: Section: .text
25// CHECK-NEXT: }
26// CHECK-NEXT: Symbol {
27// CHECK-NEXT: Name: _DYNAMIC
28// CHECK-NEXT: Value:
29// CHECK-NEXT: Size: 0
30// CHECK-NEXT: Binding: Local
31// CHECK-NEXT: Type: None
32// CHECK-NEXT: Other [ (0x2)
33// CHECK-NEXT: STV_HIDDEN
34// CHECK-NEXT: ]
35// CHECK-NEXT: Section: .dynamic
36// CHECK-NEXT: }
37// CHECK-NEXT: ]
38
39foo:
40 .quad foo - .
deps/lld/test/ELF/section-symbols.test created+35
......@@ -0,0 +1,35 @@
1# RUN: yaml2obj %s -o %t
2# RUN: ld.lld -shared %t -o %tout
3
4# Verify that lld can handle STT_SECTION symbols associated
5# with SHT_REL[A]/SHT_SYMTAB/SHT_STRTAB sections.
6
7!ELF
8FileHeader:
9 Class: ELFCLASS64
10 Data: ELFDATA2LSB
11 OSABI: ELFOSABI_FREEBSD
12 Type: ET_REL
13 Machine: EM_X86_64
14Sections:
15 - Name: .text
16 Type: SHT_PROGBITS
17 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
18 AddressAlign: 0x0000000000000010
19 Content: "00000000"
20 - Name: .rela.text
21 Type: SHT_RELA
22 Link: .symtab
23 AddressAlign: 0x0000000000000008
24 Info: .text
25 Relocations:
26Symbols:
27 Local:
28 - Type: STT_SECTION
29 Section: .rela.text
30 - Type: STT_SECTION
31 Section: .shstrtab
32 - Type: STT_SECTION
33 Section: .symtab
34 - Type: STT_SECTION
35 Section: .strtab
deps/lld/test/ELF/sectionstart-noallochdr.s created+23
......@@ -0,0 +1,23 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: ld.lld %t.o --section-start .data=0x20 \
4# RUN: --section-start .bss=0x30 --section-start .text=0x10 -o %t1
5# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
6
7# CHECK: Sections:
8# CHECK-NEXT: Idx Name Size Address Type
9# CHECK-NEXT: 0 00000000 0000000000000000
10# CHECK-NEXT: 1 .text 00000001 0000000000000010 TEXT DATA
11# CHECK-NEXT: 2 .data 00000004 0000000000000020 DATA
12# CHECK-NEXT: 3 .bss 00000004 0000000000000030 BSS
13
14.text
15.globl _start
16_start:
17 nop
18
19.data
20.long 0
21
22.bss
23.zero 4
deps/lld/test/ELF/sectionstart.s created+67
......@@ -0,0 +1,67 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: ld.lld %t.o --section-start .text=0x100000 \
4# RUN: --section-start .data=0x110000 --section-start .bss=0x200000 -o %t
5# RUN: llvm-objdump -section-headers %t | FileCheck %s
6
7# CHECK: Sections:
8# CHECK-NEXT: Idx Name Size Address Type
9# CHECK-NEXT: 0 00000000 0000000000000000
10# CHECK-NEXT: 1 .text 00000001 0000000000100000 TEXT DATA
11# CHECK-NEXT: 2 .data 00000004 0000000000110000 DATA
12# CHECK-NEXT: 3 .bss 00000004 0000000000200000 BSS
13
14## The same, but dropped "0x" prefix.
15# RUN: ld.lld %t.o --section-start .text=100000 \
16# RUN: --section-start .data=110000 --section-start .bss=0x200000 -o %t1
17# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
18
19## Use -Ttext, -Tdata, -Tbss as replacement for --section-start:
20# RUN: ld.lld %t.o -Ttext=0x100000 -Tdata=0x110000 -Tbss=0x200000 -o %t4
21# RUN: llvm-objdump -section-headers %t4 | FileCheck %s
22
23## Check Ttext-segment X and Ttext-segment=X forms.
24# RUN: ld.lld %t.o -Ttext-segment=0x100000 -Tdata=0x110000 -Tbss=0x200000 -o %t4
25# RUN: llvm-objdump -section-headers %t4 | FileCheck %s
26# RUN: ld.lld %t.o -Ttext-segment 0x100000 -Tdata=0x110000 -Tbss=0x200000 -o %t4
27# RUN: llvm-objdump -section-headers %t4 | FileCheck %s
28
29## The same, but dropped "0x" prefix.
30# RUN: ld.lld %t.o -Ttext=100000 -Tdata=110000 -Tbss=200000 -o %t5
31# RUN: llvm-objdump -section-headers %t5 | FileCheck %s
32
33## Check form without assignment:
34# RUN: ld.lld %t.o -Ttext 0x100000 -Tdata 0x110000 -Tbss 0x200000 -o %t4
35# RUN: llvm-objdump -section-headers %t4 | FileCheck %s
36
37## Errors:
38# RUN: not ld.lld %t.o --section-start .text100000 -o %t2 2>&1 \
39# RUN: | FileCheck -check-prefix=ERR1 %s
40# ERR1: invalid argument: --section-start .text100000
41
42# RUN: not ld.lld %t.o --section-start .text=1Q0000 -o %t3 2>&1 \
43# RUN: | FileCheck -check-prefix=ERR2 %s
44# ERR2: invalid argument: --section-start .text=1Q0000
45
46# RUN: not ld.lld %t.o -Ttext=1w0000 -o %t6 2>&1 \
47# RUN: | FileCheck -check-prefix=ERR3 %s
48# ERR3: invalid argument: --Ttext 1w0000
49
50# RUN: not ld.lld %t.o -Tbss=1w0000 -o %t6 2>&1 \
51# RUN: | FileCheck -check-prefix=ERR4 %s
52# ERR4: invalid argument: --Tbss 1w0000
53
54# RUN: not ld.lld %t.o -Tdata=1w0000 -o %t6 2>&1 \
55# RUN: | FileCheck -check-prefix=ERR5 %s
56# ERR5: invalid argument: --Tdata 1w0000
57
58.text
59.globl _start
60_start:
61 nop
62
63.data
64.long 0
65
66.bss
67.zero 4
deps/lld/test/ELF/segments.s created+108
......@@ -0,0 +1,108 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: ld.lld %t -o %t1
4# RUN: llvm-readobj --program-headers %t1 | FileCheck --check-prefix=ROSEGMENT %s
5
6# ROSEGMENT: ProgramHeader {
7# ROSEGMENT: Type: PT_LOAD
8# ROSEGMENT-NEXT: Offset: 0x0
9# ROSEGMENT-NEXT: VirtualAddress:
10# ROSEGMENT-NEXT: PhysicalAddress:
11# ROSEGMENT-NEXT: FileSize:
12# ROSEGMENT-NEXT: MemSize:
13# ROSEGMENT-NEXT: Flags [
14# ROSEGMENT-NEXT: PF_R
15# ROSEGMENT-NEXT: ]
16# ROSEGMENT-NEXT: Alignment: 4096
17# ROSEGMENT-NEXT: }
18# ROSEGMENT-NEXT: ProgramHeader {
19# ROSEGMENT-NEXT: Type: PT_LOAD
20# ROSEGMENT-NEXT: Offset: 0x1000
21# ROSEGMENT-NEXT: VirtualAddress:
22# ROSEGMENT-NEXT: PhysicalAddress:
23# ROSEGMENT-NEXT: FileSize:
24# ROSEGMENT-NEXT: MemSize:
25# ROSEGMENT-NEXT: Flags [
26# ROSEGMENT-NEXT: PF_R
27# ROSEGMENT-NEXT: PF_X
28# ROSEGMENT-NEXT: ]
29# ROSEGMENT-NEXT: Alignment: 4096
30# ROSEGMENT-NEXT: }
31# ROSEGMENT-NEXT: ProgramHeader {
32# ROSEGMENT-NEXT: Type: PT_LOAD
33# ROSEGMENT-NEXT: Offset: 0x2000
34# ROSEGMENT-NEXT: VirtualAddress:
35# ROSEGMENT-NEXT: PhysicalAddress:
36# ROSEGMENT-NEXT: FileSize: 1
37# ROSEGMENT-NEXT: MemSize: 1
38# ROSEGMENT-NEXT: Flags [
39# ROSEGMENT-NEXT: PF_R
40# ROSEGMENT-NEXT: PF_W
41# ROSEGMENT-NEXT: ]
42# ROSEGMENT-NEXT: Alignment: 4096
43# ROSEGMENT-NEXT: }
44
45# RUN: ld.lld -no-rosegment %t -o %t2
46# RUN: llvm-readobj --program-headers %t2 | FileCheck --check-prefix=NOROSEGMENT %s
47
48# NOROSEGMENT: ProgramHeader {
49# NOROSEGMENT: Type: PT_LOAD
50# NOROSEGMENT-NEXT: Offset: 0x0
51# NOROSEGMENT-NEXT: VirtualAddress:
52# NOROSEGMENT-NEXT: PhysicalAddress:
53# NOROSEGMENT-NEXT: FileSize:
54# NOROSEGMENT-NEXT: MemSize:
55# NOROSEGMENT-NEXT: Flags [
56# NOROSEGMENT-NEXT: PF_R
57# NOROSEGMENT-NEXT: PF_X
58# NOROSEGMENT-NEXT: ]
59# NOROSEGMENT-NEXT: Alignment: 4096
60# NOROSEGMENT-NEXT: }
61# NOROSEGMENT-NEXT: ProgramHeader {
62# NOROSEGMENT-NEXT: Type: PT_LOAD
63# NOROSEGMENT-NEXT: Offset: 0x1000
64# NOROSEGMENT-NEXT: VirtualAddress:
65# NOROSEGMENT-NEXT: PhysicalAddress:
66# NOROSEGMENT-NEXT: FileSize:
67# NOROSEGMENT-NEXT: MemSize:
68# NOROSEGMENT-NEXT: Flags [
69# NOROSEGMENT-NEXT: PF_R
70# NOROSEGMENT-NEXT: PF_W
71# NOROSEGMENT-NEXT: ]
72# NOROSEGMENT-NEXT: Alignment: 4096
73# NOROSEGMENT-NEXT: }
74# NOROSEGMENT-NEXT: ProgramHeader {
75# NOROSEGMENT-NEXT: Type: PT_GNU_STACK
76
77# RUN: ld.lld -N %t -o %t3
78# RUN: llvm-readobj --program-headers %t3 | FileCheck --check-prefix=OMAGIC %s
79
80# OMAGIC: ProgramHeader {
81# OMAGIC: Type: PT_LOAD
82# OMAGIC-NEXT: Offset: 0x0
83# OMAGIC-NEXT: VirtualAddress:
84# OMAGIC-NEXT: PhysicalAddress:
85# OMAGIC-NEXT: FileSize:
86# OMAGIC-NEXT: MemSize:
87# OMAGIC-NEXT: Flags [
88# OMAGIC-NEXT: PF_R
89# OMAGIC-NEXT: PF_W
90# OMAGIC-NEXT: PF_X
91# OMAGIC-NEXT: ]
92# OMAGIC-NEXT: Alignment: 4096
93# OMAGIC-NEXT: }
94# OMAGIC-NEXT: ProgramHeader {
95# OMAGIC-NEXT: Type: PT_GNU_STACK
96
97.global _start
98_start:
99 nop
100
101.section .ro,"a"
102nop
103
104.section .rw,"aw"
105nop
106
107.section .rx,"ax"
108nop
deps/lld/test/ELF/shared-be.s created+37
......@@ -0,0 +1,37 @@
1// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %s -o %t.o
2// RUN: llvm-mc -filetype=obj -triple=powerpc64-unknown-linux %p/Inputs/shared.s -o %t2.o
3// RUN: ld.lld -shared %t2.o -o %t2.so
4// RUN: ld.lld -dynamic-linker /lib64/ld64.so.1 -rpath foo -rpath bar --export-dynamic %t.o %t2.so -o %t
5// RUN: llvm-readobj --dynamic-table -s %t | FileCheck %s
6// REQUIRES: ppc
7
8// CHECK: Name: .rela.dyn
9// CHECK-NEXT: Type: SHT_REL
10// CHECK-NEXT: Flags [
11// CHECK-NEXT: SHF_ALLOC
12// CHECK-NEXT: ]
13// CHECK-NEXT: Address: [[RELADDR:.*]]
14// CHECK-NEXT: Offset:
15// CHECK-NEXT: Size: [[RELSIZE:.*]]
16// CHECK-NEXT: Link:
17// CHECK-NEXT: Info:
18// CHECK-NEXT: AddressAlignment:
19// CHECK-NEXT: EntrySize: [[RELENT:.*]]
20
21// CHECK: DynamicSection [
22// CHECK-NEXT: Tag Type Name/Value
23// CHECK-NEXT: 0x000000000000001D RUNPATH foo:bar
24// CHECK-NEXT: 0x0000000000000001 NEEDED Shared library: [{{.*}}2.so]
25// CHECK-NEXT: 0x0000000000000015 DEBUG 0x0
26// CHECK-NEXT: 0x0000000000000007 RELA [[RELADDR]]
27// CHECK-NEXT: 0x0000000000000008 RELASZ [[RELSIZE]] (bytes)
28// CHECK-NEXT: 0x0000000000000009 RELAENT [[RELENT]] (bytes)
29// CHECK: 0x0000000000000000 NULL 0x0
30// CHECK-NEXT: ]
31
32.global _start
33_start:
34.data
35.long bar
36.long zed
37
deps/lld/test/ELF/shared.s created+305
......@@ -0,0 +1,305 @@
1// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o
2// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/shared.s -o %t2.o
3// RUN: ld.lld -shared %t2.o -o %t2.so
4// RUN: llvm-readobj -s %t2.so | FileCheck --check-prefix=SO %s
5// RUN: ld.lld -dynamic-linker /lib64/ld-linux-x86-64.so.2 -rpath foo -rpath bar --export-dynamic %t.o %t2.so -o %t
6// RUN: llvm-readobj --program-headers --dynamic-table -t -s -dyn-symbols -section-data -hash-table %t | FileCheck %s
7// RUN: ld.lld %t.o %t2.so %t2.so -o %t2
8// RUN: llvm-readobj -dyn-symbols %t2 | FileCheck --check-prefix=DONT_EXPORT %s
9// REQUIRES: x86
10
11// Make sure .symtab is properly aligned.
12// SO: Name: .symtab
13// SO-NEXT: Type: SHT_SYMTAB
14// SO-NEXT: Flags [
15// SO-NEXT: ]
16// SO-NEXT: Address:
17// SO-NEXT: Offset: 0x1038
18// SO-NEXT: Size:
19// SO-NEXT: Link:
20// SO-NEXT: Info:
21// SO-NEXT: AddressAlignment: 4
22
23// CHECK: Name: .interp
24// CHECK-NEXT: Type: SHT_PROGBITS
25// CHECK-NEXT: Flags [
26// CHECK-NEXT: SHF_ALLOC
27// CHECK-NEXT: ]
28// CHECK-NEXT: Address: [[INTERPADDR:.*]]
29// CHECK-NEXT: Offset: [[INTERPOFFSET:.*]]
30// CHECK-NEXT: Size: [[INTERPSIZE:.*]]
31// CHECK-NEXT: Link: 0
32// CHECK-NEXT: Info: 0
33// CHECK-NEXT: AddressAlignment: 1
34// CHECK-NEXT: EntrySize: 0
35// CHECK-NEXT: SectionData (
36// CHECK-NEXT: 0000: 2F6C6962 36342F6C 642D6C69 6E75782D |/lib64/ld-linux-|
37// CHECK-NEXT: 0010: 7838362D 36342E73 6F2E3200 |x86-64.so.2.|
38// CHECK-NEXT: )
39// CHECK-NEXT: }
40
41// test that .hash is linked to .dynsym
42// CHECK: Index: 2
43// CHECK-NEXT: Name: .dynsym
44// CHECK-NEXT: Type: SHT_DYNSYM
45// CHECK-NEXT: Flags [
46// CHECK-NEXT: SHF_ALLOC
47// CHECK-NEXT: ]
48// CHECK-NEXT: Address: [[DYNSYMADDR:.*]]
49// CHECK-NEXT: Offset: 0x150
50// CHECK-NEXT: Size:
51// CHECK-NEXT: Link: [[DYNSTR:.*]]
52// CHECK-NEXT: Info: 1
53// CHECK-NEXT: AddressAlignment: 4
54// CHECK-NEXT: EntrySize: 16
55// CHECK-NEXT: SectionData (
56// CHECK-NEXT: 0000:
57// CHECK-NEXT: 0010:
58// CHECK-NEXT: 0020:
59// CHECK-NEXT: 0030:
60// CHECK-NEXT: )
61// CHECK-NEXT: }
62// CHECK-NEXT: Section {
63// CHECK-NEXT: Index: 3
64// CHECK-NEXT: Name: .hash
65// CHECK-NEXT: Type: SHT_HASH
66// CHECK-NEXT: Flags [
67// CHECK-NEXT: SHF_ALLOC
68// CHECK-NEXT: ]
69// CHECK-NEXT: Address: [[HASHADDR:.*]]
70// CHECK-NEXT: Offset:
71// CHECK-NEXT: Size:
72// CHECK-NEXT: Link: 2
73// CHECK-NEXT: Info: 0
74// CHECK-NEXT: AddressAlignment: 4
75// CHECK-NEXT: EntrySize: 4
76
77// CHECK: Index: [[DYNSTR]]
78// CHECK-NEXT: Name: .dynstr
79// CHECK-NEXT: Type: SHT_STRTAB
80// CHECK-NEXT: Flags [
81// CHECK-NEXT: SHF_ALLOC
82// CHECK-NEXT: ]
83// CHECK-NEXT: Address: [[DYNSTRADDR:.*]]
84// CHECK-NEXT: Offset:
85// CHECK-NEXT: Size:
86// CHECK-NEXT: Link: 0
87// CHECK-NEXT: Info: 0
88// CHECK-NEXT: AddressAlignment: 1
89// CHECK-NEXT: EntrySize: 0
90// CHECK-NEXT: SectionData (
91// CHECK: )
92// CHECK-NEXT: }
93
94// CHECK: Name: .rel.dyn
95// CHECK-NEXT: Type: SHT_REL
96// CHECK-NEXT: Flags [
97// CHECK-NEXT: SHF_ALLOC
98// CHECK-NEXT: ]
99// CHECK-NEXT: Address: [[RELADDR:.*]]
100// CHECK-NEXT: Offset:
101// CHECK-NEXT: Size: [[RELSIZE:.*]]
102// CHECK-NEXT: Link:
103// CHECK-NEXT: Info:
104// CHECK-NEXT: AddressAlignment:
105// CHECK-NEXT: EntrySize: [[RELENT:.*]]
106
107// CHECK: Name: .dynamic
108// CHECK-NEXT: Type: SHT_DYNAMIC
109// CHECK-NEXT: Flags [
110// CHECK-NEXT: SHF_ALLOC
111// CHECK-NEXT: SHF_WRITE
112// CHECK-NEXT: ]
113// CHECK-NEXT: Address: [[ADDR:.*]]
114// CHECK-NEXT: Offset: [[OFFSET:.*]]
115// CHECK-NEXT: Size: [[SIZE:.*]]
116// CHECK-NEXT: Link: [[DYNSTR]]
117// CHECK-NEXT: Info: 0
118// CHECK-NEXT: AddressAlignment: [[ALIGN:.*]]
119// CHECK-NEXT: EntrySize: 8
120// CHECK-NEXT: SectionData (
121// CHECK: )
122
123// CHECK: Name: .symtab
124// CHECK-NEXT: Type: SHT_SYMTAB
125// CHECK-NEXT: Flags [
126// CHECK-NEXT: ]
127// CHECK-NEXT: Address:
128// CHECK-NEXT: Offset:
129// CHECK-NEXT: Size:
130// CHECK-NEXT: Link:
131// CHECK-NEXT: Info:
132// CHECK-NEXT: AddressAlignment:
133// CHECK-NEXT: EntrySize: [[SYMENT:.*]]
134
135// CHECK: Symbols [
136// CHECK-NEXT: Symbol {
137// CHECK-NEXT: Name:
138// CHECK-NEXT: Value: 0x0
139// CHECK-NEXT: Size: 0
140// CHECK-NEXT: Binding: Local
141// CHECK-NEXT: Type: None
142// CHECK-NEXT: Other: 0
143// CHECK-NEXT: Section: Undefined
144// CHECK-NEXT: }
145// CHECK-NEXT: Symbol {
146// CHECK-NEXT: Name: _DYNAMIC
147// CHECK-NEXT: Value: 0x12000
148// CHECK-NEXT: Size: 0
149// CHECK-NEXT: Binding: Local
150// CHECK-NEXT: Type: None
151// CHECK-NEXT: Other [ (0x2)
152// CHECK-NEXT: STV_HIDDEN
153// CHECK-NEXT: ]
154// CHECK-NEXT: Section: .dynamic
155// CHECK-NEXT: }
156// CHECK-NEXT: Symbol {
157// CHECK-NEXT: Name: _start
158// CHECK-NEXT: Value: 0x11000
159// CHECK-NEXT: Size: 0
160// CHECK-NEXT: Binding: Global
161// CHECK-NEXT: Type: None
162// CHECK-NEXT: Other: 0
163// CHECK-NEXT: Section: .text
164// CHECK-NEXT: }
165// CHECK-NEXT: Symbol {
166// CHECK-NEXT: Name: bar
167// CHECK-NEXT: Value: 0x0
168// CHECK-NEXT: Size: 0
169// CHECK-NEXT: Binding: Global
170// CHECK-NEXT: Type: Function
171// CHECK-NEXT: Other: 0
172// CHECK-NEXT: Section: Undefined
173// CHECK-NEXT: }
174// CHECK-NEXT: Symbol {
175// CHECK-NEXT: Name: zed
176// CHECK-NEXT: Value: 0x0
177// CHECK-NEXT: Size: 0
178// CHECK-NEXT: Binding: Global (0x1)
179// CHECK-NEXT: Type: None (0x0)
180// CHECK-NEXT: Other: 0
181// CHECK-NEXT: Section: Undefined (0x0)
182// CHECK-NEXT: }
183// CHECK-NEXT: ]
184
185// CHECK: DynamicSymbols [
186// CHECK-NEXT: Symbol {
187// CHECK-NEXT: Name: @
188// CHECK-NEXT: Value: 0x0
189// CHECK-NEXT: Size: 0
190// CHECK-NEXT: Binding: Local
191// CHECK-NEXT: Type: None
192// CHECK-NEXT: Other: 0
193// CHECK-NEXT: Section: Undefined
194// CHECK-NEXT: }
195// CHECK-NEXT: Symbol {
196// CHECK-NEXT: Name: _start@
197// CHECK-NEXT: Value: 0x11000
198// CHECK-NEXT: Size: 0
199// CHECK-NEXT: Binding: Global
200// CHECK-NEXT: Type: Non
201// CHECK-NEXT: Other: 0
202// CHECK-NEXT: Section: .text
203// CHECK-NEXT: }
204// CHECK-NEXT: Symbol {
205// CHECK-NEXT: Name: bar@
206// CHECK-NEXT: Value: 0x0
207// CHECK-NEXT: Size: 0
208// CHECK-NEXT: Binding: Global
209// CHECK-NEXT: Type: Function
210// CHECK-NEXT: Other: 0
211// CHECK-NEXT: Section: Undefined
212// CHECK-NEXT: }
213// CHECK-NEXT: Symbol {
214// CHECK-NEXT: Name: zed@
215// CHECK-NEXT: Value: 0x0
216// CHECK-NEXT: Size: 0
217// CHECK-NEXT: Binding: Global
218// CHECK-NEXT: Type: None
219// CHECK-NEXT: Other: 0
220// CHECK-NEXT: Section: Undefined
221// CHECK-NEXT: }
222// CHECK-NEXT: ]
223
224// DONT_EXPORT: DynamicSymbols [
225// DONT_EXPORT-NEXT: Symbol {
226// DONT_EXPORT-NEXT: Name: @
227// DONT_EXPORT-NEXT: Value: 0x0
228// DONT_EXPORT-NEXT: Size: 0
229// DONT_EXPORT-NEXT: Binding: Local (0x0)
230// DONT_EXPORT-NEXT: Type: None (0x0)
231// DONT_EXPORT-NEXT: Other: 0
232// DONT_EXPORT-NEXT: Section: Undefined (0x0)
233// DONT_EXPORT-NEXT: }
234// DONT_EXPORT-NEXT: Symbol {
235// DONT_EXPORT-NEXT: Name: bar@
236// DONT_EXPORT-NEXT: Value: 0x0
237// DONT_EXPORT-NEXT: Size: 0
238// DONT_EXPORT-NEXT: Binding: Global
239// DONT_EXPORT-NEXT: Type: Function
240// DONT_EXPORT-NEXT: Other: 0
241// DONT_EXPORT-NEXT: Section: Undefined
242// DONT_EXPORT-NEXT: }
243// DONT_EXPORT-NEXT: Symbol {
244// DONT_EXPORT-NEXT: Name: zed@
245// DONT_EXPORT-NEXT: Value: 0x0
246// DONT_EXPORT-NEXT: Size: 0
247// DONT_EXPORT-NEXT: Binding: Global
248// DONT_EXPORT-NEXT: Type: None
249// DONT_EXPORT-NEXT: Other: 0
250// DONT_EXPORT-NEXT: Section: Undefined
251// DONT_EXPORT-NEXT: }
252// DONT_EXPORT-NEXT: ]
253
254// CHECK: DynamicSection [
255// CHECK-NEXT: Tag Type Name/Value
256// CHECK-NEXT: 0x0000001D RUNPATH foo:bar
257// CHECK-NEXT: 0x00000001 NEEDED Shared library: [{{.*}}2.so]
258// CHECK-NEXT: 0x00000015 DEBUG 0x0
259// CHECK-NEXT: 0x00000011 REL [[RELADDR]]
260// CHECK-NEXT: 0x00000012 RELSZ [[RELSIZE]] (bytes)
261// CHECK-NEXT: 0x00000013 RELENT [[RELENT]] (bytes)
262// CHECK-NEXT: 0x00000006 SYMTAB [[DYNSYMADDR]]
263// CHECK-NEXT: 0x0000000B SYMENT [[SYMENT]] (bytes)
264// CHECK-NEXT: 0x00000005 STRTAB [[DYNSTRADDR]]
265// CHECK-NEXT: 0x0000000A STRSZ
266// CHECK-NEXT: 0x00000004 HASH [[HASHADDR]]
267// CHECK-NEXT: 0x00000000 NULL 0x0
268// CHECK-NEXT: ]
269
270// CHECK: ProgramHeaders [
271// CHECK: Type: PT_INTERP
272// CHECK-NEXT: Offset: [[INTERPOFFSET]]
273// CHECK-NEXT: VirtualAddress: [[INTERPADDR]]
274// CHECK-NEXT: PhysicalAddress: [[INTERPADDR]]
275// CHECK-NEXT: FileSize: [[INTERPSIZE]]
276// CHECK-NEXT: MemSize: [[INTERPSIZE]]
277// CHECK-NEXT: Flags [
278// CHECK-NEXT: PF_R
279// CHECK-NEXT: ]
280// CHECK-NEXT: Alignment: 1
281// CHECK-NEXT: }
282// CHECK: Type: PT_DYNAMIC
283// CHECK-NEXT: Offset: [[OFFSET]]
284// CHECK-NEXT: VirtualAddress: [[ADDR]]
285// CHECK-NEXT: PhysicalAddress: [[ADDR]]
286// CHECK-NEXT: FileSize: [[SIZE]]
287// CHECK-NEXT: MemSize: [[SIZE]]
288// CHECK-NEXT: Flags [
289// CHECK-NEXT: PF_R
290// CHECK-NEXT: PF_W
291// CHECK-NEXT: ]
292// CHECK-NEXT: Alignment: [[ALIGN]]
293// CHECK-NEXT: }
294
295// CHECK: HashTable {
296// CHECK-NEXT: Num Buckets: 4
297// CHECK-NEXT: Num Chains: 4
298// CHECK-NEXT: Buckets: [3, 0, 2, 0]
299// CHECK-NEXT: Chains: [0, 0, 0, 1]
300// CHECK-NEXT: }
301
302.global _start
303_start:
304.long bar@GOT
305.long zed@GOT
deps/lld/test/ELF/shf-info-link.test created+32
......@@ -0,0 +1,32 @@
1# RUN: yaml2obj %s -o %t.o
2# RUN: yaml2obj %S/Inputs/shf-info-link.test -o %t2.o
3# RUN: ld.lld %t.o %t2.o -o %t3.o -r
4# RUN: llvm-readobj -s %t3.o | FileCheck %s
5
6# CHECK-NOT: Name: .rela.text
7# CHECK: Name: .rela.text
8# CHECK-NOT: Name: .rela.text
9
10
11--- !ELF
12FileHeader:
13 Class: ELFCLASS64
14 Data: ELFDATA2LSB
15 Type: ET_REL
16 Machine: EM_X86_64
17Sections:
18 - Name: .text
19 Type: SHT_PROGBITS
20 Flags: [ SHF_ALLOC, SHF_EXECINSTR ]
21 - Name: .rela.text
22 Type: SHT_RELA
23 Flags: [ SHF_INFO_LINK ]
24 Link: .symtab
25 Info: .text
26 Relocations:
27 - Offset: 0x0000000000000000
28 Symbol: foo
29 Type: R_X86_64_64
30Symbols:
31 Global:
32 - Name: foo
deps/lld/test/ELF/sht-group-gold-r.test created+17
......@@ -0,0 +1,17 @@
1# GNU gold 1.14 (the newest version as of July 2017) seems to create
2# non-standard-compliant SHT_GROUP sections when the -r option is given.
3#
4# Such SHT_GROUP sections use section names as their signatures
5# instead of symbols pointed by sh_link field. Since it is prevalent,
6# we accept such nonstandard sections.
7
8# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
9# RUN: ld.lld %p/Inputs/sht-group-gold-r.elf %t.o -o %t.exe
10# RUN: llvm-objdump -t %t.exe | FileCheck %s
11
12# CHECK: .text 00000000 bar
13# CHECK: .text 00000000 foo
14
15.globl _start
16_start:
17 ret
deps/lld/test/ELF/soname.s created+11
......@@ -0,0 +1,11 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
2// RUN: ld.lld %t.o -shared -soname=bar -o %t.so
3// RUN: ld.lld %t.o -shared --soname=bar -o %t2.so
4// RUN: ld.lld %t.o %t.so %t2.so -o %t
5// RUN: llvm-readobj --dynamic-table %t | FileCheck %s
6
7// CHECK: 0x0000000000000001 NEEDED Shared library: [bar]
8// CHECK-NOT: NEEDED
9
10.global _start
11_start:
deps/lld/test/ELF/soname2.s created+8
......@@ -0,0 +1,8 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
2// RUN: ld.lld %t.o -shared -soname=foo.so -o %t
3// RUN: llvm-readobj --dynamic-table %t | FileCheck %s
4
5// CHECK: 0x000000000000000E SONAME Library soname: [foo.so]
6
7.global _start
8_start:
deps/lld/test/ELF/sort-norosegment.s created+15
......@@ -0,0 +1,15 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
3
4# RUN: ld.lld -no-rosegment -o %t1 %t -shared
5# RUN: llvm-readobj -elf-output-style=GNU -s %t1 | FileCheck %s
6
7# CHECK: .text {{.*}} AX
8# CHECK-NEXT: .dynsym {{.*}} A
9# CHECK-NEXT: .hash {{.*}} A
10# CHECK-NEXT: .dynstr {{.*}} A
11# CHECK-NEXT: foo {{.*}} WA
12# CHECK-NEXT: .dynamic {{.*}} WA
13
14.section foo, "aw"
15.byte 0
deps/lld/test/ELF/splitstacks.s created+11
......@@ -0,0 +1,11 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
3
4# RUN: not ld.lld %t1.o -o %t 2>&1 | FileCheck %s
5# CHECK: .o: object file compiled with -fsplit-stack is not supported
6
7.globl _start
8_start:
9 nop
10
11.section .note.GNU-split-stack,"",@progbits
deps/lld/test/ELF/start-lib-comdat.s created+23
......@@ -0,0 +1,23 @@
1// REQUIRES: x86
2
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
4// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux \
5// RUN: %p/Inputs/start-lib-comdat.s -o %t2.o
6// RUN: ld.lld -shared -o %t3 %t1.o --start-lib %t2.o --end-lib
7// RUN: llvm-readobj -t %t3 | FileCheck %s
8// RUN: ld.lld -shared -o %t3 --start-lib %t2.o --end-lib %t1.o
9// RUN: llvm-readobj -t %t3 | FileCheck %s
10
11// CHECK: Name: zed
12// CHECK-NEXT: Value:
13// CHECK-NEXT: Size:
14// CHECK-NEXT: Binding: Global
15// CHECK-NEXT: Type:
16// CHECK-NEXT: Other:
17// CHECK-NEXT: Section: Undefined
18
19 call bar@plt
20// The other file also has a section in the zed comdat, but it defines the
21// symbol zed. That means that we will have a lazy symbol zed, but when adding
22// the actual file zed will be undefined.
23 .section .sec,"aG",@progbits,zed,comdat
deps/lld/test/ELF/start-lib.s created+25
......@@ -0,0 +1,25 @@
1// REQUIRES: x86
2
3// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
4// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
5// RUN: %p/Inputs/start-lib1.s -o %t2.o
6// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
7// RUN: %p/Inputs/start-lib2.s -o %t3.o
8
9// RUN: ld.lld -o %t3 %t1.o %t2.o %t3.o
10// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TEST1 %s
11// TEST1: Name: bar
12// TEST1: Name: foo
13
14// RUN: ld.lld -o %t3 %t1.o -u bar --start-lib %t2.o %t3.o
15// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TEST2 %s
16// TEST2: Name: bar
17// TEST2-NOT: Name: foo
18
19// RUN: ld.lld -o %t3 %t1.o --start-lib %t2.o %t3.o
20// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TEST3 %s
21// TEST3-NOT: Name: bar
22// TEST3-NOT: Name: foo
23
24.globl _start
25_start:
deps/lld/test/ELF/startstop-gccollect.s created+34
......@@ -0,0 +1,34 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3
4## Default run: sections foo and bar exist in output
5# RUN: ld.lld %t -o %tout
6# RUN: llvm-objdump -d %tout | FileCheck -check-prefix=DISASM %s
7
8## Check that foo and bar sections are not garbage collected,
9## we do not want to reclaim sections if they are referred
10## by __start_* and __stop_* symbols.
11# RUN: ld.lld %t --gc-sections -o %tout
12# RUN: llvm-objdump -d %tout | FileCheck -check-prefix=DISASM %s
13
14# DISASM: _start:
15# DISASM-NEXT: 201000: e8 05 00 00 00 callq 5 <__start_foo>
16# DISASM-NEXT: 201005: e8 01 00 00 00 callq 1 <__start_bar>
17# DISASM-NEXT: Disassembly of section foo:
18# DISASM-NEXT: __start_foo:
19# DISASM-NEXT: 20100a: 90 nop
20# DISASM-NEXT: Disassembly of section bar:
21# DISASM-NEXT: __start_bar:
22# DISASM-NEXT: 20100b: 90 nop
23
24.global _start
25.text
26_start:
27 callq __start_foo
28 callq __start_bar
29
30.section foo,"ax"
31 nop
32
33.section bar,"ax"
34 nop
deps/lld/test/ELF/startstop-shared.s created+28
......@@ -0,0 +1,28 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3// RUN: ld.lld %t.o -o %t.so -shared
4// RUN: llvm-readobj -r -t %t.so | FileCheck %s
5
6 .data
7 .quad __start_foo
8 .section foo,"aw"
9
10 .hidden __start_bar
11 .quad __start_bar
12 .section bar,"a"
13
14// Test that we are able to hide the symbol.
15// CHECK: R_X86_64_RELATIVE - 0x[[ADDR:.*]]
16
17// By default the symbol is visible and we need a dynamic reloc.
18// CHECK: R_X86_64_64 __start_foo 0x0
19
20// CHECK: Name: __start_bar
21// CHECK-NEXT: Value: 0x[[ADDR]]
22// CHECK-NEXT: Size:
23// CHECK-NEXT: Binding: Local
24
25// CHECK: Name: __start_foo
26// CHECK-NEXT: Value:
27// CHECK-NEXT: Size:
28// CHECK-NEXT: Binding: Global
deps/lld/test/ELF/startstop-shared2.s created+14
......@@ -0,0 +1,14 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/startstop-shared2.s -o %t.o
3// RUN: ld.lld -o %t.so %t.o -shared
4// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2.o
5// RUN: ld.lld -o %t %t2.o %t.so
6// RUN: llvm-objdump -s -h %t | FileCheck %s
7
8// CHECK: foo 00000000 0000000000201008
9
10// CHECK: Contents of section .text:
11// CHECK-NEXT: 201000 08102000 00000000
12
13.quad __start_foo
14.section foo,"ax"
deps/lld/test/ELF/startstop.s created+91
......@@ -0,0 +1,91 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3// RUN: ld.lld %t -o %tout -shared
4// RUN: llvm-objdump -d %tout | FileCheck -check-prefix=DISASM %s
5// RUN: llvm-readobj -symbols -r %tout | FileCheck -check-prefix=SYMBOL %s
6
7// DISASM: _start:
8// DISASM: 1000: {{.*}} callq 10
9// DISASM: 1005: {{.*}} callq 8
10// DISASM: 100a: {{.*}} callq 3
11// DISASM: Disassembly of section foo:
12// DISASM: __start_foo:
13// DISASM: 100f: 90 nop
14// DISASM: 1010: 90 nop
15// DISASM: 1011: 90 nop
16// DISASM: Disassembly of section bar:
17// DISASM: __start_bar:
18// DISASM: 1012: 90 nop
19// DISASM: 1013: 90 nop
20// DISASM: 1014: 90 nop
21
22
23// SYMBOL: Relocations [
24// SYMBOL-NEXT: Section ({{.*}}) .rela.dyn {
25// SYMBOL-NEXT: 0x2010 R_X86_64_64 __stop_zed1 0x0
26// SYMBOL-NEXT: 0x2018 R_X86_64_64 __stop_zed1 0x1
27// SYMBOL-NEXT: 0x2000 R_X86_64_64 __stop_zed2 0x0
28// SYMBOL-NEXT: 0x2008 R_X86_64_64 __stop_zed2 0x1
29// SYMBOL-NEXT: }
30// SYMBOL-NEXT: ]
31
32// SYMBOL: Symbol {
33// SYMBOL: Name: __start_bar
34// SYMBOL: Value: 0x1012
35// SYMBOL: STV_HIDDEN
36// SYMBOL: Section: bar
37// SYMBOL: }
38// SYMBOL-NOT: Section: __stop_bar
39// SYMBOL: Symbol {
40// SYMBOL: Name: __start_foo
41// SYMBOL: Value: 0x100F
42// SYMBOL: STV_HIDDEN
43// SYMBOL: Section: foo
44// SYMBOL: }
45// SYMBOL: Symbol {
46// SYMBOL: Name: __stop_foo
47// SYMBOL: Value: 0x1012
48// STMBOL: STV_HIDDEN
49// SYMBOL: Section: foo
50// SYMBOL: }
51
52// SYMBOL: Symbol {
53// SYMBOL: Name: __stop_zed1
54// SYMBOL: Value: 0x2010
55// STMBOL: Other: 0
56// SYMBOL: Section: zed1
57// SYMBOL: }
58// SYMBOL: Symbol {
59// SYMBOL: Name: __stop_zed2
60// SYMBOL: Value: 0x2020
61// STMBOL: Other: 0
62// SYMBOL: Section: zed2
63// SYMBOL: }
64
65.hidden __start_foo
66.hidden __stop_foo
67.hidden __start_bar
68.global _start
69.text
70_start:
71 call __start_foo
72 call __stop_foo
73 call __start_bar
74
75.section foo,"ax"
76 nop
77 nop
78 nop
79
80.section bar,"ax"
81 nop
82 nop
83 nop
84
85.section zed1, "aw"
86 .quad __stop_zed2
87 .quad __stop_zed2 + 1
88
89.section zed2, "aw"
90 .quad __stop_zed1
91 .quad __stop_zed1 + 1
deps/lld/test/ELF/static-with-export-dynamic.s created+32
......@@ -0,0 +1,32 @@
1// RUN: llvm-mc -filetype=obj -triple=i686-unknown-cloudabi %s -o %t.o
2// RUN: ld.lld --export-dynamic %t.o -o %t
3// RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
4// REQUIRES: x86
5
6// Ensure that a dynamic symbol table is present when --export-dynamic
7// is passed in, even when creating statically linked executables.
8//
9// CHECK: DynamicSymbols [
10// CHECK-NEXT: Symbol {
11// CHECK-NEXT: Name:
12// CHECK-NEXT: Value: 0x0
13// CHECK-NEXT: Size: 0
14// CHECK-NEXT: Binding: Local
15// CHECK-NEXT: Type: None
16// CHECK-NEXT: Other: 0
17// CHECK-NEXT: Section: Undefined
18// CHECK-NEXT: }
19// CHECK-NEXT: Symbol {
20// CHECK-NEXT: Name: _start
21// CHECK-NEXT: Value: 0x11000
22// CHECK-NEXT: Size: 0
23// CHECK-NEXT: Binding: Global
24// CHECK-NEXT: Type: None
25// CHECK-NEXT: Other: 0
26// CHECK-NEXT: Section: .text
27// CHECK-NEXT: }
28// CHECK-NEXT: ]
29
30.global _start
31_start:
32 ret
deps/lld/test/ELF/string-gc.s created+73
......@@ -0,0 +1,73 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
2// RUN: ld.lld %t.o -o %t --gc-sections
3// RUN: llvm-readobj -symbols %t | FileCheck %s
4
5// CHECK: Symbols [
6// CHECK-NEXT: Symbol {
7// CHECK-NEXT: Name: (0)
8// CHECK-NEXT: Value: 0x0
9// CHECK-NEXT: Size: 0
10// CHECK-NEXT: Binding: Local (0x0)
11// CHECK-NEXT: Type: None (0x0)
12// CHECK-NEXT: Other: 0
13// CHECK-NEXT: Section: Undefined (0x0)
14// CHECK-NEXT: }
15// CHECK-NEXT: Symbol {
16// CHECK-NEXT: Name: s3
17// CHECK-NEXT: Value: 0x200125
18// CHECK-NEXT: Size: 0
19// CHECK-NEXT: Binding: Local (0x0)
20// CHECK-NEXT: Type: Object (0x1)
21// CHECK-NEXT: Other: 0
22// CHECK-NEXT: Section: .rodata (0x1)
23// CHECK-NEXT: }
24// CHECK-NEXT: Symbol {
25// CHECK-NEXT: Name: s1
26// CHECK-NEXT: Value: 0x200120
27// CHECK-NEXT: Size: 0
28// CHECK-NEXT: Binding: Local (0x0)
29// CHECK-NEXT: Type: Object (0x1)
30// CHECK-NEXT: Other [ (0x2)
31// CHECK-NEXT: STV_HIDDEN (0x2)
32// CHECK-NEXT: ]
33// CHECK-NEXT: Section: .rodata (0x1)
34// CHECK-NEXT: }
35// CHECK-NEXT: Symbol {
36// CHECK-NEXT: Name: _start
37// CHECK-NEXT: Value: 0x201000
38// CHECK-NEXT: Size: 0
39// CHECK-NEXT: Binding: Global (0x1)
40// CHECK-NEXT: Type: Function (0x2)
41// CHECK-NEXT: Other: 0
42// CHECK-NEXT: Section: .text (0x2)
43// CHECK-NEXT: }
44// CHECK-NEXT: ]
45
46.text
47.globl _start
48.type _start,@function
49_start:
50movl $s1, %eax
51movl $s3, %eax
52
53.hidden s1
54.type s1,@object
55.section .rodata.str1.1,"aMS",@progbits,1
56.globl s1
57s1:
58.asciz "abcd"
59
60.hidden s2
61.type s2,@object
62.globl s2
63s2:
64.asciz "efgh"
65
66.type s3,@object
67s3:
68.asciz "ijkl"
69
70.type s4,@object
71.globl s4
72s4:
73.asciz "mnop"
deps/lld/test/ELF/string-table.s created+27
......@@ -0,0 +1,27 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
2// RUN: ld.lld %t -o %t2
3// RUN: llvm-readobj -sections %t2 | FileCheck %s
4// REQUIRES: x86
5
6.global _start
7_start:
8
9.section foobar,"",@progbits
10
11.section bar, "a"
12
13// Both sections are in the output and that the alloc section is first:
14// CHECK: Name: bar
15// CHECK-NEXT: Type: SHT_PROGBITS
16// CHECK-NEXT: Flags [
17// CHECK-NEXT: SHF_ALLOC
18// CHECK-NEXT: ]
19// CHECK-NEXT: Address: 0x200120
20
21// CHECK: Name: foobar
22// CHECK-NEXT: Type: SHT_PROGBITS
23// CHECK-NEXT: Flags [
24// CHECK-NEXT: ]
25// CHECK-NEXT: Address: 0x0
26
27// CHECK-NOT: Name: foobar
deps/lld/test/ELF/strip-all.s created+29
......@@ -0,0 +1,29 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
4# RUN: ld.lld %t.o -o %t1
5#RUN: llvm-objdump -section-headers %t1 | FileCheck %s -check-prefix BEFORE
6#BEFORE: .symtab
7#BEFORE-NEXT: .shstrtab
8#BEFORE-NEXT: .strtab
9
10#RUN: ld.lld %t.o --strip-all -o %t1
11#RUN: llvm-objdump -section-headers %t1 | FileCheck %s -check-prefix AFTER
12#AFTER-NOT: .symtab
13#AFTER: .shstrtab
14#AFTER-NOT: .strtab
15
16# Ignore --strip-all if -r is specified
17#RUN: ld.lld %t.o --strip-all -r -o %t1
18#RUN: llvm-objdump -section-headers %t1 | FileCheck %s -check-prefix BEFORE
19
20# Test alias -s
21#RUN: ld.lld %t.o -s -o %t1
22#RUN: llvm-objdump -section-headers %t1 | FileCheck %s -check-prefix AFTER
23
24# exits with return code 42 on linux
25.globl _start
26_start:
27 mov $60, %rax
28 mov $42, %rdi
29 syscall
deps/lld/test/ELF/strip-debug.s created+25
......@@ -0,0 +1,25 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux -g %s -o %t
4# RUN: ld.lld %t -o %t2
5# RUN: llvm-readobj -sections -symbols %t2 | FileCheck -check-prefix=DEFAULT %s
6# RUN: ld.lld %t -o %t2 --strip-debug
7# RUN: llvm-readobj -sections -symbols %t2 | FileCheck -check-prefix=STRIP %s
8# RUN: ld.lld %t -o %t2 -S
9# RUN: llvm-readobj -sections -symbols %t2 | FileCheck -check-prefix=STRIP %s
10# RUN: ld.lld %t -o %t2 --strip-all
11# RUN: llvm-readobj -sections -symbols %t2 | FileCheck -check-prefix=STRIP %s
12
13# DEFAULT: Name: .debug_info
14# DEFAULT: Name: .debug_abbrev
15# DEFAULT: Name: .debug_aranges
16# DEFAULT: Name: .debug_line
17
18# STRIP-NOT: Name: .debug_info
19# STRIP-NOT: Name: .debug_abbrev
20# STRIP-NOT: Name: .debug_aranges
21# STRIP-NOT: Name: .debug_line
22
23.globl _start
24_start:
25 ret
deps/lld/test/ELF/symbol-ordering-file.s created+44
......@@ -0,0 +1,44 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: ld.lld %t.o -o %t.out
4# RUN: llvm-objdump -s %t.out| FileCheck %s --check-prefix=BEFORE
5
6# BEFORE: Contents of section .foo:
7# BEFORE-NEXT: 201000 11223344 5566
8
9# RUN: echo "_foo4 " > %t_order.txt
10# RUN: echo " _foo3" >> %t_order.txt
11# RUN: echo "_foo5" >> %t_order.txt
12# RUN: echo "_foo2" >> %t_order.txt
13# RUN: echo " " >> %t_order.txt
14# RUN: echo "_foo4" >> %t_order.txt
15# RUN: echo "_bar1" >> %t_order.txt
16# RUN: echo "_foo1" >> %t_order.txt
17
18# RUN: ld.lld --symbol-ordering-file %t_order.txt %t.o -o %t2.out
19# RUN: llvm-objdump -s %t2.out| FileCheck %s --check-prefix=AFTER
20
21# AFTER: Contents of section .foo:
22# AFTER-NEXT: 201000 44335566 2211
23
24.section .foo,"ax",@progbits,unique,1
25_foo1:
26 .byte 0x11
27
28.section .foo,"ax",@progbits,unique,2
29_foo2:
30 .byte 0x22
31
32.section .foo,"ax",@progbits,unique,3
33_foo3:
34 .byte 0x33
35
36.section .foo,"ax",@progbits,unique,4
37_foo4:
38 .byte 0x44
39
40.section .foo,"ax",@progbits,unique,5
41_foo5:
42 .byte 0x55
43_bar1:
44 .byte 0x66
deps/lld/test/ELF/symbol-override.s created+46
......@@ -0,0 +1,46 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/symbol-override.s -o %t2.o
3// RUN: ld.lld -shared %t2.o -o %t2.so
4// RUN: ld.lld %t1.o %t2.so -o %t
5// RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
6
7// CHECK: DynamicSymbols [
8// CHECK-NEXT: Symbol {
9// CHECK-NEXT: Name:
10// CHECK-NEXT: Value: 0x0
11// CHECK-NEXT: Size: 0
12// CHECK-NEXT: Binding: Local
13// CHECK-NEXT: Type: None
14// CHECK-NEXT: Other: 0
15// CHECK-NEXT: Section: Undefined
16// CHECK-NEXT: }
17// CHECK-NEXT: Symbol {
18// CHECK-NEXT: Name: do
19// CHECK-NEXT: Value: 0x0
20// CHECK-NEXT: Size: 0
21// CHECK-NEXT: Binding: Global
22// CHECK-NEXT: Type: Function
23// CHECK-NEXT: Other: 0
24// CHECK-NEXT: Section: Undefined
25// CHECK-NEXT: }
26// CHECK-NEXT: Symbol {
27// CHECK-NEXT: Name: foo
28// CHECK-NEXT: Value: 0x201000
29// CHECK-NEXT: Size: 0
30// CHECK-NEXT: Binding: Global
31// CHECK-NEXT: Type: Function
32// CHECK-NEXT: Other: 0
33// CHECK-NEXT: Section: .text
34// CHECK-NEXT: }
35// CHECK-NEXT: ]
36
37.text
38.globl foo
39.type foo,@function
40foo:
41nop
42
43.text
44.globl _start
45_start:
46callq do@plt
deps/lld/test/ELF/symbols.s created+188
......@@ -0,0 +1,188 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
2// RUN: ld.lld %t -o %t2
3// RUN: llvm-readobj -symbols -sections %t2 | FileCheck %s
4// REQUIRES: x86
5
6.type _start, @function
7.globl _start
8_start:
9
10.type foo, @object
11.weak foo
12foo:
13
14.type bar, @object
15.weak bar
16.long bar
17
18.section foobar,"a",@nobits,unique,1
19.globl zed
20zed:
21 .long 0
22.globl zed2
23zed2:
24.long 0
25
26.section foobar,"a",@nobits,unique,2
27.globl zed3
28.size zed3, 4
29zed3:
30
31.globl abs
32abs = 0x123
33
34.comm common,4,4
35
36.global protected
37.protected protected
38protected:
39
40.global hidden
41.hidden hidden
42hidden:
43
44.global internal
45.internal internal
46internal:
47
48// CHECK: Name: foobar
49// CHECK-NEXT: Type: SHT_NOBITS
50// CHECK-NEXT: Flags [
51// CHECK-NEXT: SHF_ALLOC
52// CHECK-NEXT: ]
53// CHECK-NEXT: Address: 0x200158
54
55// CHECK: Name: .text
56// CHECK-NEXT: Type: SHT_PROGBITS
57// CHECK-NEXT: Flags [
58// CHECK-NEXT: SHF_ALLOC
59// CHECK-NEXT: SHF_EXECINSTR
60// CHECK-NEXT: ]
61// CHECK-NEXT: Address: 0x201000
62
63// CHECK: Name: .bss
64// CHECK-NEXT: Type: SHT_NOBITS
65// CHECK-NEXT: Flags [
66// CHECK-NEXT: SHF_ALLOC
67// CHECK-NEXT: SHF_WRITE
68// CHECK-NEXT: ]
69// CHECK-NEXT: Address: 0x202000
70// CHECK-NEXT: Offset:
71// CHECK-NEXT: Size: 4
72
73// CHECK: Symbols [
74// CHECK-NEXT: Symbol {
75// CHECK-NEXT: Name: (0)
76// CHECK-NEXT: Value: 0x0
77// CHECK-NEXT: Size: 0
78// CHECK-NEXT: Binding: Local (0x0)
79// CHECK-NEXT: Type: None (0x0)
80// CHECK-NEXT: Other: 0
81// CHECK-NEXT: Section: Undefined (0x0)
82// CHECK-NEXT: }
83// CHECK-NEXT: Symbol {
84// CHECK-NEXT: Name: hidden
85// CHECK-NEXT: Value: 0x200160
86// CHECK-NEXT: Size: 0
87// CHECK-NEXT: Binding: Local
88// CHECK-NEXT: Type: None
89// CHECK-NEXT: Other [ (0x2)
90// CHECK-NEXT: STV_HIDDEN
91// CHECK-NEXT: ]
92// CHECK-NEXT: Section: foobar
93// CHECK-NEXT: }
94// CHECK-NEXT: Symbol {
95// CHECK-NEXT: Name: internal
96// CHECK-NEXT: Value: 0x200160
97// CHECK-NEXT: Size: 0
98// CHECK-NEXT: Binding: Local
99// CHECK-NEXT: Type: None
100// CHECK-NEXT: Other [ (0x1)
101// CHECK-NEXT: STV_INTERNAL
102// CHECK-NEXT: ]
103// CHECK-NEXT: Section: foobar
104// CHECK-NEXT: }
105// CHECK-NEXT: Symbol {
106// CHECK-NEXT: Name: _start
107// CHECK-NEXT: Value: 0x201000
108// CHECK-NEXT: Size: 0
109// CHECK-NEXT: Binding: Global (0x1)
110// CHECK-NEXT: Type: Function
111// CHECK-NEXT: Other: 0
112// CHECK-NEXT: Section: .text
113// CHECK-NEXT: }
114// CHECK-NEXT: Symbol {
115// CHECK-NEXT: Name: abs
116// CHECK-NEXT: Value: 0x123
117// CHECK-NEXT: Size: 0
118// CHECK-NEXT: Binding: Global
119// CHECK-NEXT: Type: None
120// CHECK-NEXT: Other: 0
121// CHECK-NEXT: Section: Absolute
122// CHECK-NEXT: }
123// CHECK-NEXT: Symbol {
124// CHECK-NEXT: Name: bar
125// CHECK-NEXT: Value: 0x0
126// CHECK-NEXT: Size: 0
127// CHECK-NEXT: Binding: Weak (0x2)
128// CHECK-NEXT: Type: Object (0x1)
129// CHECK-NEXT: Other: 0
130// CHECK-NEXT: Section: Undefined (0x0)
131// CHECK-NEXT: }
132// CHECK-NEXT: Symbol {
133// CHECK-NEXT: Name: common
134// CHECK-NEXT: Value: 0x202000
135// CHECK-NEXT: Size: 4
136// CHECK-NEXT: Binding: Global
137// CHECK-NEXT: Type: Object
138// CHECK-NEXT: Other: 0
139// CHECK-NEXT: Section: .bss
140// CHECK-NEXT: }
141// CHECK-NEXT: Symbol {
142// CHECK-NEXT: Name: foo
143// CHECK-NEXT: Value: 0x201000
144// CHECK-NEXT: Size: 0
145// CHECK-NEXT: Binding: Weak (0x2)
146// CHECK-NEXT: Type: Object
147// CHECK-NEXT: Other: 0
148// CHECK-NEXT: Section: .text
149// CHECK-NEXT: }
150// CHECK-NEXT: Symbol {
151// CHECK-NEXT: Name: protected
152// CHECK-NEXT: Value: 0x200160
153// CHECK-NEXT: Size: 0
154// CHECK-NEXT: Binding: Global
155// CHECK-NEXT: Type: None
156// CHECK-NEXT: Other [ (0x3)
157// CHECK-NEXT: STV_PROTECTED
158// CHECK-NEXT: ]
159// CHECK-NEXT: Section: foobar
160// CHECK-NEXT: }
161// CHECK-NEXT: Symbol {
162// CHECK-NEXT: Name: zed
163// CHECK-NEXT: Value: 0x200158
164// CHECK-NEXT: Size: 0
165// CHECK-NEXT: Binding: Global (0x1)
166// CHECK-NEXT: Type: None
167// CHECK-NEXT: Other: 0
168// CHECK-NEXT: Section: foobar
169// CHECK-NEXT: }
170// CHECK-NEXT: Symbol {
171// CHECK-NEXT: Name: zed2
172// CHECK-NEXT: Value: 0x20015C
173// CHECK-NEXT: Size: 0
174// CHECK-NEXT: Binding: Global
175// CHECK-NEXT: Type: None
176// CHECK-NEXT: Other: 0
177// CHECK-NEXT: Section: foobar
178// CHECK-NEXT: }
179// CHECK-NEXT: Symbol {
180// CHECK-NEXT: Name: zed3
181// CHECK-NEXT: Value: 0x200160
182// CHECK-NEXT: Size: 4
183// CHECK-NEXT: Binding: Global
184// CHECK-NEXT: Type: None
185// CHECK-NEXT: Other: 0
186// CHECK-NEXT: Section: foobar
187// CHECK-NEXT: }
188// CHECK-NEXT: ]
deps/lld/test/ELF/symver-archive.s created+15
......@@ -0,0 +1,15 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1
3# RUN: rm -f %t.a
4# RUN: llvm-ar rcs %t.a %t1
5# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/symver-archive1.s -o %t2.o
6# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/symver-archive2.s -o %t3.o
7# RUN: ld.lld -o %t.out %t2.o %t3.o %t.a
8
9.text
10.globl x
11.type x, @function
12x:
13
14.globl xx
15xx = x
deps/lld/test/ELF/synthetic-got.s created+32
......@@ -0,0 +1,32 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: echo "SECTIONS { }" > %t0.script
4# RUN: ld.lld -shared %t.o -o %t0.out --script %t0.script
5# RUN: llvm-objdump -section-headers %t0.out | FileCheck %s --check-prefix=GOT
6# RUN: llvm-objdump -s -section=.got -section=.got.plt %t0.out \
7# RUN: | FileCheck %s --check-prefix=GOTDATA
8
9# GOT: Sections:
10# GOT: 8 .got.plt 00000020 00000000000000e0 DATA
11# GOT: 10 .got 00000008 00000000000001d0 DATA
12# GOTDATA: Contents of section .got.plt:
13# GOTDATA-NEXT: 00e0 00010000 00000000 00000000 00000000
14# GOTDATA-NEXT: 00f0 00000000 00000000 d6000000 00000000
15# GOTDATA-NEXT: Contents of section .got:
16# GOTDATA-NEXT: 01d0 00000000 00000000
17
18# RUN: echo "SECTIONS { .mygot : { *(.got) *(.got.plt) } }" > %t1.script
19# RUN: ld.lld -shared %t.o -o %t1.out --script %t1.script
20# RUN: llvm-objdump -section-headers %t1.out | FileCheck %s --check-prefix=MYGOT
21# RUN: llvm-objdump -s -section=.mygot %t1.out | FileCheck %s --check-prefix=MYGOTDATA
22
23# MYGOT: Sections:
24# MYGOT: 8 .mygot 00000028 00000000000000e0 DATA
25# MYGOT-NOT: .got
26# MYGOT-NOT: .got.plt
27# MYGOTDATA: 00e0 00000000 00000000 08010000 00000000
28# MYGOTDATA-NEXT: 00f0 00000000 00000000 00000000 00000000
29# MYGOTDATA-NEXT: 0100 d6000000 00000000
30
31mov bar@gotpcrel(%rip), %rax
32call foo@plt
deps/lld/test/ELF/sysroot.s created+38
......@@ -0,0 +1,38 @@
1// RUN: mkdir -p %t/lib
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t/m.o
3// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
4// RUN: %p/Inputs/libsearch-st.s -o %t/st.o
5// RUN: rm -f %t/lib/libls.a
6// RUN: llvm-ar rcs %t/lib/libls.a %t/st.o
7// REQUIRES: x86
8
9// Should not link because of undefined symbol _bar
10// RUN: not ld.lld -o %t/r %t/m.o 2>&1 \
11// RUN: | FileCheck --check-prefix=UNDEFINED %s
12// UNDEFINED: error: undefined symbol: _bar
13// UNDEFINED: >>> referenced by {{.*}}:(.text+0x1)
14
15// We need to be sure that there is no suitable library in the /lib directory
16// RUN: not ld.lld -o %t/r %t/m.o -L/lib -l:libls.a 2>&1 \
17// RUN: | FileCheck --check-prefix=NOLIB %s
18// NOLIB: unable to find library -l:libls.a
19
20// Should just remove the '=' symbol if --sysroot is not specified.
21// Case 1: relative path
22// RUN: cd %t && ld.lld -o %t/r %t/m.o -L=lib -l:libls.a
23// Case 2: absolute path
24// RUN: cd %p && ld.lld -o %t/r %t/m.o -L=%t/lib -l:libls.a
25
26// RUN: cd %p
27
28// Should substitute SysRoot if specified
29// RUN: ld.lld -o %t/r %t/m.o --sysroot=%t -L=lib -l:libls.a
30// RUN: ld.lld -o %t/r %t/m.o --sysroot=%t -L=/lib -l:libls.a
31
32// Should not substitute SysRoot if the directory name does not start with '='
33// RUN: not ld.lld -o %t/r %r/m.o --sysroot=%t -Llib -l:libls.a
34// RUN: not ld.lld -o %t/r %r/m.o --sysroot=%t -L/lib -l:libls.a
35
36.globl _start,_bar
37_start:
38 call _bar
deps/lld/test/ELF/tail-merge-string-align.s created+35
......@@ -0,0 +1,35 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: ld.lld %t.o -o %t.so -shared -O3
4// RUN: llvm-readobj -s -section-data %t.so | FileCheck %s
5
6 .section .rodata.4a,"aMS",@progbits,1
7 .align 4
8 .asciz "abcdef"
9
10 .section .rodata.4b,"aMS",@progbits,1
11 .align 4
12 .asciz "ef"
13
14 .section .rodata.4c,"aMS",@progbits,1
15 .align 4
16 .asciz "f"
17
18
19// CHECK: Name: .rodata
20// CHECK-NEXT: Type: SHT_PROGBITS
21// CHECK-NEXT: Flags [
22// CHECK-NEXT: SHF_ALLOC
23// CHECK-NEXT: SHF_MERGE
24// CHECK-NEXT: SHF_STRINGS
25// CHECK-NEXT: ]
26// CHECK-NEXT: Address:
27// CHECK-NEXT: Offset:
28// CHECK-NEXT: Size: 1
29// CHECK-NEXT: Link: 0
30// CHECK-NEXT: Info: 0
31// CHECK-NEXT: AddressAlignment: 4
32// CHECK-NEXT: EntrySize:
33// CHECK-NEXT: SectionData (
34// CHECK-NEXT: 0000: 61626364 65660000 6600 |abcdef..f.|
35// CHECK-NEXT: )
deps/lld/test/ELF/tls-align.s created+21
......@@ -0,0 +1,21 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3// RUN: ld.lld %t -o %tout -shared
4// RUN: llvm-readobj -program-headers %tout | FileCheck %s
5
6 .section .tbss,"awT",@nobits
7 .align 8
8 .long 0
9
10// CHECK: ProgramHeader {
11// CHECK: Type: PT_TLS
12// CHECK-NEXT: Offset:
13// CHECK-NEXT: VirtualAddress:
14// CHECK-NEXT: PhysicalAddress:
15// CHECK-NEXT: FileSize: 0
16// CHECK-NEXT: MemSize: 8
17// CHECK-NEXT: Flags [
18// CHECK-NEXT: PF_R (0x4)
19// CHECK-NEXT: ]
20// CHECK-NEXT: Alignment: 8
21// CHECK-NEXT: }
deps/lld/test/ELF/tls-archive.s created+10
......@@ -0,0 +1,10 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/tls-mismatch.s -o %t2
4// RUN: rm -f %t.a
5// RUN: llvm-ar cru %t.a %t2
6// RUN: ld.lld %t.a %t -o %t3
7
8.globl _start,tlsvar
9_start:
10 movq tlsvar@GOTTPOFF(%rip),%rdx
deps/lld/test/ELF/tls-dynamic-i686.s created+99
......@@ -0,0 +1,99 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t
3// RUN: ld.lld -shared %t -o %tout
4// RUN: llvm-readobj -sections -relocations %tout | FileCheck %s
5// RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DIS
6
7.type tls0,@object
8.section .tbss,"awT",@nobits
9.globl tls0
10.align 4
11tls0:
12 .long 0
13 .size tls0, 4
14
15.type tls1,@object
16.globl tls1
17.align 4
18tls1:
19 .long 0
20 .size tls1, 4
21
22.type tls2,@object
23.globl tls2
24.hidden tls2
25.align 4
26tls2:
27 .long 0
28 .size tls2, 8
29
30.section .text
31.globl _start
32_start:
33leal tls0@tlsgd(,%ebx,1),%eax
34call __tls_get_addr@plt
35
36leal tls1@tlsgd(,%ebx,1),%eax
37call __tls_get_addr@plt
38
39leal tls2@tlsldm(%ebx),%eax
40call __tls_get_addr@plt
41leal tls2@dtpoff(%eax),%edx
42
43leal tls2@tlsldm(%ebx),%eax
44call __tls_get_addr@plt
45leal tls2@dtpoff+4(%eax),%edx
46
47movl %gs:0,%eax
48addl tls0@gotntpoff(%ebx),%eax
49
50movl %gs:0,%eax
51addl tls1@gotntpoff(%ebx),%eax
52
53// CHECK: Name: .got (
54// CHECK-NEXT: Type: SHT_PROGBITS
55// CHECK-NEXT: Flags [
56// CHECK-NEXT: SHF_ALLOC
57// CHECK-NEXT: SHF_WRITE
58// CHECK-NEXT: ]
59// CHECK-NEXT: Address: 0x3068
60// CHECK-NEXT: Offset: 0x3068
61// CHECK-NEXT: Size: 32
62// CHECK-NEXT: Link: 0
63// CHECK-NEXT: Info: 0
64// CHECK-NEXT: AddressAlignment: 4
65// CHECK-NEXT: EntrySize: 0
66
67// CHECK: Relocations [
68// CHECK: Section ({{.+}}) .rel.dyn {
69// CHECK-NEXT: 0x3078 R_386_TLS_DTPMOD32 - 0x0
70// CHECK-NEXT: 0x3068 R_386_TLS_DTPMOD32 tls0 0x0
71// CHECK-NEXT: 0x306C R_386_TLS_DTPOFF32 tls0 0x0
72// CHECK-NEXT: 0x3080 R_386_TLS_TPOFF tls0 0x0
73// CHECK-NEXT: 0x3070 R_386_TLS_DTPMOD32 tls1 0x0
74// CHECK-NEXT: 0x3074 R_386_TLS_DTPOFF32 tls1 0x0
75// CHECK-NEXT: 0x3084 R_386_TLS_TPOFF tls1 0x0
76// CHECK-NEXT: }
77
78// DIS: Disassembly of section .text:
79// DIS-NEXT: _start:
80// General dynamic model:
81// -32 and -24 are first and second GOT entries offsets.
82// Each one is a pair of records.
83// DIS-NEXT: 1000: 8d 04 1d e0 ff ff ff leal -32(,%ebx), %eax
84// DIS-NEXT: 1007: e8 64 00 00 00 calll 100
85// DIS-NEXT: 100c: 8d 04 1d e8 ff ff ff leal -24(,%ebx), %eax
86// DIS-NEXT: 1013: e8 58 00 00 00 calll 88
87// Local dynamic model:
88// -16 is a local module tls index offset.
89// DIS-NEXT: 1018: 8d 83 f0 ff ff ff leal -16(%ebx), %eax
90// DIS-NEXT: 101e: e8 4d 00 00 00 calll 77
91// DIS-NEXT: 1023: 8d 90 08 00 00 00 leal 8(%eax), %edx
92// DIS-NEXT: 1029: 8d 83 f0 ff ff ff leal -16(%ebx), %eax
93// DIS-NEXT: 102f: e8 3c 00 00 00 calll 60
94// DIS-NEXT: 1034: 8d 90 0c 00 00 00 leal 12(%eax), %edx
95// Initial exec model:
96// DIS-NEXT: 103a: 65 a1 00 00 00 00 movl %gs:0, %eax
97// DIS-NEXT: 1040: 03 83 f8 ff ff ff addl -8(%ebx), %eax
98// DIS-NEXT: 1046: 65 a1 00 00 00 00 movl %gs:0, %eax
99// DIS-NEXT: 104c: 03 83 fc ff ff ff addl -4(%ebx), %eax
deps/lld/test/ELF/tls-dynamic.s created+87
......@@ -0,0 +1,87 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3// RUN: ld.lld -shared %t -o %tout
4// RUN: llvm-readobj -sections -relocations %tout | FileCheck %s
5// RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DIS
6
7 leaq a@tlsld(%rip), %rdi
8 callq __tls_get_addr@PLT
9 leaq b@tlsld(%rip), %rdi
10 callq __tls_get_addr@PLT
11 leaq a@dtpoff(%rax), %rcx
12 leaq b@dtpoff(%rax), %rcx
13 .long b@dtpoff, 0
14 leaq c@tlsgd(%rip), %rdi
15 rex64
16 callq __tls_get_addr@PLT
17 leaq a@dtpoff(%rax), %rcx
18 // Initial Exec Model Code Sequence, II
19 movq c@gottpoff(%rip),%rax
20 movq %fs:(%rax),%rax
21 movabs $a@dtpoff, %rax
22 movabs $b@dtpoff, %rax
23 movabs $a@dtpoff, %rax
24
25 .global a
26 .hidden a
27 .section .tbss,"awT",@nobits
28 .align 4
29a:
30 .long 0
31
32 .section .tbss,"awT",@nobits
33 .align 4
34b:
35 .long 0
36 .global c
37 .section .tbss,"awT",@nobits
38 .align 4
39c:
40 .long 0
41
42// Get the address of the got, and check that it has 4 entries.
43
44// CHECK: Sections [
45// CHECK: Name: .got (
46// CHECK-NEXT: Type: SHT_PROGBITS
47// CHECK-NEXT: Flags [
48// CHECK-NEXT: SHF_ALLOC
49// CHECK-NEXT: SHF_WRITE
50// CHECK-NEXT: ]
51// CHECK-NEXT: Address: 0x30D0
52// CHECK-NEXT: Offset:
53// CHECK-NEXT: Size: 40
54
55// CHECK: Relocations [
56// CHECK: Section ({{.+}}) .rela.dyn {
57// CHECK-NEXT: 0x30D0 R_X86_64_DTPMOD64 - 0x0
58// CHECK-NEXT: 0x30E0 R_X86_64_DTPMOD64 c 0x0
59// CHECK-NEXT: 0x30E8 R_X86_64_DTPOFF64 c 0x0
60// CHECK-NEXT: 0x30F0 R_X86_64_TPOFF64 c 0x0
61// CHECK-NEXT: }
62
63// 4297 = (0x20D0 + -4) - (0x1000 + 3) // PC relative offset to got entry.
64// 4285 = (0x20D0 + -4) - (0x100c + 3) // PC relative offset to got entry.
65// 4267 = (0x20E0 + -4) - (0x102e + 3) // PC relative offset to got entry.
66// 4263 = (0x20F0 + -4) - (0x1042 + 3) // PC relative offset to got entry.
67
68// DIS: Disassembly of section .text:
69// DIS-NEXT: .text:
70// DIS-NEXT: 1000: {{.+}} leaq 8393(%rip), %rdi
71// DIS-NEXT: 1007: {{.+}} callq
72// DIS-NEXT: 100c: {{.+}} leaq 8381(%rip), %rdi
73// DIS-NEXT: 1013: {{.+}} callq
74// DIS-NEXT: 1018: {{.+}} leaq (%rax), %rcx
75// DIS-NEXT: 101f: {{.+}} leaq 4(%rax), %rcx
76// DIS-NEXT: 1026: 04 00
77// DIS-NEXT: 1028: 00 00
78// DIS-NEXT: 102a: 00 00
79// DIS-NEXT: 102c: 00 00
80// DIS-NEXT: 102e: {{.+}} leaq 8363(%rip), %rdi
81// DIS-NEXT: 1035: {{.+}} callq
82// DIS-NEXT: 103b: {{.+}} leaq (%rax), %rcx
83// DIS-NEXT: 1042: {{.+}} movq 8359(%rip), %rax
84// DIS-NEXT: 1049: {{.+}} movq %fs:(%rax), %rax
85// DIS-NEXT: 104d: {{.+}} movabsq $0, %rax
86// DIS-NEXT: 1057: {{.+}} movabsq $4, %rax
87// DIS-NEXT: 1061: {{.+}} movabsq $0, %rax
deps/lld/test/ELF/tls-error.s created+12
......@@ -0,0 +1,12 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3// RUN: not ld.lld %t -o %tout 2>&1 | FileCheck %s
4// CHECK: R_X86_64_TPOFF32 out of range
5
6.global _start
7_start:
8 movl %fs:a@tpoff, %eax
9.global a
10.section .tbss,"awT",@nobits
11a:
12.zero 0x80000001
deps/lld/test/ELF/tls-got-entry.s created+25
......@@ -0,0 +1,25 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/tls-got-entry.s -o %tso.o
4// RUN: ld.lld -shared %tso.o -o %t.so
5// RUN: ld.lld %t.o %t.so -o %t1
6// RUN: llvm-readobj -r %t1 | FileCheck %s
7
8// CHECK: Relocations [
9// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
10// CHECK-NEXT: R_X86_64_TPOFF64 tlsshared0 0x0
11// CHECK-NEXT: }
12// CHECK-NEXT: ]
13
14.globl _start
15_start:
16 .byte 0x66
17 leaq tlsshared0@tlsgd(%rip),%rdi
18 .word 0x6666
19 rex64
20 call __tls_get_addr@plt
21 .byte 0x66
22 leaq tlsshared0@tlsgd(%rip),%rdi
23 .word 0x6666
24 rex64
25 call __tls_get_addr@plt
deps/lld/test/ELF/tls-got.s created+58
......@@ -0,0 +1,58 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/tls-got.s -o %t2.o
3// RUN: ld.lld -shared %t2.o -o %t2.so
4// RUN: ld.lld -e main %t1.o %t2.so -o %t3
5// RUN: llvm-readobj -s -r %t3 | FileCheck %s
6// RUN: llvm-objdump -d %t3 | FileCheck --check-prefix=DISASM %s
7
8// CHECK: Section {
9// CHECK: Index: 8
10// CHECK-NEXT: Name: .got
11// CHECK-NEXT: Type: SHT_PROGBITS
12// CHECK-NEXT: Flags [
13// CHECK-NEXT: SHF_ALLOC
14// CHECK-NEXT: SHF_WRITE
15// CHECK-NEXT: ]
16// CHECK-NEXT: Address: [[ADDR:.*]]
17// CHECK-NEXT: Offset: 0x20B0
18// CHECK-NEXT: Size: 16
19// CHECK-NEXT: Link: 0
20// CHECK-NEXT: Info: 0
21// CHECK-NEXT: AddressAlignment: 8
22// CHECK-NEXT: EntrySize: 0
23// CHECK-NEXT: }
24
25// CHECK: Relocations [
26// CHECK-NEXT: Section (4) .rela.dyn {
27// CHECK-NEXT: 0x2020B8 R_X86_64_TPOFF64 tls0 0x0
28// CHECK-NEXT: [[ADDR]] R_X86_64_TPOFF64 tls1 0x0
29// CHECK-NEXT: }
30// CHECK-NEXT: ]
31
32//0x201000 + 4249 + 7 = 0x2020B0
33//0x20100A + 4247 + 7 = 0x2020B8
34//0x201014 + 4237 + 7 = 0x2020B8
35//DISASM: Disassembly of section .text:
36//DISASM-NEXT: main:
37//DISASM-NEXT: 201000: 48 8b 05 a9 10 00 00 movq 4265(%rip), %rax
38//DISASM-NEXT: 201007: 64 8b 00 movl %fs:(%rax), %eax
39//DISASM-NEXT: 20100a: 48 8b 05 a7 10 00 00 movq 4263(%rip), %rax
40//DISASM-NEXT: 201011: 64 8b 00 movl %fs:(%rax), %eax
41//DISASM-NEXT: 201014: 48 8b 05 9d 10 00 00 movq 4253(%rip), %rax
42//DISASM-NEXT: 20101b: 64 8b 00 movl %fs:(%rax), %eax
43//DISASM-NEXT: 20101e: c3 retq
44
45.section .tdata,"awT",@progbits
46
47.text
48 .globl main
49 .align 16, 0x90
50 .type main,@function
51main:
52 movq tls1@GOTTPOFF(%rip), %rax
53 movl %fs:0(%rax), %eax
54 movq tls0@GOTTPOFF(%rip), %rax
55 movl %fs:0(%rax), %eax
56 movq tls0@GOTTPOFF(%rip), %rax
57 movl %fs:0(%rax), %eax
58 ret
deps/lld/test/ELF/tls-i686.s created+69
......@@ -0,0 +1,69 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t
3// RUN: ld.lld %t -o %tout
4// RUN: ld.lld %t -shared -o %tsharedout
5// RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DIS
6// RUN: llvm-readobj -r %tout | FileCheck %s --check-prefix=RELOC
7// RUN: llvm-objdump -d %tsharedout | FileCheck %s --check-prefix=DISSHARED
8// RUN: llvm-readobj -r %tsharedout | FileCheck %s --check-prefix=RELOCSHARED
9
10.section ".tdata", "awT", @progbits
11.globl var
12.globl var1
13var:
14.long 0
15var1:
16.long 1
17
18.section test, "awx"
19.global _start
20_start:
21 movl $var@tpoff, %edx
22 movl %gs:0, %ecx
23 subl %edx, %eax
24 movl $var1@tpoff, %edx
25 movl %gs:0, %ecx
26 subl %edx, %eax
27
28 movl %gs:0, %ecx
29 leal var@ntpoff(%ecx), %eax
30 movl %gs:0, %ecx
31 leal var1@ntpoff+123(%ecx), %eax
32
33// DIS: Disassembly of section test:
34// DIS-NEXT: _start:
35// DIS-NEXT: 11000: ba 08 00 00 00 movl $8, %edx
36// DIS-NEXT: 11005: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
37// DIS-NEXT: 1100c: 29 d0 subl %edx, %eax
38// DIS-NEXT: 1100e: ba 04 00 00 00 movl $4, %edx
39// DIS-NEXT: 11013: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
40// DIS-NEXT: 1101a: 29 d0 subl %edx, %eax
41// DIS-NEXT: 1101c: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
42// DIS-NEXT: 11023: 8d 81 f8 ff ff ff leal -8(%ecx), %eax
43// DIS-NEXT: 11029: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
44// DIS-NEXT: 11030: 8d 81 77 00 00 00 leal 119(%ecx), %eax
45
46// RELOC: Relocations [
47// RELOC-NEXT: ]
48
49// DISSHARED: Disassembly of section test:
50// DISSHARED-NEXT: _start:
51// DISSHARED-NEXT: 1000: ba 00 00 00 00 movl $0, %edx
52// DISSHARED-NEXT: 1005: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
53// DISSHARED-NEXT: 100c: 29 d0 subl %edx, %eax
54// DISSHARED-NEXT: 100e: ba 00 00 00 00 movl $0, %edx
55// DISSHARED-NEXT: 1013: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
56// DISSHARED-NEXT: 101a: 29 d0 subl %edx, %eax
57// DISSHARED-NEXT: 101c: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
58// DISSHARED-NEXT: 1023: 8d 81 00 00 00 00 leal (%ecx), %eax
59// DISSHARED-NEXT: 1029: 65 8b 0d 00 00 00 00 movl %gs:0, %ecx
60// DISSHARED-NEXT: 1030: 8d 81 7b 00 00 00 leal 123(%ecx), %eax
61
62// RELOCSHARED: Relocations [
63// RELOCSHARED-NEXT: Section (4) .rel.dyn {
64// RELOCSHARED-NEXT: 0x1001 R_386_TLS_TPOFF32 var 0x0
65// RELOCSHARED-NEXT: 0x1025 R_386_TLS_TPOFF var 0x0
66// RELOCSHARED-NEXT: 0x100F R_386_TLS_TPOFF32 var1 0x0
67// RELOCSHARED-NEXT: 0x1032 R_386_TLS_TPOFF var1 0x0
68// RELOCSHARED-NEXT: }
69// RELOCSHARED-NEXT: ]
deps/lld/test/ELF/tls-in-archive.s created+11
......@@ -0,0 +1,11 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/tls-in-archive.s -o %t1.o
3// RUN: llvm-ar cru %t.a %t1.o
4// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t2.o
5// RUN: ld.lld %t2.o %t.a -o %tout
6
7 .globl _start
8_start:
9 movq foo@gottpoff(%rip), %rax
10 .section .tbss,"awT",@nobits
11 .weak foo
deps/lld/test/ELF/tls-initial-exec-local.s created+36
......@@ -0,0 +1,36 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: ld.lld -shared %t.o -o %t
4// RUN: llvm-readobj -r -s %t | FileCheck %s
5// RUN: llvm-objdump -d %t | FileCheck --check-prefix=DISASM %s
6
7// CHECK: Name: .got
8// CHECK-NEXT: Type: SHT_PROGBITS
9// CHECK-NEXT: Flags [
10// CHECK-NEXT: SHF_ALLOC (0x2)
11// CHECK-NEXT: SHF_WRITE (0x1)
12// CHECK-NEXT: ]
13// CHECK-NEXT: Address: 0x2090
14
15// CHECK: Relocations [
16// CHECK-NEXT: Section ({{.*}}) .rela.dyn {
17// CHECK-NEXT: 0x2090 R_X86_64_TPOFF64 - 0x0
18// CHECK-NEXT: 0x2098 R_X86_64_TPOFF64 - 0x4
19// CHECK-NEXT: }
20// CHECK-NEXT: ]
21
22// 0x1007 + 4233 = 0x2090
23// 0x100e + 4234 = 0x2098
24// DISASM: Disassembly of section .text:
25// DISASM-NEXT: .text:
26// DISASM-NEXT: 1000: {{.*}} addq 4233(%rip), %rax
27// DISASM-NEXT: 1007: {{.*}} addq 4234(%rip), %rax
28
29 addq foo@GOTTPOFF(%rip), %rax
30 addq bar@GOTTPOFF(%rip), %rax
31
32 .section .tbss,"awT",@nobits
33foo:
34 .long 0
35bar:
36 .long 0
deps/lld/test/ELF/tls-mismatch.s created+12
......@@ -0,0 +1,12 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/tls-mismatch.s -o %t2
4// RUN: not ld.lld %t %t2 -o %t3 2>&1 | FileCheck %s
5
6// CHECK: TLS attribute mismatch: tlsvar
7// CHECK: >>> defined in
8// CHECK: >>> defined in
9
10.globl _start,tlsvar
11_start:
12 movl tlsvar,%edx
deps/lld/test/ELF/tls-offset.s created+66
......@@ -0,0 +1,66 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3// RUN: ld.lld %t -o %tout
4// RUN: llvm-readobj -s %tout | FileCheck %s
5// RUN: echo "SECTIONS { \
6// RUN: . = 0x201000; \
7// RUN: .text : { *(.text) } \
8// RUN: . = 0x202000; \
9// RUN: .tdata : { *(.tdata) } \
10// RUN: .tbss : { *(.tbss) } \
11// RUN: .data.rel.ro : { *(.data.rel.ro) } \
12// RUN: }" > %t.script
13// RUN: ld.lld -T %t.script %t -o %tout2
14// RUN: echo SCRIPT
15// RUN: llvm-readobj -s %tout2 | FileCheck %s
16 .global _start
17_start:
18 retq
19
20 .section .tdata,"awT",@progbits
21 .align 4
22 .long 42
23
24 .section .tbss,"awT",@nobits
25 .align 16
26 .zero 16
27
28 .section .data.rel.ro,"aw",@progbits
29 .long 1
30
31
32// Test that .tbss doesn't show up in the offset or in the address. If this
33// gets out of sync what we get a runtime is different from what the section
34// table says.
35
36// CHECK: Name: .tdata
37// CHECK-NEXT: Type: SHT_PROGBITS
38// CHECK-NEXT: Flags [
39// CHECK-NEXT: SHF_ALLOC
40// CHECK-NEXT: SHF_TLS
41// CHECK-NEXT: SHF_WRITE
42// CHECK-NEXT: ]
43// CHECK-NEXT: Address: 0x202000
44// CHECK-NEXT: Offset: 0x2000
45// CHECK-NEXT: Size: 4
46
47// CHECK: Name: .tbss
48// CHECK-NEXT: Type: SHT_NOBITS
49// CHECK-NEXT: Flags [
50// CHECK-NEXT: SHF_ALLOC
51// CHECK-NEXT: SHF_TLS
52// CHECK-NEXT: SHF_WRITE
53// CHECK-NEXT: ]
54// CHECK-NEXT: Address: 0x202010
55// CHECK-NEXT: Offset: 0x2004
56// CHECK-NEXT: Size: 16
57
58// CHECK: Name: .data.rel.ro
59// CHECK-NEXT: Type: SHT_PROGBITS
60// CHECK-NEXT: Flags [
61// CHECK-NEXT: SHF_ALLOC
62// CHECK-NEXT: SHF_WRITE
63// CHECK-NEXT: ]
64// CHECK-NEXT: Address: 0x202004
65// CHECK-NEXT: Offset: 0x2004
66// CHECK-NEXT: Size: 4
deps/lld/test/ELF/tls-opt-gdie.s created+52
......@@ -0,0 +1,52 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/tls-opt-gdie.s -o %tso.o
3// RUN: ld.lld -shared %tso.o -o %t.so
4// RUN: ld.lld %t.o %t.so -o %t1
5// RUN: llvm-readobj -s -r %t1 | FileCheck --check-prefix=RELOC %s
6// RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s
7
8//RELOC: Section {
9//RELOC: Index:
10//RELOC: Name: .got
11//RELOC-NEXT: Type: SHT_PROGBITS
12//RELOC-NEXT: Flags [
13//RELOC-NEXT: SHF_ALLOC
14//RELOC-NEXT: SHF_WRITE
15//RELOC-NEXT: ]
16//RELOC-NEXT: Address: 0x2020B0
17//RELOC-NEXT: Offset: 0x20B0
18//RELOC-NEXT: Size: 16
19//RELOC-NEXT: Link: 0
20//RELOC-NEXT: Info: 0
21//RELOC-NEXT: AddressAlignment: 8
22//RELOC-NEXT: EntrySize: 0
23//RELOC-NEXT: }
24//RELOC: Relocations [
25//RELOC-NEXT: Section (4) .rela.dyn {
26//RELOC-NEXT: 0x2020B0 R_X86_64_TPOFF64 tlsshared0 0x0
27//RELOC-NEXT: 0x2020B8 R_X86_64_TPOFF64 tlsshared1 0x0
28//RELOC-NEXT: }
29//RELOC-NEXT: ]
30
31//0x201009 + (4256 + 7) = 0x2020B0
32//0x201019 + (4248 + 7) = 0x2020B8
33// DISASM: Disassembly of section .text:
34// DISASM-NEXT: _start:
35// DISASM-NEXT: 201000: {{.*}} movq %fs:0, %rax
36// DISASM-NEXT: 201009: {{.*}} addq 4256(%rip), %rax
37// DISASM-NEXT: 201010: {{.*}} movq %fs:0, %rax
38// DISASM-NEXT: 201019: {{.*}} addq 4248(%rip), %rax
39
40.section .text
41.globl _start
42_start:
43 .byte 0x66
44 leaq tlsshared0@tlsgd(%rip),%rdi
45 .word 0x6666
46 rex64
47 call __tls_get_addr@plt
48 .byte 0x66
49 leaq tlsshared1@tlsgd(%rip),%rdi
50 .word 0x6666
51 rex64
52 call __tls_get_addr@plt
deps/lld/test/ELF/tls-opt-gdiele-i686.s created+59
......@@ -0,0 +1,59 @@
1// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %p/Inputs/tls-opt-gdiele-i686.s -o %tso.o
2// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
3// RUN: ld.lld -shared %tso.o -o %tso
4// RUN: ld.lld %t.o %tso -o %tout
5// RUN: llvm-readobj -r %tout | FileCheck --check-prefix=NORELOC %s
6// RUN: llvm-objdump -d %tout | FileCheck --check-prefix=DISASM %s
7
8// NORELOC: Relocations [
9// NORELOC-NEXT: Section ({{.*}}) .rel.dyn {
10// NORELOC-NEXT: 0x12058 R_386_TLS_TPOFF tlsshared0 0x0
11// NORELOC-NEXT: 0x1205C R_386_TLS_TPOFF tlsshared1 0x0
12// NORELOC-NEXT: }
13// NORELOC-NEXT: ]
14
15// DISASM: Disassembly of section .text:
16// DISASM-NEXT: _start:
17// DISASM-NEXT: 11000: 65 a1 00 00 00 00 movl %gs:0, %eax
18// DISASM-NEXT: 11006: 03 83 f8 ff ff ff addl -8(%ebx), %eax
19// DISASM-NEXT: 1100c: 65 a1 00 00 00 00 movl %gs:0, %eax
20// DISASM-NEXT: 11012: 03 83 fc ff ff ff addl -4(%ebx), %eax
21// DISASM-NEXT: 11018: 65 a1 00 00 00 00 movl %gs:0, %eax
22// DISASM-NEXT: 1101e: 81 e8 08 00 00 00 subl $8, %eax
23// DISASM-NEXT: 11024: 65 a1 00 00 00 00 movl %gs:0, %eax
24// DISASM-NEXT: 1102a: 81 e8 04 00 00 00 subl $4, %eax
25
26.type tlsexe1,@object
27.section .tbss,"awT",@nobits
28.globl tlsexe1
29.align 4
30tlsexe1:
31 .long 0
32 .size tlsexe1, 4
33
34.type tlsexe2,@object
35.section .tbss,"awT",@nobits
36.globl tlsexe2
37.align 4
38tlsexe2:
39 .long 0
40 .size tlsexe2, 4
41
42.section .text
43.globl ___tls_get_addr
44.type ___tls_get_addr,@function
45___tls_get_addr:
46
47.section .text
48.globl _start
49_start:
50//GD->IE
51leal tlsshared0@tlsgd(,%ebx,1),%eax
52call ___tls_get_addr@plt
53leal tlsshared1@tlsgd(,%ebx,1),%eax
54call ___tls_get_addr@plt
55//GD->IE
56leal tlsexe1@tlsgd(,%ebx,1),%eax
57call ___tls_get_addr@plt
58leal tlsexe2@tlsgd(,%ebx,1),%eax
59call ___tls_get_addr@plt
deps/lld/test/ELF/tls-opt-i686.s created+69
......@@ -0,0 +1,69 @@
1// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
2// RUN: ld.lld %t.o -o %t1
3// RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=NORELOC %s
4// RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s
5
6// NORELOC: Relocations [
7// NORELOC-NEXT: ]
8
9// DISASM: Disassembly of section .text:
10// DISASM-NEXT: _start:
11// LD -> LE:
12// DISASM-NEXT: 11000: 65 a1 00 00 00 00 movl %gs:0, %eax
13// DISASM-NEXT: 11006: 90 nop
14// DISASM-NEXT: 11007: 8d 74 26 00 leal (%esi), %esi
15// DISASM-NEXT: 1100b: 8d 90 f8 ff ff ff leal -8(%eax), %edx
16// DISASM-NEXT: 11011: 65 a1 00 00 00 00 movl %gs:0, %eax
17// DISASM-NEXT: 11017: 90 nop
18// DISASM-NEXT: 11018: 8d 74 26 00 leal (%esi), %esi
19// DISASM-NEXT: 1101c: 8d 90 fc ff ff ff leal -4(%eax), %edx
20// IE -> LE:
21// 4294967288 == 0xFFFFFFF8
22// 4294967292 == 0xFFFFFFFC
23// DISASM-NEXT: 11022: 65 a1 00 00 00 00 movl %gs:0, %eax
24// DISASM-NEXT: 11028: c7 c0 f8 ff ff ff movl $4294967288, %eax
25// DISASM-NEXT: 1102e: 65 a1 00 00 00 00 movl %gs:0, %eax
26// DISASM-NEXT: 11034: c7 c0 fc ff ff ff movl $4294967292, %eax
27// DISASM-NEXT: 1103a: 65 a1 00 00 00 00 movl %gs:0, %eax
28// DISASM-NEXT: 11040: 8d 80 f8 ff ff ff leal -8(%eax), %eax
29// DISASM-NEXT: 11046: 65 a1 00 00 00 00 movl %gs:0, %eax
30// DISASM-NEXT: 1104c: 8d 80 fc ff ff ff leal -4(%eax), %eax
31.type tls0,@object
32.section .tbss,"awT",@nobits
33.globl tls0
34.align 4
35tls0:
36 .long 0
37 .size tls0, 4
38
39.type tls1,@object
40.globl tls1
41.align 4
42tls1:
43 .long 0
44 .size tls1, 4
45
46.section .text
47.globl ___tls_get_addr
48.type ___tls_get_addr,@function
49___tls_get_addr:
50
51.section .text
52.globl _start
53_start:
54//LD -> LE:
55leal tls0@tlsldm(%ebx),%eax
56call ___tls_get_addr@plt
57leal tls0@dtpoff(%eax),%edx
58leal tls1@tlsldm(%ebx),%eax
59call ___tls_get_addr@plt
60leal tls1@dtpoff(%eax),%edx
61//IE -> LE:
62movl %gs:0,%eax
63movl tls0@gotntpoff(%ebx),%eax
64movl %gs:0,%eax
65movl tls1@gotntpoff(%ebx),%eax
66movl %gs:0,%eax
67addl tls0@gotntpoff(%ebx),%eax
68movl %gs:0,%eax
69addl tls1@gotntpoff(%ebx),%eax
deps/lld/test/ELF/tls-opt-iele-i686-nopic.s created+100
......@@ -0,0 +1,100 @@
1// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
2// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %p/Inputs/tls-opt-iele-i686-nopic.s -o %tso.o
3// RUN: ld.lld -shared %tso.o -o %tso
4// RUN: ld.lld %t.o %tso -o %t1
5// RUN: llvm-readobj -s -r %t1 | FileCheck --check-prefix=GOTREL %s
6// RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s
7
8// GOTREL: Section {
9// GOTREL: Index:
10// GOTREL: Name: .got
11// GOTREL-NEXT: Type: SHT_PROGBITS
12// GOTREL-NEXT: Flags [
13// GOTREL-NEXT: SHF_ALLOC
14// GOTREL-NEXT: SHF_WRITE
15// GOTREL-NEXT: ]
16// GOTREL-NEXT: Address: 0x12058
17// GOTREL-NEXT: Offset: 0x2058
18// GOTREL-NEXT: Size: 8
19// GOTREL-NEXT: Link: 0
20// GOTREL-NEXT: Info: 0
21// GOTREL-NEXT: AddressAlignment: 4
22// GOTREL-NEXT: EntrySize: 0
23// GOTREL-NEXT: }
24// GOTREL: Relocations [
25// GOTREL-NEXT: Section ({{.*}}) .rel.dyn {
26// GOTREL-NEXT: 0x12058 R_386_TLS_TPOFF tlsshared0 0x0
27// GOTREL-NEXT: 0x1205C R_386_TLS_TPOFF tlsshared1 0x0
28// GOTREL-NEXT: }
29// GOTREL-NEXT: ]
30
31// DISASM: Disassembly of section .text:
32// DISASM-NEXT: _start:
33// 4294967288 = 0xFFFFFFF8
34// 4294967292 = 0xFFFFFFFC
35// 73808 = (.got)[0] = 0x12058
36// 73812 = (.got)[1] = 0x1205C
37// DISASM-NEXT: 11000: c7 c1 f8 ff ff ff movl $4294967288, %ecx
38// DISASM-NEXT: 11006: 65 8b 01 movl %gs:(%ecx), %eax
39// DISASM-NEXT: 11009: b8 f8 ff ff ff movl $4294967288, %eax
40// DISASM-NEXT: 1100e: 65 8b 00 movl %gs:(%eax), %eax
41// DISASM-NEXT: 11011: 81 c1 f8 ff ff ff addl $4294967288, %ecx
42// DISASM-NEXT: 11017: 65 8b 01 movl %gs:(%ecx), %eax
43// DISASM-NEXT: 1101a: c7 c1 fc ff ff ff movl $4294967292, %ecx
44// DISASM-NEXT: 11020: 65 8b 01 movl %gs:(%ecx), %eax
45// DISASM-NEXT: 11023: b8 fc ff ff ff movl $4294967292, %eax
46// DISASM-NEXT: 11028: 65 8b 00 movl %gs:(%eax), %eax
47// DISASM-NEXT: 1102b: 81 c1 fc ff ff ff addl $4294967292, %ecx
48// DISASM-NEXT: 11031: 65 8b 01 movl %gs:(%ecx), %eax
49// DISASM-NEXT: 11034: 8b 0d 58 20 01 00 movl 73816, %ecx
50// DISASM-NEXT: 1103a: 65 8b 01 movl %gs:(%ecx), %eax
51// DISASM-NEXT: 1103d: 03 0d 5c 20 01 00 addl 73820, %ecx
52// DISASM-NEXT: 11043: 65 8b 01 movl %gs:(%ecx), %eax
53
54.type tlslocal0,@object
55.section .tbss,"awT",@nobits
56.globl tlslocal0
57.align 4
58tlslocal0:
59 .long 0
60 .size tlslocal0, 4
61
62.type tlslocal1,@object
63.section .tbss,"awT",@nobits
64.globl tlslocal1
65.align 4
66tlslocal1:
67 .long 0
68 .size tlslocal1, 4
69
70.section .text
71.globl ___tls_get_addr
72.type ___tls_get_addr,@function
73___tls_get_addr:
74
75.section .text
76.globl _start
77_start:
78movl tlslocal0@indntpoff,%ecx
79movl %gs:(%ecx),%eax
80
81movl tlslocal0@indntpoff,%eax
82movl %gs:(%eax),%eax
83
84addl tlslocal0@indntpoff,%ecx
85movl %gs:(%ecx),%eax
86
87movl tlslocal1@indntpoff,%ecx
88movl %gs:(%ecx),%eax
89
90movl tlslocal1@indntpoff,%eax
91movl %gs:(%eax),%eax
92
93addl tlslocal1@indntpoff,%ecx
94movl %gs:(%ecx),%eax
95
96movl tlsshared0@indntpoff,%ecx
97movl %gs:(%ecx),%eax
98
99addl tlsshared1@indntpoff,%ecx
100movl %gs:(%ecx),%eax
deps/lld/test/ELF/tls-opt-local.s created+52
......@@ -0,0 +1,52 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
2// RUN: ld.lld %t.o -o %t1
3// RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=NORELOC %s
4// RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s
5
6// NORELOC: Relocations [
7// NORELOC-NEXT: ]
8
9// DISASM: Disassembly of section .text:
10// DISASM-NEXT: _start:
11// DISASM-NEXT: 201000: 48 c7 c0 f8 ff ff ff movq $-8, %rax
12// DISASM-NEXT: 201007: 49 c7 c7 f8 ff ff ff movq $-8, %r15
13// DISASM-NEXT: 20100e: 48 8d 80 f8 ff ff ff leaq -8(%rax), %rax
14// DISASM-NEXT: 201015: 4d 8d bf f8 ff ff ff leaq -8(%r15), %r15
15// DISASM-NEXT: 20101c: 48 81 c4 f8 ff ff ff addq $-8, %rsp
16// DISASM-NEXT: 201023: 49 81 c4 f8 ff ff ff addq $-8, %r12
17// DISASM-NEXT: 20102a: 48 c7 c0 fc ff ff ff movq $-4, %rax
18// DISASM-NEXT: 201031: 49 c7 c7 fc ff ff ff movq $-4, %r15
19// DISASM-NEXT: 201038: 48 8d 80 fc ff ff ff leaq -4(%rax), %rax
20// DISASM-NEXT: 20103f: 4d 8d bf fc ff ff ff leaq -4(%r15), %r15
21// DISASM-NEXT: 201046: 48 81 c4 fc ff ff ff addq $-4, %rsp
22// DISASM-NEXT: 20104d: 49 81 c4 fc ff ff ff addq $-4, %r12
23
24.section .tbss,"awT",@nobits
25
26.type tls0,@object
27.align 4
28tls0:
29 .long 0
30 .size tls0, 4
31
32.type tls1,@object
33.align 4
34tls1:
35 .long 0
36 .size tls1, 4
37
38.section .text
39.globl _start
40_start:
41 movq tls0@GOTTPOFF(%rip), %rax
42 movq tls0@GOTTPOFF(%rip), %r15
43 addq tls0@GOTTPOFF(%rip), %rax
44 addq tls0@GOTTPOFF(%rip), %r15
45 addq tls0@GOTTPOFF(%rip), %rsp
46 addq tls0@GOTTPOFF(%rip), %r12
47 movq tls1@GOTTPOFF(%rip), %rax
48 movq tls1@GOTTPOFF(%rip), %r15
49 addq tls1@GOTTPOFF(%rip), %rax
50 addq tls1@GOTTPOFF(%rip), %r15
51 addq tls1@GOTTPOFF(%rip), %rsp
52 addq tls1@GOTTPOFF(%rip), %r12
deps/lld/test/ELF/tls-opt-no-plt.s created+34
......@@ -0,0 +1,34 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/tls-opt-gdie.s -o %t2.o
3// RUN: ld.lld %t2.o -o %t2.so -shared
4// RUN: ld.lld %t.o %t2.so -o %t.exe
5// RUN: llvm-readobj -s %t.exe | FileCheck %s
6
7// CHECK-NOT: .plt
8
9 .global _start
10_start:
11 data16
12 leaq foo@TLSGD(%rip), %rdi
13 data16
14 data16
15 rex64
16 callq __tls_get_addr@PLT
17
18 leaq bar@TLSLD(%rip), %rdi
19 callq __tls_get_addr@PLT
20 leaq bar@DTPOFF(%rax), %rax
21
22 .type bar,@object
23 .section .tdata,"awT",@progbits
24 .align 8
25bar:
26 .long 42
27
28
29 .type foo,@object
30 .section .tdata,"awT",@progbits
31 .globl foo
32 .align 8
33foo:
34 .long 42
deps/lld/test/ELF/tls-opt.s created+99
......@@ -0,0 +1,99 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
2// RUN: ld.lld %t.o -o %t1
3// RUN: llvm-readobj -r %t1 | FileCheck --check-prefix=NORELOC %s
4// RUN: llvm-objdump -d %t1 | FileCheck --check-prefix=DISASM %s
5
6// NORELOC: Relocations [
7// NORELOC-NEXT: ]
8
9// DISASM: _start:
10// DISASM-NEXT: 201000: 48 c7 c0 f8 ff ff ff movq $-8, %rax
11// DISASM-NEXT: 201007: 49 c7 c7 f8 ff ff ff movq $-8, %r15
12// DISASM-NEXT: 20100e: 48 8d 80 f8 ff ff ff leaq -8(%rax), %rax
13// DISASM-NEXT: 201015: 4d 8d bf f8 ff ff ff leaq -8(%r15), %r15
14// DISASM-NEXT: 20101c: 48 81 c4 f8 ff ff ff addq $-8, %rsp
15// DISASM-NEXT: 201023: 49 81 c4 f8 ff ff ff addq $-8, %r12
16// DISASM-NEXT: 20102a: 48 c7 c0 fc ff ff ff movq $-4, %rax
17// DISASM-NEXT: 201031: 49 c7 c7 fc ff ff ff movq $-4, %r15
18// DISASM-NEXT: 201038: 48 8d 80 fc ff ff ff leaq -4(%rax), %rax
19// DISASM-NEXT: 20103f: 4d 8d bf fc ff ff ff leaq -4(%r15), %r15
20// DISASM-NEXT: 201046: 48 81 c4 fc ff ff ff addq $-4, %rsp
21// DISASM-NEXT: 20104d: 49 81 c4 fc ff ff ff addq $-4, %r12
22
23// LD to LE:
24// DISASM-NEXT: 201054: 66 66 66 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax
25// DISASM-NEXT: 201060: 48 8d 88 f8 ff ff ff leaq -8(%rax), %rcx
26// DISASM-NEXT: 201067: 66 66 66 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax
27// DISASM-NEXT: 201073: 48 8d 88 fc ff ff ff leaq -4(%rax), %rcx
28
29// GD to LE:
30// DISASM-NEXT: 20107a: 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax
31// DISASM-NEXT: 201083: 48 8d 80 f8 ff ff ff leaq -8(%rax), %rax
32// DISASM-NEXT: 20108a: 64 48 8b 04 25 00 00 00 00 movq %fs:0, %rax
33// DISASM-NEXT: 201093: 48 8d 80 fc ff ff ff leaq -4(%rax), %rax
34
35// LD to LE:
36// DISASM: _DTPOFF64_1:
37// DISASM-NEXT: 20109a: f8 clc
38// DISASM: _DTPOFF64_2:
39// DISASM-NEXT: 2010a3: fc cld
40
41.type tls0,@object
42.section .tbss,"awT",@nobits
43.globl tls0
44.align 4
45tls0:
46 .long 0
47 .size tls0, 4
48
49.type tls1,@object
50.globl tls1
51.align 4
52tls1:
53 .long 0
54 .size tls1, 4
55
56.section .text
57.globl _start
58_start:
59 movq tls0@GOTTPOFF(%rip), %rax
60 movq tls0@GOTTPOFF(%rip), %r15
61 addq tls0@GOTTPOFF(%rip), %rax
62 addq tls0@GOTTPOFF(%rip), %r15
63 addq tls0@GOTTPOFF(%rip), %rsp
64 addq tls0@GOTTPOFF(%rip), %r12
65 movq tls1@GOTTPOFF(%rip), %rax
66 movq tls1@GOTTPOFF(%rip), %r15
67 addq tls1@GOTTPOFF(%rip), %rax
68 addq tls1@GOTTPOFF(%rip), %r15
69 addq tls1@GOTTPOFF(%rip), %rsp
70 addq tls1@GOTTPOFF(%rip), %r12
71
72 // LD to LE
73 leaq tls0@tlsld(%rip), %rdi
74 callq __tls_get_addr@PLT
75 leaq tls0@dtpoff(%rax),%rcx
76 leaq tls1@tlsld(%rip), %rdi
77 callq __tls_get_addr@PLT
78 leaq tls1@dtpoff(%rax),%rcx
79
80 // GD to LE
81 .byte 0x66
82 leaq tls0@tlsgd(%rip),%rdi
83 .word 0x6666
84 rex64
85 call __tls_get_addr@plt
86 .byte 0x66
87 leaq tls1@tlsgd(%rip),%rdi
88 .word 0x6666
89 rex64
90 call __tls_get_addr@plt
91
92 // LD to LE
93_DTPOFF64_1:
94 .quad tls0@DTPOFF
95 nop
96
97_DTPOFF64_2:
98 .quad tls1@DTPOFF
99 nop
deps/lld/test/ELF/tls-relocatable.s created+21
......@@ -0,0 +1,21 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=i686-pc-linux %s -o %t.o
3// RUN: ld.lld %t.o -r -o %tr.o
4// RUN: ld.lld %tr.o -shared -o %t1
5// RUN: llvm-readobj -t %t1 | FileCheck %s
6
7// CHECK: Symbol {
8// CHECK: Name: tls0
9// CHECK-NEXT: Value: 0x0
10// CHECK-NEXT: Size: 0
11// CHECK-NEXT: Binding: Global
12// CHECK-NEXT: Type: TLS
13// CHECK-NEXT: Other: 0
14// CHECK-NEXT: Section: .tdata
15// CHECK-NEXT: }
16
17.type tls0,@object
18.section .tdata,"awT",@progbits
19.globl tls0
20tls0:
21 .long 0
deps/lld/test/ELF/tls-static.s created+14
......@@ -0,0 +1,14 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/shared.s -o %tso
3// RUN: ld.lld -static %t -o %tout
4// RUN: ld.lld %t -o %tout
5// RUN: ld.lld -shared %tso -o %tshared
6// RUN: not ld.lld -static %t %tshared -o %tout 2>&1 | FileCheck %s
7// REQUIRES: x86
8
9.global _start
10_start:
11 call __tls_get_addr
12
13// CHECK: error: undefined symbol: __tls_get_addr
14// CHECK: >>> referenced by {{.*}}:(.text+0x1)
deps/lld/test/ELF/tls-two-relocs.s created+30
......@@ -0,0 +1,30 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3// RUN: ld.lld %t -o %tout -shared
4// RUN: llvm-readobj -r %tout | FileCheck %s
5
6 data16
7 leaq g_tls_s@TLSGD(%rip), %rdi
8 data16
9 data16
10 rex64
11 callq __tls_get_addr@PLT
12
13 data16
14 leaq g_tls_s@TLSGD(%rip), %rdi
15 data16
16 data16
17 rex64
18 callq __tls_get_addr@PLT
19
20// Check that we handle two gd relocations to the same symbol.
21
22// CHECK: Relocations [
23// CHECK-NEXT: Section (4) .rela.dyn {
24// CHECK-NEXT: R_X86_64_DTPMOD64 g_tls_s 0x0
25// CHECK-NEXT: R_X86_64_DTPOFF64 g_tls_s 0x0
26// CHECK-NEXT: }
27// CHECK-NEXT: Section (5) .rela.plt {
28// CHECK-NEXT: R_X86_64_JUMP_SLOT __tls_get_addr 0x0
29// CHECK-NEXT: }
30// CHECK-NEXT: ]
deps/lld/test/ELF/tls-weak-undef.s created+16
......@@ -0,0 +1,16 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: ld.lld %t.o -o %t --gc-sections
4
5// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux \
6// RUN: %p/Inputs/tls-in-archive.s -o %t1.o
7// RUN: llvm-ar cru %t.a %t1.o
8// RUN: ld.lld %t.o %t.a -o %t
9
10// Check that lld doesn't crash because we don't reference
11// the TLS phdr when it's not created.
12 .globl _start
13_start:
14 movq foo@gottpoff(%rip), %rax
15 .section .tbss,"awT",@nobits
16 .weak foo
deps/lld/test/ELF/tls.s created+170
......@@ -0,0 +1,170 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3// RUN: ld.lld %t -o %tout
4// RUN: llvm-readobj -symbols -sections -program-headers %tout | FileCheck %s
5// RUN: llvm-objdump -d %tout | FileCheck %s --check-prefix=DIS
6
7.global _start
8_start:
9 movl %fs:a@tpoff, %eax
10 movl %fs:b@tpoff, %eax
11 movl %fs:c@tpoff, %eax
12 movl %fs:d@tpoff, %eax
13
14 .global a
15 .section .tbss,"awT",@nobits
16a:
17 .long 0
18
19 .global b
20 .section .tdata,"awT",@progbits
21b:
22 .long 1
23
24 .global c
25 .section .thread_bss,"awT",@nobits
26c:
27 .long 0
28
29 .global d
30 .section .thread_data,"awT",@progbits
31d:
32 .long 2
33
34// CHECK: Name: .tdata
35// CHECK-NEXT: Type: SHT_PROGBITS
36// CHECK-NEXT: Flags [
37// CHECK-NEXT: SHF_ALLOC
38// CHECK-NEXT: SHF_TLS
39// CHECK-NEXT: SHF_WRITE
40// CHECK-NEXT: ]
41// CHECK-NEXT: Address: [[TDATA_ADDR:0x.*]]
42// CHECK-NEXT: Offset:
43// CHECK-NEXT: Size: 4
44// CHECK-NEXT: Link:
45// CHECK-NEXT: Info:
46// CHECK-NEXT: AddressAlignment:
47// CHECK-NEXT: EntrySize:
48// CHECK-NEXT: }
49// CHECK-NEXT: Section {
50// CHECK-NEXT: Index:
51// CHECK-NEXT: Name: .thread_data
52// CHECK-NEXT: Type: SHT_PROGBITS
53// CHECK-NEXT: Flags [
54// CHECK-NEXT: SHF_ALLOC
55// CHECK-NEXT: SHF_TLS
56// CHECK-NEXT: SHF_WRITE
57// CHECK-NEXT: ]
58// CHECK-NEXT: Address:
59// CHECK-NEXT: Offset:
60// CHECK-NEXT: Size: 4
61// CHECK-NEXT: Link:
62// CHECK-NEXT: Info:
63// CHECK-NEXT: AddressAlignment:
64// CHECK-NEXT: EntrySize:
65// CHECK-NEXT: }
66// CHECK-NEXT: Section {
67// CHECK-NEXT: Index:
68// CHECK-NEXT: Name: .tbss
69// CHECK-NEXT: Type: SHT_NOBITS
70// CHECK-NEXT: Flags [
71// CHECK-NEXT: SHF_ALLOC
72// CHECK-NEXT: SHF_TLS
73// CHECK-NEXT: SHF_WRITE
74// CHECK-NEXT: ]
75// CHECK-NEXT: Address: [[TBSS_ADDR:0x.*]]
76// CHECK-NEXT: Offset:
77// CHECK-NEXT: Size: 4
78// CHECK-NEXT: Link:
79// CHECK-NEXT: Info:
80// CHECK-NEXT: AddressAlignment:
81// CHECK-NEXT: EntrySize:
82// CHECK-NEXT: }
83// CHECK-NEXT: Section {
84// CHECK-NEXT: Index:
85// CHECK-NEXT: Name: .thread_bss
86// CHECK-NEXT: Type: SHT_NOBITS
87// CHECK-NEXT: Flags [
88// CHECK-NEXT: SHF_ALLOC
89// CHECK-NEXT: SHF_TLS
90// CHECK-NEXT: SHF_WRITE
91// CHECK-NEXT: ]
92
93// 0x20200C = TBSS_ADDR + 4
94
95// CHECK-NEXT: Address: 0x20200C
96// CHECK-NEXT: Offset:
97// CHECK-NEXT: Size: 4
98// CHECK-NEXT: Link:
99// CHECK-NEXT: Info:
100// CHECK-NEXT: AddressAlignment:
101// CHECK-NEXT: EntrySize:
102// CHECK-NEXT: }
103
104// CHECK: Symbols [
105// CHECK: Name: a
106// CHECK-NEXT: Value: 0x8
107// CHECK-NEXT: Size:
108// CHECK-NEXT: Binding: Global
109// CHECK-NEXT: Type: TLS
110// CHECK-NEXT: Other: 0
111// CHECK-NEXT: Section: .tbss
112// CHECK-NEXT: }
113// CHECK-NEXT: Symbol {
114// CHECK-NEXT: Name: b
115// CHECK-NEXT: Value: 0x0
116// CHECK-NEXT: Size:
117// CHECK-NEXT: Binding: Global
118// CHECK-NEXT: Type: TLS
119// CHECK-NEXT: Other: 0
120// CHECK-NEXT: Section: .tdata
121// CHECK-NEXT: }
122// CHECK-NEXT: Symbol {
123// CHECK-NEXT: Name: c
124// CHECK-NEXT: Value: 0xC
125// CHECK-NEXT: Size:
126// CHECK-NEXT: Binding: Global
127// CHECK-NEXT: Type: TLS
128// CHECK-NEXT: Other: 0
129// CHECK-NEXT: Section: .thread_bss
130// CHECK-NEXT: }
131// CHECK-NEXT: Symbol {
132// CHECK-NEXT: Name: d
133// CHECK-NEXT: Value: 0x4
134// CHECK-NEXT: Size:
135// CHECK-NEXT: Binding: Global
136// CHECK-NEXT: Type: TLS
137// CHECK-NEXT: Other: 0
138// CHECK-NEXT: Section: .thread_data
139// CHECK-NEXT: }
140
141// Check that the TLS NOBITS sections weren't added to the R/W PT_LOAD's size.
142
143// CHECK: ProgramHeaders [
144// CHECK: Type: PT_LOAD
145// CHECK: Type: PT_LOAD
146// CHECK: Type: PT_LOAD
147// CHECK: FileSize: 8
148// CHECK-NEXT: MemSize: 8
149// CHECK-NEXT: Flags [
150// CHECK-NEXT: PF_R
151// CHECK-NEXT: PF_W
152// CHECK-NEXT: ]
153// CHECK: Type: PT_TLS
154// CHECK-NEXT: Offset:
155// CHECK-NEXT: VirtualAddress: [[TDATA_ADDR]]
156// CHECK-NEXT: PhysicalAddress: [[TDATA_ADDR]]
157// CHECK-NEXT: FileSize: 8
158// CHECK-NEXT: MemSize: 16
159// CHECK-NEXT: Flags [
160// CHECK-NEXT: PF_R
161// CHECK-NEXT: ]
162// CHECK-NEXT: Alignment:
163// CHECK-NEXT: }
164
165// DIS: Disassembly of section .text:
166// DIS-NEXT: _start:
167// DIS-NEXT: 201000: {{.+}} movl %fs:-8, %eax
168// DIS-NEXT: 201008: {{.+}} movl %fs:-16, %eax
169// DIS-NEXT: 201010: {{.+}} movl %fs:-4, %eax
170// DIS-NEXT: 201018: {{.+}} movl %fs:-12, %eax
deps/lld/test/ELF/trace-ar.s created+21
......@@ -0,0 +1,21 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.foo.o
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/trace-ar1.s -o %t.obj1.o
4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/trace-ar2.s -o %t.obj2.o
5# RUN: llvm-ar rcs %t.boo.a %t.obj1.o %t.obj2.o
6
7## Check how -t works with achieves
8# RUN: ld.lld %t.foo.o %t.boo.a -o %t.out -t 2>&1 | FileCheck %s
9# CHECK: {{.*}}.foo.o
10# CHECK-NEXT: {{.*}}.boo.a({{.*}}.obj1.o)
11# CHECK-NOT: {{.*}}.boo.a({{.*}}.obj2.o)
12
13## Test output with --start-lib
14# RUN: ld.lld %t.foo.o --start-lib %t.obj1.o %t.obj2.o -o %t.out -t 2>&1 | FileCheck --check-prefix=STARTLIB %s
15# STARTLIB: {{.*}}.foo.o
16# STARTLIB-NEXT: {{.*}}.obj1.o
17# STARTLIB-NOT: {{.*}}.obj2.o
18
19.globl _start, _used
20_start:
21 call _used
deps/lld/test/ELF/trace-symbols.s created+78
......@@ -0,0 +1,78 @@
1# Test -y symbol and -trace-symbol=symbol
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
5# RUN: %p/Inputs/trace-symbols-foo-weak.s -o %t1
6# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
7# RUN: %p/Inputs/trace-symbols-foo-strong.s -o %t2
8# RUN: ld.lld -shared %t1 -o %t1.so
9# RUN: ld.lld -shared %t2 -o %t2.so
10# RUN: llvm-ar rcs %t1.a %t1
11# RUN: llvm-ar rcs %t2.a %t2
12
13# RUN: ld.lld -y foo -trace-symbol common -trace-symbol=hsymbol \
14# RUN: %t %t1 %t2 -o %t3 2>&1 | FileCheck -check-prefix=OBJECTRFOO %s
15# OBJECTRFOO: trace-symbols.s.tmp: reference to foo
16
17# RUN: ld.lld -y foo -trace-symbol=common -trace-symbol=hsymbol \
18# RUN: %t %t1 %t2 -o %t3 2>&1 | FileCheck -check-prefix=OBJECTDCOMMON %s
19# OBJECTDCOMMON: trace-symbols.s.tmp1: common definition of common
20
21# RUN: ld.lld -y foo -trace-symbol=common -trace-symbol=hsymbol \
22# RUN: %t %t1 %t2 -o %t3 2>&1 | FileCheck -check-prefix=OBJECTD1FOO %s
23# OBJECTD1FOO: trace-symbols.s.tmp: reference to foo
24# OBJECTD1FOO: trace-symbols.s.tmp1: common definition of common
25# OBJECTD1FOO: trace-symbols.s.tmp1: definition of foo
26# OBJECTD1FOO: trace-symbols.s.tmp2: definition of foo
27
28# RUN: ld.lld -y foo -trace-symbol=common -trace-symbol=hsymbol \
29# RUN: %t %t1 %t2 -o %t3 2>&1 | FileCheck -check-prefix=OBJECTD2FOO %s
30# RUN: ld.lld -y foo -y common --trace-symbol=hsymbol \
31# RUN: %t %t2 %t1 -o %t4 2>&1 | FileCheck -check-prefix=OBJECTD2FOO %s
32# RUN: ld.lld -y foo -y common %t %t1.so %t2 -o %t3 2>&1 | \
33# RUN: FileCheck -check-prefix=OBJECTD2FOO %s
34# RUN: ld.lld -y foo -y common %t %t2 %t1.a -o %t3 2>&1 | \
35# RUN: FileCheck -check-prefix=OBJECTD2FOO %s
36# OBJECTD2FOO: trace-symbols.s.tmp2: definition of foo
37
38# RUN: ld.lld -y foo -y common %t %t1.so %t2 -o %t3 2>&1 | \
39# RUN: FileCheck -check-prefix=SHLIBDCOMMON %s
40# SHLIBDCOMMON: trace-symbols.s.tmp1.so: definition of common
41
42# RUN: ld.lld -y foo -y common %t %t2.so %t1.so -o %t3 2>&1 | \
43# RUN: FileCheck -check-prefix=SHLIBD2FOO %s
44# RUN: ld.lld -y foo %t %t1.a %t2.so -o %t3 | \
45# RUN: FileCheck -check-prefix=NO-SHLIBD2FOO %s
46# SHLIBD2FOO: trace-symbols.s.tmp2.so: definition of foo
47# NO-SHLIBD2FOO-NOT: trace-symbols.s.tmp2.so: definition of foo
48
49# RUN: ld.lld -y foo -y common %t %t2 %t1.a -o %t3 2>&1 | \
50# RUN: FileCheck -check-prefix=ARCHIVEDCOMMON %s
51# ARCHIVEDCOMMON-NOT: trace-symbols.s.tmp1.a(trace-symbols.s.tmp1): definition of \
52# common
53
54# RUN: ld.lld -y foo %t %t1.a %t2.so -o %t3 | \
55# RUN: FileCheck -check-prefix=ARCHIVED1FOO %s
56# ARCHIVED1FOO: trace-symbols.s.tmp1.a(trace-symbols.s.tmp1): definition of foo
57
58# RUN: ld.lld -y foo %t %t1.a %t2.a -o %t3 | \
59# RUN: FileCheck -check-prefix=ARCHIVED2FOO %s
60# ARCHIVED2FOO: trace-symbols.s.tmp2.a(trace-symbols.s.tmp2): definition of foo
61
62# RUN: ld.lld -y bar %t %t1.so %t2.so -o %t3 | \
63# RUN: FileCheck -check-prefix=SHLIBDBAR %s
64# SHLIBDBAR: trace-symbols.s.tmp2.so: definition of bar
65
66# RUN: ld.lld -y foo -y bar %t %t1.so %t2.so -o %t3 | \
67# RUN: FileCheck -check-prefix=SHLIBRBAR %s
68# SHLIBRBAR-NOT: trace-symbols.s.tmp1.so: reference to bar
69
70# RUN: ld.lld -y foo -y bar %t -u bar --start-lib %t1 %t2 --end-lib -o %t3 | \
71# RUN: FileCheck -check-prefix=STARTLIB %s
72# STARTLIB: trace-symbols.s.tmp1: reference to bar
73
74.hidden hsymbol
75.globl _start
76.type _start, @function
77_start:
78call foo
deps/lld/test/ELF/trace.s created+9
......@@ -0,0 +1,9 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.foo.o
3
4## Check -t
5# RUN: ld.lld -shared %t.foo.o -o %t.so -t 2>&1 | FileCheck %s
6# CHECK: {{.*}}.foo.o
7
8## Check --trace alias
9# RUN: ld.lld -shared %t.foo.o -o %t.so -t 2>&1 | FileCheck %s
deps/lld/test/ELF/ttext-tdata-tbss.s created+66
......@@ -0,0 +1,66 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3
4## Show what regular output gives to us.
5# RUN: ld.lld %t.o -o %t1
6# RUN: llvm-readobj --elf-output-style=GNU -l -s %t1 | FileCheck %s
7# CHECK: .rodata PROGBITS 0000000000200158 000158 000008
8# CHECK-NEXT: .text PROGBITS 0000000000201000 001000 000001
9# CHECK-NEXT: .aw PROGBITS 0000000000202000 002000 000008
10# CHECK-NEXT: .data PROGBITS 0000000000202008 002008 000008
11# CHECK-NEXT: .bss NOBITS 0000000000202010 002010 000008
12# CHECK: Type
13# CHECK-NEXT: PHDR
14# CHECK-NEXT: LOAD 0x000000 0x0000000000200000
15
16## With .text at 0 there is no space to allocate the headers.
17# RUN: ld.lld -Ttext 0x0 -Tdata 0x4000 -Tbss 0x8000 %t.o -o %t2
18# RUN: llvm-readobj --elf-output-style=GNU -l -s %t2 | FileCheck %s --check-prefix=USER1
19# USER1: .text PROGBITS 0000000000000000 001000 000001
20# USER1-NEXT: .data PROGBITS 0000000000004000 002000 000008
21# USER1-NEXT: .bss NOBITS 0000000000008000 002008 000008
22# USER1-NEXT: .rodata PROGBITS 0000000000009000 003000 000008
23# USER1-NEXT: .aw PROGBITS 000000000000a000 004000 000008
24# USER1: Type
25# USER1-NEXT: LOAD 0x001000 0x0000000000000000
26
27## With .text at 0x1000 there is space to allocate the headers.
28# RUN: ld.lld -Ttext 0x1000 -Tdata 0x4000 -Tbss 0x8000 %t.o -o %t3
29# RUN: llvm-readobj --elf-output-style=GNU -l -s %t3 | FileCheck %s --check-prefix=USER2
30# USER2: .text PROGBITS 0000000000001000 001000 000001
31# USER2-NEXT: .data PROGBITS 0000000000004000 002000 000008
32# USER2-NEXT: .bss NOBITS 0000000000008000 002008 000008
33# USER2-NEXT: .rodata PROGBITS 0000000000009000 003000 000008
34# USER2-NEXT: .aw PROGBITS 000000000000a000 004000 000008
35# USER2: Type
36# USER2-NEXT: PHDR
37# USER2-NEXT: LOAD 0x000000 0x0000000000000000
38
39## With .text well above 200000 we don't need to change the image base
40# RUN: ld.lld -Ttext 0x201000 %t.o -o %t4
41# RUN: llvm-readobj --elf-output-style=GNU -l -s %t4 | FileCheck %s --check-prefix=USER3
42# USER3: .text PROGBITS 0000000000201000 001000 000001
43# USER3-NEX: .rodata PROGBITS 0000000000202000 002000 000008
44# USER3-NEX: .aw PROGBITS 0000000000203000 003000 000008
45# USER3-NEX: .data PROGBITS 0000000000203008 003008 000008
46# USER3-NEX: .bss NOBITS 0000000000203010 003010 000008
47# USER3: Type
48# USER3-NEXT: PHDR
49# USER3-NEXT: LOAD 0x000000 0x0000000000200000
50
51.text
52.globl _start
53_start:
54 nop
55
56.section .rodata,"a"
57 .quad 0
58
59.section .aw,"aw"
60 .quad 0
61
62.section .data,"aw"
63 .quad 0
64
65.section .bss,"",@nobits
66 .quad 0
deps/lld/test/ELF/undef-shared.s created+22
......@@ -0,0 +1,22 @@
1# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
2# RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s
3
4# CHECK: error: undefined symbol: hidden
5# CHECK: >>> referenced by {{.*}}:(.data+0x0)
6.global hidden
7.hidden hidden
8
9# CHECK: error: undefined symbol: internal
10# CHECK: >>> referenced by {{.*}}:(.data+0x8)
11.global internal
12.internal internal
13
14# CHECK: error: undefined symbol: protected
15# CHECK: >>> referenced by {{.*}}:(.data+0x10)
16.global protected
17.protected protected
18
19.section .data, "a"
20 .quad hidden
21 .quad internal
22 .quad protected
deps/lld/test/ELF/undef-start.s created+3
......@@ -0,0 +1,3 @@
1# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
2# RUN: ld.lld %t -o %t2 2>&1
3# REQUIRES: x86
deps/lld/test/ELF/undef-version-script.s created+40
......@@ -0,0 +1,40 @@
1# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
2# RUN: echo "{ local: *; };" > %t.script
3# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
4# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s
5
6# This does not match gold's behavior because gold does not create undefined
7# symbols in dynsym without an appropriate (e.g. PLT) relocation in the input.
8
9# CHECK: DynamicSymbols [
10# CHECK-NEXT: Symbol {
11# CHECK-NEXT: Name: @
12# CHECK-NEXT: Value: 0x0
13# CHECK-NEXT: Size: 0
14# CHECK-NEXT: Binding: Local (0x0)
15# CHECK-NEXT: Type: None (0x0)
16# CHECK-NEXT: Other: 0
17# CHECK-NEXT: Section: Undefined (0x0)
18# CHECK-NEXT: }
19# CHECK-NEXT: Symbol {
20# CHECK-NEXT: Name: bar@
21# CHECK-NEXT: Value: 0x0
22# CHECK-NEXT: Size: 0
23# CHECK-NEXT: Binding: Weak (0x2)
24# CHECK-NEXT: Type: None (0x0)
25# CHECK-NEXT: Other: 0
26# CHECK-NEXT: Section: Undefined (0x0)
27# CHECK-NEXT: }
28# CHECK-NEXT: Symbol {
29# CHECK-NEXT: Name: foo@
30# CHECK-NEXT: Value: 0x0
31# CHECK-NEXT: Size: 0
32# CHECK-NEXT: Binding: Global (0x1)
33# CHECK-NEXT: Type: None (0x0)
34# CHECK-NEXT: Other: 0
35# CHECK-NEXT: Section: Undefined (0x0)
36# CHECK-NEXT: }
37# CHECK-NEXT: ]
38
39.global foo
40.weak bar
deps/lld/test/ELF/undef-with-plt-addr-i686.s created+23
......@@ -0,0 +1,23 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o
3// RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %p/Inputs/undef-with-plt-addr.s -o %t2.o
4// RUN: ld.lld %t2.o -o %t2.so -shared
5// RUN: ld.lld %t.o %t2.so -o %t3
6// RUN: llvm-readobj -t -s %t3 | FileCheck %s
7
8.globl _start
9_start:
10mov $set_data, %eax
11
12// Test that set_data has an address in the .plt
13
14// CHECK: Name: .plt
15// CHECK-NEXT: Type: SHT_PROGBITS
16// CHECK-NEXT: Flags [
17// CHECK-NEXT: SHF_ALLOC
18// CHECK-NEXT: SHF_EXECINSTR
19// CHECK-NEXT: ]
20// CHECK-NEXT: Address: 0x11010
21
22// CHECK: Name: set_data
23// CHECK-NEXT: Value: 0x11020
deps/lld/test/ELF/undef-with-plt-addr.s created+48
......@@ -0,0 +1,48 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/undef-with-plt-addr.s -o %t2.o
4// RUN: ld.lld %t2.o -o %t2.so -shared
5// RUN: ld.lld %t.o %t2.so -o %t3
6// RUN: llvm-readobj -t -s -r %t3 | FileCheck %s
7
8// Test that -z nocopyreloc doesn't prevent the plt hack.
9// RUN: ld.lld %t.o %t2.so -o %t3 -z nocopyreloc
10
11.globl _start
12_start:
13movabsq $set_data, %rax
14
15.data
16.quad foo
17// Test that set_data has an address in the .plt, but foo is not
18
19// CHECK: Name: .plt
20// CHECK-NEXT: Type: SHT_PROGBITS
21// CHECK-NEXT: Flags [
22// CHECK-NEXT: SHF_ALLOC
23// CHECK-NEXT: SHF_EXECINSTR
24// CHECK-NEXT: ]
25// CHECK-NEXT: Address: 0x201010
26
27// CHECK: Section ({{.*}}) .rela.dyn {
28// CHECK-NEXT: 0x202000 R_X86_64_64 foo 0x0
29// CHECK-NEXT: }
30// CHECK-NEXT: Section ({{.*}}) .rela.plt {
31// CHECK-NEXT: 0x202020 R_X86_64_JUMP_SLOT set_data 0x0
32// CHECK-NEXT: }
33
34// CHECK: Name: foo
35// CHECK-NEXT: Value: 0x0
36// CHECK-NEXT: Size: 0
37// CHECK-NEXT: Binding: Global
38// CHECK-NEXT: Type: Function
39// CHECK-NEXT: Other: 0
40// CHECK-NEXT: Section: Undefined
41
42// CHECK: Name: set_data
43// CHECK-NEXT: Value: 0x201020
44// CHECK-NEXT: Size: 0
45// CHECK-NEXT: Binding: Global
46// CHECK-NEXT: Type: Function
47// CHECK-NEXT: Other: 0
48// CHECK-NEXT: Section: Undefined
deps/lld/test/ELF/undef.s created+47
......@@ -0,0 +1,47 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/undef.s -o %t2.o
4# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/undef-debug.s -o %t3.o
5# RUN: llvm-ar rc %t2.a %t2.o
6# RUN: not ld.lld %t.o %t2.a %t3.o -o %t.exe 2>&1 | FileCheck %s
7# RUN: not ld.lld -pie %t.o %t2.a %t3.o -o %t.exe 2>&1 | FileCheck %s
8
9# CHECK: error: undefined symbol: foo
10# CHECK: >>> referenced by undef.s
11# CHECK: {{.*}}:(.text+0x1)
12
13# CHECK: error: undefined symbol: bar
14# CHECK: >>> referenced by undef.s
15# CHECK: >>> {{.*}}:(.text+0x6)
16
17# CHECK: error: undefined symbol: foo(int)
18# CHECK: >>> referenced by undef.s
19# CHECK: >>> {{.*}}:(.text+0x10)
20
21# CHECK: error: undefined symbol: zed2
22# CHECK: >>> referenced by {{.*}}.o:(.text+0x0) in archive {{.*}}2.a
23
24# CHECK: error: undefined symbol: zed3
25# CHECK: >>> referenced by undef-debug.s:3 (dir{{/|\\}}undef-debug.s:3)
26# CHECK: >>> {{.*}}.o:(.text+0x0)
27
28# CHECK: error: undefined symbol: zed4
29# CHECK: >>> referenced by undef-debug.s:7 (dir{{/|\\}}undef-debug.s:7)
30# CHECK: >>> {{.*}}.o:(.text.1+0x0)
31
32# CHECK: error: undefined symbol: zed5
33# CHECK: >>> referenced by undef-debug.s:11 (dir{{/|\\}}undef-debug.s:11)
34# CHECK: >>> {{.*}}.o:(.text.2+0x0)
35
36# RUN: not ld.lld %t.o %t2.a -o %t.exe -no-demangle 2>&1 | \
37# RUN: FileCheck -check-prefix=NO-DEMANGLE %s
38# NO-DEMANGLE: error: undefined symbol: _Z3fooi
39
40.file "undef.s"
41
42 .globl _start
43_start:
44 call foo
45 call bar
46 call zed1
47 call _Z3fooi
deps/lld/test/ELF/undefined-opt.s created+68
......@@ -0,0 +1,68 @@
1# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
3# RUN: %p/Inputs/abs.s -o %tabs.o
4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
5# RUN: %p/Inputs/shared.s -o %tshared.o
6# RUN: rm -f %tar.a
7# RUN: llvm-ar rcs %tar.a %tabs.o %tshared.o
8# REQUIRES: x86
9
10# Symbols from the archive are not in if not needed
11# RUN: ld.lld -o %t1 %t.o %tar.a
12# RUN: llvm-readobj --symbols %t1 | FileCheck --check-prefix=NO-UNDEFINED %s
13# NO-UNDEFINED: Symbols [
14# NO-UNDEFINED-NOT: Name: abs
15# NO-UNDEFINED-NOT: Name: big
16# NO-UNDEFINED-NOT: Name: bar
17# NO-UNDEFINED-NOT: Name: zed
18# NO-UNDEFINED: ]
19
20# Symbols from the archive are in if needed, but only from the
21# containing object file
22# RUN: ld.lld -o %t2 %t.o %tar.a -u bar
23# RUN: llvm-readobj --symbols %t2 | FileCheck --check-prefix=ONE-UNDEFINED %s
24# ONE-UNDEFINED: Symbols [
25# ONE-UNDEFINED-NOT: Name: abs
26# ONE-UNDEFINED-NOT: Name: big
27# ONE-UNDEFINED: Name: bar
28# ONE-UNDEFINED: Name: zed
29# ONE-UNDEFINED: ]
30
31# Use the option couple of times, both short and long forms
32# RUN: ld.lld -o %t3 %t.o %tar.a -u bar --undefined=abs
33# RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TWO-UNDEFINED %s
34# RUN: ld.lld -o %t3 %t.o %tar.a -u bar --undefined abs
35# RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TWO-UNDEFINED %s
36# TWO-UNDEFINED: Symbols [
37# TWO-UNDEFINED: Name: abs
38# TWO-UNDEFINED: Name: big
39# TWO-UNDEFINED: Name: bar
40# TWO-UNDEFINED: Name: zed
41# TWO-UNDEFINED: ]
42# Now the same logic but linker script is used to set undefines
43# RUN: echo "EXTERN( bar abs )" > %t.script
44# RUN: ld.lld -o %t3 %t.o %tar.a %t.script
45# RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=TWO-UNDEFINED %s
46
47# Added undefined symbol may be left undefined without error, but
48# shouldn't show up in the dynamic table.
49# RUN: ld.lld -shared -o %t4 %t.o %tar.a -u unknown
50# RUN: llvm-readobj --dyn-symbols %t4 | \
51# RUN: FileCheck --check-prefix=UNK-UNDEFINED-SO %s
52# UNK-UNDEFINED-SO: DynamicSymbols [
53# UNK-UNDEFINED-SO-NOT: Name: unknown
54# UNK-UNDEFINED-SO: ]
55
56# Added undefined symbols should appear in the dynamic table if necessary.
57# RUN: ld.lld -shared -o %t5 %t.o -u export
58# RUN: llvm-readobj --dyn-symbols %t5 | \
59# RUN: FileCheck --check-prefix=EXPORT-SO %s
60# EXPORT-SO: DynamicSymbols [
61# EXPORT-SO: Name: export
62# EXPORT-SO: ]
63
64.globl _start
65_start:
66
67.globl export
68export:
deps/lld/test/ELF/undefined-versioned-symbol.s created+74
......@@ -0,0 +1,74 @@
1// REQUIRES: x86
2// RUN: echo ".data; \
3// RUN: .quad \"basename\"; \
4// RUN: .quad \"basename@FBSD_1.0\"; \
5// RUN: .quad \"basename@FBSD_1.1\" " > %t.s
6// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %t.s -o %t.o
7// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t2.o
8// RUN: echo "FBSD_1.0 { local: *; }; FBSD_1.1 { };" > %t2.ver
9// RUN: ld.lld --shared --version-script %t2.ver %t2.o -o %t2.so
10// RUN: echo "LIBPKG_1.3 { };" > %t.ver
11// RUN: ld.lld --shared %t.o --version-script %t.ver %t2.so -o %t.so
12// RUN: llvm-readobj --dyn-symbols -r --expand-relocs %t.so | FileCheck %s
13
14// Test that each relocation points to the correct version.
15
16// CHECK: Section ({{.*}}) .rela.dyn {
17// CHECK-NEXT: Relocation {
18// CHECK-NEXT: Offset: 0x1000
19// CHECK-NEXT: Type: R_X86_64_64 (1)
20// CHECK-NEXT: Symbol: basename (1)
21// CHECK-NEXT: Addend: 0x0
22// CHECK-NEXT: }
23// CHECK-NEXT: Relocation {
24// CHECK-NEXT: Offset: 0x1008
25// CHECK-NEXT: Type: R_X86_64_64 (1)
26// CHECK-NEXT: Symbol: basename (2)
27// CHECK-NEXT: Addend: 0x0
28// CHECK-NEXT: }
29// CHECK-NEXT: Relocation {
30// CHECK-NEXT: Offset: 0x1010
31// CHECK-NEXT: Type: R_X86_64_64 (1)
32// CHECK-NEXT: Symbol: basename (3)
33// CHECK-NEXT: Addend: 0x0
34// CHECK-NEXT: }
35// CHECK-NEXT: }
36
37
38// CHECK: DynamicSymbols [
39// CHECK-NEXT: Symbol {
40// CHECK-NEXT: Name:
41// CHECK-NEXT: Value:
42// CHECK-NEXT: Size:
43// CHECK-NEXT: Binding:
44// CHECK-NEXT: Type:
45// CHECK-NEXT: Other:
46// CHECK-NEXT: Section:
47// CHECK-NEXT: }
48// CHECK-NEXT: Symbol {
49// CHECK-NEXT: Name: basename@FBSD_1.1
50// CHECK-NEXT: Value:
51// CHECK-NEXT: Size:
52// CHECK-NEXT: Binding:
53// CHECK-NEXT: Type:
54// CHECK-NEXT: Other:
55// CHECK-NEXT: Section:
56// CHECK-NEXT: }
57// CHECK-NEXT: Symbol {
58// CHECK-NEXT: Name: basename@FBSD_1.0
59// CHECK-NEXT: Value:
60// CHECK-NEXT: Size:
61// CHECK-NEXT: Binding:
62// CHECK-NEXT: Type:
63// CHECK-NEXT: Other:
64// CHECK-NEXT: Section:
65// CHECK-NEXT: }
66// CHECK-NEXT: Symbol {
67// CHECK-NEXT: Name: basename@FBSD_1.1
68
69
70.global "basename@FBSD_1.0"
71"basename@FBSD_1.0":
72
73.global "basename@@FBSD_1.1"
74"basename@@FBSD_1.1":
deps/lld/test/ELF/unresolved-symbols.s created+65
......@@ -0,0 +1,65 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
3# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/unresolved-symbols.s -o %t2.o
4# RUN: ld.lld -shared %t2.o -o %t.so
5
6## Check that %t2.o contains undefined symbol undef.
7# RUN: not ld.lld %t1.o %t2.o -o %t 2>&1 | \
8# RUN: FileCheck -check-prefix=UNDCHECK %s
9# UNDCHECK: error: undefined symbol: undef
10# UNDCHECK: >>> referenced by {{.*}}2.o:(.text+0x1)
11
12## Error out if unknown option value was set.
13# RUN: not ld.lld %t1.o %t2.o -o %t --unresolved-symbols=xxx 2>&1 | \
14# RUN: FileCheck -check-prefix=ERR1 %s
15# ERR1: unknown --unresolved-symbols value: xxx
16
17## Ignore all should not produce error for symbols from object except
18## case when --no-undefined specified.
19# RUN: ld.lld %t2.o -o %t1_1 --unresolved-symbols=ignore-all
20# RUN: llvm-readobj %t1_1 > /dev/null 2>&1
21# RUN: not ld.lld %t2.o -o %t1_2 --unresolved-symbols=ignore-all --no-undefined 2>&1 | \
22# RUN: FileCheck -check-prefix=ERRUND %s
23# ERRUND: error: undefined symbol: undef
24# ERRUND: >>> referenced by {{.*}}:(.text+0x1)
25
26## Also ignore all should not produce error for symbols from DSOs.
27# RUN: ld.lld %t1.o %t.so -o %t1_3 --unresolved-symbols=ignore-all
28# RUN: llvm-readobj %t1_3 > /dev/null 2>&1
29
30## Ignoring undefines in objects should not produce error for symbol from object.
31# RUN: ld.lld %t1.o %t2.o -o %t2 --unresolved-symbols=ignore-in-object-files
32# RUN: llvm-readobj %t2 > /dev/null 2>&1
33## And still should not should produce for undefines from DSOs.
34# RUN: ld.lld %t1.o %t.so -o %t2_1 --unresolved-symbols=ignore-in-object-files
35# RUN: llvm-readobj %t2 > /dev/null 2>&1
36
37## Ignoring undefines in shared should produce error for symbol from object.
38# RUN: not ld.lld %t2.o -o %t3 --unresolved-symbols=ignore-in-shared-libs 2>&1 | \
39# RUN: FileCheck -check-prefix=ERRUND %s
40## And should not produce errors for symbols from DSO.
41# RUN: ld.lld %t1.o %t.so -o %t3_1 --unresolved-symbols=ignore-in-shared-libs
42# RUN: llvm-readobj %t3_1 > /dev/null 2>&1
43
44## Ignoring undefines in shared libs should not produce error for symbol from object
45## if we are linking DSO.
46# RUN: ld.lld -shared %t1.o -o %t4 --unresolved-symbols=ignore-in-shared-libs
47# RUN: llvm-readobj %t4 > /dev/null 2>&1
48
49## Do not report undefines if linking relocatable.
50# RUN: ld.lld -r %t1.o %t2.o -o %t5 --unresolved-symbols=report-all
51# RUN: llvm-readobj %t5 > /dev/null 2>&1
52
53## report-all is the default one. Check that we do not report
54## undefines from DSO and do report undefines from object. With
55## report-all specified and without.
56# RUN: ld.lld -shared %t1.o %t.so -o %t6 --unresolved-symbols=report-all
57# RUN: llvm-readobj %t6 > /dev/null 2>&1
58# RUN: ld.lld -shared %t1.o %t.so -o %t6_1
59# RUN: llvm-readobj %t6_1 > /dev/null 2>&1
60# RUN: not ld.lld %t2.o -o %t7 --unresolved-symbols=report-all 2>&1 | \
61# RUN: FileCheck -check-prefix=ERRUND %s
62# RUN: not ld.lld %t2.o -o %t7_1 2>&1 | FileCheck -check-prefix=ERRUND %s
63
64.globl _start
65_start:
deps/lld/test/ELF/user_def_init_array_start.s created+10
......@@ -0,0 +1,10 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
2// RUN: ld.lld %t.o -o %t2.so -shared
3// Allow user defined __init_array_start. This is used by musl because of the
4// the bfd linker not handling these properly. We always create them as
5// hidden, musl should not have problems with lld.
6
7 .hidden __init_array_start
8 .globl __init_array_start
9__init_array_start:
10 .zero 8
deps/lld/test/ELF/verdef-defaultver.s created+201
......@@ -0,0 +1,201 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/verdef-defaultver.s -o %t1
4# RUN: echo "V1 { global: a; local: *; };" > %t.script
5# RUN: echo "V2 { global: b; c; } V1;" >> %t.script
6# RUN: ld.lld -shared -soname shared %t1 --version-script %t.script -o %t.so
7# RUN: llvm-readobj -V -dyn-symbols %t.so | FileCheck --check-prefix=DSO %s
8
9# DSO: DynamicSymbols [
10# DSO-NEXT: Symbol {
11# DSO-NEXT: Name: @
12# DSO-NEXT: Value: 0x0
13# DSO-NEXT: Size: 0
14# DSO-NEXT: Binding: Local
15# DSO-NEXT: Type: None
16# DSO-NEXT: Other: 0
17# DSO-NEXT: Section: Undefined
18# DSO-NEXT: }
19# DSO-NEXT: Symbol {
20# DSO-NEXT: Name: a@@V1
21# DSO-NEXT: Value: 0x1000
22# DSO-NEXT: Size: 0
23# DSO-NEXT: Binding: Global
24# DSO-NEXT: Type: Function
25# DSO-NEXT: Other: 0
26# DSO-NEXT: Section: .text
27# DSO-NEXT: }
28# DSO-NEXT: Symbol {
29# DSO-NEXT: Name: b@@V2
30# DSO-NEXT: Value: 0x1002
31# DSO-NEXT: Size: 0
32# DSO-NEXT: Binding: Global
33# DSO-NEXT: Type: Function
34# DSO-NEXT: Other: 0
35# DSO-NEXT: Section: .text
36# DSO-NEXT: }
37# DSO-NEXT: Symbol {
38# DSO-NEXT: Name: b@V1
39# DSO-NEXT: Value: 0x1001
40# DSO-NEXT: Size: 0
41# DSO-NEXT: Binding: Global
42# DSO-NEXT: Type: Function
43# DSO-NEXT: Other: 0
44# DSO-NEXT: Section: .text
45# DSO-NEXT: }
46# DSO-NEXT: Symbol {
47# DSO-NEXT: Name: c@@V2
48# DSO-NEXT: Value: 0x1003
49# DSO-NEXT: Size: 0
50# DSO-NEXT: Binding: Global
51# DSO-NEXT: Type: Function
52# DSO-NEXT: Other: 0
53# DSO-NEXT: Section: .text
54# DSO-NEXT: }
55# DSO-NEXT: ]
56# DSO-NEXT: Version symbols {
57# DSO-NEXT: Section Name: .gnu.version
58# DSO-NEXT: Address: 0x240
59# DSO-NEXT: Offset: 0x240
60# DSO-NEXT: Link: 1
61# DSO-NEXT: Symbols [
62# DSO-NEXT: Symbol {
63# DSO-NEXT: Version: 0
64# DSO-NEXT: Name: @
65# DSO-NEXT: }
66# DSO-NEXT: Symbol {
67# DSO-NEXT: Version: 2
68# DSO-NEXT: Name: a@@V1
69# DSO-NEXT: }
70# DSO-NEXT: Symbol {
71# DSO-NEXT: Version: 3
72# DSO-NEXT: Name: b@@V2
73# DSO-NEXT: }
74# DSO-NEXT: Symbol {
75# DSO-NEXT: Version: 2
76# DSO-NEXT: Name: b@V1
77# DSO-NEXT: }
78# DSO-NEXT: Symbol {
79# DSO-NEXT: Version: 3
80# DSO-NEXT: Name: c@@V2
81# DSO-NEXT: }
82# DSO-NEXT: ]
83# DSO-NEXT: }
84# DSO-NEXT: SHT_GNU_verdef {
85# DSO-NEXT: Definition {
86# DSO-NEXT: Version: 1
87# DSO-NEXT: Flags: Base
88# DSO-NEXT: Index: 1
89# DSO-NEXT: Hash: 127830196
90# DSO-NEXT: Name: shared
91# DSO-NEXT: }
92# DSO-NEXT: Definition {
93# DSO-NEXT: Version: 1
94# DSO-NEXT: Flags: 0x0
95# DSO-NEXT: Index: 2
96# DSO-NEXT: Hash: 1425
97# DSO-NEXT: Name: V1
98# DSO-NEXT: }
99# DSO-NEXT: Definition {
100# DSO-NEXT: Version: 1
101# DSO-NEXT: Flags: 0x0
102# DSO-NEXT: Index: 3
103# DSO-NEXT: Hash: 1426
104# DSO-NEXT: Name: V2
105# DSO-NEXT: }
106# DSO-NEXT: }
107
108## Check that we can link against DSO produced.
109# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t2
110# RUN: ld.lld %t2 %t.so -o %t3
111# RUN: llvm-readobj -V -dyn-symbols %t3 | FileCheck --check-prefix=EXE %s
112
113# EXE: DynamicSymbols [
114# EXE-NEXT: Symbol {
115# EXE-NEXT: Name: @
116# EXE-NEXT: Value: 0x0
117# EXE-NEXT: Size: 0
118# EXE-NEXT: Binding: Local
119# EXE-NEXT: Type: None
120# EXE-NEXT: Other: 0
121# EXE-NEXT: Section: Undefined
122# EXE-NEXT: }
123# EXE-NEXT: Symbol {
124# EXE-NEXT: Name: a@V1
125# EXE-NEXT: Value: 0x201020
126# EXE-NEXT: Size: 0
127# EXE-NEXT: Binding: Global
128# EXE-NEXT: Type: Function
129# EXE-NEXT: Other: 0
130# EXE-NEXT: Section: Undefined
131# EXE-NEXT: }
132# EXE-NEXT: Symbol {
133# EXE-NEXT: Name: b@V2
134# EXE-NEXT: Value: 0x201030
135# EXE-NEXT: Size: 0
136# EXE-NEXT: Binding: Global
137# EXE-NEXT: Type: Function
138# EXE-NEXT: Other: 0
139# EXE-NEXT: Section: Undefined
140# EXE-NEXT: }
141# EXE-NEXT: Symbol {
142# EXE-NEXT: Name: c@V2
143# EXE-NEXT: Value: 0x201040
144# EXE-NEXT: Size: 0
145# EXE-NEXT: Binding: Global
146# EXE-NEXT: Type: Function
147# EXE-NEXT: Other: 0
148# EXE-NEXT: Section: Undefined
149# EXE-NEXT: }
150# EXE-NEXT: ]
151# EXE-NEXT: Version symbols {
152# EXE-NEXT: Section Name: .gnu.version
153# EXE-NEXT: Address: 0x200228
154# EXE-NEXT: Offset: 0x228
155# EXE-NEXT: Link: 1
156# EXE-NEXT: Symbols [
157# EXE-NEXT: Symbol {
158# EXE-NEXT: Version: 0
159# EXE-NEXT: Name: @
160# EXE-NEXT: }
161# EXE-NEXT: Symbol {
162# EXE-NEXT: Version: 2
163# EXE-NEXT: Name: a@V1
164# EXE-NEXT: }
165# EXE-NEXT: Symbol {
166# EXE-NEXT: Version: 3
167# EXE-NEXT: Name: b@V2
168# EXE-NEXT: }
169# EXE-NEXT: Symbol {
170# EXE-NEXT: Version: 3
171# EXE-NEXT: Name: c@V2
172# EXE-NEXT: }
173# EXE-NEXT: ]
174# EXE-NEXT: }
175# EXE-NEXT: SHT_GNU_verdef {
176# EXE-NEXT: }
177# EXE-NEXT: SHT_GNU_verneed {
178# EXE-NEXT: Dependency {
179# EXE-NEXT: Version: 1
180# EXE-NEXT: Count: 2
181# EXE-NEXT: FileName: shared
182# EXE-NEXT: Entry {
183# EXE-NEXT: Hash: 1425
184# EXE-NEXT: Flags: 0x0
185# EXE-NEXT: Index: 2
186# EXE-NEXT: Name: V1
187# EXE-NEXT: }
188# EXE-NEXT: Entry {
189# EXE-NEXT: Hash: 1426
190# EXE-NEXT: Flags: 0x0
191# EXE-NEXT: Index: 3
192# EXE-NEXT: Name: V2
193# EXE-NEXT: }
194# EXE-NEXT: }
195# EXE-NEXT: }
196
197.globl _start
198_start:
199 callq a
200 callq b
201 callq c
deps/lld/test/ELF/verdef-dependency.s created+38
......@@ -0,0 +1,38 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: echo "LIBSAMPLE_1.0 { global: a; local: *; };" > %t.script
4# RUN: echo "LIBSAMPLE_2.0 { global: b; local: *; } LIBSAMPLE_1.0;" >> %t.script
5# RUN: echo "LIBSAMPLE_3.0 { global: c; } LIBSAMPLE_2.0;" >> %t.script
6# RUN: ld.lld --version-script %t.script -shared -soname shared %t.o -o %t.so
7# RUN: llvm-readobj -V -dyn-symbols %t.so | FileCheck --check-prefix=DSO %s
8
9# DSO: SHT_GNU_verdef {
10# DSO-NEXT: Definition {
11# DSO-NEXT: Version: 1
12# DSO-NEXT: Flags: Base
13# DSO-NEXT: Index: 1
14# DSO-NEXT: Hash: 127830196
15# DSO-NEXT: Name: shared
16# DSO-NEXT: }
17# DSO-NEXT: Definition {
18# DSO-NEXT: Version: 1
19# DSO-NEXT: Flags: 0x0
20# DSO-NEXT: Index: 2
21# DSO-NEXT: Hash: 98457184
22# DSO-NEXT: Name: LIBSAMPLE_1.0
23# DSO-NEXT: }
24# DSO-NEXT: Definition {
25# DSO-NEXT: Version: 1
26# DSO-NEXT: Flags: 0x0
27# DSO-NEXT: Index: 3
28# DSO-NEXT: Hash: 98456416
29# DSO-NEXT: Name: LIBSAMPLE_2.0
30# DSO-NEXT: }
31# DSO-NEXT: Definition {
32# DSO-NEXT: Version: 1
33# DSO-NEXT: Flags: 0x0
34# DSO-NEXT: Index: 4
35# DSO-NEXT: Hash: 98456672
36# DSO-NEXT: Name: LIBSAMPLE_3.0
37# DSO-NEXT: }
38# DSO-NEXT: }
deps/lld/test/ELF/verdef.s created+119
......@@ -0,0 +1,119 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: echo "LIBSAMPLE_1.0 { global: a; local: *; };" > %t.script
4# RUN: echo "LIBSAMPLE_2.0 { global: b; local: *; };" >> %t.script
5# RUN: echo "LIBSAMPLE_3.0 { global: c; local: *; };" >> %t.script
6# RUN: ld.lld --version-script %t.script -shared -soname shared %t.o -o %t.so
7# RUN: llvm-readobj -V -dyn-symbols %t.so | FileCheck --check-prefix=DSO %s
8
9# DSO: Version symbols {
10# DSO-NEXT: Section Name: .gnu.version
11# DSO-NEXT: Address: 0x228
12# DSO-NEXT: Offset: 0x228
13# DSO-NEXT: Link: 1
14# DSO-NEXT: Symbols [
15# DSO-NEXT: Symbol {
16# DSO-NEXT: Version: 0
17# DSO-NEXT: Name: @
18# DSO-NEXT: }
19# DSO-NEXT: Symbol {
20# DSO-NEXT: Version: 2
21# DSO-NEXT: Name: a@@LIBSAMPLE_1.0
22# DSO-NEXT: }
23# DSO-NEXT: Symbol {
24# DSO-NEXT: Version: 3
25# DSO-NEXT: Name: b@@LIBSAMPLE_2.0
26# DSO-NEXT: }
27# DSO-NEXT: Symbol {
28# DSO-NEXT: Version: 4
29# DSO-NEXT: Name: c@@LIBSAMPLE_3.0
30# DSO-NEXT: }
31# DSO-NEXT: ]
32# DSO-NEXT: }
33# DSO-NEXT: SHT_GNU_verdef {
34# DSO-NEXT: Definition {
35# DSO-NEXT: Version: 1
36# DSO-NEXT: Flags: Base
37# DSO-NEXT: Index: 1
38# DSO-NEXT: Hash: 127830196
39# DSO-NEXT: Name: shared
40# DSO-NEXT: }
41# DSO-NEXT: Definition {
42# DSO-NEXT: Version: 1
43# DSO-NEXT: Flags: 0x0
44# DSO-NEXT: Index: 2
45# DSO-NEXT: Hash: 98457184
46# DSO-NEXT: Name: LIBSAMPLE_1.0
47# DSO-NEXT: }
48# DSO-NEXT: Definition {
49# DSO-NEXT: Version: 1
50# DSO-NEXT: Flags: 0x0
51# DSO-NEXT: Index: 3
52# DSO-NEXT: Hash: 98456416
53# DSO-NEXT: Name: LIBSAMPLE_2.0
54# DSO-NEXT: }
55# DSO-NEXT: Definition {
56# DSO-NEXT: Version: 1
57# DSO-NEXT: Flags: 0x0
58# DSO-NEXT: Index: 4
59# DSO-NEXT: Hash: 98456672
60# DSO-NEXT: Name: LIBSAMPLE_3.0
61# DSO-NEXT: }
62# DSO-NEXT: }
63# DSO-NEXT: SHT_GNU_verneed {
64# DSO-NEXT: }
65
66## Check that we can link agains DSO we produced.
67# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/verdef.s -o %tmain.o
68# RUN: ld.lld %tmain.o %t.so -o %tout
69# RUN: llvm-readobj -V %tout | FileCheck --check-prefix=MAIN %s
70
71# MAIN: Version symbols {
72# MAIN-NEXT: Section Name: .gnu.version
73# MAIN-NEXT: Address: 0x200228
74# MAIN-NEXT: Offset: 0x228
75# MAIN-NEXT: Link: 1
76# MAIN-NEXT: Symbols [
77# MAIN-NEXT: Symbol {
78# MAIN-NEXT: Version: 0
79# MAIN-NEXT: Name: @
80# MAIN-NEXT: }
81# MAIN-NEXT: Symbol {
82# MAIN-NEXT: Version: 2
83# MAIN-NEXT: Name: a@LIBSAMPLE_1.0
84# MAIN-NEXT: }
85# MAIN-NEXT: Symbol {
86# MAIN-NEXT: Version: 3
87# MAIN-NEXT: Name: b@LIBSAMPLE_2.0
88# MAIN-NEXT: }
89# MAIN-NEXT: Symbol {
90# MAIN-NEXT: Version: 4
91# MAIN-NEXT: Name: c@LIBSAMPLE_3.0
92# MAIN-NEXT: }
93# MAIN-NEXT: ]
94# MAIN-NEXT: }
95# MAIN-NEXT: SHT_GNU_verdef {
96# MAIN-NEXT: }
97
98# RUN: echo "VERSION {" > %t.script
99# RUN: echo "LIBSAMPLE_1.0 { global: a; local: *; };" >> %t.script
100# RUN: echo "LIBSAMPLE_2.0 { global: b; local: *; };" >> %t.script
101# RUN: echo "LIBSAMPLE_3.0 { global: c; local: *; };" >> %t.script
102# RUN: echo "}" >> %t.script
103# RUN: ld.lld --script %t.script -shared -soname shared %t.o -o %t2.so
104# RUN: llvm-readobj -V -dyn-symbols %t2.so | FileCheck --check-prefix=DSO %s
105
106.globl a
107.type a,@function
108a:
109retq
110
111.globl b
112.type b,@function
113b:
114retq
115
116.globl c
117.type c,@function
118c:
119retq
deps/lld/test/ELF/verneed-as-needed-weak.s created+14
......@@ -0,0 +1,14 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: ld.lld %t.o --as-needed %S/Inputs/verneed1.so -o %t
4# RUN: llvm-readobj -V %t | FileCheck %s
5
6# CHECK: SHT_GNU_verneed {
7# CHECK-NEXT: }
8
9.weak f1
10
11.globl _start
12_start:
13.data
14.quad f1
deps/lld/test/ELF/verneed-local.s created+9
......@@ -0,0 +1,9 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: not ld.lld %t.o %S/Inputs/verneed1.so -o %t 2>&1 | FileCheck %s
4
5# CHECK: error: undefined symbol: f3
6# CHECK: >>> referenced by {{.*}}:(.text+0x1)
7.globl _start
8_start:
9call f3
deps/lld/test/ELF/verneed.s created+173
......@@ -0,0 +1,173 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: ld.lld %t.o %S/Inputs/verneed1.so %S/Inputs/verneed2.so -o %t
4# RUN: llvm-readobj -V -sections -section-data -dyn-symbols -dynamic-table %t | FileCheck %s
5
6# CHECK: Section {
7# CHECK: Index: 1
8# CHECK-NEXT: Name: .dynsym
9# CHECK-NEXT: Type: SHT_DYNSYM (0xB)
10# CHECK-NEXT: Flags [ (0x2)
11# CHECK-NEXT: SHF_ALLOC (0x2)
12# CHECK-NEXT: ]
13# CHECK-NEXT: Address: 0x2001C8
14# CHECK-NEXT: Offset: 0x1C8
15# CHECK-NEXT: Size: 96
16# CHECK-NEXT: Link: 5
17# CHECK-NEXT: Info: 1
18# CHECK-NEXT: AddressAlignment: 8
19# CHECK-NEXT: EntrySize: 24
20# CHECK: Section {
21# CHECK-NEXT: Index: 2
22# CHECK-NEXT: Name: .gnu.version
23# CHECK-NEXT: Type: SHT_GNU_versym (0x6FFFFFFF)
24# CHECK-NEXT: Flags [ (0x2)
25# CHECK-NEXT: SHF_ALLOC (0x2)
26# CHECK-NEXT: ]
27# CHECK-NEXT: Address: 0x200228
28# CHECK-NEXT: Offset: 0x228
29# CHECK-NEXT: Size: 8
30# CHECK-NEXT: Link: 1
31# CHECK-NEXT: Info: 0
32# CHECK-NEXT: AddressAlignment: 2
33# CHECK-NEXT: EntrySize: 2
34# CHECK: Section {
35# CHECK-NEXT: Index: 3
36# CHECK-NEXT: Name: .gnu.version_r
37# CHECK-NEXT: Type: SHT_GNU_verneed (0x6FFFFFFE)
38# CHECK-NEXT: Flags [ (0x2)
39# CHECK-NEXT: SHF_ALLOC (0x2)
40# CHECK-NEXT: ]
41# CHECK-NEXT: Address: 0x200230
42# CHECK-NEXT: Offset: 0x230
43# CHECK-NEXT: Size: 80
44# CHECK-NEXT: Link: 5
45# CHECK-NEXT: Info: 2
46# CHECK-NEXT: AddressAlignment: 4
47# CHECK-NEXT: EntrySize: 0
48# CHECK: Section {
49# CHECK: Index: 5
50# CHECK-NEXT: Name: .dynstr
51# CHECK-NEXT: Type: SHT_STRTAB
52# CHECK-NEXT: Flags [ (0x2)
53# CHECK-NEXT: SHF_ALLOC (0x2)
54# CHECK-NEXT: ]
55# CHECK-NEXT: Address: 0x2002A8
56# CHECK-NEXT: Offset: 0x2A8
57# CHECK-NEXT: Size: 47
58# CHECK-NEXT: Link: 0
59# CHECK-NEXT: Info: 0
60# CHECK-NEXT: AddressAlignment: 1
61# CHECK-NEXT: EntrySize: 0
62# CHECK-NEXT: SectionData (
63# CHECK-NEXT: 0000: 00766572 6E656564 312E736F 2E300076 |.verneed1.so.0.v|
64# CHECK-NEXT: 0010: 65726E65 6564322E 736F2E30 00663100 |erneed2.so.0.f1.|
65# CHECK-NEXT: 0020: 76330066 32007632 00673100 763100 |v3.f2.v2.g1.v1.|
66# CHECK-NEXT: )
67# CHECK-NEXT: }
68
69# CHECK: DynamicSymbols [
70# CHECK-NEXT: Symbol {
71# CHECK-NEXT: Name: @
72# CHECK-NEXT: Value: 0x0
73# CHECK-NEXT: Size: 0
74# CHECK-NEXT: Binding: Local (0x0)
75# CHECK-NEXT: Type: None (0x0)
76# CHECK-NEXT: Other: 0
77# CHECK-NEXT: Section: Undefined (0x0)
78# CHECK-NEXT: }
79# CHECK-NEXT: Symbol {
80# CHECK-NEXT: Name: f1@v3
81# CHECK-NEXT: Value: 0x0
82# CHECK-NEXT: Size: 0
83# CHECK-NEXT: Binding: Global (0x1)
84# CHECK-NEXT: Type: None (0x0)
85# CHECK-NEXT: Other: 0
86# CHECK-NEXT: Section: Undefined (0x0)
87# CHECK-NEXT: }
88# CHECK-NEXT: Symbol {
89# CHECK-NEXT: Name: f2@v2
90# CHECK-NEXT: Value: 0x0
91# CHECK-NEXT: Size: 0
92# CHECK-NEXT: Binding: Global (0x1)
93# CHECK-NEXT: Type: None (0x0)
94# CHECK-NEXT: Other: 0
95# CHECK-NEXT: Section: Undefined (0x0)
96# CHECK-NEXT: }
97# CHECK-NEXT: Symbol {
98# CHECK-NEXT: Name: g1@v1
99# CHECK-NEXT: Value: 0x0
100# CHECK-NEXT: Size: 0
101# CHECK-NEXT: Binding: Global (0x1)
102# CHECK-NEXT: Type: None (0x0)
103# CHECK-NEXT: Other: 0
104# CHECK-NEXT: Section: Undefined (0x0)
105# CHECK-NEXT: }
106# CHECK-NEXT: ]
107
108# CHECK: 0x000000006FFFFFF0 VERSYM 0x200228
109# CHECK-NEXT: 0x000000006FFFFFFE VERNEED 0x200230
110# CHECK-NEXT: 0x000000006FFFFFFF VERNEEDNUM 2
111
112# CHECK: Version symbols {
113# CHECK-NEXT: Section Name: .gnu.version
114# CHECK-NEXT: Address: 0x200228
115# CHECK-NEXT: Offset: 0x228
116# CHECK-NEXT: Link: 1
117# CHECK-NEXT: Symbols [
118# CHECK-NEXT: Symbol {
119# CHECK-NEXT: Version: 0
120# CHECK-NEXT: Name: @
121# CHECK-NEXT: }
122# CHECK-NEXT: Symbol {
123# CHECK-NEXT: Version: 2
124# CHECK-NEXT: Name: f1@v3
125# CHECK-NEXT: }
126# CHECK-NEXT: Symbol {
127# CHECK-NEXT: Version: 3
128# CHECK-NEXT: Name: f2@v2
129# CHECK-NEXT: }
130# CHECK-NEXT: Symbol {
131# CHECK-NEXT: Version: 4
132# CHECK-NEXT: Name: g1@v1
133# CHECK-NEXT: }
134# CHECK-NEXT: ]
135# CHECK-NEXT: }
136# CHECK-NEXT: SHT_GNU_verdef {
137# CHECK-NEXT: }
138# CHECK-NEXT: SHT_GNU_verneed {
139# CHECK-NEXT: Dependency {
140# CHECK-NEXT: Version: 1
141# CHECK-NEXT: Count: 2
142# CHECK-NEXT: FileName: verneed1.so.0
143# CHECK-NEXT: Entry {
144# CHECK-NEXT: Hash: 1938
145# CHECK-NEXT: Flags: 0x0
146# CHECK-NEXT: Index: 3
147# CHECK-NEXT: Name: v2
148# CHECK-NEXT: }
149# CHECK-NEXT: Entry {
150# CHECK-NEXT: Hash: 1939
151# CHECK-NEXT: Flags: 0x0
152# CHECK-NEXT: Index: 2
153# CHECK-NEXT: Name: v3
154# CHECK-NEXT: }
155# CHECK-NEXT: }
156# CHECK-NEXT: Dependency {
157# CHECK-NEXT: Version: 1
158# CHECK-NEXT: Count: 1
159# CHECK-NEXT: FileName: verneed2.so.0
160# CHECK-NEXT: Entry {
161# CHECK-NEXT: Hash: 1937
162# CHECK-NEXT: Flags: 0x0
163# CHECK-NEXT: Index: 4
164# CHECK-NEXT: Name: v1
165# CHECK-NEXT: }
166# CHECK-NEXT: }
167# CHECK-NEXT: }
168
169.globl _start
170_start:
171call f1@plt
172call f2@plt
173call g1@plt
deps/lld/test/ELF/version-script-anonymous-local.s created+61
......@@ -0,0 +1,61 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3
4# RUN: echo "{ global: foo; local: bar; };" > %t.script
5# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
6# RUN: llvm-readobj -dyn-symbols -t %t.so | FileCheck %s
7
8# CHECK: Symbols [
9# CHECK: Name: bar
10# CHECK-NEXT: Value:
11# CHECK-NEXT: Size:
12# CHECK-NEXT: Binding: Local
13
14# CHECK: Name: foo
15# CHECK-NEXT: Value:
16# CHECK-NEXT: Size:
17# CHECK-NEXT: Binding: Global
18
19# CHECK: Name: zed
20# CHECK-NEXT: Value:
21# CHECK-NEXT: Size:
22# CHECK-NEXT: Binding: Global
23
24
25# CHECK: DynamicSymbols [
26# CHECK-NEXT: Symbol {
27# CHECK-NEXT: Name:
28# CHECK-NEXT: Value:
29# CHECK-NEXT: Size:
30# CHECK-NEXT: Binding:
31# CHECK-NEXT: Type:
32# CHECK-NEXT: Other:
33# CHECK-NEXT: Section:
34# CHECK-NEXT: }
35# CHECK-NEXT: Symbol {
36# CHECK-NEXT: Name: foo
37# CHECK-NEXT: Value:
38# CHECK-NEXT: Size:
39# CHECK-NEXT: Binding: Global
40# CHECK-NEXT: Type:
41# CHECK-NEXT: Other:
42# CHECK-NEXT: Section:
43# CHECK-NEXT: }
44# CHECK-NEXT: Symbol {
45# CHECK-NEXT: Name: zed
46# CHECK-NEXT: Value:
47# CHECK-NEXT: Size:
48# CHECK-NEXT: Binding: Global
49# CHECK-NEXT: Type:
50# CHECK-NEXT: Other:
51# CHECK-NEXT: Section:
52# CHECK-NEXT: }
53# CHECK-NEXT: ]
54
55
56.global foo
57foo:
58.global bar
59bar:
60.global zed
61zed:
deps/lld/test/ELF/version-script-complex-wildcards.s created+62
......@@ -0,0 +1,62 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
4# RUN: echo "FOO { global: extern \"C++\" { ab[c]*; }; };" > %t.script
5# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
6# RUN: llvm-readobj -V %t.so | FileCheck %s --check-prefix=ABC
7# ABC: Name: _Z3abbi@
8# ABC: Name: _Z3abci@@FOO
9
10# RUN: echo "FOO { global: extern \"C++\" { ab[b]*; }; };" > %t1.script
11# RUN: ld.lld --version-script %t1.script -shared %t.o -o %t1.so
12# RUN: llvm-readobj -V %t1.so | FileCheck %s --check-prefix=ABB
13# ABB: Name: _Z3abbi@@FOO
14# ABB: Name: _Z3abci@
15
16# RUN: echo "FOO { global: extern \"C++\" { ab[a-b]*; }; };" > %t2.script
17# RUN: ld.lld --version-script %t2.script -shared %t.o -o %t2.so
18# RUN: llvm-readobj -V %t2.so | FileCheck %s --check-prefix=ABB
19
20# RUN: echo "FOO { global: extern \"C++\" { ab[a-c]*; }; };" > %t3.script
21# RUN: ld.lld --version-script %t3.script -shared %t.o -o %t3.so
22# RUN: llvm-readobj -V %t3.so | FileCheck %s --check-prefix=ABBABC
23# ABBABC: Name: _Z3abbi@@FOO
24# ABBABC: Name: _Z3abci@@FOO
25
26# RUN: echo "FOO { global: extern \"C++\" { ab[a-bc-d]*; }; };" > %t4.script
27# RUN: ld.lld --version-script %t4.script -shared %t.o -o %t4.so
28# RUN: llvm-readobj -V %t4.so | FileCheck %s --check-prefix=ABBABC
29
30# RUN: echo "FOO { global: extern \"C++\" { ab[a-bd-e]*; }; };" > %t5.script
31# RUN: ld.lld --version-script %t5.script -shared %t.o -o %t5.so
32# RUN: llvm-readobj -V %t5.so | FileCheck %s --check-prefix=ABB
33
34# RUN: echo "FOO { global: extern \"C++\" { ab[^a-c]*; }; };" > %t6.script
35# RUN: ld.lld --version-script %t6.script -shared %t.o -o %t6.so
36# RUN: llvm-readobj -V %t6.so | FileCheck %s --check-prefix=NO
37# NO: Name: _Z3abbi@
38# NO: Name: _Z3abci@
39
40# RUN: echo "FOO { global: extern \"C++\" { ab[^c-z]*; }; };" > %t7.script
41# RUN: ld.lld --version-script %t7.script -shared %t.o -o %t7.so
42# RUN: llvm-readobj -V %t7.so | FileCheck %s --check-prefix=ABB
43
44# RUN: echo "FOO { global: extern \"C++\" { a[x-za-b][a-c]*; }; };" > %t8.script
45# RUN: ld.lld --version-script %t8.script -shared %t.o -o %t8.so
46# RUN: llvm-readobj -V %t8.so | FileCheck %s --check-prefix=ABBABC
47
48# RUN: echo "FOO { global: extern \"C++\" { a[; }; };" > %t9.script
49# RUN: not ld.lld --version-script %t9.script -shared %t.o -o %t9.so 2>&1 \
50# RUN: | FileCheck %s --check-prefix=ERROR
51# ERROR: invalid glob pattern: a[
52
53.text
54.globl _Z3abci
55.type _Z3abci,@function
56_Z3abci:
57retq
58
59.globl _Z3abbi
60.type _Z3abbi,@function
61_Z3abbi:
62retq
deps/lld/test/ELF/version-script-copy-rel.s created+24
......@@ -0,0 +1,24 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/copy-in-shared.s -o %t1.o
3# RUN: echo "FOOVER { global: *; };" > %t.script
4# RUN: ld.lld --version-script %t.script -shared %t1.o -o %t.so
5# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t2.o
6# RUN: ld.lld %t2.o %t.so -o %tout
7# RUN: llvm-readobj -dyn-symbols %tout | FileCheck %s
8
9# CHECK: DynamicSymbols [
10# CHECK: Symbol {
11# CHECK: Name: foo@FOOVER
12# CHECK-NEXT: Value:
13# CHECK-NEXT: Size:
14# CHECK-NEXT: Binding: Global
15# CHECK-NEXT: Type: Object
16# CHECK-NEXT: Other:
17# CHECK-NEXT: Section: .bss.rel.ro
18# CHECK-NEXT: }
19# CHECK-NEXT: ]
20
21.text
22.global _start
23_start:
24movl $0, foo
deps/lld/test/ELF/version-script-err.s created+11
......@@ -0,0 +1,11 @@
1// REQUIRES: x86
2
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
4// RUN: not ld.lld -shared %t.o -o %t.so --version-script %p/Inputs/version-script-err.script 2>&1 | FileCheck %s
5// CHECK: ; expected, but got }
6
7// RUN: echo "\"" > %terr1.script
8// RUN: not ld.lld --version-script %terr1.script -shared %t.o -o %t.so 2>&1 | \
9// RUN: FileCheck -check-prefix=ERR1 %s
10// ERR1: {{.*}}:1: unclosed quote
11// ERR1-NEXT: {{.*}}: unexpected EOF
deps/lld/test/ELF/version-script-extern-exact.s created+30
......@@ -0,0 +1,30 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
4# RUN: echo "FOO { global: extern \"C++\" { \"aaa*\"; }; };" > %t.script
5# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
6# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s --check-prefix=NOMATCH
7
8# NOMATCH: DynamicSymbols [
9# NOMATCH-NOT: _Z3aaaPf@@FOO
10# NOMATCH-NOT: _Z3aaaPi@@FOO
11# NOMATCH: ]
12
13# RUN: echo "FOO { global: extern \"C++\" { \"aaa*\"; aaa*; }; };" > %t2.script
14# RUN: ld.lld --version-script %t2.script -shared %t.o -o %t2.so
15# RUN: llvm-readobj -dyn-symbols %t2.so | FileCheck %s --check-prefix=MATCH
16# MATCH: DynamicSymbols [
17# MATCH: _Z3aaaPf@@FOO
18# MATCH: _Z3aaaPi@@FOO
19# MATCH: ]
20
21.text
22.globl _Z3aaaPi
23.type _Z3aaaPi,@function
24_Z3aaaPi:
25retq
26
27.globl _Z3aaaPf
28.type _Z3aaaPf,@function
29_Z3aaaPf:
30retq
deps/lld/test/ELF/version-script-extern-wildcards-anon.s created+74
......@@ -0,0 +1,74 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
4# RUN: echo '{ \
5# RUN: global: \
6# RUN: _Z3bari; \
7# RUN: extern "C++" { \
8# RUN: "foo(int)"; \
9# RUN: z*; \
10# RUN: std::q*; \
11# RUN: }; \
12# RUN: local: *; \
13# RUN: }; ' > %t.script
14# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
15# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s
16
17# CHECK: DynamicSymbols [
18# CHECK-NEXT: Symbol {
19# CHECK-NEXT: Name:
20# CHECK-NEXT: Value:
21# CHECK-NEXT: Size:
22# CHECK-NEXT: Binding: Local
23# CHECK-NEXT: Type:
24# CHECK-NEXT: Other:
25# CHECK-NEXT: Section:
26# CHECK-NEXT: }
27# CHECK-NEXT: Symbol {
28# CHECK-NEXT: Name: _Z3bari
29# CHECK-NEXT: Value:
30# CHECK-NEXT: Size:
31# CHECK-NEXT: Binding: Global
32# CHECK-NEXT: Type:
33# CHECK-NEXT: Other:
34# CHECK-NEXT: Section:
35# CHECK-NEXT: }
36# CHECK-NEXT: Symbol {
37# CHECK-NEXT: Name: _Z3fooi
38# CHECK-NEXT: Value:
39# CHECK-NEXT: Size:
40# CHECK-NEXT: Binding: Global
41# CHECK-NEXT: Type:
42# CHECK-NEXT: Other:
43# CHECK-NEXT: Section:
44# CHECK-NEXT: }
45# CHECK-NEXT: Symbol {
46# CHECK-NEXT: Name: _Z3zedi
47# CHECK-NEXT: Value:
48# CHECK-NEXT: Size:
49# CHECK-NEXT: Binding: Global
50# CHECK-NEXT: Type:
51# CHECK-NEXT: Other:
52# CHECK-NEXT: Section:
53# CHECK-NEXT: }
54# CHECK-NEXT: Symbol {
55# CHECK-NEXT: Name: _ZSt3qux
56# CHECK-NEXT: Value:
57# CHECK-NEXT: Size:
58# CHECK-NEXT: Binding: Global
59# CHECK-NEXT: Type:
60# CHECK-NEXT: Other:
61# CHECK-NEXT: Section:
62# CHECK-NEXT: }
63# CHECK-NEXT: ]
64
65.global _Z3fooi
66_Z3fooi:
67.global _Z3bari
68_Z3bari:
69.global _Z3zedi
70_Z3zedi:
71.global _Z3bazi
72_Z3bazi:
73.global _ZSt3qux
74_ZSt3qux:
deps/lld/test/ELF/version-script-extern-wildcards.s created+29
......@@ -0,0 +1,29 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
4# RUN: echo "FOO { global: extern \"C++\" { foo*; }; };" > %t.script
5# RUN: echo "BAR { global: extern \"C++\" { zed*; bar; }; };" >> %t.script
6# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
7# RUN: llvm-readobj -V -dyn-symbols %t.so | FileCheck %s
8
9# CHECK: Version symbols {
10# CHECK: Symbols [
11# CHECK: Name: _Z3bari@
12# CHECK: Name: _Z3fooi@@FOO
13# CHECK: Name: _Z3zedi@@BAR
14
15.text
16.globl _Z3fooi
17.type _Z3fooi,@function
18_Z3fooi:
19retq
20
21.globl _Z3bari
22.type _Z3bari,@function
23_Z3bari:
24retq
25
26.globl _Z3zedi
27.type _Z3zedi,@function
28_Z3zedi:
29retq
deps/lld/test/ELF/version-script-extern.s created+126
......@@ -0,0 +1,126 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
4# RUN: echo "LIBSAMPLE_1.0 { global:" > %t.script
5# RUN: echo ' extern "C++" { "foo(int)"; "zed(int)"; "abc::abc()"; };' >> %t.script
6# RUN: echo "};" >> %t.script
7# RUN: echo "LIBSAMPLE_2.0 { global:" >> %t.script
8# RUN: echo ' extern "C" { _Z3bari; };' >> %t.script
9# RUN: echo "};" >> %t.script
10# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
11# RUN: llvm-readobj -V -dyn-symbols %t.so | FileCheck --check-prefix=DSO %s
12
13# DSO: DynamicSymbols [
14# DSO-NEXT: Symbol {
15# DSO-NEXT: Name: @
16# DSO-NEXT: Value: 0x0
17# DSO-NEXT: Size: 0
18# DSO-NEXT: Binding: Local
19# DSO-NEXT: Type: None
20# DSO-NEXT: Other: 0
21# DSO-NEXT: Section: Undefined
22# DSO-NEXT: }
23# DSO-NEXT: Symbol {
24# DSO-NEXT: Name: _Z3bari@@LIBSAMPLE_2.0
25# DSO-NEXT: Value: 0x1001
26# DSO-NEXT: Size: 0
27# DSO-NEXT: Binding: Global
28# DSO-NEXT: Type: Function
29# DSO-NEXT: Other: 0
30# DSO-NEXT: Section: .text
31# DSO-NEXT: }
32# DSO-NEXT: Symbol {
33# DSO-NEXT: Name: _Z3fooi@@LIBSAMPLE_1.0
34# DSO-NEXT: Value: 0x1000
35# DSO-NEXT: Size: 0
36# DSO-NEXT: Binding: Global
37# DSO-NEXT: Type: Function
38# DSO-NEXT: Other: 0
39# DSO-NEXT: Section: .text
40# DSO-NEXT: }
41# DSO-NEXT: Symbol {
42# DSO-NEXT: Name: _Z3zedi@@LIBSAMPLE_1.0
43# DSO-NEXT: Value: 0x1002
44# DSO-NEXT: Size: 0
45# DSO-NEXT: Binding: Global (0x1)
46# DSO-NEXT: Type: Function (0x2)
47# DSO-NEXT: Other: 0
48# DSO-NEXT: Section: .text (0x6)
49# DSO-NEXT: }
50# DSO-NEXT: Symbol {
51# DSO-NEXT: Name: _ZN3abcC1Ev@@LIBSAMPLE_1.0
52# DSO-NEXT: Value: 0x1003
53# DSO-NEXT: Size: 0
54# DSO-NEXT: Binding: Global (0x1)
55# DSO-NEXT: Type: Function (0x2)
56# DSO-NEXT: Other: 0
57# DSO-NEXT: Section: .text (0x6)
58# DSO-NEXT: }
59# DSO-NEXT: Symbol {
60# DSO-NEXT: Name: _ZN3abcC2Ev@@LIBSAMPLE_1.0
61# DSO-NEXT: Value: 0x1004
62# DSO-NEXT: Size: 0
63# DSO-NEXT: Binding: Global (0x1)
64# DSO-NEXT: Type: Function (0x2)
65# DSO-NEXT: Other: 0
66# DSO-NEXT: Section: .text (0x6)
67# DSO-NEXT: }
68# DSO-NEXT: ]
69# DSO-NEXT: Version symbols {
70# DSO-NEXT: Section Name: .gnu.version
71# DSO-NEXT: Address: 0x258
72# DSO-NEXT: Offset: 0x258
73# DSO-NEXT: Link: 1
74# DSO-NEXT: Symbols [
75# DSO-NEXT: Symbol {
76# DSO-NEXT: Version: 0
77# DSO-NEXT: Name: @
78# DSO-NEXT: }
79# DSO-NEXT: Symbol {
80# DSO-NEXT: Version: 3
81# DSO-NEXT: Name: _Z3bari@@LIBSAMPLE_2.0
82# DSO-NEXT: }
83# DSO-NEXT: Symbol {
84# DSO-NEXT: Version: 2
85# DSO-NEXT: Name: _Z3fooi@@LIBSAMPLE_1.0
86# DSO-NEXT: }
87# DSO-NEXT: Symbol {
88# DSO-NEXT: Version: 2
89# DSO-NEXT: Name: _Z3zedi@@LIBSAMPLE_1.0
90# DSO-NEXT: }
91# DSO-NEXT: Symbol {
92# DSO-NEXT: Version: 2
93# DSO-NEXT: Name: _ZN3abcC1Ev@@LIBSAMPLE_1.0
94# DSO-NEXT: }
95# DSO-NEXT: Symbol {
96# DSO-NEXT: Version: 2
97# DSO-NEXT: Name: _ZN3abcC2Ev@@LIBSAMPLE_1.0
98# DSO-NEXT: }
99# DSO-NEXT: ]
100# DSO-NEXT: }
101
102.text
103.globl _Z3fooi
104.type _Z3fooi,@function
105_Z3fooi:
106retq
107
108.globl _Z3bari
109.type _Z3bari,@function
110_Z3bari:
111retq
112
113.globl _Z3zedi
114.type _Z3zedi,@function
115_Z3zedi:
116retq
117
118.globl _ZN3abcC1Ev
119.type _ZN3abcC1Ev,@function
120_ZN3abcC1Ev:
121retq
122
123.globl _ZN3abcC2Ev
124.type _ZN3abcC2Ev,@function
125_ZN3abcC2Ev:
126retq
deps/lld/test/ELF/version-script-glob.s created+72
......@@ -0,0 +1,72 @@
1# REQUIRES: x86
2
3# RUN: echo "{ global: foo*; bar*; local: *; };" > %t.script
4# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
5# RUN: ld.lld -shared --version-script %t.script %t.o -o %t.so
6# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s
7
8 .globl foo1
9foo1:
10
11 .globl bar1
12bar1:
13
14 .globl zed1
15zed1:
16
17 .globl local
18local:
19
20# CHECK: DynamicSymbols [
21# CHECK-NEXT: Symbol {
22# CHECK-NEXT: Name:
23# CHECK-NEXT: Value: 0x0
24# CHECK-NEXT: Size: 0
25# CHECK-NEXT: Binding: Local
26# CHECK-NEXT: Type: None
27# CHECK-NEXT: Other: 0
28# CHECK-NEXT: Section: Undefined
29# CHECK-NEXT: }
30# CHECK-NEXT: Symbol {
31# CHECK-NEXT: Name: bar1
32# CHECK-NEXT: Value: 0x1000
33# CHECK-NEXT: Size: 0
34# CHECK-NEXT: Binding: Global
35# CHECK-NEXT: Type: None
36# CHECK-NEXT: Other: 0
37# CHECK-NEXT: Section: .text
38# CHECK-NEXT: }
39# CHECK-NEXT: Symbol {
40# CHECK-NEXT: Name: foo1
41# CHECK-NEXT: Value: 0x1000
42# CHECK-NEXT: Size: 0
43# CHECK-NEXT: Binding: Global
44# CHECK-NEXT: Type: None
45# CHECK-NEXT: Other: 0
46# CHECK-NEXT: Section: .text
47# CHECK-NEXT: }
48# CHECK-NEXT: ]
49
50# RUN: echo "{ global : local; local: *; };" > %t1.script
51# RUN: ld.lld -shared --version-script %t1.script %t.o -o %t1.so
52
53# LOCAL: DynamicSymbols [
54# LOCAL-NEXT: Symbol {
55# LOCAL-NEXT: Name:
56# LOCAL-NEXT: Value: 0x0
57# LOCAL-NEXT: Size: 0
58# LOCAL-NEXT: Binding: Local
59# LOCAL-NEXT: Type: None
60# LOCAL-NEXT: Other: 0
61# LOCAL-NEXT: Section: Undefined
62# LOCAL-NEXT: }
63# LOCAL-NEXT: Symbol {
64# LOCAL-NEXT: Name: local
65# LOCAL-NEXT: Value: 0x1000
66# LOCAL-NEXT: Size: 0
67# LOCAL-NEXT: Binding: Global
68# LOCAL-NEXT: Type: None
69# LOCAL-NEXT: Other: 0
70# LOCAL-NEXT: Section: .text
71# LOCAL-NEXT: }
72# LOCAL-NEXT: ]
deps/lld/test/ELF/version-script-hide-so-symbol.s created+28
......@@ -0,0 +1,28 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
4# RUN: ld.lld -shared %t.o -o %t2.so
5# RUN: echo "{ local: *; };" > %t.script
6# RUN: ld.lld --version-script %t.script -shared %t.o %t2.so -o %t.so
7# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s
8
9# The symbol foo must be hidden. This matches bfd and gold and is
10# required to make it possible for a c++ library to hide its own
11# operator delete.
12
13# CHECK: DynamicSymbols [
14# CHECK-NEXT: Symbol {
15# CHECK-NEXT: Name: @ (0)
16# CHECK-NEXT: Value: 0x0
17# CHECK-NEXT: Size: 0
18# CHECK-NEXT: Binding: Local
19# CHECK-NEXT: Type: None
20# CHECK-NEXT: Other: 0
21# CHECK-NEXT: Section: Undefined
22# CHECK-NEXT: }
23# CHECK-NEXT: ]
24
25 .global foo
26foo:
27 nop
28
deps/lld/test/ELF/version-script-locals-extern.s created+45
......@@ -0,0 +1,45 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
4# RUN: echo "FOO { local: extern \"C++\" { \"abb(int)\"; }; };" > %t.script
5# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
6# RUN: llvm-readobj -V %t.so | FileCheck %s --check-prefix=ABB
7# ABB: Symbols [
8# ABB-NEXT: Symbol {
9# ABB-NEXT: Version: 0
10# ABB-NEXT: Name: @
11# ABB-NEXT: }
12# ABB-NEXT: Symbol {
13# ABB-NEXT: Version: 1
14# ABB-NEXT: Name: _Z3abci@
15# ABB-NEXT: }
16# ABB-NEXT: ]
17
18# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
19# RUN: echo "FOO { local: extern \"C++\" { abb*; }; };" > %t.script
20# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
21# RUN: llvm-readobj -V %t.so | FileCheck %s --check-prefix=ABB
22
23# RUN: echo "FOO { local: extern \"C++\" { abc*; }; };" > %t.script
24# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
25# RUN: llvm-readobj -V %t.so | FileCheck %s --check-prefix=ABC
26# ABC: Symbols [
27# ABC-NEXT: Symbol {
28# ABC-NEXT: Version: 0
29# ABC-NEXT: Name: @
30# ABC-NEXT: }
31# ABC-NEXT: Symbol {
32# ABC-NEXT: Version: 1
33# ABC-NEXT: Name: _Z3abbi@
34# ABC-NEXT: }
35# ABC-NEXT: ]
36
37.globl _Z3abbi
38.type _Z3abbi,@function
39_Z3abbi:
40retq
41
42.globl _Z3abci
43.type _Z3abci,@function
44_Z3abci:
45retq
deps/lld/test/ELF/version-script-locals.s created+45
......@@ -0,0 +1,45 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3
4# RUN: echo "VERSION_1.0 { local: foo1; };" > %t.script
5# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
6# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck --check-prefix=EXACT %s
7# EXACT: DynamicSymbols [
8# EXACT: _start
9# EXACT-NOT: foo1
10# EXACT: foo2
11# EXACT: foo3
12
13# RUN: echo "VERSION_1.0 { local: foo*; };" > %t.script
14# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
15# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck --check-prefix=WC %s
16# WC: DynamicSymbols [
17# WC: _start
18# WC-NOT: foo1
19# WC-NOT: foo2
20# WC-NOT: foo3
21
22# RUN: echo "VERSION_1.0 { global: *; local: foo*; };" > %t.script
23# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
24# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck --check-prefix=MIX %s
25# MIX: DynamicSymbols [
26# MIX: _start@@VERSION_1.0
27# MIX-NOT: foo1
28# MIX-NOT: foo2
29# MIX-NOT: foo3
30
31.globl foo1
32foo1:
33 ret
34
35.globl foo2
36foo2:
37 ret
38
39.globl foo3
40foo3:
41 ret
42
43.globl _start
44_start:
45 ret
deps/lld/test/ELF/version-script-missing.s created+7
......@@ -0,0 +1,7 @@
1# REQUIRES: x86
2
3# We used to crash if a symbol in a version script was not in the symbol table.
4
5# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
6# RUN: echo "{ foobar; };" > %t.script
7# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
deps/lld/test/ELF/version-script-no-warn.s created+12
......@@ -0,0 +1,12 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
4# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/shared.s -o %t2.o
5# RUN: ld.lld -shared %t2.o -soname shared -o %t2.so
6
7# RUN: echo "foo { global: bar; local: *; };" > %t.script
8# RUN: ld.lld --fatal-warnings --shared --version-script %t.script %t.o %t2.so
9
10.global bar
11bar:
12 nop
deps/lld/test/ELF/version-script-no-warn2.s created+8
......@@ -0,0 +1,8 @@
1# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/version-script-no-warn2.s -o %t1.o
2# RUN: ld.lld %t1.o -o %t1.so -shared
3# RUN: echo "{ global: foo; local: *; };" > %t.script
4# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t2.o
5# RUN: ld.lld -shared --version-script %t.script %t2.o %t1.so -o %t2.so --fatal-warnings
6
7.global foo
8foo:
deps/lld/test/ELF/version-script-noundef.s created+23
......@@ -0,0 +1,23 @@
1# REQUIRES: x86
2
3# RUN: echo "VERSION_1.0 { global: bar; };" > %t.script
4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
5# RUN: not ld.lld --version-script %t.script -shared --no-undefined-version \
6# RUN: %t.o -o %t.so 2>&1 | FileCheck -check-prefix=ERR1 %s
7# ERR1: version script assignment of 'VERSION_1.0' to symbol 'bar' failed: symbol not defined
8
9# RUN: echo "VERSION_1.0 { global: und; };" > %t2.script
10# RUN: not ld.lld --version-script %t2.script -shared --no-undefined-version \
11# RUN: %t.o -o %t.so 2>&1 | FileCheck -check-prefix=ERR2 %s
12# ERR2: version script assignment of 'VERSION_1.0' to symbol 'und' failed: symbol not defined
13
14# RUN: echo "VERSION_1.0 { local: und; };" > %t3.script
15# RUN: not ld.lld --version-script %t3.script -shared --no-undefined-version \
16# RUN: %t.o -o %t.so 2>&1 | FileCheck -check-prefix=ERR3 %s
17# ERR3: version script assignment of 'local' to symbol 'und' failed: symbol not defined
18
19.text
20.globl foo
21.type foo,@function
22foo:
23callq und@PLT
deps/lld/test/ELF/version-script-symver.s created+9
......@@ -0,0 +1,9 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: ld.lld %t.o -o %t
4
5.global _start
6.global bar
7.symver _start, bar@@VERSION
8_start:
9 jmp bar
deps/lld/test/ELF/version-script-symver2.s created+28
......@@ -0,0 +1,28 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: echo "VER1 { global: foo; local: *; }; VER2 { global: foo; }; VER3 { global: foo; };" > %t.map
4# RUN: ld.lld -shared %t.o --version-script %t.map -o %t.so --fatal-warnings
5# RUN: llvm-readobj -V %t.so | FileCheck %s
6
7# CHECK: Symbols [
8# CHECK-NEXT: Symbol {
9# CHECK-NEXT: Version: 0
10# CHECK-NEXT: Name: @
11# CHECK-NEXT: }
12# CHECK-NEXT: Symbol {
13# CHECK-NEXT: Version: 3
14# CHECK-NEXT: Name: foo@@VER2
15# CHECK-NEXT: }
16# CHECK-NEXT: Symbol {
17# CHECK-NEXT: Version: 2
18# CHECK-NEXT: Name: foo@VER1
19# CHECK-NEXT: }
20# CHECK-NEXT: ]
21
22.global bar
23bar:
24.symver bar, foo@VER1
25
26.global zed
27zed:
28.symver zed, foo@@VER2
deps/lld/test/ELF/version-script-twice.s created+14
......@@ -0,0 +1,14 @@
1# REQUIRES: x86
2
3# RUN: echo "FBSD_1.1 {}; FBSD_1.2 {};" > %t.ver
4# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
5# RUN: ld.lld -shared %t.o -o %t.so --version-script=%t.ver
6# RUN: llvm-readobj --dyn-symbols --elf-output-style=GNU %t.so | FileCheck %s
7
8 .weak openat
9openat:
10openat@FBSD_1.1 = openat
11openat@@FBSD_1.2 = openat
12
13# CHECK-DAG: openat@FBSD_1.1
14# CHECK-DAG: openat@@FBSD_1.2
deps/lld/test/ELF/version-script-undef-version.s created+12
......@@ -0,0 +1,12 @@
1# REQUIRES: x86
2
3# Test that we don't error on undefined versions when static linking.
4# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
5# RUN: ld.lld %t.o -o %t
6# RUN: echo "DEFINED { global: *; };" > %t.map
7# RUN: ld.lld %t.o --version-script %t.map -o %t
8
9.global _start
10.global bar
11.symver _start, bar@@UNDEFINED
12_start:
deps/lld/test/ELF/version-script-weak.s created+28
......@@ -0,0 +1,28 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
4# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/version-script-weak.s -o %tmp.o
5# RUN: rm -f %t.a
6# RUN: llvm-ar rcs %t.a %tmp.o
7# RUN: echo "{ local: *; };" > %t.script
8# RUN: ld.lld -shared --version-script %t.script %t.o %t.a -o %t.so
9# RUN: llvm-readobj -dyn-symbols -r %t.so | FileCheck %s
10
11# CHECK: Relocations [
12# CHECK-NEXT: Section ({{.*}}) .rela.plt {
13# CHECK-NEXT: 0x2018 R_X86_64_JUMP_SLOT foo
14# CHECK-NEXT: }
15# CHECK-NEXT: ]
16# CHECK: Symbol {
17# CHECK: Name: foo@
18# CHECK-NEXT: Value: 0x0
19# CHECK-NEXT: Size: 0
20# CHECK-NEXT: Binding: Weak
21# CHECK-NEXT: Type: None
22# CHECK-NEXT: Other: 0
23# CHECK-NEXT: Section: Undefined
24# CHECK-NEXT: }
25
26.text
27 callq foo@PLT
28.weak foo
deps/lld/test/ELF/version-script.s created+226
......@@ -0,0 +1,226 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o
4# RUN: ld.lld -shared %t2.o -soname shared -o %t2.so
5
6# RUN: echo "{ global: foo1; foo3; local: *; };" > %t.script
7# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
8# RUN: ld.lld --version-script %t.script -shared %t.o %t2.so -o %t.so
9# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck --check-prefix=DSO %s
10
11# RUN: echo "# comment" > %t3.script
12# RUN: echo "{ local: *; # comment" >> %t3.script
13# RUN: echo -n "}; # comment" >> %t3.script
14# RUN: ld.lld --version-script %t3.script -shared %t.o %t2.so -o %t3.so
15# RUN: llvm-readobj -dyn-symbols %t3.so | FileCheck --check-prefix=DSO2 %s
16
17## Also check that both "global:" and "global :" forms are accepted
18# RUN: echo "VERSION_1.0 { global : foo1; local : *; };" > %t4.script
19# RUN: echo "VERSION_2.0 { global: foo3; local: *; };" >> %t4.script
20# RUN: ld.lld --version-script %t4.script -shared %t.o %t2.so -o %t4.so
21# RUN: llvm-readobj -dyn-symbols %t4.so | FileCheck --check-prefix=VERDSO %s
22
23# RUN: echo "VERSION_1.0 { global: foo1; local: *; };" > %t5.script
24# RUN: echo "{ global: foo3; local: *; };" >> %t5.script
25# RUN: not ld.lld --version-script %t5.script -shared %t.o %t2.so -o %t5.so 2>&1 | \
26# RUN: FileCheck -check-prefix=ERR1 %s
27# ERR1: anonymous version definition is used in combination with other version definitions
28
29# RUN: echo "{ global: foo1; local: *; };" > %t5.script
30# RUN: echo "VERSION_2.0 { global: foo3; local: *; };" >> %t5.script
31# RUN: not ld.lld --version-script %t5.script -shared %t.o %t2.so -o %t5.so 2>&1 | \
32# RUN: FileCheck -check-prefix=ERR2 %s
33# ERR2: EOF expected, but got VERSION_2.0
34
35# RUN: echo "VERSION_1.0 { global: foo1; local: *; };" > %t6.script
36# RUN: echo "VERSION_2.0 { global: foo1; local: *; };" >> %t6.script
37# RUN: ld.lld --version-script %t6.script -shared %t.o %t2.so -o %t6.so 2>&1 | \
38# RUN: FileCheck -check-prefix=WARN2 %s
39# WARN2: duplicate symbol 'foo1' in version script
40
41# RUN: echo "{ foo1; foo2; };" > %t.list
42# RUN: ld.lld --version-script %t.script --dynamic-list %t.list %t.o %t2.so -o %t2
43# RUN: llvm-readobj %t2 > /dev/null
44
45# DSO: DynamicSymbols [
46# DSO-NEXT: Symbol {
47# DSO-NEXT: Name: @
48# DSO-NEXT: Value: 0x0
49# DSO-NEXT: Size: 0
50# DSO-NEXT: Binding: Local (0x0)
51# DSO-NEXT: Type: None (0x0)
52# DSO-NEXT: Other: 0
53# DSO-NEXT: Section: Undefined (0x0)
54# DSO-NEXT: }
55# DSO-NEXT: Symbol {
56# DSO-NEXT: Name: bar@
57# DSO-NEXT: Value: 0x0
58# DSO-NEXT: Size: 0
59# DSO-NEXT: Binding: Global (0x1)
60# DSO-NEXT: Type: Function (0x2)
61# DSO-NEXT: Other: 0
62# DSO-NEXT: Section: Undefined (0x0)
63# DSO-NEXT: }
64# DSO-NEXT: Symbol {
65# DSO-NEXT: Name: foo1@
66# DSO-NEXT: Value: 0x1000
67# DSO-NEXT: Size: 0
68# DSO-NEXT: Binding: Global (0x1)
69# DSO-NEXT: Type: None (0x0)
70# DSO-NEXT: Other: 0
71# DSO-NEXT: Section: .text
72# DSO-NEXT: }
73# DSO-NEXT: Symbol {
74# DSO-NEXT: Name: foo3@
75# DSO-NEXT: Value: 0x1007
76# DSO-NEXT: Size: 0
77# DSO-NEXT: Binding: Global (0x1)
78# DSO-NEXT: Type: None (0x0)
79# DSO-NEXT: Other: 0
80# DSO-NEXT: Section: .text
81# DSO-NEXT: }
82# DSO-NEXT: ]
83
84# DSO2: DynamicSymbols [
85# DSO2-NEXT: Symbol {
86# DSO2-NEXT: Name: @
87# DSO2-NEXT: Value: 0x0
88# DSO2-NEXT: Size: 0
89# DSO2-NEXT: Binding: Local (0x0)
90# DSO2-NEXT: Type: None (0x0)
91# DSO2-NEXT: Other: 0
92# DSO2-NEXT: Section: Undefined (0x0)
93# DSO2-NEXT: }
94# DSO2-NEXT: Symbol {
95# DSO2-NEXT: Name: bar@
96# DSO2-NEXT: Value: 0x0
97# DSO2-NEXT: Size: 0
98# DSO2-NEXT: Binding: Global (0x1)
99# DSO2-NEXT: Type: Function (0x2)
100# DSO2-NEXT: Other: 0
101# DSO2-NEXT: Section: Undefined (0x0)
102# DSO2-NEXT: }
103# DSO2-NEXT: ]
104
105# VERDSO: DynamicSymbols [
106# VERDSO-NEXT: Symbol {
107# VERDSO-NEXT: Name: @
108# VERDSO-NEXT: Value: 0x0
109# VERDSO-NEXT: Size: 0
110# VERDSO-NEXT: Binding: Local
111# VERDSO-NEXT: Type: None
112# VERDSO-NEXT: Other: 0
113# VERDSO-NEXT: Section: Undefined
114# VERDSO-NEXT: }
115# VERDSO-NEXT: Symbol {
116# VERDSO-NEXT: Name: bar@
117# VERDSO-NEXT: Value: 0x0
118# VERDSO-NEXT: Size: 0
119# VERDSO-NEXT: Binding: Global
120# VERDSO-NEXT: Type: Function
121# VERDSO-NEXT: Other: 0
122# VERDSO-NEXT: Section: Undefined
123# VERDSO-NEXT: }
124# VERDSO-NEXT: Symbol {
125# VERDSO-NEXT: Name: foo1@@VERSION_1.0
126# VERDSO-NEXT: Value: 0x1000
127# VERDSO-NEXT: Size: 0
128# VERDSO-NEXT: Binding: Global
129# VERDSO-NEXT: Type: None
130# VERDSO-NEXT: Other: 0
131# VERDSO-NEXT: Section: .text
132# VERDSO-NEXT: }
133# VERDSO-NEXT: Symbol {
134# VERDSO-NEXT: Name: foo3@@VERSION_2.0
135# VERDSO-NEXT: Value: 0x1007
136# VERDSO-NEXT: Size: 0
137# VERDSO-NEXT: Binding: Global
138# VERDSO-NEXT: Type: None
139# VERDSO-NEXT: Other: 0
140# VERDSO-NEXT: Section: .text
141# VERDSO-NEXT: }
142# VERDSO-NEXT: ]
143
144# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
145# RUN: ld.lld -shared %t.o %t2.so -o %t.so
146# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck --check-prefix=ALL %s
147
148# RUN: echo "{ global: foo1; foo3; };" > %t2.script
149# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
150# RUN: ld.lld --version-script %t2.script -shared %t.o %t2.so -o %t.so
151# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck --check-prefix=ALL %s
152
153# ALL: DynamicSymbols [
154# ALL-NEXT: Symbol {
155# ALL-NEXT: Name: @
156# ALL-NEXT: Value: 0x0
157# ALL-NEXT: Size: 0
158# ALL-NEXT: Binding: Local
159# ALL-NEXT: Type: None
160# ALL-NEXT: Other: 0
161# ALL-NEXT: Section: Undefined
162# ALL-NEXT: }
163# ALL-NEXT: Symbol {
164# ALL-NEXT: Name: _start@
165# ALL-NEXT: Value:
166# ALL-NEXT: Size: 0
167# ALL-NEXT: Binding: Global
168# ALL-NEXT: Type: None
169# ALL-NEXT: Other: 0
170# ALL-NEXT: Section: .text
171# ALL-NEXT: }
172# ALL-NEXT: Symbol {
173# ALL-NEXT: Name: bar@
174# ALL-NEXT: Value:
175# ALL-NEXT: Size: 0
176# ALL-NEXT: Binding: Global
177# ALL-NEXT: Type: Function
178# ALL-NEXT: Other: 0
179# ALL-NEXT: Section: Undefined
180# ALL-NEXT: }
181# ALL-NEXT: Symbol {
182# ALL-NEXT: Name: foo1@
183# ALL-NEXT: Value:
184# ALL-NEXT: Size: 0
185# ALL-NEXT: Binding: Global
186# ALL-NEXT: Type: None
187# ALL-NEXT: Other: 0
188# ALL-NEXT: Section: .text
189# ALL-NEXT: }
190# ALL-NEXT: Symbol {
191# ALL-NEXT: Name: foo2@
192# ALL-NEXT: Value:
193# ALL-NEXT: Size: 0
194# ALL-NEXT: Binding: Global
195# ALL-NEXT: Type: None
196# ALL-NEXT: Other: 0
197# ALL-NEXT: Section: .text
198# ALL-NEXT: }
199# ALL-NEXT: Symbol {
200# ALL-NEXT: Name: foo3@
201# ALL-NEXT: Value:
202# ALL-NEXT: Size: 0
203# ALL-NEXT: Binding: Global
204# ALL-NEXT: Type: None
205# ALL-NEXT: Other: 0
206# ALL-NEXT: Section: .text
207# ALL-NEXT: }
208# ALL-NEXT: ]
209
210.globl foo1
211foo1:
212 call bar@PLT
213 ret
214
215.globl foo2
216foo2:
217 ret
218
219.globl foo3
220foo3:
221 call foo2@PLT
222 ret
223
224.globl _start
225_start:
226 ret
deps/lld/test/ELF/version-symbol-error.s created+12
......@@ -0,0 +1,12 @@
1// REQUIRES: x86
2// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
3// RUN: echo "V1 {};" > %t.script
4// RUN: not ld.lld -shared -version-script=%t.script %t.o -o %t.so 2>&1 \
5// RUN: | FileCheck %s
6
7// CHECK: .o: symbol foo@V2 has undefined version V2
8
9.globl foo@V2
10.text
11foo@V2:
12 ret
deps/lld/test/ELF/version-undef-sym.s created+42
......@@ -0,0 +1,42 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: llvm-readobj --dyn-symbols %p/Inputs/version-undef-sym.so | FileCheck %s
4
5
6// Inputs/version-undef-sym.so consists of the assembly file
7//
8// .global bar
9// bar:
10// .weak abc1
11// .weak abc2
12// .weak abc3
13// .weak abc4
14// .weak abc5
15//
16// linked into a shared library with the version script
17//
18// VER_1 {
19// global:
20// bar;
21// };
22//
23// Assuming we can reproduce the desired property (a few undefined symbols
24// before bar) we should create it with lld itself once it supports that.
25
26
27// Show that the input .so has undefined symbols before bar. That is what would
28// get our version parsing out of sync.
29
30// CHECK: Section: Undefined
31// CHECK: Section: Undefined
32// CHECK: Section: Undefined
33// CHECK: Section: Undefined
34// CHECK: Section: Undefined
35// CHECK: Name: bar
36
37// But now we can successfully find bar.
38// RUN: ld.lld %t.o %p/Inputs/version-undef-sym.so -o %t.exe
39
40 .global _start
41_start:
42 call bar@plt
deps/lld/test/ELF/version-use.s created+9
......@@ -0,0 +1,9 @@
1// REQUIRES: x86
2// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
3// RUN: ld.lld %t.o %p/Inputs/version-use.so -o %t.so -shared -z defs
4// RUN: llvm-readobj -s %t.so | FileCheck %s
5
6
7 call bar@PLT
8
9// CHECK-NOT: SHT_GNU_versym
deps/lld/test/ELF/version-wildcard.test created+108
......@@ -0,0 +1,108 @@
1# REQUIRES: x86
2
3# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
4# RUN: echo "VERSION_1.0 { global: foo*; local: *; };" > %t.script
5# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so
6# RUN: llvm-readobj -dyn-symbols %t.so | FileCheck %s
7
8# CHECK: DynamicSymbols [
9# CHECK-NEXT: Symbol {
10# CHECK-NEXT: Name: @
11# CHECK-NEXT: Value: 0x0
12# CHECK-NEXT: Size: 0
13# CHECK-NEXT: Binding: Local
14# CHECK-NEXT: Type: None
15# CHECK-NEXT: Other: 0
16# CHECK-NEXT: Section: Undefined
17# CHECK-NEXT: }
18# CHECK-NEXT: Symbol {
19# CHECK-NEXT: Name: foo1@@VERSION_1.0
20# CHECK-NEXT: Value: 0x1000
21# CHECK-NEXT: Size: 0
22# CHECK-NEXT: Binding: Global
23# CHECK-NEXT: Type: None
24# CHECK-NEXT: Other: 0
25# CHECK-NEXT: Section: .text
26# CHECK-NEXT: }
27# CHECK-NEXT: Symbol {
28# CHECK-NEXT: Name: foo2@@VERSION_1.0
29# CHECK-NEXT: Value: 0x1001
30# CHECK-NEXT: Size: 0
31# CHECK-NEXT: Binding: Global
32# CHECK-NEXT: Type: None
33# CHECK-NEXT: Other: 0
34# CHECK-NEXT: Section: .text
35# CHECK-NEXT: }
36# CHECK-NEXT: Symbol {
37# CHECK-NEXT: Name: foo3@@VERSION_1.0
38# CHECK-NEXT: Value: 0x1007
39# CHECK-NEXT: Size: 0
40# CHECK-NEXT: Binding: Global
41# CHECK-NEXT: Type: None
42# CHECK-NEXT: Other: 0
43# CHECK-NEXT: Section: .text
44# CHECK-NEXT: }
45# CHECK-NEXT: ]
46
47# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
48# RUN: echo "VERSION_1.0 { global: foo2; local: *; };" > %t2.script
49# RUN: echo "VERSION_2.0 { global: foo*; };" >> %t2.script
50# RUN: ld.lld --version-script %t2.script -shared %t.o -o %t2.so
51# RUN: llvm-readobj -dyn-symbols %t2.so | FileCheck --check-prefix=MIX %s
52
53# MIX: DynamicSymbols [
54# MIX-NEXT: Symbol {
55# MIX-NEXT: Name: @
56# MIX-NEXT: Value: 0x0
57# MIX-NEXT: Size: 0
58# MIX-NEXT: Binding: Local
59# MIX-NEXT: Type: None
60# MIX-NEXT: Other: 0
61# MIX-NEXT: Section: Undefined
62# MIX-NEXT: }
63# MIX-NEXT: Symbol {
64# MIX-NEXT: Name: foo1@@VERSION_2.0
65# MIX-NEXT: Value: 0x1000
66# MIX-NEXT: Size: 0
67# MIX-NEXT: Binding: Global
68# MIX-NEXT: Type: None
69# MIX-NEXT: Other: 0
70# MIX-NEXT: Section: .text
71# MIX-NEXT: }
72# MIX-NEXT: Symbol {
73# MIX-NEXT: Name: foo2@@VERSION_1.0
74# MIX-NEXT: Value: 0x1001
75# MIX-NEXT: Size: 0
76# MIX-NEXT: Binding: Global
77# MIX-NEXT: Type: None
78# MIX-NEXT: Other: 0
79# MIX-NEXT: Section: .text
80# MIX-NEXT: }
81# MIX-NEXT: Symbol {
82# MIX-NEXT: Name: foo3@@VERSION_2.0
83# MIX-NEXT: Value: 0x1007
84# MIX-NEXT: Size: 0
85# MIX-NEXT: Binding: Global
86# MIX-NEXT: Type: None
87# MIX-NEXT: Other: 0
88# MIX-NEXT: Section: .text
89# MIX-NEXT: }
90# MIX-NEXT: ]
91
92.globl foo1
93foo1:
94 ret
95
96.globl foo2
97foo2:
98 call foo1@PLT
99 ret
100
101.globl foo3
102foo3:
103 call foo2@PLT
104 ret
105
106.globl _start
107_start:
108 ret
deps/lld/test/ELF/visibility.s created+129
......@@ -0,0 +1,129 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/visibility.s -o %t2
3// RUN: ld.lld -shared %t %t2 -o %t3
4// RUN: llvm-readobj -t -dyn-symbols %t3 | FileCheck %s
5// REQUIRES: x86
6
7// CHECK: Symbols [
8// CHECK-NEXT: Symbol {
9// CHECK-NEXT: Name:
10// CHECK-NEXT: Value: 0x0
11// CHECK-NEXT: Size: 0
12// CHECK-NEXT: Binding: Local
13// CHECK-NEXT: Type: None
14// CHECK-NEXT: Other: 0
15// CHECK-NEXT: Section: Undefined
16// CHECK-NEXT: }
17// CHECK-NEXT: Symbol {
18// CHECK-NEXT: Name: hidden
19// CHECK-NEXT: Value:
20// CHECK-NEXT: Size: 0
21// CHECK-NEXT: Binding: Local
22// CHECK-NEXT: Type: None
23// CHECK-NEXT: Other [ (0x2)
24// CHECK-NEXT: STV_HIDDEN
25// CHECK-NEXT: ]
26// CHECK-NEXT: Section: .text
27// CHECK-NEXT: }
28// CHECK-NEXT: Symbol {
29// CHECK-NEXT: Name: internal
30// CHECK-NEXT: Value:
31// CHECK-NEXT: Size: 0
32// CHECK-NEXT: Binding: Local
33// CHECK-NEXT: Type: None
34// CHECK-NEXT: Other [ (0x1)
35// CHECK-NEXT: STV_INTERNAL
36// CHECK-NEXT: ]
37// CHECK-NEXT: Section: .text
38// CHECK-NEXT: }
39// CHECK-NEXT: Symbol {
40// CHECK-NEXT: Name: protected_with_hidden
41// CHECK-NEXT: Value:
42// CHECK-NEXT: Size: 0
43// CHECK-NEXT: Binding: Local
44// CHECK-NEXT: Type: None
45// CHECK-NEXT: Other [ (0x2)
46// CHECK-NEXT: STV_HIDDEN
47// CHECK-NEXT: ]
48// CHECK-NEXT: Section: .text
49// CHECK-NEXT: }
50// CHECK-NEXT: Symbol {
51// CHECK-NEXT: Name: _DYNAMIC
52// CHECK-NEXT: Value:
53// CHECK-NEXT: Size: 0
54// CHECK-NEXT: Binding: Local
55// CHECK-NEXT: Type: None
56// CHECK-NEXT: Other [ (0x2)
57// CHECK-NEXT: STV_HIDDEN
58// CHECK-NEXT: ]
59// CHECK-NEXT: Section: .dynamic
60// CHECK-NEXT: }
61// CHECK-NEXT: Symbol {
62// CHECK-NEXT: Name: default
63// CHECK-NEXT: Value:
64// CHECK-NEXT: Size: 0
65// CHECK-NEXT: Binding: Global
66// CHECK-NEXT: Type: None
67// CHECK-NEXT: Other: 0
68// CHECK-NEXT: Section: .text
69// CHECK-NEXT: }
70// CHECK-NEXT: Symbol {
71// CHECK-NEXT: Name: protected
72// CHECK-NEXT: Value:
73// CHECK-NEXT: Size: 0
74// CHECK-NEXT: Binding: Global
75// CHECK-NEXT: Type: None
76// CHECK-NEXT: Other [ (0x3)
77// CHECK-NEXT: STV_PROTECTED
78// CHECK-NEXT: ]
79// CHECK-NEXT: Section: .text
80// CHECK-NEXT: }
81// CHECK-NEXT: ]
82
83// CHECK: DynamicSymbols [
84// CHECK-NEXT: Symbol {
85// CHECK-NEXT: Name: @
86// CHECK-NEXT: Value: 0x0
87// CHECK-NEXT: Size: 0
88// CHECK-NEXT: Binding: Local
89// CHECK-NEXT: Type: None
90// CHECK-NEXT: Other: 0
91// CHECK-NEXT: Section: Undefined
92// CHECK-NEXT: }
93// CHECK-NEXT: Symbol {
94// CHECK-NEXT: Name: default
95// CHECK-NEXT: Value:
96// CHECK-NEXT: Size: 0
97// CHECK-NEXT: Binding: Global
98// CHECK-NEXT: Type: None
99// CHECK-NEXT: Other: 0
100// CHECK-NEXT: Section: .text
101// CHECK-NEXT: }
102// CHECK-NEXT: Symbol {
103// CHECK-NEXT: Name: protected
104// CHECK-NEXT: Value:
105// CHECK-NEXT: Size: 0
106// CHECK-NEXT: Binding: Global
107// CHECK-NEXT: Type: None
108// CHECK-NEXT: Other [ (0x3)
109// CHECK-NEXT: STV_PROTECTED
110// CHECK-NEXT: ]
111// CHECK-NEXT: Section: .text
112// CHECK-NEXT: }
113// CHECK-NEXT: ]
114
115.global default
116default:
117
118.global protected
119protected:
120
121.global hidden
122hidden:
123
124.global internal
125internal:
126
127.global protected_with_hidden
128.protected
129protected_with_hidden:
deps/lld/test/ELF/warn-common.s created+25
......@@ -0,0 +1,25 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
3# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/warn-common.s -o %t2.o
4# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/warn-common2.s -o %t3.o
5
6## Report multiple commons if warn-common is specified
7# RUN: ld.lld --warn-common %t1.o %t2.o -o %t.out 2>&1 | FileCheck %s --check-prefix=WARN
8# WARN: multiple common of arr
9
10## no-warn-common is ignored
11# RUN: ld.lld --no-warn-common %t1.o %t2.o -o %t.out
12# RUN: llvm-readobj %t.out > /dev/null
13
14## Report if common is overridden
15# RUN: ld.lld --warn-common %t1.o %t3.o -o %t.out 2>&1 | FileCheck %s --check-prefix=OVER
16# OVER: common arr is overridden
17
18## Report if common is overridden, but in different order
19# RUN: ld.lld --warn-common %t3.o %t1.o -o %t.out 2>&1 | FileCheck %s --check-prefix=OVER
20
21.globl _start
22_start:
23
24.type arr,@object
25.comm arr,4,4
deps/lld/test/ELF/warn-unresolved-symbols-hidden.s created+14
......@@ -0,0 +1,14 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: not ld.lld -shared %t.o -o %t.so -z defs --warn-unresolved-symbols 2>&1| FileCheck %s
4
5# CHECK: warning: undefined symbol: foo
6# CHECK: error: undefined symbol: bar
7# CHECK: error: undefined symbol: zed
8
9.data
10.quad foo
11.hidden bar
12.quad bar
13.protected zed
14.quad zed
deps/lld/test/ELF/warn-unresolved-symbols.s created+51
......@@ -0,0 +1,51 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
3
4## The link should fail with an undef error by default
5# RUN: not ld.lld %t1.o -o %t3 2>&1 | \
6# RUN: FileCheck -check-prefix=ERRUND %s
7
8## --error-unresolved-symbols should generate an error
9# RUN: not ld.lld %t1.o -o %t4 --error-unresolved-symbols 2>&1 | \
10# RUN: FileCheck -check-prefix=ERRUND %s
11
12## --warn-unresolved-symbols should generate a warning
13# RUN: ld.lld %t1.o -o %t5 --warn-unresolved-symbols 2>&1 | \
14# RUN: FileCheck -check-prefix=WARNUND %s
15
16## Test that the last option wins
17# RUN: ld.lld %t1.o -o %t5 --error-unresolved-symbols --warn-unresolved-symbols 2>&1 | \
18# RUN: FileCheck -check-prefix=WARNUND %s
19# RUN: not ld.lld %t1.o -o %t6 --warn-unresolved-symbols --error-unresolved-symbols 2>&1 | \
20# RUN: FileCheck -check-prefix=ERRUND %s
21
22## Do not report undefines if linking relocatable or shared.
23## And while we're at it, check that we can accept single -
24## variants of these options.
25# RUN: ld.lld -r %t1.o -o %t7 -error-unresolved-symbols 2>&1 | \
26# RUN: FileCheck -allow-empty -check-prefix=NOERR %s
27# RUN: ld.lld -shared %t1.o -o %t8.so --error-unresolved-symbols 2>&1 | \
28# RUN: FileCheck -allow-empty -check-prefix=NOERR %s
29# RUN: ld.lld -r %t1.o -o %t9 -warn-unresolved-symbols 2>&1 | \
30# RUN: FileCheck -allow-empty -check-prefix=NOWARN %s
31# RUN: ld.lld -shared %t1.o -o %t10.so --warn-unresolved-symbols 2>&1 | \
32# RUN: FileCheck -allow-empty -check-prefix=NOWARN %s
33
34# ERRUND: error: undefined symbol: undef
35# ERRUND: >>> referenced by {{.*}}:(.text+0x1)
36
37# WARNUND: warning: undefined symbol: undef
38# WARNUND: >>> referenced by {{.*}}:(.text+0x1)
39
40# NOERR-NOT: error: undefined symbol: undef
41# NOERR-NOT: >>> referenced by {{.*}}:(.text+0x1)
42
43# NOWARN-NOT: warning: undefined symbol: undef
44# NOWARN-NOT: >>> referenced by {{.*}}:(.text+0x1)
45
46.globl _start
47_start:
48
49.globl _shared
50_shared:
51 callq undef@PLT
deps/lld/test/ELF/weak-and-strong-undef.s created+12
......@@ -0,0 +1,12 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
3# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/weak-and-strong-undef.s -o %t2.o
4# RUN: not ld.lld %t1.o %t2.o -o %t 2>&1 | FileCheck %s
5# RUN: not ld.lld %t2.o %t1.o -o %t 2>&1 | FileCheck %s
6
7# CHECK: error: undefined symbol: foo
8
9.long foo
10.globl _start
11_start:
12ret
deps/lld/test/ELF/weak-undef-hidden.s created+29
......@@ -0,0 +1,29 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: ld.lld %t.o -o %t.so -shared
4// RUN: llvm-readobj -r -s -section-data %t.so | FileCheck %s
5
6.data
7.weak g
8.hidden g
9.quad g
10
11// CHECK: Name: .data
12// CHECK-NEXT: Type: SHT_PROGBITS
13// CHECK-NEXT: Flags [
14// CHECK-NEXT: SHF_ALLOC
15// CHECK-NEXT: SHF_WRITE
16// CHECK-NEXT: ]
17// CHECK-NEXT: Address:
18// CHECK-NEXT: Offset:
19// CHECK-NEXT: Size: 8
20// CHECK-NEXT: Link: 0
21// CHECK-NEXT: Info: 0
22// CHECK-NEXT: AddressAlignment: 1
23// CHECK-NEXT: EntrySize: 0
24// CHECK-NEXT: SectionData (
25// CHECK-NEXT: 0000: 00000000 00000000
26// CHECK-NEXT: )
27
28// CHECK: Relocations [
29// CHECK-NEXT: ]
deps/lld/test/ELF/weak-undef-shared.s created+19
......@@ -0,0 +1,19 @@
1// REQUIRES: x86
2// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
3// RUN: llvm-mc %p/Inputs/shared.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux
4// RUN: ld.lld %t2.o -o %t2.so -shared
5// RUN: ld.lld %t.o %t2.so -o %t.exe
6// RUN: llvm-readobj -t %t.exe | FileCheck %s
7
8// CHECK: Name: bar
9// CHECK-NEXT: Value: 0x201020
10// CHECK-NEXT: Size: 0
11// CHECK-NEXT: Binding: Weak
12// CHECK-NEXT: Type: Function
13// CHECK-NEXT: Other: 0
14// CHECK-NEXT: Section: Undefined
15
16.global _start
17_start:
18 .weak bar
19 .quad bar
deps/lld/test/ELF/weak-undef.s created+21
......@@ -0,0 +1,21 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: ld.lld %t.o -o %t -pie
4# RUN: llvm-readobj -dyn-symbols %t | FileCheck %s
5
6# CHECK: DynamicSymbols [
7# CHECK-NEXT: Symbol {
8# CHECK-NEXT: Name: @
9# CHECK-NEXT: Value: 0x0
10# CHECK-NEXT: Size: 0
11# CHECK-NEXT: Binding: Local (0x0)
12# CHECK-NEXT: Type: None (0x0)
13# CHECK-NEXT: Other: 0
14# CHECK-NEXT: Section: Undefined (0x0)
15# CHECK-NEXT: }
16# CHECK-NEXT: ]
17
18.weak foo
19
20.globl _start
21_start:
deps/lld/test/ELF/whole-archive.s created+40
......@@ -0,0 +1,40 @@
1// REQUIRES: x86
2
3// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
4// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
5// RUN: %p/Inputs/whole-archive.s -o %ta.o
6// RUN: rm -f %t.a
7// RUN: llvm-ar rcs %t.a %ta.o
8
9// Should not add symbols from the archive by default as they are not required
10// RUN: ld.lld -o %t3 %t.o %t.a
11// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=NOTADDED %s
12// NOTADDED: Symbols [
13// NOTADDED-NOT: Name: _bar
14// NOTADDED: ]
15
16// Should add symbols from the archive if --whole-archive is used
17// RUN: ld.lld -o %t3 %t.o --whole-archive %t.a
18// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=ADDED %s
19// ADDED: Symbols [
20// ADDED: Name: _bar
21// ADDED: ]
22
23// --no-whole-archive should restore default behaviour
24// RUN: ld.lld -o %t3 %t.o --whole-archive --no-whole-archive %t.a
25// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=NOTADDED %s
26
27// --whole-archive and --no-whole-archive should affect only archives which follow them
28// RUN: ld.lld -o %t3 %t.o %t.a --whole-archive --no-whole-archive
29// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=NOTADDED %s
30// RUN: ld.lld -o %t3 %t.o --whole-archive %t.a --no-whole-archive
31// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=ADDED %s
32
33// --whole-archive should also work with thin archives
34// RUN: rm -f %tthin.a
35// RUN: llvm-ar --format=gnu rcsT %tthin.a %ta.o
36// RUN: ld.lld -o %t3 %t.o --whole-archive %tthin.a
37// RUN: llvm-readobj --symbols %t3 | FileCheck --check-prefix=ADDED %s
38
39.globl _start
40_start:
deps/lld/test/ELF/wrap-dynamic-undef.s created+15
......@@ -0,0 +1,15 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
3# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/wrap-dynamic-undef.s -o %t2.o
4# RUN: ld.lld %t2.o -o %t2.so -shared
5# RUN: ld.lld %t1.o %t2.so -o %t --wrap foo
6# RUN: llvm-readobj -dyn-symbols --elf-output-style=GNU %t | FileCheck %s
7
8# Test that the dynamic relocation uses foo. We used to produce a
9# relocation with __real_foo.
10
11# CHECK: NOTYPE GLOBAL DEFAULT UND foo
12
13.global _start
14_start:
15 callq __real_foo@plt
deps/lld/test/ELF/wrap.s created+31
......@@ -0,0 +1,31 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/wrap.s -o %t2
4
5// RUN: ld.lld -o %t3 %t %t2 -wrap foo -wrap nosuchsym
6// RUN: llvm-objdump -d -print-imm-hex %t3 | FileCheck %s
7// RUN: ld.lld -o %t3 %t %t2 --wrap foo -wrap=nosuchsym
8// RUN: llvm-objdump -d -print-imm-hex %t3 | FileCheck %s
9
10// CHECK: _start:
11// CHECK-NEXT: movl $0x11010, %edx
12// CHECK-NEXT: movl $0x11010, %edx
13// CHECK-NEXT: movl $0x11000, %edx
14
15// This shows an oddity of our implementation. The symbol foo gets
16// mapped to __wrap_foo, but stays in the symbol table. This results
17// in it showing up twice in the output.
18
19// RUN: llvm-readobj -t -s %t3 | FileCheck -check-prefix=SYM %s
20// SYM: Name: foo
21// SYM-NEXT: Value: 0x11000
22// SYM: Name: __wrap_foo
23// SYM-NEXT: Value: 0x11010
24// SYM: Name: __wrap_foo
25// SYM-NEXT: Value: 0x11010
26
27.global _start
28_start:
29 movl $foo, %edx
30 movl $__wrap_foo, %edx
31 movl $__real_foo, %edx
deps/lld/test/ELF/writable-merge.s created+7
......@@ -0,0 +1,7 @@
1// REQUIRES: x86
2// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
3// RUN: not ld.lld %t.o -o %t 2>&1 | FileCheck %s
4// CHECK: writable SHF_MERGE section is not supported
5
6.section .foo,"awM",@progbits,4
7.quad 0
deps/lld/test/ELF/x86-64-dyn-rel-error.s created+12
......@@ -0,0 +1,12 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/shared.s -o %t2.o
4// RUN: ld.lld %t2.o -shared -o %t2.so
5// RUN: not ld.lld %t.o %t2.so -o %t 2>&1 | FileCheck %s
6
7 .global _start
8_start:
9 .data
10 .long bar
11
12// CHECK: relocation R_X86_64_32 cannot be used against shared object; recompile with -fPIC
deps/lld/test/ELF/x86-64-dyn-rel-error2.s created+14
......@@ -0,0 +1,14 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/shared.s -o %t2.o
4// RUN: ld.lld %t2.o -shared -o %t2.so
5// RUN: not ld.lld %t.o %t2.so -o %t 2>&1 | FileCheck %s
6
7// CHECK: relocation R_X86_64_PC32 cannot be used against shared object; recompile with -fPIC
8// CHECK: >>> defined in {{.*}}.so
9// CHECK: >>> referenced by {{.*}}.o:(.data+0x0)
10
11 .global _start
12_start:
13 .data
14 .long bar - .
deps/lld/test/ELF/x86-64-rela.s created+11
......@@ -0,0 +1,11 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3// RUN: ld.lld %t.o -o %t.so -shared
4// RUN: llvm-readobj -dynamic-table %t.so | FileCheck %s
5// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux-gnux32 %s -o %t.o
6// RUN: ld.lld %t.o -o %t.so -shared
7// RUN: llvm-readobj -dynamic-table %t.so | FileCheck %s
8
9 call foo@plt
10
11// CHECK: 0x{{0+}}14 PLTREL{{ +}}RELA
deps/lld/test/ELF/x86-64-relax-got-abs.s created+16
......@@ -0,0 +1,16 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -relax-relocations -triple=x86_64-pc-linux %s \
3// RUN: -o %t.o
4// RUN: ld.lld %t.o -o %t.so -shared
5// RUN: llvm-objdump -d %t.so | FileCheck %s
6
7// We used to fail trying to relax this into a pc relocation to an absolute
8// value.
9
10// CHECK: movq 4185(%rip), %rax
11
12 movq bar@GOTPCREL(%rip), %rax
13 .data
14 .global bar
15 .hidden bar
16 bar = 42
deps/lld/test/ELF/x86-64-relax-offset.s created+13
......@@ -0,0 +1,13 @@
1// REQUIRES: x86
2// RUN: llvm-mc -filetype=obj -relax-relocations -triple=x86_64-pc-linux %s \
3// RUN: -o %t.o
4// RUN: llvm-mc -filetype=obj -relax-relocations -triple=x86_64-pc-linux \
5// RUN: %p/Inputs/x86-64-relax-offset.s -o %t2.o
6// RUN: ld.lld %t2.o %t.o -o %t.so -shared
7// RUN: llvm-objdump -d %t.so | FileCheck %s
8
9 mov foo@gotpcrel(%rip), %rax
10 nop
11
12// CHECK: 1004: {{.*}} leaq -11(%rip), %rax
13// CHECK-NEXT: 100b: {{.*}} nop
deps/lld/test/ELF/x86-64-reloc-16.s created+14
......@@ -0,0 +1,14 @@
1// REQUIRES: x86
2
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/x86-64-reloc-16.s -o %t1
4// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/x86-64-reloc-16-error.s -o %t2
5// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
6// RUN: ld.lld -shared %t %t1 -o %t3
7
8// CHECK: Contents of section .text:
9// CHECK-NEXT: 200000 42
10
11// RUN: not ld.lld -shared %t %t2 -o %t4 2>&1 | FileCheck --check-prefix=ERROR %s
12// ERROR: relocation R_X86_64_16 out of range
13
14.short foo
deps/lld/test/ELF/x86-64-reloc-32-fpic.s created+10
......@@ -0,0 +1,10 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s
4
5# CHECK: relocation R_X86_64_32 cannot be used against shared object; recompile with -fPIC
6# CHECK: >>> defined in {{.*}}
7# CHECK: >>> referenced by {{.*}}:(.data+0x0)
8
9.data
10.long _shared
deps/lld/test/ELF/x86-64-reloc-8.s created+14
......@@ -0,0 +1,14 @@
1// REQUIRES: x86
2
3// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/x86-64-reloc-8.s -o %t1
4// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/x86-64-reloc-8-error.s -o %t2
5// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
6// RUN: ld.lld -shared %t %t1 -o %t3
7
8// CHECK: Contents of section .text:
9// CHECK-NEXT: 200000 42
10
11// RUN: not ld.lld -shared %t %t2 -o %t4 2>&1 | FileCheck --check-prefix=ERROR %s
12// ERROR: relocation R_X86_64_8 out of range
13
14.byte foo
deps/lld/test/ELF/x86-64-reloc-error.s created+10
......@@ -0,0 +1,10 @@
1// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %S/Inputs/x86-64-reloc-error.s -o %tabs
2// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t
3// RUN: not ld.lld -shared %tabs %t -o %t2 2>&1 | FileCheck %s
4// REQUIRES: x86
5
6 movl $big, %edx
7 movq $foo - 0x1000000000000, %rdx
8
9# CHECK: {{.*}}:(.text+0x1): relocation R_X86_64_32 out of range
10# CHECK: {{.*}}:(.text+0x8): relocation R_X86_64_32S out of range
deps/lld/test/ELF/x86-64-reloc-pc32-fpic.s created+10
......@@ -0,0 +1,10 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
3# RUN: not ld.lld -shared %t.o -o %t.so 2>&1 | FileCheck %s
4
5# CHECK: relocation R_X86_64_PC32 cannot be used against shared object; recompile with -fPIC
6# CHECK: >>> defined in {{.*}}
7# CHECK: >>> referenced by {{.*}}:(.data+0x1)
8
9.data
10call _shared
deps/lld/test/ELF/x86-64-reloc-range.s created+13
......@@ -0,0 +1,13 @@
1// RUN: llvm-mc %s -o %t.o -triple x86_64-pc-linux -filetype=obj
2// RUN: not ld.lld %t.o -o %t.so -shared 2>&1 | FileCheck %s
3
4// CHECK: {{.*}}:(.text+0x3): relocation R_X86_64_PC32 out of range
5// CHECK-NOT: relocation
6
7 lea foo(%rip), %rax
8 lea foo(%rip), %rax
9
10 .hidden foo
11 .bss
12 .zero 0x7fffe007
13foo:
deps/lld/test/ELF/x86-64-reloc-tpoff32-fpic.s created+14
......@@ -0,0 +1,14 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: not ld.lld %t.o -shared -o %t.so 2>&1 | FileCheck %s
4
5# CHECK: relocation R_X86_64_TPOFF32 cannot be used against shared object; recompile with -fPIC
6# CHECK: >>> defined in {{.*}}.o
7# CHECK: >>> referenced by {{.*}}.o:(.tdata+0xC)
8
9.section ".tdata", "awT", @progbits
10.globl var
11var:
12
13movq %fs:0, %rax
14leaq var@TPOFF(%rax),%rax
deps/lld/test/ELF/x86-64-tls-gd-got.s created+19
......@@ -0,0 +1,19 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
3# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/x86-64-tls-gd-got.s -o %t2.o
4# RUN: ld.lld %t1.o %t2.o -o %t
5# RUN: llvm-objdump -d %t | FileCheck %s
6
7 .globl _start
8_start:
9 .byte 0x66
10 leaq bar@tlsgd(%rip), %rdi
11 .byte 0x66
12 rex64
13 call *__tls_get_addr@GOTPCREL(%rip)
14 ret
15
16// CHECK: _start:
17// CHECK-NEXT: movq %fs:0, %rax
18// CHECK-NEXT: leaq -4(%rax), %rax
19// CHECK-NEXT: retq
deps/lld/test/ELF/x86-64-tls-gd-local.s created+52
......@@ -0,0 +1,52 @@
1// REQUIRES: x86
2// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux
3// RUN: ld.lld %t.o -o %t.so -shared
4// RUN: llvm-readobj -r -s -section-data %t.so | FileCheck %s
5
6 .byte 0x66
7 leaq foo@tlsgd(%rip), %rdi
8 .value 0x6666
9 rex64
10 call __tls_get_addr@PLT
11
12 .byte 0x66
13 leaq bar@tlsgd(%rip), %rdi
14 .value 0x6666
15 rex64
16 call __tls_get_addr@PLT
17
18 .section .tbss,"awT",@nobits
19
20 .hidden foo
21 .globl foo
22foo:
23 .zero 4
24
25 .hidden bar
26 .globl bar
27bar:
28 .zero 4
29
30
31// CHECK: Name: .got (
32// CHECK-NEXT: Type: SHT_PROGBITS
33// CHECK-NEXT: Flags [
34// CHECK-NEXT: SHF_ALLOC (0x2)
35// CHECK-NEXT: SHF_WRITE (0x1)
36// CHECK-NEXT: ]
37// CHECK-NEXT: Address: 0x30D0
38// CHECK-NEXT: Offset: 0x30D0
39// CHECK-NEXT: Size: 32
40// CHECK-NEXT: Link: 0
41// CHECK-NEXT: Info: 0
42// CHECK-NEXT: AddressAlignment: 8
43// CHECK-NEXT: EntrySize: 0
44// CHECK-NEXT: SectionData (
45// CHECK-NEXT: 0000: 00000000 00000000 00000000 00000000 |................|
46// CHECK-NEXT: 0010: 00000000 00000000 04000000 00000000 |................|
47// CHECK-NEXT: )
48
49// CHECK: Section ({{.*}}) .rela.dyn {
50// CHECK-NEXT: 0x30D0 R_X86_64_DTPMOD64 - 0x0
51// CHECK-NEXT: 0x30E0 R_X86_64_DTPMOD64 - 0x0
52// CHECK-NEXT: }
deps/lld/test/ELF/x86-64-tls-pie.s created+26
......@@ -0,0 +1,26 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-cloudabi %s -o %t1.o
3# RUN: ld.lld -pie %t1.o -o %t
4# RUN: llvm-readobj -r %t | FileCheck %s
5
6# Bug 27174: R_X86_64_TPOFF32 and R_X86_64_GOTTPOFF relocations should
7# be eliminated when building a PIE executable, as the static TLS layout
8# is fixed.
9#
10# CHECK: Relocations [
11# CHECK-NEXT: ]
12
13 .globl _start
14_start:
15 movq %fs:0, %rax
16 movl $3, i@TPOFF(%rax)
17
18 movq %fs:0, %rdx
19 movq i@GOTTPOFF(%rip), %rcx
20 movl $3, (%rdx,%rcx)
21
22 .section .tbss.i,"awT",@nobits
23 .globl i
24i:
25 .long 0
26 .size i, 4
deps/lld/test/ELF/zdefs.s created+8
......@@ -0,0 +1,8 @@
1# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
2# RUN: ld.lld -shared %t.o -o %t1.so
3
4# RUN: not ld.lld -z defs -shared %t.o -o %t1.so 2>&1 | FileCheck -check-prefix=ERR %s
5# ERR: error: undefined symbol: foo
6# ERR: >>> referenced by {{.*}}:(.text+0x1)
7
8callq foo@PLT
deps/lld/test/ELF/zstack-size.s created+33
......@@ -0,0 +1,33 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3# RUN: ld.lld -z stack-size=0x1000 %t -o %t1
4# RUN: llvm-readobj -program-headers %t1 | FileCheck %s -check-prefix=CHECK1
5
6# RUN: ld.lld -z stack-size=0 %t -o %t2
7# RUN: llvm-readobj -program-headers %t2 | FileCheck %s -check-prefix=CHECK2
8
9.global _start
10_start:
11 nop
12
13# CHECK1: Type: PT_GNU_STACK (0x6474E551)
14# CHECK1-NEXT: Offset: 0x0
15# CHECK1-NEXT: VirtualAddress: 0x0
16# CHECK1-NEXT: PhysicalAddress: 0x0
17# CHECK1-NEXT: FileSize: 0
18# CHECK1-NEXT: MemSize: 4096
19# CHECK1-NEXT: Flags [ (0x6)
20# CHECK1-NEXT: PF_R (0x4)
21# CHECK1-NEXT: PF_W (0x2)
22# CHECK1-NEXT: ]
23
24# CHECK2: Type: PT_GNU_STACK (0x6474E551)
25# CHECK2-NEXT: Offset: 0x0
26# CHECK2-NEXT: VirtualAddress: 0x0
27# CHECK2-NEXT: PhysicalAddress: 0x0
28# CHECK2-NEXT: FileSize: 0
29# CHECK2-NEXT: MemSize: 0
30# CHECK2-NEXT: Flags [ (0x6)
31# CHECK2-NEXT: PF_R (0x4)
32# CHECK2-NEXT: PF_W (0x2)
33# CHECK2-NEXT: ]
deps/lld/test/ELF/ztext-text-notext.s created+36
......@@ -0,0 +1,36 @@
1# REQUIRES: x86
2# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/ztext-text-notext.s -o %t2.o
4# RUN: ld.lld %t2.o -o %t2.so -shared
5# RUN: ld.lld -z notext %t.o %t2.so -o %t -shared
6# RUN: llvm-readobj -dynamic-table -r %t | FileCheck %s
7# RUN: ld.lld -z notext %t.o %t2.so -o %t2 -pie
8# RUN: llvm-readobj -dynamic-table -r %t2 | FileCheck %s
9# RUN: ld.lld -z notext %t.o %t2.so -o %t3
10# RUN: llvm-readobj -dynamic-table -r %t3 | FileCheck --check-prefix=STATIC %s
11
12# If the preference is to have text relocations, don't create plt of copy relocations.
13
14# CHECK: Relocations [
15# CHECK-NEXT: Section {{.*}} .rela.dyn {
16# CHECK-NEXT: 0x1000 R_X86_64_RELATIVE - 0x1000
17# CHECK-NEXT: 0x1008 R_X86_64_64 bar 0x0
18# CHECK-NEXT: 0x1010 R_X86_64_PC64 zed 0x0
19# CHECK-NEXT: }
20# CHECK-NEXT: ]
21# CHECK: DynamicSection [
22# CHECK: 0x0000000000000016 TEXTREL 0x0
23
24# STATIC: Relocations [
25# STATIC-NEXT: Section {{.*}} .rela.dyn {
26# STATIC-NEXT: 0x201008 R_X86_64_64 bar 0x0
27# STATIC-NEXT: 0x201010 R_X86_64_PC64 zed 0x0
28# STATIC-NEXT: }
29# STATIC-NEXT: ]
30# STATIC: DynamicSection [
31# STATIC: 0x0000000000000016 TEXTREL 0x0
32
33foo:
34.quad foo
35.quad bar
36.quad zed - .
deps/lld/test/Unit/lit.cfg created+23
......@@ -0,0 +1,23 @@
1# -*- Python -*-
2
3# Configuration file for the 'lit' test runner.
4
5import os
6
7import lit.formats
8
9# name: The name of this test suite.
10config.name = 'lld-Unit'
11
12# suffixes: A list of file extensions to treat as test files.
13config.suffixes = []
14
15# test_source_root: The root path where unit test binaries are located.
16# test_exec_root: The root path where tests should be run.
17config.test_source_root = os.path.join(config.lld_obj_root, 'unittests')
18config.test_exec_root = config.test_source_root
19
20# testFormat: The test format to use to interpret tests.
21if not hasattr(config, 'llvm_build_mode'):
22 lit_config.fatal("unable to find llvm_build_mode value on config")
23config.test_format = lit.formats.GoogleTest(config.llvm_build_mode, 'Tests')
deps/lld/test/Unit/lit.site.cfg.in created+25
......@@ -0,0 +1,25 @@
1@LIT_SITE_CFG_IN_HEADER@
2
3config.llvm_src_root = "@LLVM_SOURCE_DIR@"
4config.llvm_obj_root = "@LLVM_BINARY_DIR@"
5config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
6config.llvm_libs_dir = "@LLVM_LIBS_DIR@"
7config.llvm_build_mode = "@LLVM_BUILD_MODE@"
8config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@"
9config.lld_obj_root = "@LLD_BINARY_DIR@"
10config.lld_src_root = "@LLD_SOURCE_DIR@"
11config.target_triple = "@TARGET_TRIPLE@"
12config.python_executable = "@PYTHON_EXECUTABLE@"
13
14# Support substitution of the tools and libs dirs with user parameters. This is
15# used when we can't determine the tool dir at configuration time.
16try:
17 config.llvm_tools_dir = config.llvm_tools_dir % lit_config.params
18 config.llvm_libs_dir = config.llvm_libs_dir % lit_config.params
19 config.llvm_build_mode = config.llvm_build_mode % lit_config.params
20except KeyError as e:
21 key, = e.args
22 lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key))
23
24# Let the main config do the real work.
25lit_config.load_config(config, "@LLD_SOURCE_DIR@/test/Unit/lit.cfg")
deps/lld/test/darwin/Inputs/native-and-mach-o.objtxt created+17
......@@ -0,0 +1,17 @@
1--- !mach-o
2arch: x86_64
3file-type: MH_OBJECT
4sections:
5 - segment: __TEXT
6 section: __text
7 type: S_REGULAR
8 attributes: [ S_ATTR_PURE_INSTRUCTIONS ]
9 address: 0
10 content: [ 0xC3 ]
11global-symbols:
12 - name: _foo
13 type: N_SECT
14 scope: [ N_EXT ]
15 sect: 1
16 desc: [ ]
17 value: 0
deps/lld/test/darwin/Inputs/native-and-mach-o2.objtxt created+19
......@@ -0,0 +1,19 @@
1--- !mach-o
2arch: x86_64
3file-type: MH_DYLIB
4flags: [ ]
5install-name: /usr/lib/libSystem.B.dylib
6sections:
7 - segment: __TEXT
8 section: __text
9 type: S_REGULAR
10 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
11 address: 0x0000000000000000
12 content: [ 0x55 ]
13
14global-symbols:
15 - name: dyld_stub_binder
16 type: N_SECT
17 scope: [ N_EXT ]
18 sect: 1
19 value: 0x0000000000000000
deps/lld/test/darwin/cmdline-objc_gc.objtxt created+15
......@@ -0,0 +1,15 @@
1# RUN: not lld -flavor darwin -arch x86_64 -objc_gc %s 2>&1 | FileCheck %s
2#
3# Test that the -objc_gc is rejected.
4#
5
6# CHECK: error: -objc_gc is not supported
7
8--- !native
9defined-atoms:
10 - name: _main
11 type: code
12 scope: global
13 content: [ 0x90 ]
14
15...
deps/lld/test/darwin/cmdline-objc_gc_compaction.objtxt created+15
......@@ -0,0 +1,15 @@
1# RUN: not lld -flavor darwin -arch x86_64 -objc_gc_compaction %s 2>&1 | FileCheck %s
2#
3# Test that the -objc_gc_compaction is rejected.
4#
5
6# CHECK: error: -objc_gc_compaction is not supported
7
8--- !native
9defined-atoms:
10 - name: _main
11 type: code
12 scope: global
13 content: [ 0x90 ]
14
15...
deps/lld/test/darwin/cmdline-objc_gc_only.objtxt created+15
......@@ -0,0 +1,15 @@
1# RUN: not lld -flavor darwin -arch x86_64 -objc_gc_only %s 2>&1 | FileCheck %s
2#
3# Test that the -objc_gc_only is rejected.
4#
5
6# CHECK: error: -objc_gc_only is not supported
7
8--- !native
9defined-atoms:
10 - name: _main
11 type: code
12 scope: global
13 content: [ 0x90 ]
14
15...
deps/lld/test/darwin/native-and-mach-o.objtxt created+27
......@@ -0,0 +1,27 @@
1# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s \
2# RUN: %p/Inputs/native-and-mach-o.objtxt \
3# RUN: %p/Inputs/native-and-mach-o2.objtxt -o %t && \
4# RUN: llvm-nm %t | FileCheck %s
5#
6# Test a mix of atoms and mach-o both encoded in yaml
7#
8
9--- !native
10defined-atoms:
11 - name: _main
12 type: code
13 scope: global
14 content: [ 55, 48, 89, E5, 30, C0, E8, 00,
15 00, 00, 00, 31, C0, 5D, C3 ]
16 references:
17 - offset: 7
18 kind: branch32
19 target: _foo
20
21undefined-atoms:
22 - name: _foo
23
24...
25
26# CHECK: {{[0-9a-f]+}} T _foo
27# CHECK: {{[0-9a-f]+}} T _main
deps/lld/test/lit.cfg created+270
......@@ -0,0 +1,270 @@
1# -*- Python -*-
2
3import os
4import platform
5import re
6import subprocess
7import locale
8
9import lit.formats
10import lit.util
11
12# Configuration file for the 'lit' test runner.
13
14# name: The name of this test suite.
15config.name = 'lld'
16
17# Tweak PATH for Win32
18if sys.platform in ['win32']:
19 # Seek sane tools in directories and set to $PATH.
20 path = getattr(config, 'lit_tools_dir', None)
21 path = lit_config.getToolsPath(path,
22 config.environment['PATH'],
23 ['cmp.exe', 'grep.exe', 'sed.exe'])
24 if path is not None:
25 path = os.path.pathsep.join((path,
26 config.environment['PATH']))
27 config.environment['PATH'] = path
28
29# Choose between lit's internal shell pipeline runner and a real shell. If
30# LIT_USE_INTERNAL_SHELL is in the environment, we use that as an override.
31use_lit_shell = os.environ.get("LIT_USE_INTERNAL_SHELL")
32if use_lit_shell:
33 # 0 is external, "" is default, and everything else is internal.
34 execute_external = (use_lit_shell == "0")
35else:
36 # Otherwise we default to internal on Windows and external elsewhere, as
37 # bash on Windows is usually very slow.
38 execute_external = (not sys.platform in ['win32'])
39
40
41# testFormat: The test format to use to interpret tests.
42#
43# For now we require '&&' between commands, until they get globally killed and
44# the test runner updated.
45config.test_format = lit.formats.ShTest(execute_external)
46
47# suffixes: A list of file extensions to treat as test files.
48config.suffixes = ['.ll', '.s', '.test', '.yaml', '.objtxt']
49
50# excludes: A list of directories to exclude from the testsuite. The 'Inputs'
51# subdirectories contain auxiliary inputs for various tests in their parent
52# directories.
53config.excludes = ['Inputs']
54
55# test_source_root: The root path where tests are located.
56config.test_source_root = os.path.dirname(__file__)
57
58# test_exec_root: The root path where tests should be run.
59lld_obj_root = getattr(config, 'lld_obj_root', None)
60if lld_obj_root is not None:
61 config.test_exec_root = os.path.join(lld_obj_root, 'test')
62
63# Set llvm_{src,obj}_root for use by others.
64config.llvm_src_root = getattr(config, 'llvm_src_root', None)
65config.llvm_obj_root = getattr(config, 'llvm_obj_root', None)
66
67# Tweak the PATH to include the tools dir and the scripts dir.
68if lld_obj_root is not None:
69 lld_tools_dir = getattr(config, 'lld_tools_dir', None)
70 if not lld_tools_dir:
71 lit_config.fatal('No LLD tools dir set!')
72 llvm_tools_dir = getattr(config, 'llvm_tools_dir', None)
73 if not llvm_tools_dir:
74 lit_config.fatal('No LLVM tools dir set!')
75 path = os.path.pathsep.join((lld_tools_dir, llvm_tools_dir, config.environment['PATH']))
76 path = os.path.pathsep.join((os.path.join(getattr(config, 'llvm_src_root', None),'test','Scripts'),path))
77
78 config.environment['PATH'] = path
79
80 lld_libs_dir = getattr(config, 'lld_libs_dir', None)
81 if not lld_libs_dir:
82 lit_config.fatal('No LLD libs dir set!')
83 llvm_libs_dir = getattr(config, 'llvm_libs_dir', None)
84 if not llvm_libs_dir:
85 lit_config.fatal('No LLVM libs dir set!')
86 path = os.path.pathsep.join((lld_libs_dir, llvm_libs_dir,
87 config.environment.get('LD_LIBRARY_PATH','')))
88 config.environment['LD_LIBRARY_PATH'] = path
89
90 # Propagate LLVM_SRC_ROOT into the environment.
91 config.environment['LLVM_SRC_ROOT'] = getattr(config, 'llvm_src_root', '')
92
93 # Propagate PYTHON_EXECUTABLE into the environment
94 config.environment['PYTHON_EXECUTABLE'] = getattr(config, 'python_executable',
95 '')
96###
97
98# Check that the object root is known.
99if config.test_exec_root is None:
100 # Otherwise, we haven't loaded the site specific configuration (the user is
101 # probably trying to run on a test file directly, and either the site
102 # configuration hasn't been created by the build system, or we are in an
103 # out-of-tree build situation).
104
105 # Check for 'lld_site_config' user parameter, and use that if available.
106 site_cfg = lit_config.params.get('lld_site_config', None)
107 if site_cfg and os.path.exists(site_cfg):
108 lit_config.load_config(config, site_cfg)
109 raise SystemExit
110
111 # Try to detect the situation where we are using an out-of-tree build by
112 # looking for 'llvm-config'.
113 #
114 # FIXME: I debated (i.e., wrote and threw away) adding logic to
115 # automagically generate the lit.site.cfg if we are in some kind of fresh
116 # build situation. This means knowing how to invoke the build system though,
117 # and I decided it was too much magic. We should solve this by just having
118 # the .cfg files generated during the configuration step.
119
120 llvm_config = lit.util.which('llvm-config', config.environment['PATH'])
121 if not llvm_config:
122 lit_config.fatal('No site specific configuration available!')
123
124 # Get the source and object roots.
125 llvm_src_root = subprocess.check_output(['llvm-config', '--src-root']).strip()
126 llvm_obj_root = subprocess.check_output(['llvm-config', '--obj-root']).strip()
127 lld_src_root = os.path.join(llvm_src_root, "tools", "lld")
128 lld_obj_root = os.path.join(llvm_obj_root, "tools", "lld")
129
130 # Validate that we got a tree which points to here, using the standard
131 # tools/lld layout.
132 this_src_root = os.path.dirname(config.test_source_root)
133 if os.path.realpath(lld_src_root) != os.path.realpath(this_src_root):
134 lit_config.fatal('No site specific configuration available!')
135
136 # Check that the site specific configuration exists.
137 site_cfg = os.path.join(lld_obj_root, 'test', 'lit.site.cfg')
138 if not os.path.exists(site_cfg):
139 lit_config.fatal(
140 'No site specific configuration available! You may need to '
141 'run "make test" in your lld build directory.')
142
143 # Okay, that worked. Notify the user of the automagic, and reconfigure.
144 lit_config.note('using out-of-tree build at %r' % lld_obj_root)
145 lit_config.load_config(config, site_cfg)
146 raise SystemExit
147
148# For each occurrence of a lld tool name as its own word, replace it
149# with the full path to the build directory holding that tool. This
150# ensures that we are testing the tools just built and not some random
151# tools that might happen to be in the user's PATH.
152
153# Regex assertions to reject neighbor hyphens/dots (seen in some tests).
154# For example, we want to prefix 'lld' and 'ld.lld' but not the 'lld' inside
155# of 'ld.lld'.
156NoPreJunk = r"(?<!(-|\.|/))"
157NoPostJunk = r"(?!(-|\.))"
158
159config.substitutions.append( (r"\bld.lld\b", 'ld.lld --full-shutdown') )
160
161tool_patterns = [r"\bFileCheck\b",
162 r"\bnot\b",
163 NoPreJunk + r"\blld\b" + NoPostJunk,
164 r"\bld.lld\b",
165 r"\blld-link\b",
166 r"\bllvm-as\b",
167 r"\bllvm-mc\b",
168 r"\bllvm-nm\b",
169 r"\bllvm-objdump\b",
170 r"\bllvm-pdbutil\b",
171 r"\bllvm-readobj\b",
172 r"\bobj2yaml\b",
173 r"\byaml2obj\b"]
174
175for pattern in tool_patterns:
176 # Extract the tool name from the pattern. This relies on the tool
177 # name being surrounded by \b word match operators. If the
178 # pattern starts with "| ", include it in the string to be
179 # substituted.
180 tool_match = re.match(r"^(\\)?((\| )?)\W+b([0-9A-Za-z-_\.]+)\\b\W*$",
181 pattern)
182 tool_pipe = tool_match.group(2)
183 tool_name = tool_match.group(4)
184 tool_path = lit.util.which(tool_name, config.environment['PATH'])
185 if not tool_path:
186 # Warn, but still provide a substitution.
187 lit_config.note('Did not find ' + tool_name + ' in ' + path)
188 tool_path = llvm_tools_dir + '/' + tool_name
189 config.substitutions.append((pattern, tool_pipe + tool_path))
190
191# Add site-specific substitutions.
192config.substitutions.append( ('%python', config.python_executable) )
193
194###
195
196# When running under valgrind, we mangle '-vg' onto the end of the triple so we
197# can check it with XFAIL and XTARGET.
198if lit_config.useValgrind:
199 config.target_triple += '-vg'
200
201# Shell execution
202if execute_external:
203 config.available_features.add('shell')
204
205# zlib compression library
206if config.have_zlib:
207 config.available_features.add("zlib")
208
209# Running on Darwin OS
210if platform.system() in ['Darwin']:
211 config.available_features.add('system-linker-mach-o')
212
213# Running on ELF based *nix
214if platform.system() in ['FreeBSD', 'Linux']:
215 config.available_features.add('system-linker-elf')
216
217# Running on Windows
218if platform.system() in ['Windows']:
219 config.available_features.add('system-windows')
220
221# Set if host-cxxabi's demangler can handle target's symbols.
222if platform.system() not in ['Windows']:
223 config.available_features.add('demangler')
224
225# llvm-config knows whether it is compiled with asserts (and)
226# whether we are operating in release/debug mode.
227import subprocess
228try:
229 llvm_config_cmd = \
230 subprocess.Popen([os.path.join(llvm_tools_dir, 'llvm-config'),
231 '--build-mode', '--assertion-mode', '--targets-built'],
232 stdout = subprocess.PIPE)
233except OSError as why:
234 print("Could not find llvm-config in " + llvm_tools_dir)
235 exit(42)
236
237llvm_config_output = llvm_config_cmd.stdout.read().decode('utf_8')
238llvm_config_output_list = llvm_config_output.split("\n")
239
240if re.search(r'DEBUG', llvm_config_output_list[0]):
241 config.available_features.add('debug')
242if re.search(r'ON', llvm_config_output_list[1]):
243 config.available_features.add('asserts')
244
245archs = llvm_config_output_list[2]
246if re.search(r'AArch64', archs):
247 config.available_features.add('aarch64')
248if re.search(r'AMDGPU', archs):
249 config.available_features.add('amdgpu')
250if re.search(r'ARM', archs):
251 config.available_features.add('arm')
252if re.search(r'AVR', archs):
253 config.available_features.add('avr')
254if re.search(r'Mips', archs):
255 config.available_features.add('mips')
256if re.search(r'PowerPC', archs):
257 config.available_features.add('ppc')
258if re.search(r'Sparc', archs):
259 config.available_features.add('sparc')
260if re.search(r'X86', archs):
261 config.available_features.add('x86')
262llvm_config_cmd.wait()
263
264# Set a fake constant version so that we get consitent output.
265config.environment['LLD_VERSION'] = 'LLD 1.0'
266
267# Indirectly check if the mt.exe Microsoft utility exists by searching for
268# cvtres, which always accompanies it.
269if lit.util.which('cvtres', config.environment['PATH']):
270 config.available_features.add('win_mt')
deps/lld/test/lit.site.cfg.in created+25
......@@ -0,0 +1,25 @@
1@LIT_SITE_CFG_IN_HEADER@
2
3config.llvm_src_root = "@LLVM_SOURCE_DIR@"
4config.llvm_obj_root = "@LLVM_BINARY_DIR@"
5config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
6config.llvm_libs_dir = "@LLVM_LIBS_DIR@"
7config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@"
8config.lld_obj_root = "@LLD_BINARY_DIR@"
9config.lld_libs_dir = "@LLVM_LIBRARY_OUTPUT_INTDIR@"
10config.lld_tools_dir = "@LLVM_RUNTIME_OUTPUT_INTDIR@"
11config.target_triple = "@TARGET_TRIPLE@"
12config.python_executable = "@PYTHON_EXECUTABLE@"
13config.have_zlib = @HAVE_LIBZ@
14
15# Support substitution of the tools and libs dirs with user parameters. This is
16# used when we can't determine the tool dir at configuration time.
17try:
18 config.llvm_tools_dir = config.llvm_tools_dir % lit_config.params
19 config.llvm_libs_dir = config.llvm_libs_dir % lit_config.params
20except KeyError as e:
21 key, = e.args
22 lit_config.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key))
23
24# Let the main config do the real work.
25lit_config.load_config(config, "@LLD_SOURCE_DIR@/test/lit.cfg")
deps/lld/test/mach-o/Inputs/DependencyDump.py created+30
......@@ -0,0 +1,30 @@
1# -*- Python -*-
2
3
4#
5# Dump out Xcode binary dependency file.
6#
7
8import sys
9
10f = open(sys.argv[1], "rb")
11byte = f.read(1)
12while byte != b'':
13 if byte == b'\000':
14 sys.stdout.write("linker-vers: ")
15 elif byte == b'\020':
16 sys.stdout.write("input-file: ")
17 elif byte == b'\021':
18 sys.stdout.write("not-found: ")
19 elif byte == b'\100':
20 sys.stdout.write("output-file: ")
21 byte = f.read(1)
22 while byte != b'\000':
23 if byte != b'\012':
24 sys.stdout.write(byte.decode("ascii"))
25 byte = f.read(1)
26 sys.stdout.write("\n")
27 byte = f.read(1)
28
29f.close()
30
deps/lld/test/mach-o/Inputs/PIE.yaml created+6
......@@ -0,0 +1,6 @@
1--- !mach-o
2arch: x86_64
3file-type: MH_DYLIB
4install-name: /usr/lib/libSystem.B.dylib
5exports:
6 - name: dyld_stub_binder
deps/lld/test/mach-o/Inputs/arm-interworking.yaml created+83
......@@ -0,0 +1,83 @@
1--- !mach-o
2arch: armv7
3file-type: MH_OBJECT
4flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
5sections:
6 - segment: __TEXT
7 section: __text
8 type: S_REGULAR
9 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
10 alignment: 2
11 address: 0x0000000000000000
12 content: [ 0xFE, 0xFF, 0xFF, 0xEB, 0x02, 0x00, 0x00, 0xFA,
13 0xFC, 0xFF, 0xFF, 0xEB, 0xFB, 0xFF, 0xFF, 0xFA,
14 0x1E, 0xFF, 0x2F, 0xE1, 0x1E, 0xFF, 0x2F, 0xE1 ]
15 relocations:
16 - offset: 0x0000000C
17 type: ARM_RELOC_BR24
18 length: 2
19 pc-rel: true
20 extern: true
21 symbol: 4
22 - offset: 0x00000008
23 type: ARM_RELOC_BR24
24 length: 2
25 pc-rel: true
26 extern: true
27 symbol: 3
28 - offset: 0x00000004
29 type: ARM_RELOC_BR24
30 length: 2
31 pc-rel: true
32 extern: false
33 symbol: 1
34 - offset: 0x00000000
35 type: ARM_RELOC_BR24
36 length: 2
37 pc-rel: true
38 extern: false
39 symbol: 1
40 - segment: __DATA
41 section: __data
42 type: S_REGULAR
43 attributes: [ ]
44 address: 0x0000000000000018
45 content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
46 relocations:
47 - offset: 0x00000004
48 type: ARM_RELOC_VANILLA
49 length: 2
50 pc-rel: false
51 extern: false
52 symbol: 1
53 - offset: 0x00000000
54 type: ARM_RELOC_VANILLA
55 length: 2
56 pc-rel: false
57 extern: true
58 symbol: 3
59local-symbols:
60 - name: _d2
61 type: N_SECT
62 sect: 2
63 value: 0x0000000000000018
64global-symbols:
65 - name: _a1
66 type: N_SECT
67 scope: [ N_EXT ]
68 sect: 1
69 value: 0x0000000000000000
70 - name: _a2
71 type: N_SECT
72 scope: [ N_EXT ]
73 sect: 1
74 value: 0x0000000000000014
75undefined-symbols:
76 - name: _t1
77 type: N_UNDF
78 scope: [ N_EXT ]
79 value: 0x0000000000000000
80 - name: _t2
81 type: N_UNDF
82 scope: [ N_EXT ]
83 value: 0x0000000000000000
deps/lld/test/mach-o/Inputs/arm-shims.yaml created+60
......@@ -0,0 +1,60 @@
1--- !mach-o
2arch: armv7
3file-type: MH_OBJECT
4flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
5sections:
6 - segment: __TEXT
7 section: __text
8 type: S_REGULAR
9 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
10 alignment: 2
11 address: 0x0000000000000000
12 content: [ 0x00, 0xBF, 0xFF, 0xF7, 0xFE, 0xEF, 0xFF, 0xF7,
13 0xFB, 0xBF, 0x00, 0x00, 0x00, 0xF0, 0x20, 0xE3,
14 0xFA, 0xFF, 0xFF, 0xFA, 0xF9, 0xFF, 0xFF, 0xEA ]
15 relocations:
16 - offset: 0x00000014
17 type: ARM_RELOC_BR24
18 length: 2
19 pc-rel: true
20 extern: true
21 symbol: 3
22 - offset: 0x00000010
23 type: ARM_RELOC_BR24
24 length: 2
25 pc-rel: true
26 extern: true
27 symbol: 3
28 - offset: 0x00000006
29 type: ARM_THUMB_RELOC_BR22
30 length: 2
31 pc-rel: true
32 extern: true
33 symbol: 2
34 - offset: 0x00000002
35 type: ARM_THUMB_RELOC_BR22
36 length: 2
37 pc-rel: true
38 extern: true
39 symbol: 2
40global-symbols:
41 - name: _a2
42 type: N_SECT
43 scope: [ N_EXT ]
44 sect: 1
45 value: 0x000000000000000C
46 - name: _t2
47 type: N_SECT
48 scope: [ N_EXT ]
49 sect: 1
50 desc: [ N_ARM_THUMB_DEF ]
51 value: 0x0000000000000000
52undefined-symbols:
53 - name: _a1
54 type: N_UNDF
55 scope: [ N_EXT ]
56 value: 0x0000000000000000
57 - name: _t1
58 type: N_UNDF
59 scope: [ N_EXT ]
60 value: 0x0000000000000000
deps/lld/test/mach-o/Inputs/arm64/libSystem.yaml created+13
......@@ -0,0 +1,13 @@
1#
2# For use by test cases that create dynamic output types which may needs stubs
3# and therefore will need a dylib definition of dyld_stub_binder.
4#
5
6--- !mach-o
7arch: arm64
8file-type: MH_DYLIB
9install-name: /usr/lib/libSystem.B.dylib
10exports:
11 - name: dyld_stub_binder
12
13...
deps/lld/test/mach-o/Inputs/armv7/libSystem.yaml created+13
......@@ -0,0 +1,13 @@
1#
2# For use by test cases that create dynamic output types which may needs stubs
3# and therefore will need a dylib definition of dyld_stub_binder.
4#
5
6--- !mach-o
7arch: armv7
8file-type: MH_DYLIB
9install-name: /usr/lib/libSystem.B.dylib
10exports:
11 - name: dyld_stub_binder
12
13...
deps/lld/test/mach-o/Inputs/bar.yaml created+18
......@@ -0,0 +1,18 @@
1
2--- !mach-o
3arch: x86_64
4file-type: MH_OBJECT
5flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
6sections:
7 - segment: __TEXT
8 section: __text
9 type: S_REGULAR
10 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
11 address: 0x0000000000000000
12 content: [ 0xC3 ]
13global-symbols:
14 - name: _bar
15 type: N_SECT
16 scope: [ N_EXT ]
17 sect: 1
18 value: 0x0000000000000000
deps/lld/test/mach-o/Inputs/cstring-sections.yaml created+25
......@@ -0,0 +1,25 @@
1--- !mach-o
2arch: x86_64
3file-type: MH_OBJECT
4flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
5has-UUID: false
6OS: unknown
7sections:
8 - segment: __TEXT
9 section: __objc_methname
10 type: S_CSTRING_LITERALS
11 attributes: [ ]
12 address: 0x0000000000000000
13 content: [ 0x61, 0x62, 0x63, 0x00 ]
14 - segment: __TEXT
15 section: __objc_classname
16 type: S_CSTRING_LITERALS
17 attributes: [ ]
18 address: 0x0000000000000006
19 content: [ 0x61, 0x62, 0x63, 0x00 ]
20 - segment: __TEXT
21 section: __cstring
22 type: S_CSTRING_LITERALS
23 attributes: [ ]
24 address: 0x000000000000000A
25 content: [ 0x61, 0x62, 0x63, 0x00 ]
deps/lld/test/mach-o/Inputs/exported_symbols_list.exp created+6
......@@ -0,0 +1,6 @@
1#
2# For use with exported_symbols_list.yaml
3#
4_foo
5_b
6
deps/lld/test/mach-o/Inputs/full.filelist created+3
......@@ -0,0 +1,3 @@
1/foo/bar/a.o
2/foo/bar/b.o
3/foo/x.a
deps/lld/test/mach-o/Inputs/got-order.yaml created+53
......@@ -0,0 +1,53 @@
1--- !mach-o
2arch: x86_64
3file-type: MH_OBJECT
4flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
5sections:
6 - segment: __TEXT
7 section: __text
8 type: S_REGULAR
9 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
10 address: 0x0000000000000000
11 content: [ 0x55, 0x48, 0x89, 0xE5, 0x48, 0x8B, 0x0D, 0x00,
12 0x00, 0x00, 0x00, 0x48, 0x8B, 0x05, 0x00, 0x00,
13 0x00, 0x00, 0x8B, 0x00, 0x03, 0x01, 0x48, 0x8B,
14 0x0D, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x5D,
15 0xC3 ]
16 relocations:
17 - offset: 0x00000019
18 type: X86_64_RELOC_GOT_LOAD
19 length: 2
20 pc-rel: true
21 extern: true
22 symbol: 2
23 - offset: 0x0000000E
24 type: X86_64_RELOC_GOT_LOAD
25 length: 2
26 pc-rel: true
27 extern: true
28 symbol: 1
29 - offset: 0x00000007
30 type: X86_64_RELOC_GOT_LOAD
31 length: 2
32 pc-rel: true
33 extern: true
34 symbol: 3
35global-symbols:
36 - name: _main
37 type: N_SECT
38 scope: [ N_EXT ]
39 sect: 1
40 value: 0x0000000000000000
41undefined-symbols:
42 - name: _bar
43 type: N_UNDF
44 scope: [ N_EXT ]
45 value: 0x0000000000000000
46 - name: _foo
47 type: N_UNDF
48 scope: [ N_EXT ]
49 value: 0x0000000000000000
50 - name: _zazzle
51 type: N_UNDF
52 scope: [ N_EXT ]
53 value: 0x0000000000000000
deps/lld/test/mach-o/Inputs/got-order2.yaml created+11
......@@ -0,0 +1,11 @@
1--- !mach-o
2arch: x86_64
3file-type: MH_DYLIB
4install-name: /usr/lib/libfoobar.dylib
5exports:
6 - name: _bar
7 - name: _zazzle
8 - name: _foo
9 - name: _aaa
10 - name: _fff
11 - name: _zzz
deps/lld/test/mach-o/Inputs/hello-world-arm64.yaml created+8
......@@ -0,0 +1,8 @@
1--- !mach-o
2arch: arm64
3file-type: MH_DYLIB
4install-name: /usr/lib/libSystem.B.dylib
5exports:
6 - name: _fprintf
7 - name: ___stdoutp
8 - name: dyld_stub_binder
deps/lld/test/mach-o/Inputs/hello-world-armv6.yaml created+7
......@@ -0,0 +1,7 @@
1--- !mach-o
2arch: armv6
3file-type: MH_DYLIB
4install-name: /usr/lib/libSystem.B.dylib
5exports:
6 - name: _printf
7 - name: dyld_stub_binder
deps/lld/test/mach-o/Inputs/hello-world-armv7.yaml created+7
......@@ -0,0 +1,7 @@
1--- !mach-o
2arch: armv7
3file-type: MH_DYLIB
4install-name: /usr/lib/libSystem.B.dylib
5exports:
6 - name: _printf
7 - name: dyld_stub_binder
deps/lld/test/mach-o/Inputs/hello-world-x86.yaml created+7
......@@ -0,0 +1,7 @@
1--- !mach-o
2arch: x86
3file-type: MH_DYLIB
4install-name: /usr/lib/libSystem.B.dylib
5exports:
6 - name: _printf
7 - name: dyld_stub_binder
deps/lld/test/mach-o/Inputs/hello-world-x86_64.yaml created+8
......@@ -0,0 +1,8 @@
1--- !mach-o
2arch: x86_64
3file-type: MH_DYLIB
4install-name: /usr/lib/libSystem.B.dylib
5exports:
6 - name: _fprintf
7 - name: dyld_stub_binder
8 - name: ___stdoutp
deps/lld/test/mach-o/Inputs/hw.raw_bytes created+1
......@@ -0,0 +1 @@
1hello
deps/lld/test/mach-o/Inputs/interposing-section.yaml created+6
......@@ -0,0 +1,6 @@
1--- !mach-o
2arch: x86_64
3file-type: MH_DYLIB
4install-name: /usr/lib/libSystem.B.dylib
5exports:
6 - name: _open
deps/lld/test/mach-o/Inputs/lazy-bind-x86_64-2.yaml created+8
......@@ -0,0 +1,8 @@
1--- !mach-o
2arch: x86_64
3file-type: MH_DYLIB
4install-name: /usr/lib/libfoo.dylib
5compat-version: 2.0
6current-version: 3.4
7exports:
8 - name: _foo
deps/lld/test/mach-o/Inputs/lazy-bind-x86_64-3.yaml created+8
......@@ -0,0 +1,8 @@
1--- !mach-o
2arch: x86_64
3file-type: MH_DYLIB
4install-name: /usr/lib/libbaz.dylib
5compat-version: 3.0
6current-version: 4.5
7exports:
8 - name: _baz
deps/lld/test/mach-o/Inputs/lazy-bind-x86_64.yaml created+8
......@@ -0,0 +1,8 @@
1--- !mach-o
2arch: x86_64
3file-type: MH_DYLIB
4install-name: /usr/lib/libbar.dylib
5compat-version: 1.0
6current-version: 2.3
7exports:
8 - name: _bar
deps/lld/test/mach-o/Inputs/lib-search-paths/usr/lib/libmyshared.dylib created
Binary files /dev/null and b/deps/lld/test/mach-o/Inputs/lib-search-paths/usr/lib/libmyshared.dylib differ
deps/lld/test/mach-o/Inputs/lib-search-paths/usr/lib/libmystatic.a created
Binary files /dev/null and b/deps/lld/test/mach-o/Inputs/lib-search-paths/usr/lib/libmystatic.a differ
deps/lld/test/mach-o/Inputs/lib-search-paths/usr/local/lib/file.o created
Binary files /dev/null and b/deps/lld/test/mach-o/Inputs/lib-search-paths/usr/local/lib/file.o differ
deps/lld/test/mach-o/Inputs/libbar.a created
Binary files /dev/null and b/deps/lld/test/mach-o/Inputs/libbar.a differ
deps/lld/test/mach-o/Inputs/libfoo.a created
Binary files /dev/null and b/deps/lld/test/mach-o/Inputs/libfoo.a differ
deps/lld/test/mach-o/Inputs/linker-as-ld.yaml created+6
......@@ -0,0 +1,6 @@
1--- !mach-o
2arch: x86_64
3file-type: MH_DYLIB
4install-name: /usr/lib/libSystem.B.dylib
5exports:
6 - name: dyld_stub_binder
deps/lld/test/mach-o/Inputs/no-version-min-load-command-object.yaml created+22
......@@ -0,0 +1,22 @@
1
2# This object file has no version min and so will prevent any -r link from emitting
3# a version min.
4
5--- !mach-o
6arch: x86_64
7file-type: MH_OBJECT
8flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
9sections:
10 - segment: __TEXT
11 section: __text
12 type: S_REGULAR
13 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
14 address: 0x0000000000000000
15 content: [ 0x00, 0x00, 0x00, 0x00 ]
16global-symbols:
17 - name: _main2
18 type: N_SECT
19 scope: [ N_EXT ]
20 sect: 1
21 value: 0x0000000000000000
22...
deps/lld/test/mach-o/Inputs/order_file-basic.order created+11
......@@ -0,0 +1,11 @@
1
2# input file for order_file-basic.yaml
3
4_func2
5libfoo.a(foo.o):_foo # tests file specific ordering within archive
6i386:_func3 # wrong arch, so ignored
7armv7:_func3 # wrong arch, so ignored
8_func1
9_notfound # unknown symbol silently ignored
10_data3 # data symbols should be orderable
11
deps/lld/test/mach-o/Inputs/partial.filelist created+3
......@@ -0,0 +1,3 @@
1bar/a.o
2bar/b.o
3x.a
deps/lld/test/mach-o/Inputs/re-exported-dylib-ordinal.yaml created+21
......@@ -0,0 +1,21 @@
1--- !mach-o
2arch: x86_64
3file-type: MH_DYLIB
4flags: [ MH_TWOLEVEL ]
5install-name: /junk/libfoo.dylib
6sections:
7 - segment: __TEXT
8 section: __text
9 type: S_REGULAR
10 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
11 address: 0x0000000000000F9A
12 content: [ 0x55, 0x48, 0x89, 0xE5, 0x5D, 0xC3 ]
13global-symbols:
14 - name: _foo
15 type: N_SECT
16 scope: [ N_EXT ]
17 sect: 1
18 value: 0x0000000000000F9A
19dependents:
20 - path: /junk/libbar.dylib
21 kind: LC_REEXPORT_DYLIB
deps/lld/test/mach-o/Inputs/re-exported-dylib-ordinal2.yaml created+18
......@@ -0,0 +1,18 @@
1--- !mach-o
2arch: x86_64
3file-type: MH_DYLIB
4flags: [ MH_TWOLEVEL ]
5install-name: /junk/libbar.dylib
6sections:
7 - segment: __TEXT
8 section: __text
9 type: S_REGULAR
10 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
11 address: 0x0000000000000F9A
12 content: [ 0x55, 0x48, 0x89, 0xE5, 0x5D, 0xC3 ]
13global-symbols:
14 - name: _bar
15 type: N_SECT
16 scope: [ N_EXT ]
17 sect: 1
18 value: 0x0000000000000F9A
deps/lld/test/mach-o/Inputs/re-exported-dylib-ordinal3.yaml created+19
......@@ -0,0 +1,19 @@
1--- !mach-o
2arch: x86_64
3file-type: MH_DYLIB
4flags: [ MH_TWOLEVEL ]
5install-name: /usr/lib/libSystem.B.dylib
6sections:
7 - segment: __TEXT
8 section: __text
9 type: S_REGULAR
10 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
11 address: 0x0000000000000000
12 content: [ 0x55 ]
13
14global-symbols:
15 - name: dyld_stub_binder
16 type: N_SECT
17 scope: [ N_EXT ]
18 sect: 1
19 value: 0x0000000000000000
deps/lld/test/mach-o/Inputs/swift-version-1.yaml created+18
......@@ -0,0 +1,18 @@
1# RUN: not lld -flavor darwin -arch x86_64 -r %s %p/Inputs/hello-world-x86_64.yaml 2>&1 | FileCheck %s
2
3--- !mach-o
4arch: x86_64
5file-type: MH_OBJECT
6flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
7compat-version: 0.0
8current-version: 0.0
9has-UUID: false
10OS: unknown
11sections:
12 - segment: __DATA
13 section: __objc_imageinfo
14 type: S_REGULAR
15 attributes: [ S_ATTR_NO_DEAD_STRIP ]
16 address: 0x0000000000000100
17 content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00 ]
18...
deps/lld/test/mach-o/Inputs/unwind-info-simple-arm64.yaml created+13
......@@ -0,0 +1,13 @@
1--- !mach-o
2arch: arm64
3file-type: MH_DYLIB
4install-name: /usr/lib/libc++.dylib
5exports:
6 - name: __Unwind_Resume
7 - name: __ZTIl
8 - name: __ZTIi
9 - name: ___cxa_end_catch
10 - name: ___cxa_begin_catch
11 - name: ___cxa_allocate_exception
12 - name: ___cxa_throw
13 - name: ___gxx_personality_v0
deps/lld/test/mach-o/Inputs/use-dylib-install-names.yaml created+28
......@@ -0,0 +1,28 @@
1--- !mach-o
2arch: x86_64
3file-type: MH_OBJECT
4flags: [ ]
5has-UUID: false
6OS: unknown
7sections:
8 - segment: __TEXT
9 section: __text
10 type: S_REGULAR
11 attributes: [ S_ATTR_PURE_INSTRUCTIONS ]
12 address: 0x0000000000000000
13 content: [ 0x55, 0x48, 0x89, 0xE5, 0xE8, 0x00, 0x00, 0x00,
14 0x00, 0xE8, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x00,
15 0x00, 0x00, 0x00, 0xE8, 0x00, 0x00, 0x00, 0x00,
16 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0xE9, 0x00,
17 0x00, 0x00, 0x00 ]
18global-symbols:
19 - name: _foo
20 type: N_SECT
21 scope: [ N_EXT ]
22 sect: 1
23 value: 0x0000000000000000
24undefined-symbols:
25 - name: _myGlobal
26 type: N_UNDF
27 scope: [ N_EXT ]
28 value: 0x0000000000000000
deps/lld/test/mach-o/Inputs/use-simple-dylib.yaml created+58
......@@ -0,0 +1,58 @@
1--- !mach-o
2arch: x86_64
3file-type: MH_DYLIB
4flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
5has-UUID: false
6OS: unknown
7sections:
8 - segment: __TEXT
9 section: __text
10 type: S_REGULAR
11 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
12 alignment: 4
13 address: 0x0000000000000000
14 content: [ 0xCC, 0xC3, 0x90, 0xC3, 0x90, 0x90, 0xC3, 0x90,
15 0x90, 0x90, 0xC3, 0x90, 0x90, 0x90, 0x90, 0xC3,
16 0x31, 0xC0, 0xC3 ]
17local-symbols:
18 - name: _myStatic
19 type: N_SECT
20 sect: 1
21 value: 0x000000000000000B
22 - name: _myVariablePreviouslyKnownAsPrivateExtern
23 type: N_SECT
24 scope: [ N_PEXT ]
25 sect: 1
26 desc: [ N_SYMBOL_RESOLVER ]
27 value: 0x0000000000000011
28global-symbols:
29 - name: _myGlobal
30 type: N_SECT
31 scope: [ N_EXT ]
32 sect: 1
33 value: 0x0000000000000001
34 - name: _myGlobalWeak
35 type: N_SECT
36 scope: [ N_EXT ]
37 sect: 1
38 desc: [ N_WEAK_DEF ]
39 value: 0x0000000000000002
40 - name: _myHidden
41 type: N_SECT
42 scope: [ N_EXT, N_PEXT ]
43 sect: 1
44 value: 0x0000000000000004
45 - name: _myHiddenWeak
46 type: N_SECT
47 scope: [ N_EXT, N_PEXT ]
48 sect: 1
49 desc: [ N_WEAK_DEF ]
50 value: 0x0000000000000007
51 - name: _myResolver
52 type: N_SECT
53 scope: [ N_EXT ]
54 sect: 1
55 desc: [ N_SYMBOL_RESOLVER ]
56 value: 0x0000000000000010
57
58install-name: libspecial.dylib
deps/lld/test/mach-o/Inputs/write-final-sections.yaml created+20
......@@ -0,0 +1,20 @@
1--- !mach-o
2arch: x86_64
3file-type: MH_DYLIB
4flags: [ ]
5install-name: /usr/lib/libSystem.B.dylib
6sections:
7 - segment: __TEXT
8 section: __text
9 type: S_REGULAR
10 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
11 address: 0x0000000000000000
12 content: [ 0x55 ]
13
14global-symbols:
15 - name: dyld_stub_binder
16 type: N_SECT
17 scope: [ N_EXT ]
18 sect: 1
19 value: 0x0000000000000000
20
deps/lld/test/mach-o/Inputs/wrong-arch-error.yaml created+24
......@@ -0,0 +1,24 @@
1# RUN: not lld -flavor darwin -arch x86_64 -r %s 2> %t.err
2# RUN: FileCheck %s < %t.err
3
4--- !mach-o
5arch: x86
6file-type: MH_OBJECT
7flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
8has-UUID: false
9OS: unknown
10sections:
11 - segment: __TEXT
12 section: __text
13 type: S_REGULAR
14 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
15 alignment: 4
16 address: 0x0000000000000000
17 content: [ 0xC3 ]
18
19global-symbols:
20 - name: _bar
21 type: N_SECT
22 scope: [ N_EXT ]
23 sect: 1
24 value: 0x0000000000000000
deps/lld/test/mach-o/Inputs/x86/libSystem.yaml created+13
......@@ -0,0 +1,13 @@
1#
2# For use by test cases that create dynamic output types which may needs stubs
3# and therefore will need a dylib definition of dyld_stub_binder.
4#
5
6--- !mach-o
7arch: x86
8file-type: MH_DYLIB
9install-name: /usr/lib/libSystem.B.dylib
10exports:
11 - name: dyld_stub_binder
12
13...
deps/lld/test/mach-o/Inputs/x86_64/libSystem.yaml created+13
......@@ -0,0 +1,13 @@
1#
2# For use by test cases that create dynamic output types which may needs stubs
3# and therefore will need a dylib definition of dyld_stub_binder.
4#
5
6--- !mach-o
7arch: x86_64
8file-type: MH_DYLIB
9install-name: /usr/lib/libSystem.B.dylib
10exports:
11 - name: dyld_stub_binder
12
13...
deps/lld/test/mach-o/PIE.yaml created+40
......@@ -0,0 +1,40 @@
1# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s \
2# RUN: %p/Inputs/PIE.yaml -o %t && \
3# RUN: llvm-objdump -macho -private-headers %t | FileCheck %s
4#
5# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s \
6# RUN: %p/Inputs/PIE.yaml -pie -o %t\
7# RUN: && llvm-objdump -macho -private-headers %t | FileCheck %s
8#
9# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s \
10# RUN: %p/Inputs/PIE.yaml -no_pie -o %t\
11# RUN: && llvm-objdump -macho -private-headers %t \
12# RUN: | FileCheck --check-prefix=CHECK_NO_PIE %s
13#
14# Test various PIE options.
15#
16
17--- !mach-o
18arch: x86_64
19file-type: MH_OBJECT
20flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
21has-UUID: false
22OS: unknown
23sections:
24 - segment: __TEXT
25 section: __text
26 type: S_REGULAR
27 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
28 address: 0x0000000000000000
29 content: [ 0xC3 ]
30global-symbols:
31 - name: _main
32 type: N_SECT
33 scope: [ N_EXT ]
34 sect: 1
35 value: 0x0000000000000000
36
37...
38
39# CHECK: MH_MAGIC_64 {{[0-9a-zA-Z _]+}} TWOLEVEL PIE
40# CHECK_NO_PIE-NOT: MH_MAGIC_64 {{[0-9a-zA-Z _]+}} TWOLEVEL PIE
deps/lld/test/mach-o/align_text.yaml created+45
......@@ -0,0 +1,45 @@
1# RUN: lld -flavor darwin -arch x86_64 -r %s -o %t -print_atoms | FileCheck %s
2# RUN: lld -flavor darwin -arch x86_64 -r %t -o %t2 -print_atoms | FileCheck %s
3#
4# Test that alignment info round trips through -r
5#
6
7--- !mach-o
8arch: x86_64
9file-type: MH_OBJECT
10flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
11sections:
12 - segment: __TEXT
13 section: __text
14 type: S_REGULAR
15 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
16 alignment: 16
17 address: 0x0000000000000000
18 content: [ 0x90, 0x90, 0x90, 0xC3, 0xC3, 0xC3 ]
19local-symbols:
20 - name: _f1
21 type: N_SECT
22 sect: 1
23 value: 0x0000000000000003
24 - name: _f2
25 type: N_SECT
26 sect: 1
27 value: 0x0000000000000004
28 - name: _f3
29 type: N_SECT
30 sect: 1
31 value: 0x0000000000000005
32...
33
34# CHECK: defined-atoms:
35# CHECK: - content: [ 90, 90, 90 ]
36# CHECK: alignment: 16
37# CHECK: - name: _f1
38# CHECK: content: [ C3 ]
39# CHECK: alignment: 3 mod 16
40# CHECK: - name: _f2
41# CHECK: content: [ C3 ]
42# CHECK: alignment: 4 mod 16
43# CHECK: - name: _f3
44# CHECK: content: [ C3 ]
45# CHECK: alignment: 5 mod 16
deps/lld/test/mach-o/arm-interworking-movw.yaml created+393
......@@ -0,0 +1,393 @@
1# REQUIRES: arm
2# RUN: lld -flavor darwin -arch armv7 -r -print_atoms %s -o %t | FileCheck %s
3# RUN: lld -flavor darwin -arch armv7 -dylib -print_atoms %t -o %t2 \
4# RUN: %p/Inputs/armv7/libSystem.yaml -sectalign __TEXT __text 0x1000 | FileCheck %s
5# RUN: llvm-objdump -d -macho -no-symbolic-operands %t2 | FileCheck -check-prefix=CODE %s
6#
7# Test thumb and arm branches round trip through -r.
8# Test movw/movt pairs have low bit set properly for thumb vs arm.
9#
10#
11
12--- !mach-o
13arch: armv7
14file-type: MH_OBJECT
15flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
16sections:
17 - segment: __TEXT
18 section: __text
19 type: S_REGULAR
20 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
21 alignment: 2
22 address: 0x0000000000000000
23 content: [ 0x40, 0xF2, 0x25, 0x00, 0xC0, 0xF2, 0x00, 0x00,
24 0x40, 0xF2, 0x01, 0x01, 0xC0, 0xF2, 0x00, 0x01,
25 0x40, 0xF2, 0x4E, 0x02, 0xC0, 0xF2, 0x00, 0x02,
26 0x40, 0xF2, 0x2A, 0x03, 0xC0, 0xF2, 0x00, 0x03,
27 0x78, 0x44, 0x70, 0x47, 0x70, 0x47, 0x25, 0x00,
28 0x00, 0xE3, 0x00, 0x00, 0x40, 0xE3, 0xD7, 0x1F,
29 0x0F, 0xE3, 0xFF, 0x1F, 0x4F, 0xE3, 0x4E, 0x20,
30 0x00, 0xE3, 0x00, 0x20, 0x40, 0xE3, 0x00, 0x30,
31 0x00, 0xE3, 0x00, 0x30, 0x40, 0xE3, 0x0F, 0x00,
32 0x80, 0xE0, 0x1E, 0xFF, 0x2F, 0xE1, 0x1E, 0xFF,
33 0x2F, 0xE1 ]
34 relocations:
35 - offset: 0x00000042
36 scattered: true
37 type: ARM_RELOC_HALF_SECTDIFF
38 length: 1
39 pc-rel: false
40 value: 0x0000004E
41 - offset: 0x00000000
42 scattered: true
43 type: ARM_RELOC_PAIR
44 length: 1
45 pc-rel: false
46 value: 0x00000046
47 - offset: 0x0000003E
48 scattered: true
49 type: ARM_RELOC_HALF_SECTDIFF
50 length: 0
51 pc-rel: false
52 value: 0x0000004E
53 - offset: 0x00000000
54 scattered: true
55 type: ARM_RELOC_PAIR
56 length: 0
57 pc-rel: false
58 value: 0x00000046
59 - offset: 0x0000003A
60 type: ARM_RELOC_HALF
61 length: 1
62 pc-rel: false
63 extern: false
64 symbol: 1
65 - offset: 0x0000004E
66 type: ARM_RELOC_PAIR
67 length: 1
68 pc-rel: false
69 extern: false
70 symbol: 16777215
71 - offset: 0x00000036
72 type: ARM_RELOC_HALF
73 length: 0
74 pc-rel: false
75 extern: false
76 symbol: 1
77 - offset: 0x00000000
78 type: ARM_RELOC_PAIR
79 length: 0
80 pc-rel: false
81 extern: false
82 symbol: 16777215
83 - offset: 0x00000032
84 scattered: true
85 type: ARM_RELOC_HALF_SECTDIFF
86 length: 1
87 pc-rel: false
88 value: 0x00000024
89 - offset: 0x0000FFD6
90 scattered: true
91 type: ARM_RELOC_PAIR
92 length: 1
93 pc-rel: false
94 value: 0x00000046
95 - offset: 0x0000002E
96 scattered: true
97 type: ARM_RELOC_HALF_SECTDIFF
98 length: 0
99 pc-rel: false
100 value: 0x00000024
101 - offset: 0x0000FFFF
102 scattered: true
103 type: ARM_RELOC_PAIR
104 length: 0
105 pc-rel: false
106 value: 0x00000046
107 - offset: 0x0000002A
108 type: ARM_RELOC_HALF
109 length: 1
110 pc-rel: false
111 extern: false
112 symbol: 1
113 - offset: 0x00000025
114 type: ARM_RELOC_PAIR
115 length: 1
116 pc-rel: false
117 extern: false
118 symbol: 16777215
119 - offset: 0x00000026
120 type: ARM_RELOC_HALF
121 length: 0
122 pc-rel: false
123 extern: false
124 symbol: 1
125 - offset: 0x00000000
126 type: ARM_RELOC_PAIR
127 length: 0
128 pc-rel: false
129 extern: false
130 symbol: 16777215
131 - offset: 0x0000001C
132 scattered: true
133 type: ARM_RELOC_HALF_SECTDIFF
134 length: 3
135 pc-rel: false
136 value: 0x0000004E
137 - offset: 0x0000002A
138 scattered: true
139 type: ARM_RELOC_PAIR
140 length: 3
141 pc-rel: false
142 value: 0x00000020
143 - offset: 0x00000018
144 scattered: true
145 type: ARM_RELOC_HALF_SECTDIFF
146 length: 2
147 pc-rel: false
148 value: 0x0000004E
149 - offset: 0x00000000
150 scattered: true
151 type: ARM_RELOC_PAIR
152 length: 2
153 pc-rel: false
154 value: 0x00000020
155 - offset: 0x00000014
156 type: ARM_RELOC_HALF
157 length: 3
158 pc-rel: false
159 extern: false
160 symbol: 1
161 - offset: 0x0000004E
162 type: ARM_RELOC_PAIR
163 length: 3
164 pc-rel: false
165 extern: false
166 symbol: 16777215
167 - offset: 0x00000010
168 type: ARM_RELOC_HALF
169 length: 2
170 pc-rel: false
171 extern: false
172 symbol: 1
173 - offset: 0x00000000
174 type: ARM_RELOC_PAIR
175 length: 2
176 pc-rel: false
177 extern: false
178 symbol: 16777215
179 - offset: 0x0000000C
180 scattered: true
181 type: ARM_RELOC_HALF_SECTDIFF
182 length: 3
183 pc-rel: false
184 value: 0x00000024
185 - offset: 0x00000000
186 scattered: true
187 type: ARM_RELOC_PAIR
188 length: 3
189 pc-rel: false
190 value: 0x00000020
191 - offset: 0x00000008
192 scattered: true
193 type: ARM_RELOC_HALF_SECTDIFF
194 length: 2
195 pc-rel: false
196 value: 0x00000024
197 - offset: 0x00000000
198 scattered: true
199 type: ARM_RELOC_PAIR
200 length: 2
201 pc-rel: false
202 value: 0x00000020
203 - offset: 0x00000004
204 type: ARM_RELOC_HALF
205 length: 3
206 pc-rel: false
207 extern: false
208 symbol: 1
209 - offset: 0x00000025
210 type: ARM_RELOC_PAIR
211 length: 3
212 pc-rel: false
213 extern: false
214 symbol: 16777215
215 - offset: 0x00000000
216 type: ARM_RELOC_HALF
217 length: 2
218 pc-rel: false
219 extern: false
220 symbol: 1
221 - offset: 0x00000000
222 type: ARM_RELOC_PAIR
223 length: 2
224 pc-rel: false
225 extern: false
226 symbol: 16777215
227local-symbols:
228 - name: _t1
229 type: N_SECT
230 sect: 1
231 desc: [ N_ARM_THUMB_DEF ]
232 value: 0x0000000000000000
233 - name: _t2
234 type: N_SECT
235 sect: 1
236 desc: [ N_ARM_THUMB_DEF ]
237 value: 0x0000000000000024
238 - name: _a2
239 type: N_SECT
240 sect: 1
241 value: 0x000000000000004E
242 - name: _a1
243 type: N_SECT
244 sect: 1
245 value: 0x0000000000000026
246...
247
248# CHECK: defined-atoms:
249# CHECK: - name: _t1
250# CHECK: references:
251# CHECK: - kind: modeThumbCode
252# CHECK: offset: 0
253# CHECK: target: _t1
254# CHECK: - kind: thumb_movw
255# CHECK: offset: 0
256# CHECK: target: _t2
257# CHECK-NOT: addend:
258# CHECK: - kind: thumb_movt
259# CHECK: offset: 4
260# CHECK: target: _t2
261# CHECK-NOT: addend:
262# CHECK: - kind: thumb_movw_funcRel
263# CHECK: offset: 8
264# CHECK: target: _t2
265# CHECK: addend: -36
266# CHECK: - kind: thumb_movt_funcRel
267# CHECK: offset: 12
268# CHECK: target: _t2
269# CHECK: addend: -36
270# CHECK: - kind: thumb_movw
271# CHECK: offset: 16
272# CHECK: target: _a2
273# CHECK-NOT: addend:
274# CHECK: - kind: thumb_movt
275# CHECK: offset: 20
276# CHECK: target: _a2
277# CHECK-NOT: addend:
278# CHECK: - kind: thumb_movw_funcRel
279# CHECK: offset: 24
280# CHECK: target: _a2
281# CHECK: addend: -36
282# CHECK: - kind: thumb_movt_funcRel
283# CHECK: offset: 28
284# CHECK: target: _a2
285# CHECK: addend: -36
286# CHECK: - name: _t2
287# CHECK: references:
288# CHECK: - kind: modeThumbCode
289# CHECK: offset: 0
290# CHECK: target: _t2
291# CHECK: - name: _a1
292# CHECK: references:
293# CHECK: - kind: arm_movw
294# CHECK: offset: 0
295# CHECK: target: _t2
296# CHECK-NOT: addend:
297# CHECK: - kind: arm_movt
298# CHECK: offset: 4
299# CHECK: target: _t2
300# CHECK-NOT: addend:
301# CHECK: - kind: arm_movw_funcRel
302# CHECK: offset: 8
303# CHECK: target: _t2
304# CHECK: addend: -40
305# CHECK: - kind: arm_movt_funcRel
306# CHECK: offset: 12
307# CHECK: target: _t2
308# CHECK: addend: -40
309# CHECK: - kind: arm_movw
310# CHECK: offset: 16
311# CHECK: target: _a2
312# CHECK-NOT: addend:
313# CHECK: - kind: arm_movt
314# CHECK: offset: 20
315# CHECK: target: _a2
316# CHECK-NOT: addend:
317# CHECK: - kind: arm_movw_funcRel
318# CHECK: offset: 24
319# CHECK: target: _a2
320# CHECK: addend: -40
321# CHECK: - kind: arm_movt_funcRel
322# CHECK: offset: 28
323# CHECK: target: _a2
324# CHECK: addend: -40
325# CHECK: - name: _a2
326
327
328# CODE: _t1:
329# CODE-NEXT: movw r0, #4133
330# CODE-NEXT: movt r0, #0
331# CODE-NEXT: movw r1, #1
332# CODE-NEXT: movt r1, #0
333# CODE-NEXT: movw r2, #4174
334# CODE-NEXT: movt r2, #0
335# CODE-NEXT: movw r3, #42
336# CODE-NEXT: movt r3, #0
337
338
339# CODE: _a1:
340# CODE-NEXT: movw r0, #4133
341# CODE-NEXT: movt r0, #0
342# CODE-NEXT: movw r1, #65495
343# CODE-NEXT: movt r1, #65535
344# CODE-NEXT: movw r2, #4174
345# CODE-NEXT: movt r2, #0
346# CODE-NEXT: movw r3, #0
347# CODE-NEXT: movt r3, #0
348
349
350
351# .syntax unified
352# .align 2
353#
354# .code 16
355# .thumb_func _t1
356#_t1:
357# movw r0, :lower16:(_t2)
358# movt r0, :upper16:(_t2)
359# movw r1, :lower16:(_t2-(L0+4))
360# movt r1, :upper16:(_t2-(L0+4))
361# movw r2, :lower16:(_a2)
362# movt r2, :upper16:(_a2)
363# movw r3, :lower16:(_a2-(L0+4))
364# movt r3, :upper16:(_a2-(L0+4))
365#L0:
366# add r0, pc
367# bx lr
368#
369#
370# .code 16
371# .thumb_func _t2
372#_t2:
373# bx lr
374#
375#
376#
377# .code 32
378#_a1:
379# movw r0, :lower16:(_t2)
380# movt r0, :upper16:(_t2)
381# movw r1, :lower16:(_t2-(L1+8))
382# movt r1, :upper16:(_t2-(L1+8))
383# movw r2, :lower16:(_a2)
384# movt r2, :upper16:(_a2)
385# movw r3, :lower16:(_a2-(L1+8))
386# movt r3, :upper16:(_a2-(L1+8))
387#L1:
388# add r0, pc
389# bx lr
390#
391#_a2:
392# bx lr
393
deps/lld/test/mach-o/arm-interworking.yaml created+288
......@@ -0,0 +1,288 @@
1# RUN: lld -flavor darwin -arch armv7 -r -print_atoms %s \
2# RUN: %p/Inputs/arm-interworking.yaml -o %t | FileCheck %s \
3# RUN: && lld -flavor darwin -arch armv7 -dylib -print_atoms \
4# RUN: %p/Inputs/armv7/libSystem.yaml %t -o %t2 | FileCheck %s \
5# RUN: && llvm-readobj -s -sd %t2 | FileCheck -check-prefix=CODE %s
6#
7# Test thumb and arm branches round trip through -r.
8# Test bl/blx instructions are fixed up properly.
9#
10#
11
12--- !mach-o
13arch: armv7
14file-type: MH_OBJECT
15flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
16sections:
17 - segment: __TEXT
18 section: __text
19 type: S_REGULAR
20 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
21 alignment: 2
22 address: 0x0000000000000000
23 content: [ 0xFF, 0xF7, 0xFE, 0xFF, 0xC0, 0x46, 0xFF, 0xF7,
24 0xFC, 0xEF, 0xC0, 0x46, 0xFF, 0xF7, 0xF8, 0xEF,
25 0xFF, 0xF7, 0xF6, 0xFF, 0xC0, 0x46, 0xFF, 0xF7,
26 0xF3, 0xFF, 0xC0, 0x46, 0x00, 0xF0, 0x06, 0xE8,
27 0xC0, 0x46, 0x00, 0xF0, 0x03, 0xF8, 0x00, 0xF0,
28 0x02, 0xF8, 0x70, 0x47, 0x70, 0x47, 0x70, 0x47 ]
29 relocations:
30 - offset: 0x00000026
31 type: ARM_THUMB_RELOC_BR22
32 length: 2
33 pc-rel: true
34 extern: false
35 symbol: 1
36 - offset: 0x00000022
37 type: ARM_THUMB_RELOC_BR22
38 length: 2
39 pc-rel: true
40 extern: false
41 symbol: 1
42 - offset: 0x0000001C
43 type: ARM_THUMB_RELOC_BR22
44 length: 2
45 pc-rel: true
46 extern: false
47 symbol: 1
48 - offset: 0x00000016
49 type: ARM_THUMB_RELOC_BR22
50 length: 2
51 pc-rel: true
52 extern: false
53 symbol: 1
54 - offset: 0x00000010
55 type: ARM_THUMB_RELOC_BR22
56 length: 2
57 pc-rel: true
58 extern: false
59 symbol: 1
60 - offset: 0x0000000C
61 type: ARM_THUMB_RELOC_BR22
62 length: 2
63 pc-rel: true
64 extern: true
65 symbol: 5
66 - offset: 0x00000006
67 type: ARM_THUMB_RELOC_BR22
68 length: 2
69 pc-rel: true
70 extern: true
71 symbol: 5
72 - offset: 0x00000000
73 type: ARM_THUMB_RELOC_BR22
74 length: 2
75 pc-rel: true
76 extern: true
77 symbol: 4
78 - segment: __DATA
79 section: __data
80 type: S_REGULAR
81 attributes: [ ]
82 address: 0x0000000000000030
83 content: [ 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
84 relocations:
85 - offset: 0x00000004
86 type: ARM_RELOC_VANILLA
87 length: 2
88 pc-rel: false
89 extern: true
90 symbol: 4
91 - offset: 0x00000000
92 type: ARM_RELOC_VANILLA
93 length: 2
94 pc-rel: false
95 extern: false
96 symbol: 1
97local-symbols:
98 - name: _t3
99 type: N_SECT
100 sect: 1
101 desc: [ N_ARM_THUMB_DEF ]
102 value: 0x000000000000002E
103 - name: _d1
104 type: N_SECT
105 sect: 2
106 value: 0x0000000000000030
107global-symbols:
108 - name: _t1
109 type: N_SECT
110 scope: [ N_EXT ]
111 sect: 1
112 desc: [ N_ARM_THUMB_DEF ]
113 value: 0x0000000000000000
114 - name: _t2
115 type: N_SECT
116 scope: [ N_EXT ]
117 sect: 1
118 desc: [ N_ARM_THUMB_DEF ]
119 value: 0x000000000000002C
120undefined-symbols:
121 - name: _a1
122 type: N_UNDF
123 scope: [ N_EXT ]
124 value: 0x0000000000000000
125 - name: _a2
126 type: N_UNDF
127 scope: [ N_EXT ]
128 value: 0x0000000000000000
129
130...
131
132
133# CHECK: defined-atoms:
134# CHECK: - name: _d1
135# CHECK: type: data
136# CHECK: references:
137# CHECK: - kind: pointer32
138# CHECK: offset: 0
139# CHECK: target: _t2
140# CHECK: - kind: pointer32
141# CHECK: offset: 4
142# CHECK: target: _a1
143# CHECK: - name: _d2
144# CHECK: type: data
145# CHECK: references:
146# CHECK: - kind: pointer32
147# CHECK: offset: 0
148# CHECK: target: _t1
149# CHECK: - kind: pointer32
150# CHECK: offset: 4
151# CHECK: target: _a1
152# CHECK: - name: _t1
153# CHECK: scope: global
154# CHECK: references:
155# CHECK: - kind: modeThumbCode
156# CHECK: offset: 0
157# CHECK: target: _t1
158# CHECK: - kind: thumb_bl22
159# CHECK: offset: 0
160# CHECK: target: _a1
161# CHECK: - kind: thumb_bl22
162# CHECK: offset: 6
163# CHECK: target: _a2
164# CHECK: - kind: thumb_bl22
165# CHECK: offset: 12
166# CHECK: target: _a2
167# CHECK: - kind: thumb_bl22
168# CHECK: offset: 16
169# CHECK: target: _t1
170# CHECK: - kind: thumb_bl22
171# CHECK: offset: 22
172# CHECK: target: _t1
173# CHECK: - kind: thumb_bl22
174# CHECK: offset: 28
175# CHECK: target: _t2
176# CHECK: - kind: thumb_bl22
177# CHECK: offset: 34
178# CHECK: target: _t2
179# CHECK: - kind: thumb_bl22
180# CHECK: offset: 38
181# CHECK: target: _t3
182# CHECK: - name: _t2
183# CHECK: scope: global
184# CHECK: content: [ 70, 47 ]
185# CHECK: references:
186# CHECK: - kind: modeThumbCode
187# CHECK: offset: 0
188# CHECK: target: _t2
189# CHECK: - name: _t3
190# CHECK: content: [ 70, 47 ]
191# CHECK: references:
192# CHECK: - kind: modeThumbCode
193# CHECK: offset: 0
194# CHECK: target: _t3
195# CHECK: - name: _a1
196# CHECK: scope: global
197# CHECK: references:
198# CHECK: - kind: arm_bl24
199# CHECK: offset: 0
200# CHECK: target: _a1
201# CHECK: - kind: arm_bl24
202# CHECK: offset: 4
203# CHECK: target: _a2
204# CHECK: - kind: arm_bl24
205# CHECK: offset: 8
206# CHECK: target: _t1
207# CHECK: - kind: arm_bl24
208# CHECK: offset: 12
209# CHECK: target: _t2
210# CHECK: - name: _a2
211# CHECK: scope: global
212
213# CODE: Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00)
214# CODE: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
215# CODE: SectionData (
216# CODE: 0000: 00F016E8 C04600F0 1EE8C046 00F01AE8
217# CODE: 0010: FFF7F6FF C046FFF7 F3FFC046 00F006F8
218# CODE: 0020: C04600F0 03F800F0 02F87047 70477047
219# CODE: 0030: FEFFFFEB 020000EB F0FFFFFA FAFFFFFA
220# CODE: 0040: 1EFF2FE1 1EFF2FE1
221# CODE: )
222
223# CODE: Name: __data (5F 5F 64 61 74 61 00 00 00 00 00 00 00 00 00 00)
224# CODE: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
225# CODE: SectionData (
226# CODE: 0000: E50F0000 E80F0000 B90F0000 E80F0000
227# CODE: )
228
229# When we get a good mach-o disassembler the above __text section content check can be change to be symbolic.
230# Verify the low (thumb) bit is set on the first and third pointers but not the second and fourth.
231
232
233
234# Input file one:
235#
236# .align 2
237# .code 16
238# .globl _t1
239# .thumb_func _t1
240#_t1:
241# bl _a1
242# nop
243# blx _a2
244# nop
245# blx _a2
246# bl _t1
247# nop
248# bl _t1
249# nop
250# blx _t2
251# nop
252# blx _t2
253# bx lr
254#
255# .globl _t2
256# .thumb_func _t2
257#_t2:
258# bx lr
259#
260# .data
261#_d1: .long _t2
262# .long _a1
263
264
265
266# Input file two:
267#
268# .align 2
269# .code 32
270# .globl _a1
271#_a1:
272# bl _a1
273# blx _a2
274# bl _t1
275# blx _t2
276# bx lr
277#
278# .globl _a2
279#_a2:
280# bx lr
281#
282# .data
283#_d2: .long _t1
284# .long _a1
285
286
287
288
deps/lld/test/mach-o/arm-shims.yaml created+126
......@@ -0,0 +1,126 @@
1# RUN: lld -flavor darwin -arch armv7 %s %p/Inputs/arm-shims.yaml \
2# RUN: -dylib %p/Inputs/armv7/libSystem.yaml -o %t
3# RUN: llvm-readobj -s -sd %t | FileCheck %s
4#
5# Test b from arm to thumb or vice versa has shims added.s
6#
7#
8
9--- !mach-o
10arch: armv7
11file-type: MH_OBJECT
12flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
13sections:
14 - segment: __TEXT
15 section: __text
16 type: S_REGULAR
17 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
18 alignment: 2
19 address: 0x0000000000000000
20 content: [ 0x00, 0xBF, 0xFF, 0xF7, 0xFE, 0xEF, 0xFF, 0xF7,
21 0xFB, 0xBF, 0x00, 0x00, 0x00, 0xF0, 0x20, 0xE3,
22 0xFA, 0xFF, 0xFF, 0xFA, 0xF9, 0xFF, 0xFF, 0xEA ]
23 relocations:
24 - offset: 0x00000014
25 type: ARM_RELOC_BR24
26 length: 2
27 pc-rel: true
28 extern: true
29 symbol: 3
30 - offset: 0x00000010
31 type: ARM_RELOC_BR24
32 length: 2
33 pc-rel: true
34 extern: true
35 symbol: 3
36 - offset: 0x00000006
37 type: ARM_THUMB_RELOC_BR22
38 length: 2
39 pc-rel: true
40 extern: true
41 symbol: 2
42 - offset: 0x00000002
43 type: ARM_THUMB_RELOC_BR22
44 length: 2
45 pc-rel: true
46 extern: true
47 symbol: 2
48global-symbols:
49 - name: _a1
50 type: N_SECT
51 scope: [ N_EXT ]
52 sect: 1
53 value: 0x000000000000000C
54 - name: _t1
55 type: N_SECT
56 scope: [ N_EXT ]
57 sect: 1
58 desc: [ N_ARM_THUMB_DEF ]
59 value: 0x0000000000000000
60undefined-symbols:
61 - name: _a2
62 type: N_UNDF
63 scope: [ N_EXT ]
64 value: 0x0000000000000000
65 - name: _t2
66 type: N_UNDF
67 scope: [ N_EXT ]
68 value: 0x0000000000000000
69
70...
71
72# CHECK: Section {
73# CHECK: Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00)
74# CHECK: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
75# CHECK: SectionData (
76# CHECK: 0000: 00BF00F0 10E800F0 19B80000 00F020E3
77# CHECK: 0010: 000000FA 0F0000EA 00BFFFF7 F8EF00F0
78# CHECK: 0020: 07B80000 00F020E3 F4FFFFFA 050000EA
79# CHECK: 0030: DFF804C0 FF446047 D4FFFFFF DFF804C0
80# CHECK: 0040: FF446047 E0FFFFFF 04C09FE5 0CC08FE0
81# CHECK: 0050: 1CFF2FE1 ADFFFFFF 04C09FE5 0CC08FE0
82# CHECK: 0060: 1CFF2FE1 B5FFFFFF
83# CHECK: )
84
85# When we get a good mach-o disassembler the above __text section content check can be change to be symbolic.
86
87
88# Input file one:
89#
90# .align 2
91# .code 16
92# .globl _t1
93# .thumb_func _t1
94#_t1:
95# nop
96# blx _a2
97# b _a2
98#
99# .code 32
100# .align 2
101# .globl _a1
102#_a1:
103# nop
104# blx _t2
105# b _t2
106
107
108
109# Input file two:
110#
111# .align 2
112# .code 16
113# .globl _t2
114# .thumb_func _t2
115#_t2:
116# nop
117# blx _a1
118# b _a1
119#
120# .code 32
121# .align 2
122# .globl _a2
123#_a2:
124# nop
125# blx _t1
126# b _t1
deps/lld/test/mach-o/arm-subsections-via-symbols.yaml created+60
......@@ -0,0 +1,60 @@
1# RUN: lld -flavor darwin -arch armv7 %s -r -print_atoms -o %t | FileCheck %s
2#
3# Test that assembly written without .subsections_via_symbols is parsed so
4# that atoms are non-dead-strip and there is a layout-after references
5# chaining atoms together.
6#
7
8--- !mach-o
9arch: armv7
10file-type: MH_OBJECT
11flags: [ ]
12has-UUID: false
13OS: unknown
14sections:
15 - segment: __TEXT
16 section: __text
17 type: S_REGULAR
18 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
19 alignment: 2
20 address: 0x0000000000000000
21 content: [ 0x04, 0x10, 0x9F, 0xE5, 0x04, 0x20, 0x9F, 0xE5,
22 0x1E, 0xFF, 0x2F, 0xE1, 0x78, 0x56, 0x34, 0x12,
23 0x21, 0x43, 0x65, 0x87 ]
24local-symbols:
25 - name: constants1
26 type: N_SECT
27 sect: 1
28 value: 0x000000000000000C
29 - name: constants2
30 type: N_SECT
31 sect: 1
32 value: 0x0000000000000010
33global-symbols:
34 - name: _foo
35 type: N_SECT
36 scope: [ N_EXT ]
37 sect: 1
38 value: 0x0000000000000000
39...
40
41
42# CHECK:defined-atoms:
43# CHECK: - name: _foo
44# CHECK: scope: global
45# CHECK: content: [ 04, 10, 9F, E5, 04, 20, 9F, E5, 1E, FF, 2F, E1 ]
46# CHECK: dead-strip: never
47# CHECK: references:
48# CHECK: - kind: layout-after
49# CHECK: offset: 0
50# CHECK: target: constants1
51# CHECK: - name: constants1
52# CHECK: content: [ 78, 56, 34, 12 ]
53# CHECK: dead-strip: never
54# CHECK: references:
55# CHECK: - kind: layout-after
56# CHECK: offset: 0
57# CHECK: target: constants2
58# CHECK: - name: constants2
59# CHECK: content: [ 21, 43, 65, 87 ]
60# CHECK: dead-strip: never
deps/lld/test/mach-o/arm64-reloc-negDelta32-fixup.yaml created+124
......@@ -0,0 +1,124 @@
1# RUN: lld -flavor darwin -arch arm64 -r %s -o %t
2# RUN: lld -flavor darwin -arch arm64 -r %t -o %t2
3# RUN: llvm-objdump -s -section="__eh_frame" %t | FileCheck %s
4# RUN: llvm-objdump -s -section="__eh_frame" %t2 | FileCheck %s
5
6# The reference from FDE->CIE is implicitly created as a negDelta32.
7# We don't emit these in to the binary as relocations, so we need to
8# make sure that the offset in the FDE to the CIE is the correct value.
9# CHECK: {{[0-9abcdef]*}} 10000000 00000000 017a5200 01781e01
10# CHECK: {{[0-9abcdef]*}} 100c1f00 20000000 18000000 b8ffffff
11# Note, this one that matters ^~~~~~~~
12# It needs to be 0x18 as that is the offset back to 0 where the CIE is.
13# CHECK: {{[0-9abcdef]*}} ffffffff 20000000 00000000 00480e10
14# CHECK: {{[0-9abcdef]*}} 9e019d02 00000000
15
16--- !mach-o
17arch: arm64
18file-type: MH_OBJECT
19flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
20compat-version: 0.0
21current-version: 0.0
22has-UUID: false
23OS: unknown
24sections:
25 - segment: __TEXT
26 section: __text
27 type: S_REGULAR
28 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
29 alignment: 4
30 address: 0x0000000000000000
31 content: [ 0xFD, 0x7B, 0xBF, 0xA9, 0xFD, 0x03, 0x00, 0x91,
32 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x91,
33 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x80, 0x52,
34 0xFD, 0x7B, 0xC1, 0xA8, 0xC0, 0x03, 0x5F, 0xD6 ]
35 relocations:
36 - offset: 0x00000010
37 type: ARM64_RELOC_BRANCH26
38 length: 2
39 pc-rel: true
40 extern: true
41 symbol: 6
42 - offset: 0x0000000C
43 type: ARM64_RELOC_PAGEOFF12
44 length: 2
45 pc-rel: false
46 extern: true
47 symbol: 1
48 - offset: 0x00000008
49 type: ARM64_RELOC_PAGE21
50 length: 2
51 pc-rel: true
52 extern: true
53 symbol: 1
54 - segment: __TEXT
55 section: __cstring
56 type: S_CSTRING_LITERALS
57 attributes: [ ]
58 address: 0x0000000000000020
59 content: [ 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F,
60 0x72, 0x6C, 0x64, 0x00 ]
61 - segment: __LD
62 section: __compact_unwind
63 type: S_REGULAR
64 attributes: [ ]
65 alignment: 8
66 address: 0x0000000000000030
67 content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
69 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
71 relocations:
72 - offset: 0x00000000
73 type: ARM64_RELOC_UNSIGNED
74 length: 3
75 pc-rel: false
76 extern: false
77 symbol: 1
78 - segment: __TEXT
79 section: __eh_frame
80 type: S_COALESCED
81 attributes: [ ]
82 alignment: 8
83 address: 0x0000000000000050
84 content: [ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
85 0x01, 0x7A, 0x52, 0x00, 0x01, 0x78, 0x1E, 0x01,
86 0x10, 0x0C, 0x1F, 0x00, 0x20, 0x00, 0x00, 0x00,
87 0x18, 0x00, 0x00, 0x00, 0x94, 0xFF, 0xFF, 0xFF,
88 0xFF, 0xFF, 0xFF, 0xFF, 0x20, 0x00, 0x00, 0x00,
89 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x0E, 0x10,
90 0x9E, 0x01, 0x9D, 0x02, 0x00, 0x00, 0x00, 0x00 ]
91local-symbols:
92 - name: ltmp0
93 type: N_SECT
94 sect: 1
95 value: 0x0000000000000000
96 - name: L_str
97 type: N_SECT
98 sect: 2
99 value: 0x0000000000000020
100 - name: ltmp1
101 type: N_SECT
102 sect: 2
103 value: 0x0000000000000020
104 - name: ltmp2
105 type: N_SECT
106 sect: 3
107 value: 0x0000000000000030
108 - name: ltmp3
109 type: N_SECT
110 sect: 4
111 value: 0x0000000000000050
112global-symbols:
113 - name: __Z3fooi
114 type: N_SECT
115 scope: [ N_EXT ]
116 sect: 1
117 value: 0x0000000000000000
118undefined-symbols:
119 - name: _puts
120 type: N_UNDF
121 scope: [ N_EXT ]
122 value: 0x0000000000000000
123page-size: 0x00000000
124...
deps/lld/test/mach-o/arm64-relocs-errors-delta64-offset.yaml created+65
......@@ -0,0 +1,65 @@
1# RUN: not lld -flavor darwin -arch arm64 %s -r \
2# RUN: 2> %t.err
3# RUN: FileCheck %s < %t.err
4
5
6--- !mach-o
7arch: arm64
8file-type: MH_OBJECT
9flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
10sections:
11 - segment: __TEXT
12 section: __text
13 type: S_REGULAR
14 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
15 alignment: 4
16 address: 0x0000000000000000
17 content: [ 0xFF, 0x83, 0x00, 0xD1, 0xE0, 0x0B, 0x00, 0xF9,
18 0x08, 0x00, 0x40, 0xB9, 0x08, 0x0D, 0x00, 0x71,
19 0x08, 0x09, 0x00, 0x71, 0xE8, 0x0F, 0x00, 0xB9,
20 0xC8, 0x00, 0x00, 0x54, 0x01, 0x00, 0x00, 0x14,
21 0xE8, 0x03, 0x00, 0x32, 0x08, 0x01, 0x00, 0x12,
22 0xE8, 0x7F, 0x00, 0x39, 0x02, 0x00, 0x00, 0x14 ]
23 - segment: __DATA
24 section: __data
25 type: S_REGULAR
26 attributes: [ ]
27 alignment: 8
28 address: 0x000000000001C348
29 content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
30 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
31 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
32 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
33 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
34 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
35 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
36 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
37 relocations:
38
39# Make sure that the offsets of the subtractor and unsigned both match.
40# CHECK: bad relocation (paired relocs must have the same offset) in section __DATA/__data (r1_address=1, r1_type=1, r1_extern=1, r1_length=3, r1_pcrel=0, r1_symbolnum=1), (r2_address=0, r2_type=0, r2_extern=1, r2_length=3, r2_pcrel=0, r2_symbolnum=1)
41 - offset: 0x00000001
42 type: ARM64_RELOC_SUBTRACTOR
43 length: 3
44 pc-rel: false
45 extern: true
46 symbol: 1
47 - offset: 0x00000000
48 type: ARM64_RELOC_UNSIGNED
49 length: 3
50 pc-rel: false
51 extern: true
52 symbol: 1
53global-symbols:
54 - name: _f1
55 type: N_SECT
56 sect: 2
57 value: 0x000000000001C348
58 - name: _f2
59 type: N_SECT
60 sect: 1
61 value: 0x0000000000000010
62 - name: _f3
63 type: N_SECT
64 sect: 1
65 value: 0x0000000000000020
deps/lld/test/mach-o/arm64-section-order.yaml created+67
......@@ -0,0 +1,67 @@
1# RUN: lld -flavor darwin -arch arm64 -r -print_atoms %s -o %t
2# RUN: lld -flavor darwin -arch arm64 -r -print_atoms %t -o %t2
3# RUN: llvm-objdump -section-headers %t | FileCheck %s
4# RUN: llvm-objdump -section-headers %t2 | FileCheck %s
5
6# Make sure that the sections are sorted. Currently we want this order:
7# __text, __unwind_info
8
9# CHECK: Sections:
10# CHECK: 0 __text {{.*}} TEXT
11# CHECK: 1 __compact_unwind {{.*}}
12
13
14--- !mach-o
15arch: arm64
16file-type: MH_OBJECT
17flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
18compat-version: 0.0
19current-version: 0.0
20has-UUID: false
21OS: unknown
22sections:
23 - segment: __TEXT
24 section: __text
25 type: S_REGULAR
26 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
27 alignment: 8
28 address: 0x0000000000000000
29 content: [ 0xC0, 0x03, 0x5F, 0xD6, 0xC0, 0x03, 0x5F, 0xD6 ]
30 - segment: __LD
31 section: __compact_unwind
32 type: S_REGULAR
33 attributes: [ ]
34 alignment: 8
35 address: 0x0000000000000008
36 content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
37 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
38 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
40 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
41 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
42 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
43 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
44 relocations:
45 - offset: 0x00000020
46 type: ARM64_RELOC_UNSIGNED
47 length: 3
48 pc-rel: false
49 extern: false
50 symbol: 1
51 - offset: 0x00000000
52 type: ARM64_RELOC_UNSIGNED
53 length: 3
54 pc-rel: false
55 extern: false
56 symbol: 1
57global-symbols:
58 - name: __Z3fooi
59 type: N_SECT
60 scope: [ N_EXT ]
61 sect: 1
62 value: 0x0000000000000000
63 - name: __Z4foo2i
64 type: N_SECT
65 scope: [ N_EXT ]
66 sect: 1
67 value: 0x0000000000000004
deps/lld/test/mach-o/bind-opcodes.yaml created+143
......@@ -0,0 +1,143 @@
1# RUN: lld -flavor darwin -arch arm64 %s %p/Inputs/hello-world-arm64.yaml -o %t
2# RUN: obj2yaml %t | FileCheck %s
3#
4
5--- !mach-o
6arch: arm64
7file-type: MH_OBJECT
8flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
9sections:
10 - segment: __TEXT
11 section: __text
12 type: S_REGULAR
13 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
14 alignment: 2
15 address: 0x0000000000000000
16 content: [ 0xFD, 0x7B, 0xBF, 0xA9, 0xFD, 0x03, 0x00, 0x91,
17 0x08, 0x00, 0x00, 0x90, 0x08, 0x01, 0x40, 0xF9,
18 0x00, 0x01, 0x40, 0xF9, 0x01, 0x00, 0x00, 0x90,
19 0x21, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x94,
20 0x00, 0x00, 0x80, 0x52, 0xFD, 0x7B, 0xC1, 0xA8,
21 0xC0, 0x03, 0x5F, 0xD6 ]
22 relocations:
23 - offset: 0x0000001C
24 type: ARM64_RELOC_BRANCH26
25 length: 2
26 pc-rel: true
27 extern: true
28 symbol: 5
29 - offset: 0x00000018
30 type: ARM64_RELOC_PAGEOFF12
31 length: 2
32 pc-rel: false
33 extern: true
34 symbol: 1
35 - offset: 0x00000014
36 type: ARM64_RELOC_PAGE21
37 length: 2
38 pc-rel: true
39 extern: true
40 symbol: 1
41 - offset: 0x0000000C
42 type: ARM64_RELOC_GOT_LOAD_PAGEOFF12
43 length: 2
44 pc-rel: false
45 extern: true
46 symbol: 4
47 - offset: 0x00000008
48 type: ARM64_RELOC_GOT_LOAD_PAGE21
49 length: 2
50 pc-rel: true
51 extern: true
52 symbol: 4
53 - segment: __TEXT
54 section: __cstring
55 type: S_CSTRING_LITERALS
56 attributes: [ ]
57 address: 0x000000000000002C
58 content: [ 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x00 ]
59local-symbols:
60 - name: ltmp0
61 type: N_SECT
62 sect: 1
63 value: 0x0000000000000000
64 - name: l_.str
65 type: N_SECT
66 sect: 2
67 value: 0x000000000000002C
68 - name: ltmp1
69 type: N_SECT
70 sect: 2
71 value: 0x000000000000002C
72global-symbols:
73 - name: _main
74 type: N_SECT
75 scope: [ N_EXT ]
76 sect: 1
77 value: 0x0000000000000000
78undefined-symbols:
79 - name: ___stdoutp
80 type: N_UNDF
81 scope: [ N_EXT ]
82 value: 0x0000000000000000
83 - name: _fprintf
84 type: N_UNDF
85 scope: [ N_EXT ]
86 value: 0x0000000000000000
87...
88
89
90# CHECK: BindOpcodes:
91# CHECK: - Opcode: BIND_OPCODE_SET_DYLIB_ORDINAL_IMM
92# CHECK: Imm: 1
93# CHECK: Symbol: ''
94# CHECK: - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM
95# CHECK: Imm: 0
96# CHECK: Symbol: dyld_stub_binder
97# CHECK: - Opcode: BIND_OPCODE_SET_TYPE_IMM
98# CHECK: Imm: 1
99# CHECK: Symbol: ''
100# CHECK: - Opcode: BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
101# CHECK: Imm: 2
102# CHECK: ULEBExtraData:
103# CHECK: - 0x0000000000000000
104# CHECK: Symbol: ''
105# CHECK: - Opcode: BIND_OPCODE_DO_BIND
106# CHECK: Imm: 0
107# CHECK: Symbol: ''
108# CHECK: - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM
109# CHECK: Imm: 0
110# CHECK: Symbol: ___stdoutp
111# CHECK: - Opcode: BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
112# CHECK: Imm: 2
113# CHECK: ULEBExtraData:
114# CHECK: - 0x0000000000000010
115# CHECK: Symbol: ''
116# CHECK: - Opcode: BIND_OPCODE_DO_BIND
117# CHECK: Imm: 0
118# CHECK: Symbol: ''
119# CHECK: - Opcode: BIND_OPCODE_DONE
120# CHECK: Imm: 0
121# CHECK: Symbol: ''
122
123# CHECK: LazyBindOpcodes:
124# CHECK: - Opcode: BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
125# CHECK: Imm: 2
126# CHECK: ULEBExtraData:
127# CHECK: - 0x0000000000000018
128# CHECK: Symbol: ''
129# CHECK: - Opcode: BIND_OPCODE_SET_DYLIB_ORDINAL_IMM
130# CHECK: Imm: 1
131# CHECK: Symbol: ''
132# CHECK: - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM
133# CHECK: Imm: 0
134# CHECK: Symbol: _fprintf
135# CHECK: - Opcode: BIND_OPCODE_DO_BIND
136# CHECK: Imm: 0
137# CHECK: Symbol: ''
138# CHECK: - Opcode: BIND_OPCODE_DONE
139# CHECK: Imm: 0
140# CHECK: Symbol: ''
141# CHECK: - Opcode: BIND_OPCODE_DONE
142# CHECK: Imm: 0
143# CHECK: Symbol: ''
\ No newline at end of file
deps/lld/test/mach-o/cstring-sections.yaml created+65
......@@ -0,0 +1,65 @@
1# RUN: lld -flavor darwin -arch x86_64 -r %s -o %t -print_atoms | FileCheck %s
2#
3# Test -keep_private_externs in -r mode.
4#
5
6--- !mach-o
7arch: x86_64
8file-type: MH_OBJECT
9flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
10sections:
11 - segment: __TEXT
12 section: __objc_methname
13 type: S_CSTRING_LITERALS
14 attributes: [ ]
15 address: 0x0000000000000000
16 content: [ 0x61, 0x62, 0x63, 0x00, 0x64, 0x65, 0x66, 0x00 ]
17 - segment: __TEXT
18 section: __objc_classname
19 type: S_CSTRING_LITERALS
20 attributes: [ ]
21 address: 0x0000000000000006
22 content: [ 0x61, 0x62, 0x63, 0x00, 0x67, 0x68, 0x69, 0x00 ]
23 - segment: __TEXT
24 section: __cstring
25 type: S_CSTRING_LITERALS
26 attributes: [ ]
27 address: 0x000000000000000A
28 content: [ 0x61, 0x62, 0x63, 0x00, 0x6A, 0x6B, 0x6C, 0x00 ]
29
30
31...
32
33# CHECK: defined-atoms:
34# CHECK: - scope: hidden
35# CHECK: type: c-string
36# CHECK: content: [ 61, 62, 63, 00 ]
37# CHECK: merge: by-content
38# CHECK: section-choice: custom-required
39# CHECK: section-name: __TEXT/__objc_methname
40# CHECK: - scope: hidden
41# CHECK: type: c-string
42# CHECK: content: [ 64, 65, 66, 00 ]
43# CHECK: merge: by-content
44# CHECK: section-choice: custom-required
45# CHECK: section-name: __TEXT/__objc_methname
46# CHECK: - scope: hidden
47# CHECK: type: c-string
48# CHECK: content: [ 61, 62, 63, 00 ]
49# CHECK: merge: by-content
50# CHECK: section-choice: custom-required
51# CHECK: section-name: __TEXT/__objc_classname
52# CHECK: - scope: hidden
53# CHECK: type: c-string
54# CHECK: content: [ 67, 68, 69, 00 ]
55# CHECK: merge: by-content
56# CHECK: section-choice: custom-required
57# CHECK: section-name: __TEXT/__objc_classname
58# CHECK: - scope: hidden
59# CHECK: type: c-string
60# CHECK: content: [ 61, 62, 63, 00 ]
61# CHECK: merge: by-content
62# CHECK: - scope: hidden
63# CHECK: type: c-string
64# CHECK: content: [ 6A, 6B, 6C, 00 ]
65# CHECK: merge: by-content
deps/lld/test/mach-o/data-in-code-load-command.yaml created+35
......@@ -0,0 +1,35 @@
1# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml && llvm-objdump -private-headers %t | FileCheck %s
2# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -static -data_in_code_info && llvm-objdump -private-headers %t | FileCheck %s
3# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -no_data_in_code_info && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_DATA_IN_CODE_INFO
4# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -static -data_in_code_info -no_data_in_code_info && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_DATA_IN_CODE_INFO
5# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -static && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_DATA_IN_CODE_INFO
6# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -r && llvm-objdump -private-headers %t | FileCheck %s
7# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -r -data_in_code_info && llvm-objdump -private-headers %t | FileCheck %s
8# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -r -no_data_in_code_info && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_DATA_IN_CODE_INFO
9
10--- !mach-o
11arch: x86_64
12file-type: MH_OBJECT
13flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
14sections:
15 - segment: __TEXT
16 section: __text
17 type: S_REGULAR
18 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
19 address: 0x0000000000000000
20 content: [ 0x00, 0x00, 0x00, 0x00 ]
21global-symbols:
22 - name: _main
23 type: N_SECT
24 scope: [ N_EXT ]
25 sect: 1
26 value: 0x0000000000000000
27...
28
29# CHECK: Load command {{[0-9]*}}
30# CHECK: cmd LC_DATA_IN_CODE
31# CHECK: cmdsize 16
32# CHECK: dataoff
33# CHECK: datasize
34
35# NO_DATA_IN_CODE_INFO-NOT: LC_DATA_IN_CODE
deps/lld/test/mach-o/data-only-dylib.yaml created+27
......@@ -0,0 +1,27 @@
1# RUN: lld -flavor darwin -arch x86_64 -dylib %s -o %t %p/Inputs/x86_64/libSystem.yaml
2# RUN: llvm-nm %t | FileCheck %s
3#
4# Test that a data-only dylib can be built.
5#
6
7--- !mach-o
8arch: x86_64
9file-type: MH_OBJECT
10flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
11sections:
12 - segment: __DATA
13 section: __data
14 type: S_REGULAR
15 attributes: [ ]
16 alignment: 2
17 address: 0x0000000000000000
18 content: [ 0x00, 0x00, 0x00, 0x00 ]
19global-symbols:
20 - name: _myData
21 type: N_SECT
22 scope: [ N_EXT ]
23 sect: 1
24 value: 0x0000000000000000
25...
26
27# CHECK: _myData
deps/lld/test/mach-o/dead-strip-globals.yaml created+31
......@@ -0,0 +1,31 @@
1# RUN: lld -flavor darwin -arch x86_64 -dead_strip -export_dynamic %s -dylib %p/Inputs/x86_64/libSystem.yaml -o %t.dylib -print_atoms | FileCheck -check-prefix=CHECK1 %s
2# RUN: lld -flavor darwin -arch x86_64 -export_dynamic -dead_strip %s -dylib %p/Inputs/x86_64/libSystem.yaml -o %t.dylib -print_atoms | FileCheck -check-prefix=CHECK1 %s
3# RUN: lld -flavor darwin -arch x86_64 -dead_strip %s -dylib %p/Inputs/x86_64/libSystem.yaml -o %t2.dylib -print_atoms | FileCheck -check-prefix=CHECK2 %s
4
5# RUN: lld -flavor darwin -arch x86_64 -r %s -dylib %p/Inputs/x86_64/libSystem.yaml -o %t3.o
6# RUN: llvm-nm -m %t3.o | FileCheck -check-prefix=RELOCATABLE_SYMBOLS %s
7
8#
9# Test that -export_dynamic -dead-strip from removing globals.
10#
11
12---
13defined-atoms:
14 - name: def
15 scope: global
16 dead-strip: never
17 - name: dead
18 scope: global
19shared-library-atoms:
20 - name: dyld_stub_binder
21 load-name: /usr/lib/libSystem.B.dylib
22 type: unknown
23...
24
25# CHECK1: name: def
26# CHECK1: name: dead
27
28# CHECK2: name: def
29# CHECK2-NOT: name: dead
30
31# RELOCATABLE_SYMBOLS: external def
deps/lld/test/mach-o/debug-syms.yaml created+249
......@@ -0,0 +1,249 @@
1# RUN: lld -flavor darwin -arch x86_64 -o %t %s -dylib %p/Inputs/x86_64/libSystem.yaml && \
2# RUN: llvm-nm -no-sort -debug-syms %t | FileCheck %s
3
4# CHECK: 0000000000000000 - 00 0000 SO /Users/lhames/Projects/lld/lld-svn-tot/scratch/
5# CHECK-NEXT: 0000000000000000 - 00 0000 SO hw.c
6# CHECK-NEXT: {{[0-9a-f]+}} - 03 0001 OSO {{.*}}{{/|\\}}test{{/|\\}}mach-o{{/|\\}}debug-syms.yaml
7# CHECK-NEXT: 0000000000000fa0 - 01 0000 BNSYM
8# CHECK-NEXT: 0000000000000fa0 - 01 0000 FUN _main
9# CHECK-NEXT: 0000000000000016 - 00 0000 FUN
10# CHECK-NEXT: 0000000000000016 - 01 0000 ENSYM
11# CHECK-NEXT: 0000000000000000 - 01 0000 SO
12
13--- !mach-o
14arch: x86_64
15file-type: MH_OBJECT
16flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
17compat-version: 0.0
18current-version: 0.0
19has-UUID: false
20OS: unknown
21min-os-version-kind: LC_VERSION_MIN_MACOSX
22sections:
23 - segment: __TEXT
24 section: __text
25 type: S_REGULAR
26 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
27 alignment: 16
28 address: 0x0000000000000000
29 content: [ 0x55, 0x48, 0x89, 0xE5, 0x31, 0xC0, 0xC7, 0x45,
30 0xFC, 0x00, 0x00, 0x00, 0x00, 0x89, 0x7D, 0xF8,
31 0x48, 0x89, 0x75, 0xF0, 0x5D, 0xC3 ]
32 - segment: __DWARF
33 section: __debug_str
34 type: S_REGULAR
35 attributes: [ S_ATTR_DEBUG ]
36 address: 0x0000000000000016
37 content: [ 0x41, 0x70, 0x70, 0x6C, 0x65, 0x20, 0x4C, 0x4C,
38 0x56, 0x4D, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69,
39 0x6F, 0x6E, 0x20, 0x38, 0x2E, 0x30, 0x2E, 0x30,
40 0x20, 0x28, 0x63, 0x6C, 0x61, 0x6E, 0x67, 0x2D,
41 0x38, 0x30, 0x30, 0x2E, 0x30, 0x2E, 0x32, 0x34,
42 0x2E, 0x31, 0x29, 0x00, 0x68, 0x77, 0x2E, 0x63,
43 0x00, 0x2F, 0x55, 0x73, 0x65, 0x72, 0x73, 0x2F,
44 0x6C, 0x68, 0x61, 0x6D, 0x65, 0x73, 0x2F, 0x50,
45 0x72, 0x6F, 0x6A, 0x65, 0x63, 0x74, 0x73, 0x2F,
46 0x6C, 0x6C, 0x64, 0x2F, 0x6C, 0x6C, 0x64, 0x2D,
47 0x73, 0x76, 0x6E, 0x2D, 0x74, 0x6F, 0x74, 0x2F,
48 0x73, 0x63, 0x72, 0x61, 0x74, 0x63, 0x68, 0x00,
49 0x6D, 0x61, 0x69, 0x6E, 0x00, 0x69, 0x6E, 0x74,
50 0x00, 0x61, 0x72, 0x67, 0x63, 0x00, 0x61, 0x72,
51 0x67, 0x76, 0x00, 0x63, 0x68, 0x61, 0x72, 0x00 ]
52 - segment: __DWARF
53 section: __debug_loc
54 type: S_REGULAR
55 attributes: [ S_ATTR_DEBUG ]
56 address: 0x000000000000008E
57 - segment: __DWARF
58 section: __debug_abbrev
59 type: S_REGULAR
60 attributes: [ S_ATTR_DEBUG ]
61 address: 0x000000000000008E
62 content: [ 0x01, 0x11, 0x01, 0x25, 0x0E, 0x13, 0x05, 0x03,
63 0x0E, 0x10, 0x06, 0x1B, 0x0E, 0x11, 0x01, 0x12,
64 0x01, 0x00, 0x00, 0x02, 0x2E, 0x01, 0x11, 0x01,
65 0x12, 0x01, 0x40, 0x0A, 0x03, 0x0E, 0x3A, 0x0B,
66 0x3B, 0x0B, 0x27, 0x0C, 0x49, 0x13, 0x3F, 0x0C,
67 0x00, 0x00, 0x03, 0x05, 0x00, 0x02, 0x0A, 0x03,
68 0x0E, 0x3A, 0x0B, 0x3B, 0x0B, 0x49, 0x13, 0x00,
69 0x00, 0x04, 0x24, 0x00, 0x03, 0x0E, 0x3E, 0x0B,
70 0x0B, 0x0B, 0x00, 0x00, 0x05, 0x0F, 0x00, 0x49,
71 0x13, 0x00, 0x00, 0x00 ]
72 - segment: __DWARF
73 section: __debug_info
74 type: S_REGULAR
75 attributes: [ S_ATTR_DEBUG ]
76 address: 0x00000000000000DA
77 content: [ 0x7F, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
78 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00,
79 0x0C, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00,
80 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00,
81 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00,
82 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
83 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16,
84 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
85 0x56, 0x60, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01,
86 0x6A, 0x00, 0x00, 0x00, 0x01, 0x03, 0x02, 0x91,
87 0x78, 0x69, 0x00, 0x00, 0x00, 0x01, 0x01, 0x6A,
88 0x00, 0x00, 0x00, 0x03, 0x02, 0x91, 0x70, 0x6E,
89 0x00, 0x00, 0x00, 0x01, 0x01, 0x71, 0x00, 0x00,
90 0x00, 0x00, 0x04, 0x65, 0x00, 0x00, 0x00, 0x05,
91 0x04, 0x05, 0x76, 0x00, 0x00, 0x00, 0x05, 0x7B,
92 0x00, 0x00, 0x00, 0x04, 0x73, 0x00, 0x00, 0x00,
93 0x06, 0x01, 0x00 ]
94 relocations:
95 - offset: 0x00000037
96 type: X86_64_RELOC_UNSIGNED
97 length: 3
98 pc-rel: false
99 extern: false
100 symbol: 1
101 - offset: 0x0000002F
102 type: X86_64_RELOC_UNSIGNED
103 length: 3
104 pc-rel: false
105 extern: false
106 symbol: 1
107 - offset: 0x00000026
108 type: X86_64_RELOC_UNSIGNED
109 length: 3
110 pc-rel: false
111 extern: false
112 symbol: 1
113 - offset: 0x0000001E
114 type: X86_64_RELOC_UNSIGNED
115 length: 3
116 pc-rel: false
117 extern: false
118 symbol: 1
119 - segment: __DWARF
120 section: __debug_ranges
121 type: S_REGULAR
122 attributes: [ S_ATTR_DEBUG ]
123 address: 0x000000000000015D
124 - segment: __DWARF
125 section: __debug_macinfo
126 type: S_REGULAR
127 attributes: [ S_ATTR_DEBUG ]
128 address: 0x000000000000015D
129 content: [ 0x00 ]
130 - segment: __DWARF
131 section: __apple_names
132 type: S_REGULAR
133 attributes: [ S_ATTR_DEBUG ]
134 address: 0x000000000000015E
135 content: [ 0x48, 0x53, 0x41, 0x48, 0x01, 0x00, 0x00, 0x00,
136 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
137 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
138 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00,
139 0x00, 0x00, 0x00, 0x00, 0x6A, 0x7F, 0x9A, 0x7C,
140 0x2C, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00,
141 0x01, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00,
142 0x00, 0x00, 0x00, 0x00 ]
143 - segment: __DWARF
144 section: __apple_objc
145 type: S_REGULAR
146 attributes: [ S_ATTR_DEBUG ]
147 address: 0x000000000000019A
148 content: [ 0x48, 0x53, 0x41, 0x48, 0x01, 0x00, 0x00, 0x00,
149 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
150 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
151 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00,
152 0xFF, 0xFF, 0xFF, 0xFF ]
153 - segment: __DWARF
154 section: __apple_namespac
155 type: S_REGULAR
156 attributes: [ S_ATTR_DEBUG ]
157 address: 0x00000000000001BE
158 content: [ 0x48, 0x53, 0x41, 0x48, 0x01, 0x00, 0x00, 0x00,
159 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
160 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
161 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00,
162 0xFF, 0xFF, 0xFF, 0xFF ]
163 - segment: __DWARF
164 section: __apple_types
165 type: S_REGULAR
166 attributes: [ S_ATTR_DEBUG ]
167 address: 0x00000000000001E2
168 content: [ 0x48, 0x53, 0x41, 0x48, 0x01, 0x00, 0x00, 0x00,
169 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
170 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
171 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00,
172 0x03, 0x00, 0x05, 0x00, 0x04, 0x00, 0x0B, 0x00,
173 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
174 0x30, 0x80, 0x88, 0x0B, 0x63, 0x20, 0x95, 0x7C,
175 0x40, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00,
176 0x65, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
177 0x6A, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
178 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x01,
179 0x00, 0x00, 0x00, 0x7B, 0x00, 0x00, 0x00, 0x24,
180 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
181 - segment: __DWARF
182 section: __apple_exttypes
183 type: S_REGULAR
184 attributes: [ S_ATTR_DEBUG ]
185 address: 0x0000000000000248
186 content: [ 0x48, 0x53, 0x41, 0x48, 0x01, 0x00, 0x00, 0x00,
187 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
188 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
189 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x06, 0x00,
190 0xFF, 0xFF, 0xFF, 0xFF ]
191 - segment: __LD
192 section: __compact_unwind
193 type: S_REGULAR
194 attributes: [ S_ATTR_DEBUG ]
195 alignment: 8
196 address: 0x0000000000000270
197 content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
198 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
199 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
200 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
201 relocations:
202 - offset: 0x00000000
203 type: X86_64_RELOC_UNSIGNED
204 length: 3
205 pc-rel: false
206 extern: false
207 symbol: 1
208 - segment: __TEXT
209 section: __eh_frame
210 type: S_COALESCED
211 attributes: [ ]
212 alignment: 8
213 address: 0x0000000000000290
214 content: [ 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
215 0x01, 0x7A, 0x52, 0x00, 0x01, 0x78, 0x10, 0x01,
216 0x10, 0x0C, 0x07, 0x08, 0x90, 0x01, 0x00, 0x00,
217 0x24, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00,
218 0x50, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
219 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
220 0x00, 0x41, 0x0E, 0x10, 0x86, 0x02, 0x43, 0x0D,
221 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
222 - segment: __DWARF
223 section: __debug_line
224 type: S_REGULAR
225 attributes: [ S_ATTR_DEBUG ]
226 address: 0x00000000000002D0
227 content: [ 0x37, 0x00, 0x00, 0x00, 0x02, 0x00, 0x1B, 0x00,
228 0x00, 0x00, 0x01, 0x01, 0xFB, 0x0E, 0x0D, 0x00,
229 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01,
230 0x00, 0x00, 0x01, 0x00, 0x68, 0x77, 0x2E, 0x63,
231 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x02,
232 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
233 0x01, 0x05, 0x03, 0x0A, 0x08, 0x3D, 0x02, 0x02,
234 0x00, 0x01, 0x01 ]
235 relocations:
236 - offset: 0x00000028
237 type: X86_64_RELOC_UNSIGNED
238 length: 3
239 pc-rel: false
240 extern: false
241 symbol: 1
242global-symbols:
243 - name: _main
244 type: N_SECT
245 scope: [ N_EXT ]
246 sect: 1
247 value: 0x0000000000000000
248page-size: 0x00000000
249...
deps/lld/test/mach-o/demangle.yaml created+74
......@@ -0,0 +1,74 @@
1# REQUIRES: system-linker-mach-o
2#
3# RUN: not lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s \
4# RUN: -dylib -o %t %p/Inputs/x86_64/libSystem.yaml 2> %t.err
5# RUN: FileCheck %s < %t.err
6#
7# RUN: not lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s \
8# RUN: -dylib -o %t %p/Inputs/x86_64/libSystem.yaml -demangle 2> %t.err2
9# RUN: FileCheck %s --check-prefix=DCHECK < %t.err2
10#
11# Test -demangle option works on undefined symbol errors.
12#
13
14--- !mach-o
15arch: x86_64
16file-type: MH_OBJECT
17flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
18sections:
19 - segment: __TEXT
20 section: __text
21 type: S_REGULAR
22 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
23 address: 0x0000000000000000
24 content: [ 0xE8, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x00, 0x00,
25 0x00, 0x00, 0xE8, 0x00, 0x00, 0x00, 0x00 ]
26 relocations:
27 - offset: 0x0000000B
28 type: X86_64_RELOC_BRANCH
29 length: 2
30 pc-rel: true
31 extern: true
32 symbol: 2
33 - offset: 0x00000006
34 type: X86_64_RELOC_BRANCH
35 length: 2
36 pc-rel: true
37 extern: true
38 symbol: 3
39 - offset: 0x00000001
40 type: X86_64_RELOC_BRANCH
41 length: 2
42 pc-rel: true
43 extern: true
44 symbol: 1
45global-symbols:
46 - name: __Z1xv
47 type: N_SECT
48 scope: [ N_EXT ]
49 sect: 1
50 value: 0x0000000000000000
51undefined-symbols:
52 - name: __Znam
53 type: N_UNDF
54 scope: [ N_EXT ]
55 value: 0x0000000000000000
56 - name: __Znotcpp
57 type: N_UNDF
58 scope: [ N_EXT ]
59 value: 0x0000000000000000
60 - name: _foo
61 type: N_UNDF
62 scope: [ N_EXT ]
63 value: 0x0000000000000000
64
65...
66
67# CHECK: __Znotcpp
68# CHECK: __Znam
69# CHECK: _foo
70
71# DCHECK: __Znotcpp
72# DCHECK: operator new[](unsigned long)
73# DCHECK: _foo
74
deps/lld/test/mach-o/dependency_info.yaml created+19
......@@ -0,0 +1,19 @@
1# Test -dependency_info option
2#
3# RUN: lld -flavor darwin -arch x86_64 -test_file_usage \
4# RUN: -dependency_info %t.info \
5# RUN: -path_exists /System/Library/Frameworks \
6# RUN: -path_exists /System/Library/Frameworks/Foo.framework/Foo \
7# RUN: -path_exists /Custom/Frameworks \
8# RUN: -path_exists /Custom/Frameworks/Bar.framework/Bar \
9# RUN: -F/Custom/Frameworks \
10# RUN: -framework Bar \
11# RUN: -framework Foo
12# RUN: %python %p/Inputs/DependencyDump.py %t.info | FileCheck %s
13
14
15# CHECK: linker-vers: lld
16# CHECK: input-file: /Custom/Frameworks{{[/\\]}}Bar.framework{{[/\\]}}Bar
17# CHECK: not-found: /Custom/Frameworks{{[/\\]}}Foo.framework{{[/\\]}}Foo
18# CHECK: input-file: /System/Library/Frameworks{{[/\\]}}Foo.framework{{[/\\]}}Foo
19# CHECK: output-file: a.out
deps/lld/test/mach-o/do-not-emit-unwind-fde-arm64.yaml created+208
......@@ -0,0 +1,208 @@
1# RUN: lld -flavor darwin -arch arm64 -r -print_atoms %s -o %t | FileCheck %s
2# RUN: lld -flavor darwin -arch arm64 -r -print_atoms %t -o %t2 | FileCheck %s
3# RUN: llvm-objdump -r -s -section="__eh_frame" -macho %t | FileCheck -check-prefix=CODE %s
4# RUN: llvm-objdump -r -s -section="__eh_frame" -macho %t2 | FileCheck -check-prefix=CODE %s
5
6
7--- !mach-o
8arch: arm64
9file-type: MH_OBJECT
10flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
11compat-version: 0.0
12current-version: 0.0
13has-UUID: false
14OS: unknown
15sections:
16 - segment: __TEXT
17 section: __text
18 type: S_REGULAR
19 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
20 alignment: 4
21 address: 0x0000000000000000
22 content: [ 0xFD, 0x7B, 0xBF, 0xA9, 0xFD, 0x03, 0x00, 0x91,
23 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x91,
24 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x80, 0x52,
25 0xFD, 0x7B, 0xC1, 0xA8, 0xC0, 0x03, 0x5F, 0xD6 ]
26 relocations:
27 - offset: 0x00000010
28 type: ARM64_RELOC_BRANCH26
29 length: 2
30 pc-rel: true
31 extern: true
32 symbol: 9
33 - offset: 0x0000000C
34 type: ARM64_RELOC_PAGEOFF12
35 length: 2
36 pc-rel: false
37 extern: true
38 symbol: 1
39 - offset: 0x00000008
40 type: ARM64_RELOC_PAGE21
41 length: 2
42 pc-rel: true
43 extern: true
44 symbol: 1
45 - segment: __TEXT
46 section: __cstring
47 type: S_CSTRING_LITERALS
48 attributes: [ ]
49 address: 0x0000000000000020
50 content: [ 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x77, 0x6F,
51 0x72, 0x6C, 0x64, 0x00 ]
52 - segment: __LD
53 section: __compact_unwind
54 type: S_REGULAR
55 attributes: [ ]
56 alignment: 8
57 address: 0x0000000000000030
58 content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
59 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
60 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
62 relocations:
63 - offset: 0x00000000
64 type: ARM64_RELOC_UNSIGNED
65 length: 3
66 pc-rel: false
67 extern: false
68 symbol: 1
69 - segment: __TEXT
70 section: __eh_frame
71 type: S_COALESCED
72 attributes: [ ]
73 alignment: 8
74 address: 0x0000000000000050
75 content: [ 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
76 0x01, 0x7A, 0x50, 0x4C, 0x52, 0x00, 0x01, 0x78,
77 0x1E, 0x07, 0x00, 0x9D, 0xFF, 0xFF, 0xFF, 0xFF,
78 0xFF, 0xFF, 0xFF, 0x00, 0x10, 0x0C, 0x1F, 0x00,
79 0x24, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
80 0x88, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
81 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82 0x08, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83 0x00, 0x48, 0x0E, 0x10, 0x9E, 0x01, 0x9D, 0x02 ]
84 - segment: __TEXT
85 section: __gcc_except_tab
86 type: S_REGULAR
87 attributes: [ ]
88 address: 0x00000000000000A0
89 content: [ 0x00, 0x00, 0x00, 0x00 ]
90local-symbols:
91 - name: ltmp0
92 type: N_SECT
93 sect: 1
94 value: 0x0000000000000000
95 - name: L_str
96 type: N_SECT
97 sect: 2
98 value: 0x0000000000000020
99 - name: ltmp1
100 type: N_SECT
101 sect: 2
102 value: 0x0000000000000020
103 - name: ltmp2
104 type: N_SECT
105 sect: 3
106 value: 0x0000000000000030
107 - name: ltmp3
108 type: N_SECT
109 sect: 4
110 value: 0x0000000000000050
111 - name: ltmp4
112 type: N_SECT
113 sect: 4
114 value: 0x0000000000000070
115global-symbols:
116 - name: __Z3fooi
117 type: N_SECT
118 scope: [ N_EXT ]
119 sect: 1
120 value: 0x0000000000000000
121undefined-symbols:
122 - name: __gxx_personality_v0
123 type: N_UNDF
124 scope: [ N_EXT ]
125 value: 0x0000000000000000
126 - name: _bar
127 type: N_UNDF
128 scope: [ N_EXT ]
129 value: 0x0000000000000000
130 - name: _puts
131 type: N_UNDF
132 scope: [ N_EXT ]
133 value: 0x0000000000000000
134page-size: 0x00000000
135
136# CHECK: defined-atoms:
137# CHECK: - ref-name: L{{[0-9]*}}
138# CHECK: scope: hidden
139# CHECK: type: c-string
140# CHECK: content: [ 48, 65, 6C, 6C, 6F, 20, 77, 6F, 72, 6C, 64, 00 ]
141# CHECK: merge: by-content
142# CHECK: - ref-name: L{{[0-9]*}}
143# CHECK: type: unwind-cfi
144# CHECK: content: [ 1C, 00, 00, 00, 00, 00, 00, 00, 01, 7A, 50, 4C,
145# CHECK: 52, 00, 01, 78, 1E, 07, 00, {{..}}, {{..}}, {{..}}, {{..}}, {{..}},
146# CHECK: {{..}}, {{..}}, {{..}}, 00, 10, 0C, 1F, 00 ]
147# CHECK: - type: unwind-cfi
148# CHECK: content: [ 24, 00, 00, 00, 24, 00, 00, 00, {{..}}, {{..}}, {{..}}, {{..}},
149# CHECK: {{..}}, {{..}}, {{..}}, {{..}}, 20, 00, 00, 00, 00, 00, 00, 00,
150# CHECK: 08, {{..}}, {{..}}, {{..}}, {{..}}, {{..}}, {{..}}, {{..}}, {{..}}, 48, 0E, 10,
151# CHECK: 9E, 01, 9D, 02 ]
152# CHECK: references:
153# CHECK: - kind: negDelta32
154# CHECK: offset: 4
155# CHECK: target: L{{[0-9]*}}
156# CHECK: - kind: unwindFDEToFunction
157# CHECK: offset: 8
158# CHECK: target: __Z3fooi
159# CHECK: - kind: unwindFDEToFunction
160# CHECK: offset: 25
161# CHECK: target: L{{[0-9]*}}
162# CHECK: - ref-name: L{{[0-9]*}}
163# CHECK: type: unwind-lsda
164# CHECK: content: [ 00, 00, 00, 00 ]
165# CHECK: - type: compact-unwind
166# CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00, 20, 00, 00, 00,
167# CHECK: 00, 00, 00, 03, 00, 00, 00, 00, 00, 00, 00, 00,
168# CHECK: 00, 00, 00, 00, 00, 00, 00, 00 ]
169# CHECK: alignment: 8
170# CHECK: references:
171# CHECK: - kind: pointer64
172# CHECK: offset: 0
173# CHECK: target: __Z3fooi
174# CHECK: - name: __Z3fooi
175# CHECK: scope: global
176# CHECK: content: [ FD, 7B, BF, A9, FD, 03, 00, 91, 00, 00, 00, 90,
177# CHECK: 00, 00, 00, 91, 00, 00, 00, 94, 00, 00, 80, 52,
178# CHECK: FD, 7B, C1, A8, C0, 03, 5F, D6 ]
179# CHECK: alignment: 4
180# CHECK: references:
181# CHECK: - kind: page21
182# CHECK: offset: 8
183# CHECK: target: L{{[0-9]*}}
184# CHECK: - kind: offset12
185# CHECK: offset: 12
186# CHECK: target: L{{[0-9]*}}
187# CHECK: - kind: branch26
188# CHECK: offset: 16
189# CHECK: target: _puts
190
191# Make sure we don't have any relocations in the __eh_frame section
192# CODE-NOT: RELOCATION RECORDS FOR [__eh_frame]
193
194# Also make sure the reloc for the FDE->function is the correct offset
195# It should be the offset from the fixup location back to the address
196# of the function we are referencing
197# CODE: Contents of section __eh_frame:
198# This is the CIE:
199# CODE-NEXT: {{[0-9abcdef]*}} 1c000000 00000000 017a504c 52000178
200# CODE-NEXT: {{[0-9abcdef]*}} 1e0700bd ffffffff ffffff00 100c1f00
201# This is the FDE:
202# CODE-NEXT: {{[0-9abcdef]*}} 24000000 24000000 a8ffffff ffffffff
203# This is the important offset for FDE->func ^~~~~~~~ ~~~~~~~~
204
205# CODE-NEXT: {{[0-9abcdef]*}} 20000000 00000000 08c3ffff ffffffff
206# And this is the offset for FDE->lsda ^~~~~~~~ ~~~~~~
207# CODE-NEXT: {{[0-9abcdef]*}} ff480e10 9e019d02
208# And this byte ^~
deps/lld/test/mach-o/dso_handle.yaml created+62
......@@ -0,0 +1,62 @@
1# RUN: lld -flavor darwin -arch x86_64 %s %p/Inputs/x86_64/libSystem.yaml -o %t1
2# RUN: llvm-nm -m -n %t1 | FileCheck %s
3#
4# RUN: lld -flavor darwin -arch x86_64 %s %p/Inputs/x86_64/libSystem.yaml -dead_strip -o %t2
5# RUN: llvm-nm -m -n %t2 | FileCheck %s
6#
7# RUN: lld -flavor darwin -arch x86_64 %s %p/Inputs/x86_64/libSystem.yaml -dylib -o %t3
8# RUN: llvm-nm -m -n %t3 | FileCheck %s
9#
10# RUN: lld -flavor darwin -arch x86_64 %s %p/Inputs/x86_64/libSystem.yaml -bundle -o %t4
11# RUN: llvm-nm -m -n %t4 | FileCheck %s
12#
13# Test that ___dso_handle symbol is available for executables, bundles, and dylibs
14#
15
16--- !mach-o
17arch: x86_64
18file-type: MH_OBJECT
19flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
20sections:
21 - segment: __TEXT
22 section: __text
23 type: S_REGULAR
24 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
25 address: 0x0000000000000000
26 content: [ 0x55, 0x48, 0x89, 0xE5, 0x31, 0xC0, 0x5D, 0xC3 ]
27 - segment: __DATA
28 section: __data
29 type: S_REGULAR
30 attributes: [ ]
31 alignment: 8
32 address: 0x0000000000000008
33 content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
34 relocations:
35 - offset: 0x00000000
36 type: X86_64_RELOC_UNSIGNED
37 length: 3
38 pc-rel: false
39 extern: true
40 symbol: 2
41global-symbols:
42 - name: _d
43 type: N_SECT
44 scope: [ N_EXT ]
45 sect: 2
46 value: 0x0000000000000008
47 - name: _main
48 type: N_SECT
49 scope: [ N_EXT ]
50 sect: 1
51 value: 0x0000000000000000
52undefined-symbols:
53 - name: ___dso_handle
54 type: N_UNDF
55 scope: [ N_EXT ]
56 value: 0x0000000000000000
57
58
59...
60
61# CHECK_NOT: ___dso_handle
62# CHECK: _main
deps/lld/test/mach-o/dylib-install-names.yaml created+74
......@@ -0,0 +1,74 @@
1# Check we accept -install_name correctly:
2# RUN: lld -flavor darwin -arch x86_64 -install_name libwibble.dylib -dylib \
3# RUN: -compatibility_version 2.0 -current_version 5.3 \
4# RUN: %p/Inputs/x86_64/libSystem.yaml %s -o %t.dylib
5# RUN: llvm-objdump -private-headers %t.dylib | FileCheck %s --check-prefix=CHECK-BINARY-WRITE
6
7# Check we read LC_ID_DYLIB correctly:
8# RUN: lld -flavor darwin -arch x86_64 %p/Inputs/use-dylib-install-names.yaml \
9# RUN: %p/Inputs/x86_64/libSystem.yaml %t.dylib -dylib -o %t2.dylib
10# RUN: llvm-objdump -private-headers %t2.dylib | FileCheck %s --check-prefix=CHECK-BINARY-READ
11
12# Check we default the install-name to the output file:
13# RUN: lld -flavor darwin -arch x86_64 -dylib %s -o libwibble.dylib \
14# RUN: -compatibility_version 2.0 -current_version 5.3 \
15# RUN: %p/Inputs/x86_64/libSystem.yaml
16# RUN: llvm-objdump -private-headers libwibble.dylib | FileCheck %s --check-prefix=CHECK-BINARY-WRITE
17# RUN: rm -f libwibble.dylib
18
19# Check -single_module does nothing
20# RUN: lld -flavor darwin -arch x86_64 -dylib %s -install_name libwibble.dylib \
21# RUN: -compatibility_version 2.0 -current_version 5.3 \
22# RUN: -single_module -o %t2.dylib %p/Inputs/x86_64/libSystem.yaml
23# RUN: llvm-objdump -private-headers %t2.dylib | FileCheck %s --check-prefix=CHECK-BINARY-WRITE
24
25--- !mach-o
26arch: x86_64
27file-type: MH_OBJECT
28flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
29has-UUID: false
30OS: unknown
31sections:
32 - segment: __TEXT
33 section: __text
34 type: S_REGULAR
35 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
36 alignment: 4
37 address: 0x0000000000000000
38 content: [ 0xCC, 0xC3, 0x90, 0xC3, 0x90, 0x90, 0xC3, 0x90,
39 0x90, 0x90, 0xC3, 0x90, 0x90, 0x90, 0x90, 0xC3,
40 0x31, 0xC0, 0xC3 ]
41local-symbols:
42 - name: _myStatic
43 type: N_SECT
44 sect: 1
45 value: 0x000000000000000B
46global-symbols:
47 - name: _myGlobal
48 type: N_SECT
49 scope: [ N_EXT ]
50 sect: 1
51 value: 0x0000000000000001
52...
53
54
55# CHECK-BINARY-WRITE: cmd LC_ID_DYLIB
56# CHECK-BINARY-WRITE-NEXT: cmdsize 40
57# CHECK-BINARY-WRITE-NEXT: name libwibble.dylib (offset 24)
58# CHECK-BINARY-WRITE-NEXT: time stamp 1
59# CHECK-BINARY-WRITE-NEXT: current version 5.3.0
60# CHECK-BINARY-WRITE-NEXT: compatibility version 2.0.0
61
62# CHECK-BINARY-READ: cmd LC_LOAD_DYLIB
63# CHECK-BINARY-READ-NEXT: cmdsize 56
64# CHECK-BINARY-READ-NEXT: name /usr/lib/libSystem.B.dylib (offset 24)
65# CHECK-BINARY-READ-NEXT: time stamp 2
66# CHECK-BINARY-READ-NEXT: current version 1.0.0
67# CHECK-BINARY-READ-NEXT: compatibility version 1.0.0
68
69# CHECK-BINARY-READ: cmd LC_LOAD_DYLIB
70# CHECK-BINARY-READ-NEXT: cmdsize 40
71# CHECK-BINARY-READ-NEXT: name libwibble.dylib (offset 24)
72# CHECK-BINARY-READ-NEXT: time stamp 2
73# CHECK-BINARY-READ-NEXT: current version 5.3.0
74# CHECK-BINARY-READ-NEXT: compatibility version 2.0.0
deps/lld/test/mach-o/eh-frame-relocs-arm64.yaml created+318
......@@ -0,0 +1,318 @@
1# RUN: lld -flavor darwin -arch arm64 -r -print_atoms %s -o %t | FileCheck %s
2# RUN: lld -flavor darwin -arch arm64 -r -print_atoms %t -o %t2 | FileCheck %s
3# RUN: llvm-objdump -r -s -section="__eh_frame" -macho %t | FileCheck -check-prefix=CODE %s
4# RUN: llvm-objdump -r -s -section="__eh_frame" -macho %t2 | FileCheck -check-prefix=CODE %s
5
6
7--- !mach-o
8arch: arm64
9file-type: MH_OBJECT
10flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
11compat-version: 0.0
12current-version: 0.0
13has-UUID: false
14OS: unknown
15sections:
16 - segment: __TEXT
17 section: __text
18 type: S_REGULAR
19 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
20 alignment: 4
21 address: 0x0000000000000000
22 content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
23 0xC0, 0x03, 0x5F, 0xD6, 0xC0, 0x03, 0x5F, 0xD6,
24 0xC0, 0x03, 0x5F, 0xD6 ]
25 - segment: __TEXT
26 section: __gcc_except_tab
27 type: S_REGULAR
28 attributes: [ ]
29 address: 0x0000000000000014
30 content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
31 - segment: __DATA
32 section: __data
33 type: S_REGULAR
34 attributes: [ ]
35 address: 0x000000000000001C
36 content: [ 0x00, 0x00, 0x00, 0x00 ]
37 - segment: __LD
38 section: __compact_unwind
39 type: S_REGULAR
40 attributes: [ ]
41 alignment: 8
42 address: 0x0000000000000020
43 content: [ 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
44 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
45 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
48 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
49 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
51 relocations:
52 - offset: 0x00000020
53 type: ARM64_RELOC_UNSIGNED
54 length: 3
55 pc-rel: false
56 extern: false
57 symbol: 1
58 - offset: 0x00000000
59 type: ARM64_RELOC_UNSIGNED
60 length: 3
61 pc-rel: false
62 extern: false
63 symbol: 1
64 - segment: __TEXT
65 section: __eh_frame
66 type: S_COALESCED
67 attributes: [ ]
68 alignment: 8
69 address: 0x0000000000000060
70 content: [ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
71 0x03, 0x7A, 0x50, 0x4C, 0x52, 0x00, 0x01, 0x78,
72 0x1E, 0x07, 0x9B, 0xED, 0xFF, 0xFF, 0xFF, 0x10,
73 0x10, 0x0C, 0x1F, 0x00, 0x28, 0x00, 0x00, 0x00,
74 0x20, 0x00, 0x00, 0x00, 0xDC, 0xFF, 0xFF, 0xFF,
75 0xFF, 0xFF, 0xFF, 0xFF, 0x04, 0x00, 0x00, 0x00,
76 0x00, 0x00, 0x00, 0x00, 0x08, 0xCB, 0xFF, 0xFF,
77 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0E, 0x10, 0x9E,
78 0x01, 0x9D, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
79 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80 0x03, 0x7A, 0x50, 0x4C, 0x52, 0x00, 0x01, 0x78,
81 0x1E, 0x07, 0x9B, 0xA9, 0xFF, 0xFF, 0xFF, 0x10,
82 0x10, 0x0C, 0x1F, 0x00, 0x28, 0x00, 0x00, 0x00,
83 0x20, 0x00, 0x00, 0x00, 0x94, 0xFF, 0xFF, 0xFF,
84 0xFF, 0xFF, 0xFF, 0xFF, 0x04, 0x00, 0x00, 0x00,
85 0x00, 0x00, 0x00, 0x00, 0x08, 0x83, 0xFF, 0xFF,
86 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0E, 0x10, 0x9E,
87 0x01, 0x9D, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 ]
88 relocations:
89 - offset: 0x0000007D
90 type: ARM64_RELOC_SUBTRACTOR
91 length: 3
92 pc-rel: false
93 extern: true
94 symbol: 6
95 - offset: 0x0000007D
96 type: ARM64_RELOC_UNSIGNED
97 length: 3
98 pc-rel: false
99 extern: true
100 symbol: 3
101 - offset: 0x0000006C
102 type: ARM64_RELOC_SUBTRACTOR
103 length: 3
104 pc-rel: false
105 extern: true
106 symbol: 6
107 - offset: 0x0000006C
108 type: ARM64_RELOC_UNSIGNED
109 length: 3
110 pc-rel: false
111 extern: true
112 symbol: 8
113 - offset: 0x0000005B
114 type: ARM64_RELOC_POINTER_TO_GOT
115 length: 2
116 pc-rel: true
117 extern: true
118 symbol: 10
119 - offset: 0x00000035
120 type: ARM64_RELOC_SUBTRACTOR
121 length: 3
122 pc-rel: false
123 extern: true
124 symbol: 6
125 - offset: 0x00000035
126 type: ARM64_RELOC_UNSIGNED
127 length: 3
128 pc-rel: false
129 extern: true
130 symbol: 2
131 - offset: 0x00000024
132 type: ARM64_RELOC_SUBTRACTOR
133 length: 3
134 pc-rel: false
135 extern: true
136 symbol: 6
137 - offset: 0x00000024
138 type: ARM64_RELOC_UNSIGNED
139 length: 3
140 pc-rel: false
141 extern: true
142 symbol: 7
143 - offset: 0x00000013
144 type: ARM64_RELOC_POINTER_TO_GOT
145 length: 2
146 pc-rel: true
147 extern: true
148 symbol: 9
149local-symbols:
150 - name: ltmp0
151 type: N_SECT
152 sect: 1
153 value: 0x0000000000000000
154 - name: ltmp1
155 type: N_SECT
156 sect: 2
157 value: 0x0000000000000014
158 - name: _bar1
159 type: N_SECT
160 sect: 2
161 value: 0x0000000000000014
162 - name: _bar2
163 type: N_SECT
164 sect: 2
165 value: 0x0000000000000018
166 - name: ltmp12
167 type: N_SECT
168 sect: 3
169 value: 0x000000000000001C
170 - name: ltmp13
171 type: N_SECT
172 sect: 4
173 value: 0x0000000000000020
174 - name: ltmp16
175 type: N_SECT
176 sect: 5
177 value: 0x0000000000000060
178global-symbols:
179 - name: __Z3fooi
180 type: N_SECT
181 scope: [ N_EXT ]
182 sect: 1
183 value: 0x0000000000000008
184 - name: __Z4foo2i
185 type: N_SECT
186 scope: [ N_EXT ]
187 sect: 1
188 value: 0x000000000000000C
189 - name: __gxx_personality_v0
190 type: N_SECT
191 scope: [ N_EXT ]
192 sect: 1
193 value: 0x0000000000000000
194 - name: __gxx_personality_v1
195 type: N_SECT
196 scope: [ N_EXT ]
197 sect: 1
198 value: 0x0000000000000004
199 - name: _main
200 type: N_SECT
201 scope: [ N_EXT ]
202 sect: 1
203 value: 0x0000000000000010
204 - name: _someData
205 type: N_SECT
206 scope: [ N_EXT ]
207 sect: 3
208 value: 0x000000000000001C
209page-size: 0x00000000
210...
211
212# CHECK: --- !native
213# CHECK: path: '<linker-internal>'
214# CHECK: defined-atoms:
215# CHECK: - ref-name: L000
216# CHECK: type: unwind-cfi
217# CHECK: content: [ 18, 00, 00, 00, 00, 00, 00, 00, 03, 7A, 50, 4C,
218# CHECK: 52, 00, 01, 78, 1E, 07, 9B, {{..}}, {{..}}, {{..}}, {{..}}, 10,
219# CHECK: 10, 0C, 1F, 00 ]
220# CHECK: alignment: 8
221# CHECK: references:
222# CHECK: - kind: unwindCIEToPersonalityFunction
223# CHECK: offset: 19
224# CHECK: target: __gxx_personality_v0
225# CHECK: - type: unwind-cfi
226# CHECK: content: [ 28, 00, 00, 00, 20, 00, 00, 00, {{..}}, {{..}}, {{..}}, {{..}},
227# CHECK: {{..}}, {{..}}, {{..}}, {{..}}, 04, 00, 00, 00, 00, 00, 00, 00,
228# CHECK: 08, {{..}}, {{..}}, {{..}}, {{..}}, {{..}}, {{..}}, {{..}}, {{..}}, 0E, 10, 9E,
229# CHECK: 01, 9D, 02, 00, 00, 00, 00, 00 ]
230# CHECK: alignment: 4 mod 8
231# CHECK: references:
232# CHECK: - kind: negDelta32
233# CHECK: offset: 4
234# CHECK: target: L000
235# CHECK: - kind: unwindFDEToFunction
236# CHECK: offset: 8
237# CHECK: target: __Z3fooi
238# CHECK: - kind: unwindFDEToFunction
239# CHECK: offset: 25
240# CHECK: target: _bar1
241# CHECK: - ref-name: L001
242# CHECK: type: unwind-cfi
243# CHECK: content: [ 18, 00, 00, 00, 00, 00, 00, 00, 03, 7A, 50, 4C,
244# CHECK: 52, 00, 01, 78, 1E, 07, 9B, {{..}}, {{..}}, {{..}}, {{..}}, 10,
245# CHECK: 10, 0C, 1F, 00 ]
246# CHECK: alignment: 8
247# CHECK: references:
248# CHECK: - kind: unwindCIEToPersonalityFunction
249# CHECK: offset: 19
250# CHECK: target: __gxx_personality_v1
251# CHECK: - type: unwind-cfi
252# CHECK: content: [ 28, 00, 00, 00, 20, 00, 00, 00, {{..}}, {{..}}, {{..}}, {{..}},
253# CHECK: {{..}}, {{..}}, {{..}}, {{..}}, 04, 00, 00, 00, 00, 00, 00, 00,
254# CHECK: 08, {{..}}, {{..}}, {{..}}, {{..}}, {{..}}, {{..}}, {{..}}, {{..}}, 0E, 10, 9E,
255# CHECK: 01, 9D, 02, 00, 00, 00, 00, 00 ]
256# CHECK: alignment: 4 mod 8
257# CHECK: references:
258# CHECK: - kind: negDelta32
259# CHECK: offset: 4
260# CHECK: target: L001
261# CHECK: - kind: unwindFDEToFunction
262# CHECK: offset: 8
263# CHECK: target: __Z4foo2i
264# CHECK: - kind: unwindFDEToFunction
265# CHECK: offset: 25
266# CHECK: target: _bar2
267# CHECK: - name: _bar1
268# CHECK: type: unwind-lsda
269# CHECK: content: [ 00, 00, 00, 00 ]
270# CHECK: - name: _bar2
271# CHECK: type: unwind-lsda
272# CHECK: content: [ 00, 00, 00, 00 ]
273# CHECK: - name: _someData
274# CHECK: scope: global
275# CHECK: type: data
276# CHECK: content: [ 00, 00, 00, 00 ]
277# CHECK: - name: __gxx_personality_v0
278# CHECK: scope: global
279# CHECK: content: [ 00, 00, 00, 00 ]
280# CHECK: alignment: 4
281# CHECK: - name: __gxx_personality_v1
282# CHECK: scope: global
283# CHECK: content: [ 00, 00, 00, 00 ]
284# CHECK: alignment: 4
285# CHECK: - name: __Z3fooi
286# CHECK: scope: global
287# CHECK: content: [ C0, 03, 5F, D6 ]
288# CHECK: alignment: 4
289# CHECK: - name: __Z4foo2i
290# CHECK: scope: global
291# CHECK: content: [ C0, 03, 5F, D6 ]
292# CHECK: alignment: 4
293# CHECK: - name: _main
294# CHECK: scope: global
295# CHECK: content: [ C0, 03, 5F, D6 ]
296# CHECK: alignment: 4
297# CHECK: ...
298
299# # Make sure we don't have any relocations in the __eh_frame section
300# CODE-NOT: RELOCATION RECORDS FOR [__eh_frame]
301
302# Also make sure the reloc for the CIE->personality function is the
303# correct offset
304# It should be the offset from the fixup location back to the address
305# of the function we are referencing
306# CODE: Contents of section __eh_frame:
307# This is the CIE:
308# CODE-NEXT: {{[0-9abcdef]*}} 18000000 00000000 037a504c 52000178
309# CODE-NEXT: {{[0-9abcdef]*}} 1e079bd1 ffffff10 100c1f00 28000000
310# This is the important offset for CIE->pfunc
311# ^~~~~~~~~
312# Then we have an FDE starting from 28000000 above
313# CODE-NEXT: {{[0-9abcdef]*}} 20000000 c8ffffff ffffffff 04000000
314# CODE-NEXT: {{[0-9abcdef]*}} 00000000 08c3ffff ffffffff ff0e109e
315# And a new CIE starts at this 00000018 right below here
316# CODE-NEXT: {{[0-9abcdef]*}} 019d0200 00000000 18000000 00000000
317# CODE-NEXT: {{[0-9abcdef]*}} 037a504c 52000178 1e079b8d ffffff10
318# This is the important offset for its CIE->pfunc ^~~~~~~~~
\ No newline at end of file
deps/lld/test/mach-o/error-simulator-vs-macosx.yaml created+30
......@@ -0,0 +1,30 @@
1# RUN: lld -flavor darwin -arch i386 -macosx_version_min 10.8 %s %p/Inputs/hello-world-x86.yaml -o %t && llvm-nm -m %t | FileCheck %s
2# RUN: not lld -flavor darwin -arch i386 -ios_simulator_version_min 5.0 %s %p/Inputs/hello-world-x86.yaml -o %t 2>&1 | FileCheck %s --check-prefix=ERROR
3#
4# Test that i386 can link with a macos version but gives an error with a simululator version.
5#
6
7--- !mach-o
8arch: x86
9OS: Mac OS X
10file-type: MH_OBJECT
11flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
12sections:
13 - segment: __TEXT
14 section: __text
15 type: S_REGULAR
16 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
17 address: 0x0000000000000000
18 content: [ 0x90 ]
19global-symbols:
20 - name: _main
21 type: N_SECT
22 scope: [ N_EXT ]
23 sect: 1
24 value: 0x0000000000000000
25...
26
27# CHECK: {{[0-9a-f]+}} (__TEXT,__text) external _main
28# CHECK: (undefined) external dyld_stub_binder (from libSystem)
29
30# ERROR: cannot be linked due to incompatible operating systems
deps/lld/test/mach-o/exe-offsets.yaml created+45
......@@ -0,0 +1,45 @@
1# RUN: lld -flavor darwin -arch x86_64 %s -o %t -e start %p/Inputs/x86_64/libSystem.yaml
2# RUN: llvm-readobj -sections %t | FileCheck %s
3
4# Make sure data gets put at offset
5
6--- !native
7defined-atoms:
8 - name: start
9 scope: global
10 content: [ 90 ]
11
12 - name: _s1
13 type: data
14 content: [ 31, 32, 33, 34 ]
15
16 - name: _s2
17 type: zero-fill
18 size: 8192
19
20 - name: _s3
21 type: zero-fill
22 size: 100
23
24 - name: _s4
25 type: data
26 content: [ 01 ]
27
28
29# CHECK-LABEL: Section {
30# CHECK: Name: __text
31# CHECK: Segment: __TEXT
32# CHECK: Size: 0x1
33# CHECK: Offset: 0
34
35# CHECK-LABEL: Section {
36# CHECK: Name: __data
37# CHECK: Segment: __DATA
38# CHECK: Size: 0x5
39# CHECK: Offset: 4096
40
41# CHECK-LABEL: Section {
42# CHECK: Name: __bss
43# CHECK: Segment: __DATA
44# CHECK: Size: 0x2064
45# CHECK: Offset: 0
deps/lld/test/mach-o/exe-segment-overlap.yaml created+44
......@@ -0,0 +1,44 @@
1# RUN: lld -flavor darwin -arch x86_64 %s -o %t %p/Inputs/x86_64/libSystem.yaml
2# RUN: llvm-readobj -sections -section-data %t | FileCheck %s
3
4--- !native
5defined-atoms:
6 - name: _main
7 scope: global
8 content: [ 90 ]
9
10 - name: _s2
11 type: data
12 content: [ 31, 32, 33, 34 ]
13
14 - name: _kustom
15 scope: global
16 type: unknown
17 content: [ 01, 02, 03, 04, 05, 06, 07, 08 ]
18 section-choice: custom-required
19 section-name: __CUST/__custom
20
21
22# CHECK-LABEL: Section {
23# CHECK: Name: __text
24# CHECK: Segment: __TEXT
25# CHECK: Size: 0x1
26# CHECK: Offset: 4095
27
28# CHECK-LABEL: Section {
29# CHECK: Name: __data
30# CHECK: Segment: __DATA
31# CHECK: Size: 0x4
32# CHECK: Offset: 4096
33# CHECK: SectionData (
34# CHECK-NEXT: 0000: 31323334
35# CHECK-NEXT: )
36
37# CHECK-LABEL: Section {
38# CHECK: Name: __custom{{ }}
39# CHECK: Segment: __CUST{{ }}
40# CHECK: Size: 0x8
41# CHECK: Offset: 8192
42# CHECK: SectionData (
43# CHECK-NEXT: 0000: 01020304 05060708
44# CHECK-NEXT: )
deps/lld/test/mach-o/executable-exports.yaml created+46
......@@ -0,0 +1,46 @@
1# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 \
2# RUN: %s %p/Inputs/x86_64/libSystem.yaml -o %t && \
3# RUN: llvm-objdump -exports-trie %t | FileCheck %s
4#
5#
6# Tests that exports trie builds properly.
7#
8
9--- !mach-o
10arch: x86_64
11file-type: MH_OBJECT
12flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
13sections:
14 - segment: __TEXT
15 section: __text
16 type: S_REGULAR
17 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
18 address: 0x0000000000000000
19 content: [ 0xC3, 0xC3, 0xC3, 0xC3 ]
20global-symbols:
21 - name: _myHidden
22 type: N_SECT
23 scope: [ N_EXT, N_PEXT ]
24 sect: 1
25 value: 0x0000000000000000
26 - name: _myRegular
27 type: N_SECT
28 scope: [ N_EXT ]
29 sect: 1
30 value: 0x0000000000000001
31 - name: _myWeak
32 type: N_SECT
33 scope: [ N_EXT ]
34 sect: 1
35 desc: [ N_WEAK_DEF ]
36 value: 0x0000000000000002
37 - name: _main
38 type: N_SECT
39 scope: [ N_EXT ]
40 sect: 1
41 value: 0x0000000000000003
42...
43
44# CHECK-NOT: _myHidden
45# CHECK: 0x100000FFD _myRegular
46# CHECK: 0x100000FFE _myWeak [weak_def]
deps/lld/test/mach-o/export-trie-order.yaml created+62
......@@ -0,0 +1,62 @@
1# RUN: lld -flavor darwin -arch i386 %s %p/Inputs/hello-world-x86.yaml -o %t
2# RUN: llvm-objdump -exports-trie %t | FileCheck %s
3#
4# Test that the export trie is emitted in order.
5#
6
7--- !mach-o
8arch: x86
9file-type: MH_OBJECT
10flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
11sections:
12 - segment: __TEXT
13 section: __text
14 type: S_REGULAR
15 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
16 address: 0x0000000000000000
17 content: [ 0x55, 0x89, 0xE5, 0x83, 0xEC, 0x08, 0xE8, 0x00,
18 0x00, 0x00, 0x00, 0x58, 0x8D, 0x80, 0x16, 0x00,
19 0x00, 0x00, 0x89, 0x04, 0x24, 0xE8, 0xE6, 0xFF,
20 0xFF, 0xFF, 0x31, 0xC0, 0x83, 0xC4, 0x08, 0x5D,
21 0xC3 ]
22 relocations:
23 - offset: 0x00000016
24 type: GENERIC_RELOC_VANILLA
25 length: 2
26 pc-rel: true
27 extern: true
28 symbol: 1
29 - offset: 0x0000000E
30 scattered: true
31 type: GENERIC_RELOC_LOCAL_SECTDIFF
32 length: 2
33 pc-rel: false
34 value: 0x00000021
35 - offset: 0x00000000
36 scattered: true
37 type: GENERIC_RELOC_PAIR
38 length: 2
39 pc-rel: false
40 value: 0x0000000B
41 - segment: __TEXT
42 section: __cstring
43 type: S_CSTRING_LITERALS
44 attributes: [ ]
45 address: 0x0000000000000021
46 content: [ 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x00 ]
47global-symbols:
48 - name: _main
49 type: N_SECT
50 scope: [ N_EXT ]
51 sect: 1
52 value: 0x0000000000000000
53undefined-symbols:
54 - name: _printf
55 type: N_UNDF
56 scope: [ N_EXT ]
57 value: 0x0000000000000000
58...
59
60# CHECK: Exports trie:
61# CHECK-NEXT: __mh_execute_header
62# CHECK-NEXT: _main
deps/lld/test/mach-o/exported_symbols_list-dylib.yaml created+77
......@@ -0,0 +1,77 @@
1# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 -dylib \
2# RUN: %s %p/Inputs/x86_64/libSystem.yaml -o %t \
3# RUN: -exported_symbols_list %p/Inputs/exported_symbols_list.exp && \
4# RUN: llvm-nm -m %t | FileCheck %s
5#
6# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 -dylib \
7# RUN: %s %p/Inputs/x86_64/libSystem.yaml -o %t2 \
8# RUN: -exported_symbol _foo -exported_symbol _b && \
9# RUN: llvm-nm -m %t2 | FileCheck %s
10#
11# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 -dylib \
12# RUN: %s %p/Inputs/x86_64/libSystem.yaml -o %t3 \
13# RUN: -unexported_symbol _bar -unexported_symbol _a && \
14# RUN: llvm-nm -m %t3 | FileCheck %s
15#
16# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 -dylib \
17# RUN: %s %p/Inputs/x86_64/libSystem.yaml -dead_strip -o %t \
18# RUN: -exported_symbols_list %p/Inputs/exported_symbols_list.exp && \
19# RUN: llvm-nm -m %t | FileCheck -check-prefix=CHECK_DEAD %s
20#
21# Test -exported_symbols_list and -exported_symbol properly changes visibility.
22#
23
24--- !mach-o
25arch: x86_64
26file-type: MH_OBJECT
27flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
28sections:
29 - segment: __TEXT
30 section: __text
31 type: S_REGULAR
32 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
33 address: 0x0000000000000000
34 content: [ 0x55, 0x48, 0x89, 0xE5, 0x5D, 0xC3, 0x55, 0x48,
35 0x89, 0xE5, 0x5D, 0xC3 ]
36 - segment: __DATA
37 section: __data
38 type: S_REGULAR
39 attributes: [ ]
40 alignment: 2
41 address: 0x000000000000000C
42 content: [ 0x0A, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00 ]
43
44global-symbols:
45 - name: _a
46 type: N_SECT
47 scope: [ N_EXT ]
48 sect: 2
49 value: 0x000000000000000C
50 - name: _b
51 type: N_SECT
52 scope: [ N_EXT ]
53 sect: 2
54 value: 0x0000000000000010
55 - name: _bar
56 type: N_SECT
57 scope: [ N_EXT ]
58 sect: 1
59 value: 0x0000000000000006
60 - name: _foo
61 type: N_SECT
62 scope: [ N_EXT ]
63 sect: 1
64 value: 0x0000000000000000
65
66
67...
68
69# CHECK: (__DATA,__data) non-external (was a private external) _a
70# CHECK: (__DATA,__data) external _b
71# CHECK: (__TEXT,__text) non-external (was a private external) _bar
72# CHECK: (__TEXT,__text) external _foo
73
74# CHECK_DEAD-NOT: (__DATA,__data) non-external (was a private external) _a
75# CHECK_DEAD: (__DATA,__data) external _b
76# CHECK_DEAD-NOT: (__TEXT,__text) non-external (was a private external) _bar
77# CHECK_DEAD: (__TEXT,__text) external _foo
deps/lld/test/mach-o/exported_symbols_list-obj.yaml created+67
......@@ -0,0 +1,67 @@
1# RUN: lld -flavor darwin -arch x86_64 -r %s -o %t -exported_symbol _bar \
2# RUN: && llvm-nm -m %t | FileCheck %s
3#
4# RUN: lld -flavor darwin -arch x86_64 -r %s -o %t2 -keep_private_externs \
5# RUN: -exported_symbol _bar && \
6# RUN: llvm-nm -m %t2 | FileCheck -check-prefix=CHECK_KPE %s
7#
8# RUN: not lld -flavor darwin -arch x86_64 -r %s -o %t3 \
9# RUN: -exported_symbol _foo 2> %t4
10
11# Test -exported_symbols_list properly changes visibility in -r mode.
12#
13
14--- !mach-o
15arch: x86_64
16file-type: MH_OBJECT
17flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
18sections:
19 - segment: __TEXT
20 section: __text
21 type: S_REGULAR
22 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
23 address: 0x0000000000000000
24 content: [ 0x55, 0x48, 0x89, 0xE5, 0x5D, 0xC3, 0x55, 0x48,
25 0x89, 0xE5, 0x5D, 0xC3 ]
26 - segment: __DATA
27 section: __data
28 type: S_REGULAR
29 attributes: [ ]
30 alignment: 2
31 address: 0x000000000000000C
32 content: [ 0x0A, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00 ]
33
34global-symbols:
35 - name: _a
36 type: N_SECT
37 scope: [ N_EXT ]
38 sect: 2
39 value: 0x000000000000000C
40 - name: _b
41 type: N_SECT
42 scope: [ N_EXT, N_PEXT ]
43 sect: 2
44 value: 0x0000000000000010
45 - name: _bar
46 type: N_SECT
47 scope: [ N_EXT ]
48 sect: 1
49 value: 0x0000000000000006
50 - name: _foo
51 type: N_SECT
52 scope: [ N_EXT, N_PEXT ]
53 sect: 1
54 value: 0x0000000000000000
55
56
57...
58
59# CHECK: (__DATA,__data) non-external (was a private external) _a
60# CHECK: (__DATA,__data) non-external (was a private external) _b
61# CHECK: (__TEXT,__text) external _bar
62# CHECK: (__TEXT,__text) non-external (was a private external) _foo
63
64# CHECK_KPE: (__DATA,__data) non-external (was a private external) _a
65# CHECK_KPE: (__DATA,__data) private external _b
66# CHECK_KPE: (__TEXT,__text) external _bar
67# CHECK_KPE: (__TEXT,__text) private external _foo
deps/lld/test/mach-o/exported_symbols_list-undef.yaml created+55
......@@ -0,0 +1,55 @@
1# RUN: not lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 -dylib \
2# RUN: %s %p/Inputs/x86_64/libSystem.yaml -o %t -exported_symbol _foobar 2> %t2
3#
4# Test -exported_symbol fails if exported symbol not found.
5#
6
7--- !mach-o
8arch: x86_64
9file-type: MH_OBJECT
10flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
11sections:
12 - segment: __TEXT
13 section: __text
14 type: S_REGULAR
15 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
16 address: 0x0000000000000000
17 content: [ 0x55, 0x48, 0x89, 0xE5, 0x5D, 0xC3, 0x55, 0x48,
18 0x89, 0xE5, 0x5D, 0xC3 ]
19 - segment: __DATA
20 section: __data
21 type: S_REGULAR
22 attributes: [ ]
23 alignment: 2
24 address: 0x000000000000000C
25 content: [ 0x0A, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00 ]
26
27global-symbols:
28 - name: _a
29 type: N_SECT
30 scope: [ N_EXT ]
31 sect: 2
32 value: 0x000000000000000C
33 - name: _b
34 type: N_SECT
35 scope: [ N_EXT ]
36 sect: 2
37 value: 0x0000000000000010
38 - name: _bar
39 type: N_SECT
40 scope: [ N_EXT ]
41 sect: 1
42 value: 0x0000000000000006
43 - name: _foo
44 type: N_SECT
45 scope: [ N_EXT ]
46 sect: 1
47 value: 0x0000000000000000
48
49
50...
51
52# CHECK: (__DATA,__data) private external _a
53# CHECK: (__DATA,__data) external _b
54# CHECK: (__TEXT,__text) private external _bar
55# CHECK: (__TEXT,__text) external _foo
deps/lld/test/mach-o/fat-archive.yaml created+45
......@@ -0,0 +1,45 @@
1# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t \
2# RUN: -L %p/Inputs -lfoo %p/Inputs/x86_64/libSystem.yaml
3# RUN: llvm-nm -m -n %t | FileCheck %s
4#
5# Test that fat archives are handled.
6#
7
8--- !mach-o
9arch: x86_64
10file-type: MH_OBJECT
11flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
12sections:
13 - segment: __TEXT
14 section: __text
15 type: S_REGULAR
16 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
17 alignment: 4
18 address: 0x0000000000000000
19 content: [ 0x55, 0x48, 0x89, 0xE5, 0x48, 0x83, 0xEC, 0x10,
20 0xC7, 0x45, 0xFC, 0x00, 0x00, 0x00, 0x00, 0xB0,
21 0x00, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x31, 0xC0,
22 0x48, 0x83, 0xC4, 0x10, 0x5D, 0xC3 ]
23 relocations:
24 - offset: 0x00000012
25 type: X86_64_RELOC_BRANCH
26 length: 2
27 pc-rel: true
28 extern: true
29 symbol: 1
30global-symbols:
31 - name: _main
32 type: N_SECT
33 scope: [ N_EXT ]
34 sect: 1
35 value: 0x0000000000000000
36undefined-symbols:
37 - name: _foo
38 type: N_UNDF
39 scope: [ N_EXT ]
40 value: 0x0000000000000000
41
42...
43
44# CHECK: {{[0-9a-f]+}} (__TEXT,__text) external _main
45# CHECK: {{[0-9a-f]+}} (__TEXT,__text) external _foo
deps/lld/test/mach-o/filelist.yaml created+18
......@@ -0,0 +1,18 @@
1# RUN: lld -flavor darwin -test_file_usage \
2# RUN: -filelist %p/Inputs/full.filelist \
3# RUN: -path_exists /foo/bar/a.o \
4# RUN: -path_exists /foo/bar/b.o \
5# RUN: -path_exists /foo/x.a \
6# RUN: 2>&1 | FileCheck %s
7#
8# RUN: lld -flavor darwin -test_file_usage -t \
9# RUN: -filelist %p/Inputs/partial.filelist,/foo \
10# RUN: -path_exists /foo/bar/a.o \
11# RUN: -path_exists /foo/bar/b.o \
12# RUN: -path_exists /foo/x.a \
13# RUN: 2>&1 | FileCheck %s
14
15
16# CHECK: Found filelist entry /foo/bar/a.o
17# CHECK: Found filelist entry /foo/bar/b.o
18# CHECK: Found filelist entry /foo/x.a
deps/lld/test/mach-o/flat_namespace_undef_error.yaml created+17
......@@ -0,0 +1,17 @@
1# RUN: not lld -flavor darwin -arch x86_64 -macosx_version_min 10.9 -flat_namespace -undefined error %s -o %t %p/Inputs/x86_64/libSystem.yaml 2>&1 | FileCheck %s
2
3--- !native
4defined-atoms:
5 - name: _main
6 scope: global
7 content: [ E9, 00, 00, 00, 00 ]
8 alignment: 16
9 references:
10 - kind: branch32
11 offset: 1
12 target: _bar
13undefined-atoms:
14 - name: _bar
15
16# Make sure we error out for -flat_namespace -undefined error.
17# CHECK: Undefined symbol: : _bar
deps/lld/test/mach-o/flat_namespace_undef_suppress.yaml created+17
......@@ -0,0 +1,17 @@
1# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.9 -flat_namespace -undefined suppress %s -o %t %p/Inputs/x86_64/libSystem.yaml
2#
3# Sanity check '-flat_namespace -undefined suppress'.
4# This should pass without error, even though '_bar' is undefined.
5
6--- !native
7defined-atoms:
8 - name: _main
9 scope: global
10 content: [ E9, 00, 00, 00, 00 ]
11 alignment: 16
12 references:
13 - kind: branch32
14 offset: 1
15 target: _bar
16undefined-atoms:
17 - name: _bar
deps/lld/test/mach-o/force_load-dylib.yaml created+45
......@@ -0,0 +1,45 @@
1# RUN: lld -flavor darwin -arch x86_64 -dylib %p/Inputs/bar.yaml \
2# RUN: -install_name /usr/lib/libbar.dylib %p/Inputs/x86_64/libSystem.yaml -o %t1.dylib
3# RUN: lld -flavor darwin -arch x86_64 -dylib %s -all_load %t1.dylib \
4# RUN: -install_name /usr/lib/libfoo.dylib %p/Inputs/x86_64/libSystem.yaml -o %t
5# RUN: llvm-nm -m %t | FileCheck %s
6#
7#
8# Test -all_load does not break linking with dylibs
9#
10
11--- !mach-o
12arch: x86_64
13file-type: MH_OBJECT
14flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
15sections:
16 - segment: __TEXT
17 section: __text
18 type: S_REGULAR
19 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
20 address: 0x0000000000000000
21 content: [ 0x55, 0x48, 0x89, 0xE5, 0x31, 0xC0, 0x5D, 0xE9,
22 0x00, 0x00, 0x00, 0x00 ]
23 relocations:
24 - offset: 0x00000008
25 type: X86_64_RELOC_BRANCH
26 length: 2
27 pc-rel: true
28 extern: true
29 symbol: 1
30global-symbols:
31 - name: _foo
32 type: N_SECT
33 scope: [ N_EXT ]
34 sect: 1
35 value: 0x0000000000000000
36undefined-symbols:
37 - name: _bar
38 type: N_UNDF
39 scope: [ N_EXT ]
40 value: 0x0000000000000000
41
42...
43
44
45# CHECK: (__TEXT,__text) external _foo
deps/lld/test/mach-o/force_load-x86_64.yaml created+38
......@@ -0,0 +1,38 @@
1# RUN: lld -flavor darwin -arch x86_64 %s %p/Inputs/x86_64/libSystem.yaml \
2# RUN: %p/Inputs/libfoo.a %p/Inputs/libbar.a -o %t1
3# RUN: llvm-nm -m -n %t1 | FileCheck %s
4#
5# RUN: lld -flavor darwin -arch x86_64 %s %p/Inputs/x86_64/libSystem.yaml \
6# RUN: -force_load %p/Inputs/libfoo.a %p/Inputs/libbar.a -o %t2
7# RUN: llvm-nm -m -n %t2 | FileCheck --check-prefix=CHECKF %s
8#
9# Test that -force_load causes members of static library to be loaded.
10#
11
12--- !mach-o
13arch: x86_64
14file-type: MH_OBJECT
15flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
16has-UUID: false
17OS: unknown
18sections:
19 - segment: __TEXT
20 section: __text
21 type: S_REGULAR
22 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
23 address: 0x0000000000000000
24 content: [ 0xC3 ]
25global-symbols:
26 - name: _main
27 type: N_SECT
28 scope: [ N_EXT ]
29 sect: 1
30 value: 0x0000000000000000
31...
32
33# CHECK: {{[0-9a-f]+}} (__TEXT,__text) external _main
34# CHECK-NOT: {{[0-9a-f]+}} (__TEXT,__text) external _main
35
36# CHECKF: {{[0-9a-f]+}} (__TEXT,__text) external _main
37# CHECKF: {{[0-9a-f]+}} (__TEXT,__text) external _foo
38# CHECKF-NOT: {{[0-9a-f]+}} (__TEXT,__text) external _bar
deps/lld/test/mach-o/framework-user-paths.yaml created+41
......@@ -0,0 +1,41 @@
1#
2# Test framework and SDK search paths.
3# myFrameworks is not an absolute path, so it should not by found in SDK
4# /Custom/Frameworks should be found in SDK
5# /opt/Frameworks should not be found in SDK
6# /System/Library/Frameworks is implicit and should be in SDK
7#
8# RUN: lld -flavor darwin -arch x86_64 -r -test_file_usage -v \
9# RUN: -path_exists myFrameworks \
10# RUN: -path_exists myFrameworks/my.framework/my \
11# RUN: -path_exists /opt/Frameworks \
12# RUN: -path_exists /opt/Frameworks/other.framework/other \
13# RUN: -path_exists /Custom/Frameworks \
14# RUN: -path_exists /Custom/Frameworks/Bar.framework/Bar \
15# RUN: -path_exists /System/Library/Frameworks \
16# RUN: -path_exists /System/Library/Frameworks/Foo.framework/Foo \
17# RUN: -path_exists /SDK/myFrameworks \
18# RUN: -path_exists /SDK/myFrameworks/my.framework/my \
19# RUN: -path_exists /SDK/Custom/Frameworks \
20# RUN: -path_exists /SDK/Custom/Frameworks/Bar.framework/Bar \
21# RUN: -path_exists /SDK/System/Library/Frameworks \
22# RUN: -path_exists /SDK/System/Library/Frameworks/Foo.framework/Foo \
23# RUN: -syslibroot /SDK \
24# RUN: -FmyFrameworks \
25# RUN: -F/Custom/Frameworks \
26# RUN: -F/opt/Frameworks \
27# RUN: -framework my \
28# RUN: -framework Bar \
29# RUN: -framework Foo \
30# RUN: -framework other \
31# RUN: 2>&1 | FileCheck %s
32
33# CHECK: Framework search paths:
34# CHECK-NEXT: myFrameworks
35# CHECK-NEXT: /SDK/Custom/Frameworks
36# CHECK-NEXT: /opt/Frameworks
37# CHECK-NEXT: /SDK/System/Library/Frameworks
38# CHECK: Found framework myFrameworks/my.framework/my
39# CHECK: Found framework /SDK/Custom/Frameworks/Bar.framework/Bar
40# CHECK: Found framework /SDK/System/Library/Frameworks/Foo.framework/Foo
41# CHECK: Found framework /opt/Frameworks/other.framework/other
deps/lld/test/mach-o/function-starts-load-command.yaml created+32
......@@ -0,0 +1,32 @@
1# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml && llvm-objdump -private-headers %t | FileCheck %s
2# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -static -function_starts && llvm-objdump -private-headers %t | FileCheck %s
3# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -no_function_starts && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_FUNCTION_STARTS
4# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -static -function_starts -no_function_starts && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_FUNCTION_STARTS
5# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -static && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_FUNCTION_STARTS
6
7--- !mach-o
8arch: x86_64
9file-type: MH_OBJECT
10flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
11sections:
12 - segment: __TEXT
13 section: __text
14 type: S_REGULAR
15 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
16 address: 0x0000000000000000
17 content: [ 0x00, 0x00, 0x00, 0x00 ]
18global-symbols:
19 - name: _main
20 type: N_SECT
21 scope: [ N_EXT ]
22 sect: 1
23 value: 0x0000000000000000
24...
25
26# CHECK: Load command {{[0-9]*}}
27# CHECK: cmd LC_FUNCTION_STARTS
28# CHECK: cmdsize 16
29# CHECK: dataoff
30# CHECK: datasize
31
32# NO_FUNCTION_STARTS-NOT: LC_FUNCTION_STARTS
deps/lld/test/mach-o/gcc_except_tab-got-arm64.yaml created+53
......@@ -0,0 +1,53 @@
1# RUN: lld -flavor darwin -arch arm64 %s \
2# RUN: -dylib %p/Inputs/arm64/libSystem.yaml -o %t
3# RUN: llvm-objdump -section-headers %t | FileCheck %s
4
5# Make sure that the GOT relocation from gcc_except_tab to the data
6# is not removed.
7
8--- !native
9defined-atoms:
10 - name: _main
11 scope: global
12 content: [ FD, 7B, BF, A9, FD, 03, 00, 91, FF, 43, 00, D1,
13 BF, C3, 1F, B8, 00, 00, 00, 94, BF, 03, 00, 91,
14 FD, 7B, C1, A8, C0, 03, 5F, D6 ]
15 alignment: 4
16 - name: __ZTSP1A
17 scope: hidden
18 type: constant
19 content: [ 50, 31, 41, 00 ]
20 merge: as-weak
21 - name: GCC_except_table0
22 type: unwind-lsda
23 content: [ FF, 9B, E7, 80, 00, 03, 5B, 00, 00, 00, 00, 1C,
24 00, 00, 00, 00, 00, 00, 00, 00, 1C, 00, 00, 00,
25 18, 00, 00, 00, 84, 00, 00, 00, 03, 40, 00, 00,
26 00, 10, 00, 00, 00, 94, 00, 00, 00, 03, 60, 00,
27 00, 00, 20, 00, 00, 00, B4, 00, 00, 00, 05, 80,
28 00, 00, 00, 68, 00, 00, 00, 00, 00, 00, 00, 00,
29 E8, 00, 00, 00, 08, 00, 00, 00, 28, 01, 00, 00,
30 00, F0, 00, 00, 00, 74, 00, 00, 00, 00, 00, 00,
31 00, 00, 00, 00, 01, 7D, 01, 00, A8, FF, FF, FF ]
32 alignment: 4
33 references:
34 - kind: delta32ToGOT
35 offset: 104
36 target: __ZTIP1A
37 - name: __ZTIP1A
38 scope: hidden
39 type: data
40 content: [ 10, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
41 00, 00, 00, 80, 00, 00, 00, 00, 00, 00, 00, 00,
42 00, 00, 00, 00, 00, 00, 00, 00 ]
43 merge: as-weak
44 alignment: 16
45shared-library-atoms:
46 - name: dyld_stub_binder
47 load-name: /usr/lib/libSystem.B.dylib
48 type: unknown
49...
50
51# Make sure we have a GOT relocation.
52# This could only have come from __gcc_except_tab to __ZTIP1A
53# CHECK: __got
\ No newline at end of file
deps/lld/test/mach-o/got-order.yaml created+69
......@@ -0,0 +1,69 @@
1# RUN: lld -flavor darwin -arch x86_64 %s %p/Inputs/got-order.yaml \
2# RUN: %p/Inputs/got-order2.yaml -o %t %p/Inputs/x86_64/libSystem.yaml
3# RUN: llvm-objdump -bind %t | FileCheck %s
4#
5# Test that GOT slots are sorted by name
6#
7
8--- !mach-o
9arch: x86_64
10file-type: MH_OBJECT
11flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
12sections:
13 - segment: __TEXT
14 section: __text
15 type: S_REGULAR
16 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
17 address: 0x0000000000000000
18 content: [ 0x55, 0x48, 0x89, 0xE5, 0x48, 0x8B, 0x0D, 0x00,
19 0x00, 0x00, 0x00, 0x48, 0x8B, 0x05, 0x00, 0x00,
20 0x00, 0x00, 0x8B, 0x00, 0x03, 0x01, 0x48, 0x8B,
21 0x0D, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x5D,
22 0xC3 ]
23 relocations:
24 - offset: 0x00000019
25 type: X86_64_RELOC_GOT_LOAD
26 length: 2
27 pc-rel: true
28 extern: true
29 symbol: 2
30 - offset: 0x0000000E
31 type: X86_64_RELOC_GOT_LOAD
32 length: 2
33 pc-rel: true
34 extern: true
35 symbol: 1
36 - offset: 0x00000007
37 type: X86_64_RELOC_GOT_LOAD
38 length: 2
39 pc-rel: true
40 extern: true
41 symbol: 3
42global-symbols:
43 - name: _func
44 type: N_SECT
45 scope: [ N_EXT ]
46 sect: 1
47 value: 0x0000000000000000
48undefined-symbols:
49 - name: _aaa
50 type: N_UNDF
51 scope: [ N_EXT ]
52 value: 0x0000000000000000
53 - name: _fff
54 type: N_UNDF
55 scope: [ N_EXT ]
56 value: 0x0000000000000000
57 - name: _zzz
58 type: N_UNDF
59 scope: [ N_EXT ]
60 value: 0x0000000000000000
61...
62
63
64# CHECK: __DATA __got {{[0-9a-zA-Z _]+}} pointer 0 libfoobar _aaa
65# CHECK-NEXT: __DATA __got {{[0-9a-zA-Z _]+}} pointer 0 libfoobar _bar
66# CHECK-NEXT: __DATA __got {{[0-9a-zA-Z _]+}} pointer 0 libfoobar _fff
67# CHECK-NEXT: __DATA __got {{[0-9a-zA-Z _]+}} pointer 0 libfoobar _foo
68# CHECK-NEXT: __DATA __got {{[0-9a-zA-Z _]+}} pointer 0 libfoobar _zazzle
69# CHECK-NEXT: __DATA __got {{[0-9a-zA-Z _]+}} pointer 0 libfoobar _zzz
deps/lld/test/mach-o/hello-world-arm64.yaml created+102
......@@ -0,0 +1,102 @@
1# RUN: lld -flavor darwin -arch arm64 %s %p/Inputs/hello-world-arm64.yaml -o %t
2# RUN: llvm-nm -m -n %t | FileCheck %s
3# RUN: llvm-objdump -private-headers %t | FileCheck %s --check-prefix=CHECK-PRIVATE-HEADER
4#
5# Test that arm64 hello-world can be linked into a mach-o executable
6#
7
8--- !mach-o
9arch: arm64
10file-type: MH_OBJECT
11flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
12sections:
13 - segment: __TEXT
14 section: __text
15 type: S_REGULAR
16 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
17 alignment: 2
18 address: 0x0000000000000000
19 content: [ 0xFD, 0x7B, 0xBF, 0xA9, 0xFD, 0x03, 0x00, 0x91,
20 0x08, 0x00, 0x00, 0x90, 0x08, 0x01, 0x40, 0xF9,
21 0x00, 0x01, 0x40, 0xF9, 0x01, 0x00, 0x00, 0x90,
22 0x21, 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x94,
23 0x00, 0x00, 0x80, 0x52, 0xFD, 0x7B, 0xC1, 0xA8,
24 0xC0, 0x03, 0x5F, 0xD6 ]
25 relocations:
26 - offset: 0x0000001C
27 type: ARM64_RELOC_BRANCH26
28 length: 2
29 pc-rel: true
30 extern: true
31 symbol: 5
32 - offset: 0x00000018
33 type: ARM64_RELOC_PAGEOFF12
34 length: 2
35 pc-rel: false
36 extern: true
37 symbol: 1
38 - offset: 0x00000014
39 type: ARM64_RELOC_PAGE21
40 length: 2
41 pc-rel: true
42 extern: true
43 symbol: 1
44 - offset: 0x0000000C
45 type: ARM64_RELOC_GOT_LOAD_PAGEOFF12
46 length: 2
47 pc-rel: false
48 extern: true
49 symbol: 4
50 - offset: 0x00000008
51 type: ARM64_RELOC_GOT_LOAD_PAGE21
52 length: 2
53 pc-rel: true
54 extern: true
55 symbol: 4
56 - segment: __TEXT
57 section: __cstring
58 type: S_CSTRING_LITERALS
59 attributes: [ ]
60 address: 0x000000000000002C
61 content: [ 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x00 ]
62local-symbols:
63 - name: ltmp0
64 type: N_SECT
65 sect: 1
66 value: 0x0000000000000000
67 - name: l_.str
68 type: N_SECT
69 sect: 2
70 value: 0x000000000000002C
71 - name: ltmp1
72 type: N_SECT
73 sect: 2
74 value: 0x000000000000002C
75global-symbols:
76 - name: _main
77 type: N_SECT
78 scope: [ N_EXT ]
79 sect: 1
80 value: 0x0000000000000000
81undefined-symbols:
82 - name: ___stdoutp
83 type: N_UNDF
84 scope: [ N_EXT ]
85 value: 0x0000000000000000
86 - name: _fprintf
87 type: N_UNDF
88 scope: [ N_EXT ]
89 value: 0x0000000000000000
90...
91
92# CHECK: (undefined) external ___stdoutp (from libSystem)
93# CHECK: (undefined) external _fprintf (from libSystem)
94# CHECK: (undefined) external dyld_stub_binder (from libSystem)
95# CHECK: {{[0-9a-f]+}} (__TEXT,__text) external _main
96
97# CHECK-PRIVATE-HEADER: sectname __stubs
98# CHECK-PRIVATE-HEADER-NEXT: segname __TEXT
99# CHECK-PRIVATE-HEADER-NEXT: addr
100# CHECK-PRIVATE-HEADER-NEXT: size
101# CHECK-PRIVATE-HEADER-NEXT: offset
102# CHECK-PRIVATE-HEADER-NEXT: align 2^1 (2)
deps/lld/test/mach-o/hello-world-armv6.yaml created+64
......@@ -0,0 +1,64 @@
1# RUN: lld -flavor darwin -arch armv6 %s %p/Inputs/hello-world-armv6.yaml -o %t
2# RUN: llvm-nm -m %t | FileCheck %s
3#
4# Test that armv6 (arm) hello-world can be linked into a mach-o executable
5#
6
7--- !mach-o
8arch: armv6
9file-type: MH_OBJECT
10flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
11has-UUID: false
12OS: unknown
13sections:
14 - segment: __TEXT
15 section: __text
16 type: S_REGULAR
17 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
18 alignment: 2
19 address: 0x0000000000000000
20 content: [ 0x80, 0x40, 0x2D, 0xE9, 0x10, 0x00, 0x9F, 0xE5,
21 0x0D, 0x70, 0xA0, 0xE1, 0x00, 0x00, 0x8F, 0xE0,
22 0xFA, 0xFF, 0xFF, 0xEB, 0x00, 0x00, 0xA0, 0xE3,
23 0x80, 0x80, 0xBD, 0xE8, 0x0C, 0x00, 0x00, 0x00 ]
24 relocations:
25 - offset: 0x0000001C
26 scattered: true
27 type: ARM_RELOC_SECTDIFF
28 length: 2
29 pc-rel: false
30 value: 0x00000020
31 - offset: 0x00000000
32 scattered: true
33 type: ARM_RELOC_PAIR
34 length: 2
35 pc-rel: false
36 value: 0x0000000C
37 - offset: 0x00000010
38 type: ARM_RELOC_BR24
39 length: 2
40 pc-rel: true
41 extern: true
42 symbol: 1
43 - segment: __TEXT
44 section: __cstring
45 type: S_CSTRING_LITERALS
46 attributes: [ ]
47 address: 0x0000000000000020
48 content: [ 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x00 ]
49global-symbols:
50 - name: _main
51 type: N_SECT
52 scope: [ N_EXT ]
53 sect: 1
54 value: 0x0000000000000000
55undefined-symbols:
56 - name: _printf
57 type: N_UNDF
58 scope: [ N_EXT ]
59 value: 0x0000000000000000
60...
61
62# CHECK: {{[0-9a-f]+}} (__TEXT,__text) external _main
63# CHECK: (undefined) external _printf (from libSystem)
64# CHECK: (undefined) external dyld_stub_binder (from libSystem)
deps/lld/test/mach-o/hello-world-armv7.yaml created+76
......@@ -0,0 +1,76 @@
1# RUN: lld -flavor darwin -arch armv7 %s %p/Inputs/hello-world-armv7.yaml -o %t
2# RUN: llvm-nm -m -n %t | FileCheck %s
3#
4# Test that armv7 (thumb) hello-world can be linked into a mach-o executable
5#
6
7--- !mach-o
8arch: armv7
9file-type: MH_OBJECT
10flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
11has-UUID: false
12OS: unknown
13sections:
14 - segment: __TEXT
15 section: __text
16 type: S_REGULAR
17 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
18 alignment: 2
19 address: 0x0000000000000000
20 content: [ 0x80, 0xB5, 0x40, 0xF2, 0x06, 0x00, 0x6F, 0x46,
21 0xC0, 0xF2, 0x00, 0x00, 0x78, 0x44, 0xFF, 0xF7,
22 0xF8, 0xEF, 0x00, 0x20, 0x80, 0xBD ]
23 relocations:
24 - offset: 0x0000000E
25 type: ARM_THUMB_RELOC_BR22
26 length: 2
27 pc-rel: true
28 extern: true
29 symbol: 1
30 - offset: 0x00000008
31 scattered: true
32 type: ARM_RELOC_HALF_SECTDIFF
33 length: 3
34 pc-rel: false
35 value: 0x00000016
36 - offset: 0x00000006
37 scattered: true
38 type: ARM_RELOC_PAIR
39 length: 3
40 pc-rel: false
41 value: 0x0000000C
42 - offset: 0x00000002
43 scattered: true
44 type: ARM_RELOC_HALF_SECTDIFF
45 length: 2
46 pc-rel: false
47 value: 0x00000016
48 - offset: 0x00000000
49 scattered: true
50 type: ARM_RELOC_PAIR
51 length: 2
52 pc-rel: false
53 value: 0x0000000C
54 - segment: __TEXT
55 section: __cstring
56 type: S_CSTRING_LITERALS
57 attributes: [ ]
58 address: 0x0000000000000016
59 content: [ 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x00 ]
60global-symbols:
61 - name: _main
62 type: N_SECT
63 scope: [ N_EXT ]
64 sect: 1
65 desc: [ N_ARM_THUMB_DEF ]
66 value: 0x0000000000000000
67undefined-symbols:
68 - name: _printf
69 type: N_UNDF
70 scope: [ N_EXT ]
71 value: 0x0000000000000000
72...
73
74# CHECK: (undefined) external _printf (from libSystem)
75# CHECK: (undefined) external dyld_stub_binder (from libSystem)
76# CHECK: {{[0-9a-f]+}} (__TEXT,__text) external [Thumb] _main
deps/lld/test/mach-o/hello-world-x86.yaml created+62
......@@ -0,0 +1,62 @@
1# RUN: lld -flavor darwin -arch i386 %s %p/Inputs/hello-world-x86.yaml -o %t
2# RUN: llvm-nm -m %t | FileCheck %s
3#
4# Test that i386 hello-world can be linked into a mach-o executable
5#
6
7--- !mach-o
8arch: x86
9file-type: MH_OBJECT
10flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
11sections:
12 - segment: __TEXT
13 section: __text
14 type: S_REGULAR
15 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
16 address: 0x0000000000000000
17 content: [ 0x55, 0x89, 0xE5, 0x83, 0xEC, 0x08, 0xE8, 0x00,
18 0x00, 0x00, 0x00, 0x58, 0x8D, 0x80, 0x16, 0x00,
19 0x00, 0x00, 0x89, 0x04, 0x24, 0xE8, 0xE6, 0xFF,
20 0xFF, 0xFF, 0x31, 0xC0, 0x83, 0xC4, 0x08, 0x5D,
21 0xC3 ]
22 relocations:
23 - offset: 0x00000016
24 type: GENERIC_RELOC_VANILLA
25 length: 2
26 pc-rel: true
27 extern: true
28 symbol: 1
29 - offset: 0x0000000E
30 scattered: true
31 type: GENERIC_RELOC_LOCAL_SECTDIFF
32 length: 2
33 pc-rel: false
34 value: 0x00000021
35 - offset: 0x00000000
36 scattered: true
37 type: GENERIC_RELOC_PAIR
38 length: 2
39 pc-rel: false
40 value: 0x0000000B
41 - segment: __TEXT
42 section: __cstring
43 type: S_CSTRING_LITERALS
44 attributes: [ ]
45 address: 0x0000000000000021
46 content: [ 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x00 ]
47global-symbols:
48 - name: _main
49 type: N_SECT
50 scope: [ N_EXT ]
51 sect: 1
52 value: 0x0000000000000000
53undefined-symbols:
54 - name: _printf
55 type: N_UNDF
56 scope: [ N_EXT ]
57 value: 0x0000000000000000
58...
59
60# CHECK: {{[0-9a-f]+}} (__TEXT,__text) external _main
61# CHECK: (undefined) external _printf (from libSystem)
62# CHECK: (undefined) external dyld_stub_binder (from libSystem)
deps/lld/test/mach-o/hello-world-x86_64.yaml created+120
......@@ -0,0 +1,120 @@
1# RUN: lld -flavor darwin -arch x86_64 %s %p/Inputs/hello-world-x86_64.yaml \
2# RUN: -o %t
3# RUN: llvm-nm -m -n %t | FileCheck %s
4#
5# RUN: lld -flavor darwin -arch x86_64 %s %p/Inputs/hello-world-x86_64.yaml \
6# RUN: -dead_strip -o %t2
7# RUN: llvm-nm -m -n %t2 | FileCheck %s
8#
9# Test that x86_64 hello-world can be linked into a mach-o executable
10#
11
12--- !mach-o
13arch: x86_64
14file-type: MH_OBJECT
15flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
16has-UUID: false
17OS: unknown
18sections:
19 - segment: __TEXT
20 section: __text
21 type: S_REGULAR
22 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
23 address: 0x0000000000000000
24 content: [ 0x55, 0x48, 0x89, 0xE5, 0x48, 0x8B, 0x05, 0x00,
25 0x00, 0x00, 0x00, 0x48, 0x8B, 0x38, 0x48, 0x8D,
26 0x35, 0x00, 0x00, 0x00, 0x00, 0x31, 0xC0, 0xE8,
27 0x00, 0x00, 0x00, 0x00, 0x31, 0xC0, 0x5D, 0xC3 ]
28 relocations:
29 - offset: 0x00000018
30 type: X86_64_RELOC_BRANCH
31 length: 2
32 pc-rel: true
33 extern: true
34 symbol: 5
35 - offset: 0x00000011
36 type: X86_64_RELOC_SIGNED
37 length: 2
38 pc-rel: true
39 extern: true
40 symbol: 0
41 - offset: 0x00000007
42 type: X86_64_RELOC_GOT_LOAD
43 length: 2
44 pc-rel: true
45 extern: true
46 symbol: 4
47 - segment: __TEXT
48 section: __cstring
49 type: S_CSTRING_LITERALS
50 attributes: [ ]
51 address: 0x0000000000000020
52 content: [ 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x00 ]
53 - segment: __LD
54 section: __compact_unwind
55 type: S_REGULAR
56 attributes: [ ]
57 alignment: 8
58 address: 0x0000000000000028
59 content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
60 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
61 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
63 relocations:
64 - offset: 0x00000000
65 type: X86_64_RELOC_UNSIGNED
66 length: 3
67 pc-rel: false
68 extern: false
69 symbol: 1
70 - segment: __TEXT
71 section: __eh_frame
72 type: S_COALESCED
73 attributes: [ ]
74 alignment: 8
75 address: 0x0000000000000048
76 content: [ 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
77 0x01, 0x7A, 0x52, 0x00, 0x01, 0x78, 0x10, 0x01,
78 0x10, 0x0C, 0x07, 0x08, 0x90, 0x01, 0x00, 0x00,
79 0x24, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00,
80 0x98, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
81 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82 0x00, 0x41, 0x0E, 0x10, 0x86, 0x02, 0x43, 0x0D,
83 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
84local-symbols:
85 - name: L1
86 type: N_SECT
87 sect: 2
88 value: 0x0000000000000020
89 - name: EH_frame0
90 type: N_SECT
91 sect: 4
92 value: 0x0000000000000048
93global-symbols:
94 - name: _main
95 type: N_SECT
96 scope: [ N_EXT ]
97 sect: 1
98 value: 0x0000000000000000
99 - name: _main.eh
100 type: N_SECT
101 scope: [ N_EXT ]
102 sect: 4
103 value: 0x0000000000000060
104undefined-symbols:
105 - name: ___stdoutp
106 type: N_UNDF
107 scope: [ N_EXT ]
108 value: 0x0000000000000000
109 - name: _fprintf
110 type: N_UNDF
111 scope: [ N_EXT ]
112 value: 0x0000000000000000
113
114...
115
116# CHECK: (undefined) external ___stdoutp (from libSystem)
117# CHECK: (undefined) external _fprintf (from libSystem)
118# CHECK: (undefined) external dyld_stub_binder (from libSystem)
119# CHECK: {{[0-9a-f]+}} (__TEXT,__text) [referenced dynamically] external __mh_execute_header
120# CHECK: {{[0-9a-f]+}} (__TEXT,__text) external _main
deps/lld/test/mach-o/image-base.yaml created+28
......@@ -0,0 +1,28 @@
1# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.9 %s -o %t -image_base 31415926000 %p/Inputs/x86_64/libSystem.yaml
2# RUN: llvm-readobj -macho-segment %t | FileCheck %s
3# RUN: not lld -flavor darwin -arch x86_64 -image_base 0x31415926530 %s >/dev/null 2> %t
4# RUN: FileCheck < %t %s --check-prefix=CHECK-ERROR-MISPAGED
5# RUN: not lld -flavor darwin -arch x86_64 -image_base 1000 %s >/dev/null 2> %t
6# RUN: FileCheck < %t %s --check-prefix=CHECK-ERROR-OVERLAP
7# RUN: not lld -flavor darwin -arch x86_64 -image_base hithere %s >/dev/null 2> %t
8# RUN: FileCheck < %t %s --check-prefix=CHECK-ERROR-NOTHEX
9
10--- !native
11defined-atoms:
12 - name: _main
13 scope: global
14 content: []
15
16# CHECK: Segment {
17# CHECK: Cmd: LC_SEGMENT_64
18# CHECK: Name: __TEXT
19# CHECK-NEXT: Size: 152
20# CHECK-NEXT: vmaddr: 0x31415926000
21# CHECK-NEXT: vmsize: 0x1000
22
23
24# CHECK-ERROR-MISPAGED: error: image_base must be a multiple of page size (0x1000)
25
26# CHECK-ERROR-OVERLAP: error: image_base overlaps with __PAGEZERO
27
28# CHECK-ERROR-NOTHEX: error: image_base expects a hex number
deps/lld/test/mach-o/infer-arch.yaml created+29
......@@ -0,0 +1,29 @@
1# RUN: lld -flavor darwin -arch i386 -macosx_version_min 10.8 %s -r -o %t \
2# RUN: && lld -flavor darwin -r %t -o %t2 -print_atoms | FileCheck %s
3#
4# Test linker can detect architecture without -arch option.
5#
6
7--- !mach-o
8arch: x86
9file-type: MH_OBJECT
10flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
11sections:
12 - segment: __TEXT
13 section: __text
14 type: S_REGULAR
15 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
16 address: 0x0000000000000000
17 content: [ 0xC3 ]
18global-symbols:
19 - name: _foo
20 type: N_SECT
21 scope: [ N_EXT ]
22 sect: 1
23 value: 0x0000000000000000
24
25...
26
27
28# CHECK: defined-atoms:
29# CHECK: - name: _foo
deps/lld/test/mach-o/interposing-section.yaml created+72
......@@ -0,0 +1,72 @@
1# RUN: lld -flavor darwin -arch x86_64 %s %p/Inputs/interposing-section.yaml \
2# RUN: -dylib -o %t %p/Inputs/x86_64/libSystem.yaml
3# RUN: llvm-objdump -private-headers %t | FileCheck %s
4#
5# RUN: lld -flavor darwin -arch x86_64 %s -r -o %t1
6# RUN: llvm-objdump -private-headers %t1 | FileCheck %s
7#
8# Test that interposing section is preserved by linker.
9#
10
11--- !mach-o
12arch: x86_64
13file-type: MH_OBJECT
14flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
15sections:
16 - segment: __TEXT
17 section: __text
18 type: S_REGULAR
19 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
20 address: 0x0000000000000000
21 content: [ 0x55, 0x48, 0x89, 0xE5, 0x31, 0xC0, 0x5D, 0xE9,
22 0x00, 0x00, 0x00, 0x00 ]
23 relocations:
24 - offset: 0x00000008
25 type: X86_64_RELOC_BRANCH
26 length: 2
27 pc-rel: true
28 extern: true
29 symbol: 2
30 - segment: __DATA
31 section: __interpose
32 type: S_INTERPOSING
33 attributes: [ ]
34 alignment: 8
35 address: 0x0000000000000010
36 content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
37 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
38 relocations:
39 - offset: 0x00000008
40 type: X86_64_RELOC_UNSIGNED
41 length: 3
42 pc-rel: false
43 extern: true
44 symbol: 2
45 - offset: 0x00000000
46 type: X86_64_RELOC_UNSIGNED
47 length: 3
48 pc-rel: false
49 extern: true
50 symbol: 0
51local-symbols:
52 - name: _my_open
53 type: N_SECT
54 sect: 1
55 value: 0x0000000000000000
56 - name: __interpose_open
57 type: N_SECT
58 sect: 2
59 desc: [ N_NO_DEAD_STRIP ]
60 value: 0x0000000000000010
61undefined-symbols:
62 - name: _open
63 type: N_UNDF
64 scope: [ N_EXT ]
65 value: 0x0000000000000000
66...
67
68
69# CHECK: sectname __interposing
70# CHECK: segname __DATA
71# CHECK: type S_INTERPOSING
72
deps/lld/test/mach-o/keep_private_externs.yaml created+63
......@@ -0,0 +1,63 @@
1# RUN: lld -flavor darwin -arch x86_64 -r %s -o %t \
2# RUN: && llvm-nm -m %t | FileCheck %s
3#
4# RUN: lld -flavor darwin -arch x86_64 -r %s -o %t2 -keep_private_externs \
5# RUN: && llvm-nm -m %t2 | FileCheck -check-prefix=CHECK_KPE %s
6#
7# Test -keep_private_externs in -r mode.
8#
9
10--- !mach-o
11arch: x86_64
12file-type: MH_OBJECT
13flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
14sections:
15 - segment: __TEXT
16 section: __text
17 type: S_REGULAR
18 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
19 address: 0x0000000000000000
20 content: [ 0x55, 0x48, 0x89, 0xE5, 0x5D, 0xC3, 0x55, 0x48,
21 0x89, 0xE5, 0x5D, 0xC3 ]
22 - segment: __DATA
23 section: __data
24 type: S_REGULAR
25 attributes: [ ]
26 alignment: 2
27 address: 0x000000000000000C
28 content: [ 0x0A, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00 ]
29
30global-symbols:
31 - name: _a
32 type: N_SECT
33 scope: [ N_EXT ]
34 sect: 2
35 value: 0x000000000000000C
36 - name: _b
37 type: N_SECT
38 scope: [ N_EXT, N_PEXT ]
39 sect: 2
40 value: 0x0000000000000010
41 - name: _bar
42 type: N_SECT
43 scope: [ N_EXT ]
44 sect: 1
45 value: 0x0000000000000006
46 - name: _foo
47 type: N_SECT
48 scope: [ N_EXT, N_PEXT ]
49 sect: 1
50 value: 0x0000000000000000
51
52
53...
54
55# CHECK: (__DATA,__data) external _a
56# CHECK: (__DATA,__data) non-external (was a private external) _b
57# CHECK: (__TEXT,__text) external _bar
58# CHECK: (__TEXT,__text) non-external (was a private external) _foo
59
60# CHECK_KPE: (__DATA,__data) external _a
61# CHECK_KPE: (__DATA,__data) private external _b
62# CHECK_KPE: (__TEXT,__text) external _bar
63# CHECK_KPE: (__TEXT,__text) private external _foo
deps/lld/test/mach-o/lazy-bind-x86_64.yaml created+111
......@@ -0,0 +1,111 @@
1# REQUIRES: x86
2
3# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s \
4# RUN: %p/Inputs/lazy-bind-x86_64.yaml %p/Inputs/lazy-bind-x86_64-2.yaml \
5# RUN: %p/Inputs/lazy-bind-x86_64-3.yaml -o %t \
6# RUN: %p/Inputs/x86_64/libSystem.yaml
7# RUN: llvm-objdump -lazy-bind %t | FileCheck %s
8# RUN: llvm-nm -m %t | FileCheck --check-prefix=CHECK-NM %s
9# RUN: llvm-objdump -disassemble %t | FileCheck --check-prefix=CHECK-HELPERS %s
10# RUN: llvm-objdump -private-headers %t | FileCheck --check-prefix=CHECK-DYLIBS %s
11#
12# Test that correct two-level namespace ordinals are used for lazy bindings.
13#
14
15--- !mach-o
16arch: x86_64
17file-type: MH_OBJECT
18flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
19sections:
20 - segment: __TEXT
21 section: __text
22 type: S_REGULAR
23 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
24 address: 0x0000000000000000
25 content: [ 0x55, 0x48, 0x89, 0xE5, 0x31, 0xC0, 0xE8, 0x00,
26 0x00, 0x00, 0x00, 0x31, 0xC0, 0xE8, 0x00, 0x00,
27 0x00, 0x00, 0x31, 0xC0, 0xE8, 0x00, 0x00, 0x00,
28 0x00, 0x31, 0xC0, 0x5D, 0xC3 ]
29 relocations:
30 - offset: 0x00000015
31 type: X86_64_RELOC_BRANCH
32 length: 2
33 pc-rel: true
34 extern: true
35 symbol: 3
36 - offset: 0x0000000E
37 type: X86_64_RELOC_BRANCH
38 length: 2
39 pc-rel: true
40 extern: true
41 symbol: 2
42 - offset: 0x00000007
43 type: X86_64_RELOC_BRANCH
44 length: 2
45 pc-rel: true
46 extern: true
47 symbol: 1
48global-symbols:
49 - name: _main
50 type: N_SECT
51 scope: [ N_EXT ]
52 sect: 1
53 value: 0x0000000000000000
54undefined-symbols:
55 - name: _bar
56 type: N_UNDF
57 scope: [ N_EXT ]
58 value: 0x0000000000000000
59 - name: _baz
60 type: N_UNDF
61 scope: [ N_EXT ]
62 value: 0x0000000000000000
63 - name: _foo
64 type: N_UNDF
65 scope: [ N_EXT ]
66 value: 0x0000000000000000
67
68...
69
70
71# CHECK: libbar _bar
72# CHECK: libbaz _baz
73# CHECK: libfoo _foo
74
75
76# CHECK-NM: (undefined) external _bar (from libbar)
77# CHECK-NM: (undefined) external _baz (from libbaz)
78# CHECK-NM: (undefined) external _foo (from libfoo)
79
80
81# CHECK-HELPERS:Disassembly of section __TEXT,__stub_helper:
82# CHECK-HELPERS: 68 00 00 00 00 pushq $0
83# CHECK-HELPERS: 68 0b 00 00 00 pushq $11
84# CHECK-HELPERS: 68 16 00 00 00 pushq $22
85
86# Make sure the stub helper is correctly aligned
87# CHECK-DYLIBS: sectname __stub_helper
88# CHECK-DYLIBS-NEXT: segname __TEXT
89# CHECK-DYLIBS-NEXT: addr
90# CHECK-DYLIBS-NEXT: size
91# CHECK-DYLIBS-NEXT: offset
92# CHECK-DYLIBS-NEXT: align 2^2 (4)
93
94# Make sure the __nl_symbol_ptr section is used instea of __got as this is x86_64
95# CHECK-DYLIBS: sectname __nl_symbol_ptr
96# CHECK-DYLIBS-NEXT: segname __DATA
97
98# CHECK-DYLIBS: cmd LC_LOAD_DYLIB
99# CHECK-DYLIBS: name /usr/lib/libbar.dylib (offset 24)
100# CHECK-DYLIBS: current version 2.3.0
101# CHECK-DYLIBS: compatibility version 1.0.0
102# CHECK-DYLIBS: cmd LC_LOAD_DYLIB
103# CHECK-DYLIBS: name /usr/lib/libfoo.dylib (offset 24)
104# CHECK-DYLIBS: current version 3.4.0
105# CHECK-DYLIBS: compatibility version 2.0.0
106# CHECK-DYLIBS: cmd LC_LOAD_DYLIB
107# CHECK-DYLIBS: name /usr/lib/libbaz.dylib (offset 24)
108# CHECK-DYLIBS: current version 4.5.0
109# CHECK-DYLIBS: compatibility version 3.0.0
110
111
deps/lld/test/mach-o/lc_segment_filesize.yaml created+31
......@@ -0,0 +1,31 @@
1# RUN: lld -flavor darwin -arch x86_64 -r -o %t %s && llvm-objdump -private-headers %t | FileCheck %s
2
3# CHECK: filesize 19
4
5--- !mach-o
6arch: x86_64
7file-type: MH_OBJECT
8flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
9sections:
10 - segment: __TEXT
11 section: __text
12 type: S_REGULAR
13 attributes: [ S_ATTR_PURE_INSTRUCTIONS ]
14 alignment: 16
15 address: 0x0000000000000000
16 content: [ 0x00, 0x00, 0x00 ]
17 - segment: __TEXT
18 section: __alt
19 type: S_REGULAR
20 attributes: [ S_ATTR_PURE_INSTRUCTIONS ]
21 alignment: 16
22 address: 0x0000000000000010
23 content: [ 0x00, 0x00, 0x00 ]
24global-symbols:
25 - name: _main
26 type: N_SECT
27 scope: [ N_EXT ]
28 sect: 1
29 value: 0x0000000000000000
30page-size: 0x00000000
31...
deps/lld/test/mach-o/lib-search-paths.yaml created+16
......@@ -0,0 +1,16 @@
1# RUN: lld -flavor darwin -arch x86_64 %s -syslibroot %p/Inputs/lib-search-paths -lmyshared -lmystatic -lfile.o -r -print_atoms 2>&1 | FileCheck %s
2
3--- !native
4undefined-atoms:
5 - name: _from_myshared
6 - name: _from_mystatic
7 - name: _from_fileo
8
9# CHECK: defined-atoms:
10# CHECK: - name: _from_fileo
11# CHECK: content: [ 2A, 00, 00, 00 ]
12# CHECK: - name: _from_mystatic
13# CHECK: content: [ 02, 00, 00, 00 ]
14# CHECK: shared-library-atoms:
15# CHECK: - name: _from_myshared
16# CHECK: load-name: libmyshared.dylib
deps/lld/test/mach-o/library-order.yaml created+45
......@@ -0,0 +1,45 @@
1# RUN: lld -flavor darwin -arch x86_64 %p/Inputs/libfoo.a %s -o %t \
2# RUN: %p/Inputs/x86_64/libSystem.yaml
3# RUN: llvm-nm -m -n %t | FileCheck %s
4#
5# Test that if library is before object file on command line, it still is used.
6#
7
8--- !mach-o
9arch: x86_64
10file-type: MH_OBJECT
11flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
12sections:
13 - segment: __TEXT
14 section: __text
15 type: S_REGULAR
16 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
17 alignment: 4
18 address: 0x0000000000000000
19 content: [ 0x55, 0x48, 0x89, 0xE5, 0x48, 0x83, 0xEC, 0x10,
20 0xC7, 0x45, 0xFC, 0x00, 0x00, 0x00, 0x00, 0xB0,
21 0x00, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x31, 0xC0,
22 0x48, 0x83, 0xC4, 0x10, 0x5D, 0xC3 ]
23 relocations:
24 - offset: 0x00000012
25 type: X86_64_RELOC_BRANCH
26 length: 2
27 pc-rel: true
28 extern: true
29 symbol: 1
30global-symbols:
31 - name: _main
32 type: N_SECT
33 scope: [ N_EXT ]
34 sect: 1
35 value: 0x0000000000000000
36undefined-symbols:
37 - name: _foo
38 type: N_UNDF
39 scope: [ N_EXT ]
40 value: 0x0000000000000000
41
42...
43
44# CHECK: {{[0-9a-f]+}} (__TEXT,__text) external _main
45# CHECK: {{[0-9a-f]+}} (__TEXT,__text) external _foo
deps/lld/test/mach-o/library-rescan.yaml created+46
......@@ -0,0 +1,46 @@
1# RUN: lld -flavor darwin -arch x86_64 %p/Inputs/libfoo.a %p/Inputs/libbar.a \
2# RUN: %s -o %t %p/Inputs/x86_64/libSystem.yaml
3# RUN: llvm-nm -m -n %t | FileCheck %s
4#
5# Test that static libraries are automatically rescanned (bar needs foo).
6#
7
8--- !mach-o
9arch: x86_64
10file-type: MH_OBJECT
11flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
12sections:
13 - segment: __TEXT
14 section: __text
15 type: S_REGULAR
16 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
17 alignment: 4
18 address: 0x0000000000000000
19 content: [ 0x55, 0x48, 0x89, 0xE5, 0x48, 0x83, 0xEC, 0x10,
20 0xC7, 0x45, 0xFC, 0x00, 0x00, 0x00, 0x00, 0xB0,
21 0x00, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x31, 0xC0,
22 0x48, 0x83, 0xC4, 0x10, 0x5D, 0xC3 ]
23 relocations:
24 - offset: 0x00000012
25 type: X86_64_RELOC_BRANCH
26 length: 2
27 pc-rel: true
28 extern: true
29 symbol: 1
30global-symbols:
31 - name: _main
32 type: N_SECT
33 scope: [ N_EXT ]
34 sect: 1
35 value: 0x0000000000000000
36undefined-symbols:
37 - name: _bar
38 type: N_UNDF
39 scope: [ N_EXT ]
40 value: 0x0000000000000000
41
42...
43
44# CHECK: {{[0-9a-f]+}} (__TEXT,__text) external _main
45# CHECK: {{[0-9a-f]+}} (__TEXT,__text) external _bar
46# CHECK: {{[0-9a-f]+}} (__TEXT,__text) external _foo
deps/lld/test/mach-o/libresolve-bizarre-root-override.yaml created+17
......@@ -0,0 +1,17 @@
1# RUN: not lld -flavor darwin -test_file_usage -v \
2# RUN: -path_exists /usr/lib \
3# RUN: -path_exists /Applications/MySDK/usr/local/lib \
4# RUN: -path_exists /Applications/MySDK/usr/lib \
5# RUN: -path_exists /Applications/MySDK/usr/lib/libSystem.dylib \
6# RUN: -syslibroot /Applications/MySDK \
7# RUN: -syslibroot / \
8# RUN: -lSystem \
9# RUN: 2>&1 | FileCheck %s
10
11# When the last -syslibroot is simply "/", all of them get discarded. So in this
12# case, only /usr/lib should show up.
13
14# CHECK: Library search paths:
15# CHECK: /usr/lib
16# CHECK-NOT: /usr/local/lib
17# CHECK: Unable to find library for -lSystem
deps/lld/test/mach-o/libresolve-multiple-syslibroots.yaml created+17
......@@ -0,0 +1,17 @@
1# RUN: lld -flavor darwin -test_file_usage -v \
2# RUN: -path_exists /usr/lib \
3# RUN: -path_exists /Applications/MyFirstSDK/usr/local/lib \
4# RUN: -path_exists /Applications/MySecondSDK/usr/local/lib \
5# RUN: -path_exists /Applications/MyFirstSDK/usr/local/lib/libSystem.a \
6# RUN: -path_exists /Applications/MySecondSDK/usr/local/lib/libSystem.a \
7# RUN: -syslibroot /Applications/MyFirstSDK \
8# RUN: -syslibroot /Applications/MySecondSDK \
9# RUN: -lSystem \
10# RUN: 2>&1 | FileCheck %s
11
12
13# CHECK: Library search paths:
14# CHECK: /usr/lib
15# CHECK: /Applications/MyFirstSDK/usr/local/lib
16# CHECK: /Applications/MySecondSDK/usr/local/lib
17# CHECK: Found library /Applications/MyFirstSDK/usr/local/lib/libSystem.a
deps/lld/test/mach-o/libresolve-one-syslibroot.yaml created+25
......@@ -0,0 +1,25 @@
1# RUN: lld -flavor darwin -test_file_usage -v \
2# RUN: -path_exists /usr/lib \
3# RUN: -path_exists /Applications/MySDK/usr/local/lib \
4# RUN: -path_exists /Applications/MySDK/usr/local/lib/libSystem.a \
5# RUN: -path_exists /hasFoo \
6# RUN: -path_exists /hasFoo/foo.o \
7# RUN: -syslibroot /Applications/MySDK \
8# RUN: -L/hasFoo \
9# RUN: -lSystem -lfoo.o \
10# RUN: 2>&1 | FileCheck %s
11
12# When just one -syslibroot is specified, we apparently want to skip *system*
13# paths that aren't found. User ones should still get added. In this case
14# /usr/lib exists, but not the equivalent in the -syslibroot, so there should be
15# no mention of /usr/lib.
16
17# CHECK: Library search paths:
18# CHECK: /hasFoo
19# CHECK-NOT: /usr/lib
20# CHECK-NOT: /usr/local/lib
21# CHECK: /Applications/MySDK/usr/local/lib
22# CHECK-NOT: /usr/lib
23# CHECK-NOT: /usr/local/lib
24# CHECK: Found library /Applications/MySDK/usr/local/lib/libSystem.a
25# CHECK: Found library /hasFoo/foo.o
deps/lld/test/mach-o/libresolve-simple.yaml created+21
......@@ -0,0 +1,21 @@
1# RUN: lld -flavor darwin -arch x86_64 -r -test_file_usage -v \
2# RUN: -path_exists /usr/lib \
3# RUN: -path_exists /usr/local/lib \
4# RUN: -path_exists /usr/lib/libSystem.dylib \
5# RUN: -path_exists hasFoo \
6# RUN: -path_exists hasFoo/libFoo.dylib \
7# RUN: -path_exists /hasBar \
8# RUN: -path_exists /hasBar/libBar.dylib \
9# RUN: -L hasFoo \
10# RUN: -L /hasBar \
11# RUN: -lSystem -lFoo -lBar \
12# RUN: 2>&1 | FileCheck %s
13
14# CHECK: Library search paths:
15# CHECK: hasFoo
16# CHECK: /hasBar
17# CHECK: /usr/lib
18# CHECK: /usr/local/lib
19# CHECK: Found library /usr/lib/libSystem.dylib
20# CHECK: Found library hasFoo/libFoo.dylib
21# CHECK: Found library /hasBar/libBar.dylib
deps/lld/test/mach-o/libresolve-user-paths.yaml created+20
......@@ -0,0 +1,20 @@
1# RUN: lld -flavor darwin -arch x86_64 -r -test_file_usage -v \
2# RUN: -path_exists hasFoo \
3# RUN: -path_exists hasFoo/libFoo.dylib \
4# RUN: -path_exists /hasBar \
5# RUN: -path_exists /hasBar/libBar.dylib \
6# RUN: -path_exists /SDK/hasFoo \
7# RUN: -path_exists /SDK/hasFoo/libFoo.dylib \
8# RUN: -path_exists /SDK/hasBar \
9# RUN: -path_exists /SDK/hasBar/libBar.dylib \
10# RUN: -syslibroot /SDK \
11# RUN: -L hasFoo \
12# RUN: -L /hasBar \
13# RUN: -lFoo -lBar \
14# RUN: 2>&1 | FileCheck %s
15
16# CHECK: Library search paths:
17# CHECK: hasFoo
18# CHECK: /SDK/hasBar
19# CHECK: Found library hasFoo/libFoo.dylib
20# CHECK: Found library /SDK/hasBar/libBar.dylib
deps/lld/test/mach-o/libresolve-z.yaml created+21
......@@ -0,0 +1,21 @@
1# RUN: lld -flavor darwin -arch x86_64 -r -test_file_usage -v \
2# RUN: -path_exists /usr/lib \
3# RUN: -path_exists /usr/local/lib \
4# RUN: -path_exists /usr/lib/libSystem.dylib \
5# RUN: -path_exists hasFoo \
6# RUN: -path_exists hasFoo/libFoo.dylib \
7# RUN: -path_exists /hasBar \
8# RUN: -path_exists /hasBar/libBar.dylib \
9# RUN: -L hasFoo \
10# RUN: -L /hasBar \
11# RUN: -Z \
12# RUN: -lFoo -lBar \
13# RUN: 2>&1 | FileCheck %s
14
15# CHECK: Library search paths:
16# CHECK: hasFoo
17# CHECK: /hasBar
18# CHECK-NOT: /usr/lib
19# CHECK-NOT: /usr/local/lib
20# CHECK: Found library hasFoo/libFoo.dylib
21# CHECK: Found library /hasBar/libBar.dylib
deps/lld/test/mach-o/linker-as-ld.yaml created+32
......@@ -0,0 +1,32 @@
1# REQUIRES: system-linker-mach-o
2#
3# RUN: rm -rf %T/ld && ln -s `which lld` %T/ld \
4# RUN: && %T/ld -arch x86_64 -macosx_version_min 10.8 %s \
5# RUN: %p/Inputs/linker-as-ld.yaml -o %t \
6# RUN: && llvm-nm %t | FileCheck %s
7#
8# Test linker run as "ld" on darwin works as darwin linker.
9#
10
11--- !mach-o
12arch: x86_64
13file-type: MH_OBJECT
14flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
15has-UUID: false
16OS: unknown
17sections:
18 - segment: __TEXT
19 section: __text
20 type: S_REGULAR
21 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
22 address: 0x0000000000000000
23 content: [ 0xC3 ]
24global-symbols:
25 - name: _main
26 type: N_SECT
27 scope: [ N_EXT ]
28 sect: 1
29 value: 0x0000000000000000
30...
31
32# CHECK: T _main
deps/lld/test/mach-o/lit.local.cfg created+4
......@@ -0,0 +1,4 @@
1
2# mach-o test cases encode input files in yaml and use .yaml extension
3config.suffixes = ['.yaml']
4config.excludes = ['Inputs']
deps/lld/test/mach-o/mach_header-cpusubtype.yaml created+34
......@@ -0,0 +1,34 @@
1# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.4 %s %p/Inputs/hello-world-x86_64.yaml -o %t && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_LIB64
2# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.5 %s %p/Inputs/hello-world-x86_64.yaml -o %t && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=LIB64
3# RUN: lld -flavor darwin -arch x86_64 -dylib -macosx_version_min 10.5 %s %p/Inputs/hello-world-x86_64.yaml -o %t && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=DYLIB
4
5--- !mach-o
6arch: x86_64
7file-type: MH_OBJECT
8flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
9has-UUID: false
10OS: unknown
11sections:
12 - segment: __TEXT
13 section: __text
14 type: S_REGULAR
15 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
16 address: 0x0000000000000000
17 content: [ 0x00, 0x00 ]
18global-symbols:
19 - name: _main
20 type: N_SECT
21 scope: [ N_EXT ]
22 sect: 1
23 value: 0x0000000000000000
24 - name: start
25 type: N_SECT
26 scope: [ N_EXT ]
27 sect: 1
28 value: 0x0000000000000001
29
30...
31
32# NO_LIB64: MH_MAGIC_64 X86_64 ALL 0x00 EXECUTE
33# LIB64: MH_MAGIC_64 X86_64 ALL LIB64 EXECUTE
34# DYLIB: MH_MAGIC_64 X86_64 ALL 0x00 DYLIB
deps/lld/test/mach-o/mh_bundle_header.yaml created+54
......@@ -0,0 +1,54 @@
1# RUN: lld -flavor darwin -arch x86_64 %s -bundle -o %t %p/Inputs/x86_64/libSystem.yaml && llvm-nm -m -n %t | FileCheck %s
2# RUN: lld -flavor darwin -arch x86_64 %s -bundle -dead_strip -o %t %p/Inputs/x86_64/libSystem.yaml && llvm-nm -m -n %t | FileCheck %s
3#
4# Test that __mh_bundle_header symbol is available for bundles
5#
6
7--- !mach-o
8arch: x86_64
9file-type: MH_OBJECT
10flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
11sections:
12 - segment: __TEXT
13 section: __text
14 type: S_REGULAR
15 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
16 address: 0x0000000000000000
17 content: [ 0x55, 0x48, 0x89, 0xE5, 0x31, 0xC0, 0x5D, 0xC3 ]
18 - segment: __DATA
19 section: __data
20 type: S_REGULAR
21 attributes: [ ]
22 alignment: 8
23 address: 0x0000000000000008
24 content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
25 relocations:
26 - offset: 0x00000000
27 type: X86_64_RELOC_UNSIGNED
28 length: 3
29 pc-rel: false
30 extern: true
31 symbol: 2
32global-symbols:
33 - name: _d
34 type: N_SECT
35 scope: [ N_EXT ]
36 sect: 2
37 value: 0x0000000000000008
38 - name: _foo
39 type: N_SECT
40 scope: [ N_EXT ]
41 sect: 1
42 desc: [ N_NO_DEAD_STRIP ]
43 value: 0x0000000000000000
44undefined-symbols:
45 - name: __mh_bundle_header
46 type: N_UNDF
47 scope: [ N_EXT ]
48 value: 0x0000000000000000
49
50
51...
52
53# CHECK: __mh_bundle_header
54# CHECK: _foo
deps/lld/test/mach-o/mh_dylib_header.yaml created+53
......@@ -0,0 +1,53 @@
1# RUN: lld -flavor darwin -arch x86_64 %s -dylib -o %t %p/Inputs/x86_64/libSystem.yaml
2# RUN: llvm-nm -m -n %t | FileCheck %s
3#
4# Test that __mh_dylib_header symbol is available for dylibs
5#
6
7--- !mach-o
8arch: x86_64
9file-type: MH_OBJECT
10flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
11sections:
12 - segment: __TEXT
13 section: __text
14 type: S_REGULAR
15 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
16 address: 0x0000000000000000
17 content: [ 0x55, 0x48, 0x89, 0xE5, 0x31, 0xC0, 0x5D, 0xC3 ]
18 - segment: __DATA
19 section: __data
20 type: S_REGULAR
21 attributes: [ ]
22 alignment: 8
23 address: 0x0000000000000008
24 content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
25 relocations:
26 - offset: 0x00000000
27 type: X86_64_RELOC_UNSIGNED
28 length: 3
29 pc-rel: false
30 extern: true
31 symbol: 2
32global-symbols:
33 - name: _d
34 type: N_SECT
35 scope: [ N_EXT ]
36 sect: 2
37 value: 0x0000000000000008
38 - name: _foo
39 type: N_SECT
40 scope: [ N_EXT ]
41 sect: 1
42 value: 0x0000000000000000
43undefined-symbols:
44 - name: __mh_dylib_header
45 type: N_UNDF
46 scope: [ N_EXT ]
47 value: 0x0000000000000000
48
49
50...
51
52# CHECK_NOT: __mh_dylib_header
53# CHECK: _foo
deps/lld/test/mach-o/objc-category-list-atom.yaml created+70
......@@ -0,0 +1,70 @@
1# RUN: lld -flavor darwin -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s
2# RUN: lld -flavor darwin -arch x86_64 -r -print_atoms %t -o %t2 | FileCheck %s
3
4
5--- !mach-o
6arch: x86_64
7file-type: MH_OBJECT
8flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
9compat-version: 0.0
10current-version: 0.0
11has-UUID: false
12OS: unknown
13sections:
14 - segment: __DATA
15 section: __objc_catlist
16 type: S_REGULAR
17 attributes: [ S_ATTR_NO_DEAD_STRIP ]
18 alignment: 8
19 address: 0x00000000000003F8
20 content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
21 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
22 relocations:
23 - offset: 0x00000008
24 type: X86_64_RELOC_UNSIGNED
25 length: 3
26 pc-rel: false
27 extern: true
28 symbol: 0
29 - offset: 0x00000000
30 type: X86_64_RELOC_UNSIGNED
31 length: 3
32 pc-rel: false
33 extern: true
34 symbol: 1
35undefined-symbols:
36 - name: __category1
37 type: N_UNDF
38 scope: [ N_EXT ]
39 value: 0x0000000000000000
40 - name: __category2
41 type: N_UNDF
42 scope: [ N_EXT ]
43 value: 0x0000000000000000
44page-size: 0x00000000
45...
46
47# Make sure we atomize the category list section by pointer sized atoms.
48
49# CHECK: path: '<linker-internal>'
50# CHECK: defined-atoms:
51# CHECK: - type: objc-category-list
52# CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ]
53# CHECK: merge: by-content
54# CHECK: alignment: 8
55# CHECK: references:
56# CHECK: - kind: pointer64
57# CHECK: offset: 0
58# CHECK: target: __category2
59# CHECK: - type: objc-category-list
60# CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ]
61# CHECK: merge: by-content
62# CHECK: alignment: 8
63# CHECK: references:
64# CHECK: - kind: pointer64
65# CHECK: offset: 0
66# CHECK: target: __category1
67# CHECK: undefined-atoms:
68# CHECK: - name: __category1
69# CHECK: - name: __category2
70# CHECK: ...
deps/lld/test/mach-o/objc-image-info-host-vs-simulator.yaml created+23
......@@ -0,0 +1,23 @@
1# RUN: not lld -flavor darwin -arch x86_64 -r %s 2>&1 | FileCheck %s
2
3# The file is built for the host, but the objc image info flags are for
4# the simulator.
5
6--- !mach-o
7arch: x86_64
8file-type: MH_OBJECT
9flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
10compat-version: 0.0
11current-version: 0.0
12has-UUID: false
13OS: unknown
14sections:
15 - segment: __DATA
16 section: __objc_imageinfo
17 type: S_REGULAR
18 attributes: [ S_ATTR_NO_DEAD_STRIP ]
19 address: 0x0000000000000100
20 content: [ 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00 ]
21...
22
23# CHECK: {{.*}} cannot be linked. It contains ObjC built for the simulator while we are linking a non-simulator target
\ No newline at end of file
deps/lld/test/mach-o/objc-image-info-invalid-size.yaml created+20
......@@ -0,0 +1,20 @@
1# RUN: not lld -flavor darwin -arch x86_64 -r %s 2>&1 | FileCheck %s
2
3--- !mach-o
4arch: x86_64
5file-type: MH_OBJECT
6flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
7compat-version: 0.0
8current-version: 0.0
9has-UUID: false
10OS: unknown
11sections:
12 - segment: __DATA
13 section: __objc_imageinfo
14 type: S_REGULAR
15 attributes: [ S_ATTR_NO_DEAD_STRIP ]
16 address: 0x0000000000000100
17 content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
18...
19
20# CHECK: error: __DATA/__objc_imageinfo in file {{.*}} should be 8 bytes in size
\ No newline at end of file
deps/lld/test/mach-o/objc-image-info-invalid-version.yaml created+20
......@@ -0,0 +1,20 @@
1# RUN: not lld -flavor darwin -arch x86_64 -r %s 2>&1 | FileCheck %s
2
3--- !mach-o
4arch: x86_64
5file-type: MH_OBJECT
6flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
7compat-version: 0.0
8current-version: 0.0
9has-UUID: false
10OS: unknown
11sections:
12 - segment: __DATA
13 section: __objc_imageinfo
14 type: S_REGULAR
15 attributes: [ S_ATTR_NO_DEAD_STRIP ]
16 address: 0x0000000000000100
17 content: [ 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 ]
18...
19
20# CHECK: error: __DATA/__objc_imageinfo in file {{.*}} should have version=0
\ No newline at end of file
deps/lld/test/mach-o/objc-image-info-mismatched-swift-version.yaml created+20
......@@ -0,0 +1,20 @@
1# RUN: not lld -flavor darwin -arch x86_64 -r %s %p/Inputs/swift-version-1.yaml 2>&1 | FileCheck %s
2
3--- !mach-o
4arch: x86_64
5file-type: MH_OBJECT
6flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
7compat-version: 0.0
8current-version: 0.0
9has-UUID: false
10OS: unknown
11sections:
12 - segment: __DATA
13 section: __objc_imageinfo
14 type: S_REGULAR
15 attributes: [ S_ATTR_NO_DEAD_STRIP ]
16 address: 0x0000000000000100
17 content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00 ]
18...
19
20# CHECK: different swift versions
\ No newline at end of file
deps/lld/test/mach-o/objc-image-info-pass-output.yaml created+30
......@@ -0,0 +1,30 @@
1# RUN: lld -flavor darwin -ios_simulator_version_min 5.0 -arch x86_64 -r %s -o %t -print_atoms | FileCheck %s
2
3# Make sure that we have an objc image info in the output. It should have
4# been generated by the objc pass.
5
6--- !mach-o
7arch: x86_64
8file-type: MH_OBJECT
9flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
10compat-version: 0.0
11current-version: 0.0
12has-UUID: false
13OS: unknown
14sections:
15 - segment: __DATA
16 section: __objc_imageinfo
17 type: S_REGULAR
18 attributes: [ S_ATTR_NO_DEAD_STRIP ]
19 address: 0x0000000000000100
20 content: [ 0x00, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00 ]
21...
22
23# CHECK: --- !native
24# CHECK: path: '<linker-internal>'
25# CHECK: defined-atoms:
26# CHECK: - scope: hidden
27# CHECK: type: objc-image-info
28# CHECK: content: [ 00, 00, 00, 00, 20, 02, 00, 00 ]
29# CHECK: alignment: 4
30# CHECK: ...
\ No newline at end of file
deps/lld/test/mach-o/objc-image-info-simulator-vs-host.yaml created+23
......@@ -0,0 +1,23 @@
1# RUN: not lld -flavor darwin -ios_simulator_version_min 5.0 -arch x86_64 -r %s 2>&1 | FileCheck %s
2
3# The file is built for the simulator, but the objc image info flags are for
4# the host.
5
6--- !mach-o
7arch: x86_64
8file-type: MH_OBJECT
9flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
10compat-version: 0.0
11current-version: 0.0
12has-UUID: false
13OS: unknown
14sections:
15 - segment: __DATA
16 section: __objc_imageinfo
17 type: S_REGULAR
18 attributes: [ S_ATTR_NO_DEAD_STRIP ]
19 address: 0x0000000000000100
20 content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
21...
22
23# CHECK: {{.*}} cannot be linked. It contains ObjC built for a non-simulator target while we are linking a simulator target
\ No newline at end of file
deps/lld/test/mach-o/objc-image-info-unsupported-gc.yaml created+20
......@@ -0,0 +1,20 @@
1# RUN: not lld -flavor darwin -arch x86_64 -r %s 2>&1 | FileCheck %s
2
3--- !mach-o
4arch: x86_64
5file-type: MH_OBJECT
6flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
7compat-version: 0.0
8current-version: 0.0
9has-UUID: false
10OS: unknown
11sections:
12 - segment: __DATA
13 section: __objc_imageinfo
14 type: S_REGULAR
15 attributes: [ S_ATTR_NO_DEAD_STRIP ]
16 address: 0x0000000000000100
17 content: [ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00 ]
18...
19
20# CHECK: error: __DATA/__objc_imageinfo in file {{.*}} uses GC. This is not supported
\ No newline at end of file
deps/lld/test/mach-o/objc_export_list.yaml created+63
......@@ -0,0 +1,63 @@
1# RUN: lld -flavor darwin -arch x86_64 -dylib %s -o %t \
2# RUN: -exported_symbol .objc_class_name_Foo %p/Inputs/x86_64/libSystem.yaml
3# RUN: llvm-nm -m %t | FileCheck %s
4#
5# Test that exported objc classes can be specificed using old naming
6# (.e.g .objc_class_name_Foo instead of _OBJC_CLASS_$_Foo)
7#
8
9--- !mach-o
10arch: x86_64
11file-type: MH_OBJECT
12flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
13sections:
14 - segment: __DATA
15 section: __objc_data
16 type: S_REGULAR
17 attributes: [ ]
18 alignment: 8
19 address: 0x0000000000000000
20 content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
21 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
22 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
23 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
24 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
25 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
26 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
27 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
28 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
29 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
30 relocations:
31 - offset: 0x00000030
32 type: X86_64_RELOC_UNSIGNED
33 length: 3
34 pc-rel: false
35 extern: true
36 symbol: 0
37 - offset: 0x00000028
38 type: X86_64_RELOC_UNSIGNED
39 length: 3
40 pc-rel: false
41 extern: true
42 symbol: 1
43 - offset: 0x00000000
44 type: X86_64_RELOC_UNSIGNED
45 length: 3
46 pc-rel: false
47 extern: true
48 symbol: 1
49global-symbols:
50 - name: '_OBJC_CLASS_$_Foo'
51 type: N_SECT
52 scope: [ N_EXT ]
53 sect: 1
54 value: 0x0000000000000000
55 - name: '_OBJC_METACLASS_$_Foo'
56 type: N_SECT
57 scope: [ N_EXT ]
58 sect: 1
59 value: 0x0000000000000028
60...
61
62# CHECK: (__DATA,__objc_data) external _OBJC_CLASS_$_Foo
63# CHECK: (__DATA,__objc_data) external _OBJC_METACLASS_$_Foo
deps/lld/test/mach-o/order_file-basic.yaml created+75
......@@ -0,0 +1,75 @@
1# RUN: lld -flavor darwin -arch x86_64 %s %p/Inputs/x86_64/libSystem.yaml \
2# RUN: -order_file %p/Inputs/order_file-basic.order \
3# RUN: -force_load %p/Inputs/libfoo.a -o %t
4# RUN: llvm-nm -m -n %t | FileCheck %s
5#
6# Test -order_file
7#
8
9--- !mach-o
10arch: x86_64
11file-type: MH_OBJECT
12flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
13sections:
14 - segment: __TEXT
15 section: __text
16 type: S_REGULAR
17 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
18 address: 0x0000000000000000
19 content: [ 0xC3, 0xC3, 0xC3, 0xC3 ]
20 - segment: __DATA
21 section: __data
22 type: S_REGULAR
23 attributes: [ ]
24 alignment: 2
25 address: 0x0000000000000014
26 content: [ 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
27 0x07, 0x00, 0x00, 0x00 ]
28global-symbols:
29 - name: _data1
30 type: N_SECT
31 scope: [ N_EXT ]
32 sect: 2
33 value: 0x0000000000000014
34 - name: _data2
35 type: N_SECT
36 scope: [ N_EXT ]
37 sect: 2
38 value: 0x0000000000000018
39 - name: _data3
40 type: N_SECT
41 scope: [ N_EXT ]
42 sect: 2
43 value: 0x000000000000001C
44 - name: _func1
45 type: N_SECT
46 scope: [ N_EXT ]
47 sect: 1
48 value: 0x0000000000000000
49 - name: _func2
50 type: N_SECT
51 scope: [ N_EXT ]
52 sect: 1
53 value: 0x0000000000000001
54 - name: _func3
55 type: N_SECT
56 scope: [ N_EXT ]
57 sect: 1
58 value: 0x0000000000000002
59 - name: _main
60 type: N_SECT
61 scope: [ N_EXT ]
62 sect: 1
63 value: 0x0000000000000003
64...
65
66
67# CHECK: {{[0-9a-f]+}} (__TEXT,__text) external _func2
68# CHECK: {{[0-9a-f]+}} (__TEXT,__text) external _foo
69# CHECK: {{[0-9a-f]+}} (__TEXT,__text) external _func1
70# CHECK: {{[0-9a-f]+}} (__TEXT,__text) external _func3
71# CHECK: {{[0-9a-f]+}} (__TEXT,__text) external _main
72# CHECK: {{[0-9a-f]+}} (__DATA,__data) external _data3
73# CHECK: {{[0-9a-f]+}} (__DATA,__data) external _data1
74# CHECK: {{[0-9a-f]+}} (__DATA,__data) external _data2
75
deps/lld/test/mach-o/parse-aliases.yaml created+90
......@@ -0,0 +1,90 @@
1# RUN: lld -flavor darwin -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s
2#
3# Test multiple labels to same address parse into aliases.
4#
5
6--- !mach-o
7arch: x86_64
8file-type: MH_OBJECT
9flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
10has-UUID: false
11OS: unknown
12sections:
13 - segment: __TEXT
14 section: __text
15 type: S_REGULAR
16 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
17 alignment: 4
18 address: 0x0000000000000000
19 content: [ 0xCC, 0xC3 ]
20local-symbols:
21 - name: _pad
22 type: N_SECT
23 scope: [ N_EXT ]
24 sect: 1
25 value: 0x0000000000000000
26 - name: _myStaticAlias1
27 type: N_SECT
28 sect: 1
29 value: 0x0000000000000001
30 - name: _myStaticAlias3
31 type: N_SECT
32 sect: 1
33 value: 0x0000000000000001
34 - name: _myStaticAlias2
35 type: N_SECT
36 sect: 1
37 value: 0x0000000000000001
38global-symbols:
39 - name: _myGlobalFunc1
40 type: N_SECT
41 scope: [ N_EXT ]
42 sect: 1
43 value: 0x0000000000000001
44 - name: _myGlobalFunc2
45 type: N_SECT
46 scope: [ N_EXT ]
47 sect: 1
48 value: 0x0000000000000001
49 - name: _myGlobalFunc3
50 type: N_SECT
51 scope: [ N_EXT ]
52 sect: 1
53 value: 0x0000000000000001
54 - name: _myHiddenAlias1
55 type: N_SECT
56 scope: [ N_EXT, N_PEXT ]
57 sect: 1
58 value: 0x0000000000000001
59 - name: _myHiddenAlias2
60 type: N_SECT
61 scope: [ N_EXT, N_PEXT ]
62 sect: 1
63 value: 0x0000000000000001
64 - name: _myHiddenAlias3
65 type: N_SECT
66 scope: [ N_EXT, N_PEXT ]
67 sect: 1
68 value: 0x0000000000000001
69...
70
71# CHECK: defined-atoms:
72# CHECK: - name: _pad
73# CHECK: scope: global
74# CHECK: content: [ CC ]
75# CHECK: - name: _myStaticAlias1
76# CHECK: - name: _myStaticAlias2
77# CHECK: - name: _myStaticAlias3
78# CHECK: - name: _myHiddenAlias1
79# CHECK: scope: hidden
80# CHECK: - name: _myHiddenAlias2
81# CHECK: scope: hidden
82# CHECK: - name: _myHiddenAlias3
83# CHECK: scope: hidden
84# CHECK: - name: _myGlobalFunc1
85# CHECK: scope: global
86# CHECK: - name: _myGlobalFunc2
87# CHECK: scope: global
88# CHECK: - name: _myGlobalFunc3
89# CHECK: scope: global
90# CHECK: content: [ C3 ]
deps/lld/test/mach-o/parse-arm-relocs.yaml created+818
......@@ -0,0 +1,818 @@
1# RUN: lld -flavor darwin -arch armv7 -r -print_atoms %s -o %t | FileCheck %s
2# RUN: lld -flavor darwin -arch armv7 -r -print_atoms %t -o %t2 | FileCheck %s
3#
4# Test parsing of armv7 relocations.
5#
6#
7
8--- !mach-o
9arch: armv7
10file-type: MH_OBJECT
11flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
12sections:
13 - segment: __TEXT
14 section: __text
15 type: S_REGULAR
16 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
17 alignment: 2
18 address: 0x0000000000000000
19 content: [ 0x00, 0xF0, 0x4E, 0xF8, 0x00, 0xF0, 0x4E, 0xF8,
20 0xFF, 0xF7, 0xFA, 0xFF, 0xFF, 0xF7, 0xFA, 0xFF,
21 0xFF, 0xF7, 0xF6, 0xBF, 0x40, 0xF2, 0x72, 0x01,
22 0xC0, 0xF2, 0x00, 0x01, 0x40, 0xF2, 0x7A, 0x02,
23 0xC0, 0xF2, 0x00, 0x02, 0x40, 0xF2, 0x29, 0x01,
24 0xC0, 0xF2, 0x00, 0x01, 0x79, 0x44, 0x40, 0xF2,
25 0xA0, 0x03, 0xC0, 0xF2, 0x00, 0x03, 0x40, 0xF2,
26 0xA8, 0x04, 0xC0, 0xF2, 0x00, 0x04, 0x40, 0xF2,
27 0x57, 0x03, 0xC0, 0xF2, 0x00, 0x03, 0x40, 0xF2,
28 0x00, 0x05, 0xC0, 0xF2, 0x00, 0x05, 0x40, 0xF2,
29 0x08, 0x06, 0xC0, 0xF2, 0x00, 0x06, 0xC0, 0x46,
30 0x10, 0x00, 0x00, 0xEB, 0x10, 0x00, 0x00, 0xEB,
31 0xE6, 0xFF, 0xFF, 0xEB, 0xE6, 0xFF, 0xFF, 0xEB,
32 0xE4, 0xFF, 0xFF, 0xEA, 0x20, 0x10, 0x00, 0xE3,
33 0x00, 0x10, 0x40, 0xE3, 0x28, 0x20, 0x00, 0xE3,
34 0x00, 0x20, 0x40, 0xE3, 0x0F, 0x10, 0x81, 0xE0,
35 0xA0, 0x30, 0x00, 0xE3, 0x00, 0x30, 0x40, 0xE3,
36 0xA8, 0x40, 0x00, 0xE3, 0x00, 0x40, 0x40, 0xE3,
37 0x00, 0x50, 0x00, 0xE3, 0x00, 0x50, 0x40, 0xE3,
38 0x08, 0x60, 0x00, 0xE3, 0x00, 0x60, 0x40, 0xE3 ]
39 relocations:
40 - offset: 0x0000009C
41 type: ARM_RELOC_HALF
42 length: 1
43 pc-rel: false
44 extern: true
45 symbol: 4
46 - offset: 0x00000008
47 type: ARM_RELOC_PAIR
48 length: 1
49 pc-rel: false
50 extern: false
51 symbol: 16777215
52 - offset: 0x00000098
53 type: ARM_RELOC_HALF
54 length: 0
55 pc-rel: false
56 extern: true
57 symbol: 4
58 - offset: 0x00000000
59 type: ARM_RELOC_PAIR
60 length: 0
61 pc-rel: false
62 extern: false
63 symbol: 16777215
64 - offset: 0x00000094
65 type: ARM_RELOC_HALF
66 length: 1
67 pc-rel: false
68 extern: true
69 symbol: 4
70 - offset: 0x00000000
71 type: ARM_RELOC_PAIR
72 length: 1
73 pc-rel: false
74 extern: false
75 symbol: 16777215
76 - offset: 0x00000090
77 type: ARM_RELOC_HALF
78 length: 0
79 pc-rel: false
80 extern: true
81 symbol: 4
82 - offset: 0x00000000
83 type: ARM_RELOC_PAIR
84 length: 0
85 pc-rel: false
86 extern: false
87 symbol: 16777215
88 - offset: 0x0000008C
89 scattered: true
90 type: ARM_RELOC_HALF
91 length: 1
92 pc-rel: false
93 value: 0x000000A0
94 - offset: 0x000000A8
95 type: ARM_RELOC_PAIR
96 length: 1
97 pc-rel: false
98 extern: false
99 symbol: 16777215
100 - offset: 0x00000088
101 scattered: true
102 type: ARM_RELOC_HALF
103 length: 0
104 pc-rel: false
105 value: 0x000000A0
106 - offset: 0x00000000
107 type: ARM_RELOC_PAIR
108 length: 0
109 pc-rel: false
110 extern: false
111 symbol: 16777215
112 - offset: 0x00000084
113 type: ARM_RELOC_HALF
114 length: 1
115 pc-rel: false
116 extern: false
117 symbol: 2
118 - offset: 0x000000A0
119 type: ARM_RELOC_PAIR
120 length: 1
121 pc-rel: false
122 extern: false
123 symbol: 16777215
124 - offset: 0x00000080
125 type: ARM_RELOC_HALF
126 length: 0
127 pc-rel: false
128 extern: false
129 symbol: 2
130 - offset: 0x00000000
131 type: ARM_RELOC_PAIR
132 length: 0
133 pc-rel: false
134 extern: false
135 symbol: 16777215
136 - offset: 0x00000078
137 scattered: true
138 type: ARM_RELOC_HALF_SECTDIFF
139 length: 1
140 pc-rel: false
141 value: 0x000000A0
142 - offset: 0x00000028
143 scattered: true
144 type: ARM_RELOC_PAIR
145 length: 1
146 pc-rel: false
147 value: 0x00000080
148 - offset: 0x00000074
149 scattered: true
150 type: ARM_RELOC_HALF_SECTDIFF
151 length: 0
152 pc-rel: false
153 value: 0x000000A0
154 - offset: 0x00000000
155 scattered: true
156 type: ARM_RELOC_PAIR
157 length: 0
158 pc-rel: false
159 value: 0x00000080
160 - offset: 0x00000070
161 scattered: true
162 type: ARM_RELOC_HALF_SECTDIFF
163 length: 1
164 pc-rel: false
165 value: 0x000000A0
166 - offset: 0x00000020
167 scattered: true
168 type: ARM_RELOC_PAIR
169 length: 1
170 pc-rel: false
171 value: 0x00000080
172 - offset: 0x0000006C
173 scattered: true
174 type: ARM_RELOC_HALF_SECTDIFF
175 length: 0
176 pc-rel: false
177 value: 0x000000A0
178 - offset: 0x00000000
179 scattered: true
180 type: ARM_RELOC_PAIR
181 length: 0
182 pc-rel: false
183 value: 0x00000080
184 - offset: 0x00000068
185 type: ARM_RELOC_BR24
186 length: 2
187 pc-rel: true
188 extern: true
189 symbol: 4
190 - offset: 0x00000064
191 type: ARM_RELOC_BR24
192 length: 2
193 pc-rel: true
194 extern: true
195 symbol: 4
196 - offset: 0x00000060
197 type: ARM_RELOC_BR24
198 length: 2
199 pc-rel: true
200 extern: true
201 symbol: 4
202 - offset: 0x0000005C
203 scattered: true
204 type: ARM_RELOC_BR24
205 length: 2
206 pc-rel: true
207 value: 0x000000A0
208 - offset: 0x00000058
209 type: ARM_RELOC_BR24
210 length: 2
211 pc-rel: true
212 extern: false
213 symbol: 2
214 - offset: 0x00000052
215 type: ARM_RELOC_HALF
216 length: 3
217 pc-rel: false
218 extern: true
219 symbol: 4
220 - offset: 0x00000008
221 type: ARM_RELOC_PAIR
222 length: 3
223 pc-rel: false
224 extern: false
225 symbol: 16777215
226 - offset: 0x0000004E
227 type: ARM_RELOC_HALF
228 length: 2
229 pc-rel: false
230 extern: true
231 symbol: 4
232 - offset: 0x00000000
233 type: ARM_RELOC_PAIR
234 length: 2
235 pc-rel: false
236 extern: false
237 symbol: 16777215
238 - offset: 0x0000004A
239 type: ARM_RELOC_HALF
240 length: 3
241 pc-rel: false
242 extern: true
243 symbol: 4
244 - offset: 0x00000000
245 type: ARM_RELOC_PAIR
246 length: 3
247 pc-rel: false
248 extern: false
249 symbol: 16777215
250 - offset: 0x00000046
251 type: ARM_RELOC_HALF
252 length: 2
253 pc-rel: false
254 extern: true
255 symbol: 4
256 - offset: 0x00000000
257 type: ARM_RELOC_PAIR
258 length: 2
259 pc-rel: false
260 extern: false
261 symbol: 16777215
262 - offset: 0x00000042
263 type: ARM_RELOC_HALF
264 length: 3
265 pc-rel: false
266 extern: false
267 symbol: 1
268 - offset: 0x00000057
269 type: ARM_RELOC_PAIR
270 length: 3
271 pc-rel: false
272 extern: false
273 symbol: 16777215
274 - offset: 0x0000003E
275 type: ARM_RELOC_HALF
276 length: 2
277 pc-rel: false
278 extern: false
279 symbol: 1
280 - offset: 0x00000000
281 type: ARM_RELOC_PAIR
282 length: 2
283 pc-rel: false
284 extern: false
285 symbol: 16777215
286 - offset: 0x0000003A
287 scattered: true
288 type: ARM_RELOC_HALF
289 length: 3
290 pc-rel: false
291 value: 0x000000A0
292 - offset: 0x000000A8
293 type: ARM_RELOC_PAIR
294 length: 3
295 pc-rel: false
296 extern: false
297 symbol: 16777215
298 - offset: 0x00000036
299 scattered: true
300 type: ARM_RELOC_HALF
301 length: 2
302 pc-rel: false
303 value: 0x000000A0
304 - offset: 0x00000000
305 type: ARM_RELOC_PAIR
306 length: 2
307 pc-rel: false
308 extern: false
309 symbol: 16777215
310 - offset: 0x00000032
311 type: ARM_RELOC_HALF
312 length: 3
313 pc-rel: false
314 extern: false
315 symbol: 2
316 - offset: 0x000000A0
317 type: ARM_RELOC_PAIR
318 length: 3
319 pc-rel: false
320 extern: false
321 symbol: 16777215
322 - offset: 0x0000002E
323 type: ARM_RELOC_HALF
324 length: 2
325 pc-rel: false
326 extern: false
327 symbol: 2
328 - offset: 0x00000000
329 type: ARM_RELOC_PAIR
330 length: 2
331 pc-rel: false
332 extern: false
333 symbol: 16777215
334 - offset: 0x00000028
335 scattered: true
336 type: ARM_RELOC_HALF_SECTDIFF
337 length: 3
338 pc-rel: false
339 value: 0x00000056
340 - offset: 0x00000028
341 scattered: true
342 type: ARM_RELOC_PAIR
343 length: 3
344 pc-rel: false
345 value: 0x0000002E
346 - offset: 0x00000024
347 scattered: true
348 type: ARM_RELOC_HALF_SECTDIFF
349 length: 2
350 pc-rel: false
351 value: 0x00000056
352 - offset: 0x00000000
353 scattered: true
354 type: ARM_RELOC_PAIR
355 length: 2
356 pc-rel: false
357 value: 0x0000002E
358 - offset: 0x00000020
359 scattered: true
360 type: ARM_RELOC_HALF_SECTDIFF
361 length: 3
362 pc-rel: false
363 value: 0x000000A0
364 - offset: 0x0000007A
365 scattered: true
366 type: ARM_RELOC_PAIR
367 length: 3
368 pc-rel: false
369 value: 0x0000002E
370 - offset: 0x0000001C
371 scattered: true
372 type: ARM_RELOC_HALF_SECTDIFF
373 length: 2
374 pc-rel: false
375 value: 0x000000A0
376 - offset: 0x00000000
377 scattered: true
378 type: ARM_RELOC_PAIR
379 length: 2
380 pc-rel: false
381 value: 0x0000002E
382 - offset: 0x00000018
383 scattered: true
384 type: ARM_RELOC_HALF_SECTDIFF
385 length: 3
386 pc-rel: false
387 value: 0x000000A0
388 - offset: 0x00000072
389 scattered: true
390 type: ARM_RELOC_PAIR
391 length: 3
392 pc-rel: false
393 value: 0x0000002E
394 - offset: 0x00000014
395 scattered: true
396 type: ARM_RELOC_HALF_SECTDIFF
397 length: 2
398 pc-rel: false
399 value: 0x000000A0
400 - offset: 0x00000000
401 scattered: true
402 type: ARM_RELOC_PAIR
403 length: 2
404 pc-rel: false
405 value: 0x0000002E
406 - offset: 0x00000010
407 type: ARM_THUMB_RELOC_BR22
408 length: 2
409 pc-rel: true
410 extern: true
411 symbol: 4
412 - offset: 0x0000000C
413 type: ARM_THUMB_RELOC_BR22
414 length: 2
415 pc-rel: true
416 extern: true
417 symbol: 4
418 - offset: 0x00000008
419 type: ARM_THUMB_RELOC_BR22
420 length: 2
421 pc-rel: true
422 extern: true
423 symbol: 4
424 - offset: 0x00000004
425 scattered: true
426 type: ARM_THUMB_RELOC_BR22
427 length: 2
428 pc-rel: true
429 value: 0x000000A0
430 - offset: 0x00000000
431 type: ARM_THUMB_RELOC_BR22
432 length: 2
433 pc-rel: true
434 extern: false
435 symbol: 2
436 - segment: __DATA
437 section: __data
438 type: S_REGULAR
439 attributes: [ ]
440 address: 0x00000000000000A0
441 content: [ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
442 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
443 0x04, 0x00, 0x00, 0x00, 0xA4, 0xFF, 0xFF, 0xFF,
444 0xA4, 0xFF, 0xFF, 0xFF, 0x45, 0xFF, 0xFF, 0xFF,
445 0x45, 0xFF, 0xFF, 0xFF ]
446 relocations:
447 - offset: 0x00000020
448 scattered: true
449 type: ARM_RELOC_SECTDIFF
450 length: 2
451 pc-rel: false
452 value: 0x00000000
453 - offset: 0x00000000
454 scattered: true
455 type: ARM_RELOC_PAIR
456 length: 2
457 pc-rel: false
458 value: 0x000000C0
459 - offset: 0x0000001C
460 scattered: true
461 type: ARM_RELOC_SECTDIFF
462 length: 2
463 pc-rel: false
464 value: 0x00000000
465 - offset: 0x00000000
466 scattered: true
467 type: ARM_RELOC_PAIR
468 length: 2
469 pc-rel: false
470 value: 0x000000BC
471 - offset: 0x00000018
472 scattered: true
473 type: ARM_RELOC_SECTDIFF
474 length: 2
475 pc-rel: false
476 value: 0x00000058
477 - offset: 0x00000000
478 scattered: true
479 type: ARM_RELOC_PAIR
480 length: 2
481 pc-rel: false
482 value: 0x000000B8
483 - offset: 0x00000014
484 scattered: true
485 type: ARM_RELOC_SECTDIFF
486 length: 2
487 pc-rel: false
488 value: 0x00000058
489 - offset: 0x00000000
490 scattered: true
491 type: ARM_RELOC_PAIR
492 length: 2
493 pc-rel: false
494 value: 0x000000B4
495 - offset: 0x00000010
496 type: ARM_RELOC_VANILLA
497 length: 2
498 pc-rel: false
499 extern: true
500 symbol: 4
501 - offset: 0x0000000C
502 type: ARM_RELOC_VANILLA
503 length: 2
504 pc-rel: false
505 extern: true
506 symbol: 4
507 - offset: 0x00000008
508 scattered: true
509 type: ARM_RELOC_VANILLA
510 length: 2
511 pc-rel: false
512 value: 0x00000000
513 - offset: 0x00000004
514 type: ARM_RELOC_VANILLA
515 length: 2
516 pc-rel: false
517 extern: false
518 symbol: 1
519local-symbols:
520 - name: _foo_thumb
521 type: N_SECT
522 sect: 1
523 desc: [ N_ARM_THUMB_DEF ]
524 value: 0x0000000000000000
525 - name: _x
526 type: N_SECT
527 sect: 2
528 value: 0x00000000000000A0
529 - name: _t1
530 type: N_SECT
531 sect: 1
532 desc: [ N_ARM_THUMB_DEF ]
533 value: 0x0000000000000056
534 - name: _foo_arm
535 type: N_SECT
536 sect: 1
537 value: 0x0000000000000058
538undefined-symbols:
539 - name: _undef
540 type: N_UNDF
541 scope: [ N_EXT ]
542 value: 0x0000000000000000
543...
544
545# CHECK: defined-atoms:
546# CHECK: - name: _x
547# CHECK: type: data
548# CHECK: references:
549# CHECK: - kind: pointer32
550# CHECK: offset: 4
551# CHECK: target: _foo_thumb
552# CHECK-NOT: addend:
553# CHECK: - kind: pointer32
554# CHECK: offset: 8
555# CHECK: target: _foo_thumb
556# CHECK: addend: 4
557# CHECK: - kind: pointer32
558# CHECK: offset: 12
559# CHECK: target: _undef
560# CHECK-NOT: addend:
561# CHECK: - kind: pointer32
562# CHECK: offset: 16
563# CHECK: target: _undef
564# CHECK: addend: 4
565# CHECK: - kind: delta32
566# CHECK: offset: 20
567# CHECK: target: _foo_arm
568# CHECK-NOT: addend:
569# CHECK: - kind: delta32
570# CHECK: offset: 24
571# CHECK: target: _foo_arm
572# CHECK: addend: 4
573# CHECK: - kind: delta32
574# CHECK: offset: 28
575# CHECK: target: _foo_thumb
576# CHECK-NOT: addend:
577# CHECK: - kind: delta32
578# CHECK: offset: 32
579# CHECK: target: _foo_thumb
580# CHECK: addend: 4
581# CHECK: - name: _foo_thumb
582# CHECK: references:
583# CHECK: - kind: modeThumbCode
584# CHECK: offset: 0
585# CHECK: - kind: thumb_bl22
586# CHECK: offset: 0
587# CHECK: target: _x
588# CHECK-NOT: addend:
589# CHECK: - kind: thumb_bl22
590# CHECK: offset: 4
591# CHECK: target: _x
592# CHECK: addend: 4
593# CHECK: - kind: thumb_bl22
594# CHECK: offset: 8
595# CHECK: target: _undef
596# CHECK-NOT: addend:
597# CHECK: - kind: thumb_bl22
598# CHECK: offset: 12
599# CHECK: target: _undef
600# CHECK: addend: 4
601# CHECK: - kind: thumb_b22
602# CHECK: offset: 16
603# CHECK: target: _undef
604# CHECK-NOT: addend:
605# CHECK: - kind: thumb_movw_funcRel
606# CHECK: offset: 20
607# CHECK: target: _x
608# CHECK: addend: -46
609# CHECK: - kind: thumb_movt_funcRel
610# CHECK: offset: 24
611# CHECK: target: _x
612# CHECK: addend: -46
613# CHECK: - kind: thumb_movw_funcRel
614# CHECK: offset: 28
615# CHECK: target: _x
616# CHECK: addend: -38
617# CHECK: - kind: thumb_movt_funcRel
618# CHECK: offset: 32
619# CHECK: target: _x
620# CHECK: addend: -38
621# CHECK: - kind: thumb_movw_funcRel
622# CHECK: offset: 36
623# CHECK: target: _t1
624# CHECK: addend: -46
625# CHECK: - kind: thumb_movt_funcRel
626# CHECK: offset: 40
627# CHECK: target: _t1
628# CHECK: addend: -46
629# CHECK: - kind: thumb_movw
630# CHECK: offset: 46
631# CHECK: target: _x
632# CHECK-NOT: addend:
633# CHECK: - kind: thumb_movt
634# CHECK: offset: 50
635# CHECK: target: _x
636# CHECK-NOT: addend:
637# CHECK: - kind: thumb_movw
638# CHECK: offset: 54
639# CHECK: target: _x
640# CHECK: addend: 8
641# CHECK: - kind: thumb_movt
642# CHECK: offset: 58
643# CHECK: target: _x
644# CHECK: addend: 8
645# CHECK: - kind: thumb_movw
646# CHECK: offset: 62
647# CHECK: target: _t1
648# CHECK-NOT: addend:
649# CHECK: - kind: thumb_movt
650# CHECK: offset: 66
651# CHECK: target: _t1
652# CHECK-NOT: addend:
653# CHECK: - kind: thumb_movw
654# CHECK: offset: 70
655# CHECK: target: _undef
656# CHECK-NOT: addend:
657# CHECK: - kind: thumb_movt
658# CHECK: offset: 74
659# CHECK: target: _undef
660# CHECK-NOT: addend:
661# CHECK: - kind: thumb_movw
662# CHECK: offset: 78
663# CHECK: target: _undef
664# CHECK: addend: 8
665# CHECK: - kind: thumb_movt
666# CHECK: offset: 82
667# CHECK: target: _undef
668# CHECK: addend: 8
669# CHECK: - name: _t1
670# CHECK: content: [ C0, 46 ]
671# CHECK: references:
672# CHECK: - kind: modeThumbCode
673# CHECK: offset: 0
674# CHECK: - name: _foo_arm
675# CHECK: references:
676# CHECK-NOT: - kind: modeThumbCode
677# CHECK: - kind: arm_bl24
678# CHECK: offset: 0
679# CHECK: target: _x
680# CHECK-NOT: addend:
681# CHECK: - kind: arm_bl24
682# CHECK: offset: 4
683# CHECK: target: _x
684# CHECK: addend: 4
685# CHECK: - kind: arm_bl24
686# CHECK: offset: 8
687# CHECK: target: _undef
688# CHECK-NOT: addend:
689# CHECK: - kind: arm_bl24
690# CHECK: offset: 12
691# CHECK: target: _undef
692# CHECK: addend: 4
693# CHECK: - kind: arm_b24
694# CHECK: offset: 16
695# CHECK: target: _undef
696# CHECK-NOT: addend:
697# CHECK: - kind: arm_movw_funcRel
698# CHECK: offset: 20
699# CHECK: target: _x
700# CHECK: addend: -40
701# CHECK: - kind: arm_movt_funcRel
702# CHECK: offset: 24
703# CHECK: target: _x
704# CHECK: addend: -40
705# CHECK: - kind: arm_movw_funcRel
706# CHECK: offset: 28
707# CHECK: target: _x
708# CHECK: addend: -32
709# CHECK: - kind: arm_movt_funcRel
710# CHECK: offset: 32
711# CHECK: target: _x
712# CHECK: addend: -32
713# CHECK: - kind: arm_movw
714# CHECK: offset: 40
715# CHECK: target: _x
716# CHECK-NOT: addend:
717# CHECK: - kind: arm_movt
718# CHECK: offset: 44
719# CHECK: target: _x
720# CHECK-NOT: addend:
721# CHECK: - kind: arm_movw
722# CHECK: offset: 48
723# CHECK: target: _x
724# CHECK: addend: 8
725# CHECK: - kind: arm_movt
726# CHECK: offset: 52
727# CHECK: target: _x
728# CHECK: addend: 8
729# CHECK: - kind: arm_movw
730# CHECK: offset: 56
731# CHECK: target: _undef
732# CHECK-NOT: addend:
733# CHECK: - kind: arm_movt
734# CHECK: offset: 60
735# CHECK: target: _undef
736# CHECK-NOT: addend:
737# CHECK: - kind: arm_movw
738# CHECK: offset: 64
739# CHECK: target: _undef
740# CHECK: addend: 8
741# CHECK: - kind: arm_movt
742# CHECK: offset: 68
743# CHECK: target: _undef
744# CHECK: addend: 8
745# CHECK: undefined-atoms:
746# CHECK: - name: _undef
747
748
749
750
751# .align 2
752# .code 16
753# .thumb_func _foo_thumb
754#_foo_thumb:
755# bl _x
756# bl _x+4
757# bl _undef
758# bl _undef+4
759# b _undef
760# movw r1, :lower16:(_x-L1)
761# movt r1, :upper16:(_x-L1)
762# movw r2, :lower16:(_x+8-L1)
763# movt r2, :upper16:(_x+8-L1)
764# movw r1, :lower16:(_t1-L1)
765# movt r1, :upper16:(_t1-L1)
766# add r1, pc
767#L1:
768# movw r3, :lower16:_x
769# movt r3, :upper16:_x
770# movw r4, :lower16:_x+8
771# movt r4, :upper16:_x+8
772# movw r3, :lower16:_t1
773# movt r3, :upper16:_t1
774# movw r5, :lower16:_undef
775# movt r5, :upper16:_undef
776# movw r6, :lower16:_undef+8
777# movt r6, :upper16:_undef+8
778#
779# .thumb_func _t1
780#_t1:
781# nop
782#
783#
784# .code 32
785# .align 2
786#_foo_arm:
787# bl _x
788# bl _x+4
789# bl _undef
790# bl _undef+4
791# b _undef
792# movw r1, :lower16:(_x-L2)
793# movt r1, :upper16:(_x-L2)
794# movw r2, :lower16:(_x+8-L2)
795# movt r2, :upper16:(_x+8-L2)
796# add r1, pc
797#L2:
798# movw r3, :lower16:_x
799# movt r3, :upper16:_x
800# movw r4, :lower16:_x+8
801# movt r4, :upper16:_x+8
802# movw r5, :lower16:_undef
803# movt r5, :upper16:_undef
804# movw r6, :lower16:_undef+8
805# movt r6, :upper16:_undef+8
806#
807#
808# .data
809#_x: .long 0
810# .long _foo_thumb
811# .long _foo_thumb+4
812# .long _undef
813# .long _undef+4
814# .long _foo_arm - .
815# .long _foo_arm+4- .
816# .long _foo_thumb - .
817# .long _foo_thumb+4 - .
818#
deps/lld/test/mach-o/parse-cfstring32.yaml created+94
......@@ -0,0 +1,94 @@
1# RUN: lld -flavor darwin -arch i386 -r -print_atoms %s -o %t | FileCheck %s
2#
3# Test parsing of mach-o functions.
4#
5
6--- !mach-o
7arch: x86
8file-type: MH_OBJECT
9flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
10has-UUID: false
11OS: unknown
12sections:
13 - segment: __TEXT
14 section: __cstring
15 type: S_CSTRING_LITERALS
16 attributes: [ ]
17 address: 0x0000000000000000
18 content: [ 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x00, 0x74, 0x68,
19 0x65, 0x72, 0x65, 0x00 ]
20 - segment: __DATA
21 section: __cfstring
22 type: S_REGULAR
23 attributes: [ ]
24 alignment: 8
25 address: 0x0000000000000010
26 content: [ 0x00, 0x00, 0x00, 0x00, 0xC8, 0x07, 0x00, 0x00,
27 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
28 0x00, 0x00, 0x00, 0x00, 0xC8, 0x07, 0x00, 0x00,
29 0x06, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00 ]
30 relocations:
31 - offset: 0x00000018
32 type: GENERIC_RELOC_VANILLA
33 length: 2
34 pc-rel: false
35 extern: false
36 symbol: 1
37 - offset: 0x00000010
38 type: GENERIC_RELOC_VANILLA
39 length: 2
40 pc-rel: false
41 extern: true
42 symbol: 0
43 - offset: 0x00000008
44 type: GENERIC_RELOC_VANILLA
45 length: 2
46 pc-rel: false
47 extern: false
48 symbol: 1
49 - offset: 0x00000000
50 type: GENERIC_RELOC_VANILLA
51 length: 2
52 pc-rel: false
53 extern: true
54 symbol: 0
55undefined-symbols:
56 - name: ___CFConstantStringClassReference
57 type: N_UNDF
58 scope: [ N_EXT ]
59 value: 0x0000000000000000
60...
61
62# CHECK: defined-atoms:
63# CHECK: - ref-name: [[STR1:L[L0-9]+]]
64# CHECK: scope: hidden
65# CHECK: type: c-string
66# CHECK: content: [ 68, 65, 6C, 6C, 6F, 00 ]
67# CHECK: merge: by-content
68# CHECK: - ref-name: [[STR2:L[L0-9]+]]
69# CHECK: scope: hidden
70# CHECK: type: c-string
71# CHECK: content: [ 74, 68, 65, 72, 65, 00 ]
72# CHECK: merge: by-content
73# CHECK: - scope: hidden
74# CHECK: type: cfstring
75# CHECK: merge: by-content
76# CHECK: references:
77# CHECK: - kind: pointer32
78# CHECK: offset: 0
79# CHECK: target: ___CFConstantStringClassReference
80# CHECK: - kind: pointer32
81# CHECK: offset: 8
82# CHECK: target: [[STR1]]
83# CHECK: - scope: hidden
84# CHECK: type: cfstring
85# CHECK: merge: by-content
86# CHECK: references:
87# CHECK: - kind: pointer32
88# CHECK: offset: 0
89# CHECK: target: ___CFConstantStringClassReference
90# CHECK: - kind: pointer32
91# CHECK: offset: 8
92# CHECK: target: [[STR2]]
93# CHECK:undefined-atoms:
94# CHECK: - name: ___CFConstantStringClassReference
deps/lld/test/mach-o/parse-cfstring64.yaml created+108
......@@ -0,0 +1,108 @@
1# RUN: lld -flavor darwin -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s
2#
3# Test parsing of CFString constants.
4#
5
6--- !mach-o
7arch: x86_64
8file-type: MH_OBJECT
9flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
10has-UUID: false
11OS: unknown
12sections:
13 - segment: __TEXT
14 section: __cstring
15 type: S_CSTRING_LITERALS
16 attributes: [ ]
17 address: 0x0000000000000000
18 content: [ 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x00, 0x74, 0x68,
19 0x65, 0x72, 0x65, 0x00 ]
20 - segment: __DATA
21 section: __cfstring
22 type: S_REGULAR
23 attributes: [ ]
24 alignment: 4
25 address: 0x0000000000000010
26 content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
27 0xC8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
28 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
29 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
30 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
31 0xC8, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
32 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
33 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
34 relocations:
35 - offset: 0x00000030
36 type: X86_64_RELOC_UNSIGNED
37 length: 3
38 pc-rel: false
39 extern: true
40 symbol: 1
41 - offset: 0x00000020
42 type: X86_64_RELOC_UNSIGNED
43 length: 3
44 pc-rel: false
45 extern: true
46 symbol: 2
47 - offset: 0x00000010
48 type: X86_64_RELOC_UNSIGNED
49 length: 3
50 pc-rel: false
51 extern: true
52 symbol: 0
53 - offset: 0x00000000
54 type: X86_64_RELOC_UNSIGNED
55 length: 3
56 pc-rel: false
57 extern: true
58 symbol: 2
59local-symbols:
60 - name: Lstr1
61 type: N_SECT
62 sect: 1
63 value: 0x0000000000000000
64 - name: Lstr2
65 type: N_SECT
66 sect: 1
67 value: 0x0000000000000006
68undefined-symbols:
69 - name: ___CFConstantStringClassReference
70 type: N_UNDF
71 scope: [ N_EXT ]
72 value: 0x0000000000000000
73...
74
75# CHECK:defined-atoms:
76# CHECK: - ref-name: L000
77# CHECK: scope: hidden
78# CHECK: type: c-string
79# CHECK: content: [ 68, 65, 6C, 6C, 6F, 00 ]
80# CHECK: merge: by-content
81# CHECK: - ref-name: L001
82# CHECK: scope: hidden
83# CHECK: type: c-string
84# CHECK: content: [ 74, 68, 65, 72, 65, 00 ]
85# CHECK: merge: by-content
86# CHECK: - scope: hidden
87# CHECK: type: cfstring
88# CHECK: merge: by-content
89# CHECK: references:
90# CHECK: - kind: pointer64
91# CHECK: offset: 0
92# CHECK: target: ___CFConstantStringClassReference
93# CHECK: - kind: pointer64
94# CHECK: offset: 16
95# CHECK: target: L000
96# CHECK: - scope: hidden
97# CHECK: type: cfstring
98# CHECK: merge: by-content
99# CHECK: references:
100# CHECK: - kind: pointer64
101# CHECK: offset: 0
102# CHECK: target: ___CFConstantStringClassReference
103# CHECK: - kind: pointer64
104# CHECK: offset: 16
105# CHECK: target: L001
106# CHECK:undefined-atoms:
107# CHECK: - name: ___CFConstantStringClassReference
108
deps/lld/test/mach-o/parse-compact-unwind32.yaml created+72
......@@ -0,0 +1,72 @@
1# RUN: lld -flavor darwin -arch i386 -r -print_atoms %s -o %t | FileCheck %s
2#
3# Test parsing of __LD/__compact_unwind (compact unwind) section.
4#
5
6--- !mach-o
7arch: x86
8file-type: MH_OBJECT
9flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
10has-UUID: false
11OS: unknown
12sections:
13 - segment: __TEXT
14 section: __text
15 type: S_REGULAR
16 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
17 alignment: 4
18 address: 0x0000000000000000
19 content: [ 0x55, 0x89, 0xE5, 0xB8, 0x0A, 0x00, 0x00, 0x00,
20 0x5D, 0xC3, 0x55, 0x89, 0xE5, 0xB8, 0x0A, 0x00,
21 0x00, 0x00, 0x5D, 0xC3 ]
22 - segment: __LD
23 section: __compact_unwind
24 type: S_REGULAR
25 attributes: [ ]
26 alignment: 2
27 address: 0x000000000000001C
28 content: [ 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,
29 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
30 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00,
31 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
32 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
33 relocations:
34 - offset: 0x00000014
35 type: GENERIC_RELOC_VANILLA
36 length: 2
37 pc-rel: false
38 extern: false
39 symbol: 1
40 - offset: 0x00000000
41 type: GENERIC_RELOC_VANILLA
42 length: 2
43 pc-rel: false
44 extern: false
45 symbol: 1
46global-symbols:
47 - name: __Z3barv
48 type: N_SECT
49 scope: [ N_EXT ]
50 sect: 1
51 value: 0x000000000000000A
52 - name: __Z3foov
53 type: N_SECT
54 scope: [ N_EXT ]
55 sect: 1
56 value: 0x0000000000000000
57...
58
59# CHECK: defined-atoms:
60# CHECK: - type: compact-unwind
61# CHECK: content: [ 00, 00, 00, 00, 0A, 00, 00, 00, 00, 00, 00, 01,
62# CHECK: 00, 00, 00, 00, 00, 00, 00, 00 ]
63# CHECK: - type: compact-unwind
64# CHECK: content: [ 10, 00, 00, 00, 0A, 00, 00, 00, 00, 00, 00, 01,
65# CHECK: 00, 00, 00, 00, 00, 00, 00, 00 ]
66# CHECK: - name: __Z3foov
67# CHECK: scope: global
68# CHECK: content: [ 55, 89, E5, B8, 0A, 00, 00, 00, 5D, C3 ]
69# CHECK: - name: __Z3barv
70# CHECK: scope: global
71# CHECK: content: [ 55, 89, E5, B8, 0A, 00, 00, 00, 5D, C3 ]
72
deps/lld/test/mach-o/parse-compact-unwind64.yaml created+76
......@@ -0,0 +1,76 @@
1# RUN: lld -flavor darwin -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s
2#
3# Test parsing of __LD/__compact_unwind (compact unwind) section.
4#
5
6--- !mach-o
7arch: x86_64
8file-type: MH_OBJECT
9flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
10has-UUID: false
11OS: unknown
12sections:
13 - segment: __TEXT
14 section: __text
15 type: S_REGULAR
16 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
17 alignment: 4
18 address: 0x0000000000000000
19 content: [ 0x55, 0x48, 0x89, 0xE5, 0xB8, 0x0A, 0x00, 0x00,
20 0x00, 0x5D, 0xC3, 0x55, 0x48, 0x89, 0xE5, 0xB8,
21 0x0A, 0x00, 0x00, 0x00, 0x5D, 0xC3 ]
22 - segment: __LD
23 section: __compact_unwind
24 type: S_REGULAR
25 attributes: [ ]
26 alignment: 8
27 address: 0x0000000000000020
28 content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
29 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
30 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
31 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
32 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
33 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
34 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
35 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
36 relocations:
37 - offset: 0x00000020
38 type: X86_64_RELOC_UNSIGNED
39 length: 3
40 pc-rel: false
41 extern: false
42 symbol: 1
43 - offset: 0x00000000
44 type: X86_64_RELOC_UNSIGNED
45 length: 3
46 pc-rel: false
47 extern: false
48 symbol: 1
49global-symbols:
50 - name: __Z3barv
51 type: N_SECT
52 scope: [ N_EXT ]
53 sect: 1
54 value: 0x0000000000000000
55 - name: __Z3foov
56 type: N_SECT
57 scope: [ N_EXT ]
58 sect: 1
59 value: 0x000000000000000B
60...
61
62# CHECK: defined-atoms:
63# CHECK: - type: compact-unwind
64# CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00, 0B, 00, 00, 00,
65# CHECK: 00, 00, 00, 01, 00, 00, 00, 00, 00, 00, 00, 00,
66# CHECK: 00, 00, 00, 00, 00, 00, 00, 00 ]
67# CHECK: - type: compact-unwind
68# CHECK: content: [ 10, 00, 00, 00, 00, 00, 00, 00, 0B, 00, 00, 00,
69# CHECK: 00, 00, 00, 01, 00, 00, 00, 00, 00, 00, 00, 00,
70# CHECK: 00, 00, 00, 00, 00, 00, 00, 00 ]
71# CHECK: - name: __Z3barv
72# CHECK: scope: global
73# CHECK: content: [ 55, 48, 89, E5, B8, 0A, 00, 00, 00, 5D, C3 ]
74# CHECK: - name: __Z3foov
75# CHECK: scope: global
76# CHECK: content: [ 55, 48, 89, E5, B8, 0A, 00, 00, 00, 5D, C3 ]
deps/lld/test/mach-o/parse-data-in-code-armv7.yaml created+157
......@@ -0,0 +1,157 @@
1# RUN: lld -flavor darwin -arch armv7 -r -print_atoms %s -o %t | FileCheck %s
2# RUN: lld -flavor darwin -arch armv7 -r -print_atoms %t -o %t2 | FileCheck %s
3# RUN: lld -flavor darwin -arch armv7 -dylib %s -o %t3.dylib %p/Inputs/armv7/libSystem.yaml \
4# RUN: && llvm-objdump -macho -private-headers %t3.dylib | FileCheck --check-prefix=CHECK2 %s
5#
6# Test parsing LC_DATA_IN_CODE
7#
8#
9
10--- !mach-o
11arch: armv7
12file-type: MH_OBJECT
13flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
14sections:
15 - segment: __TEXT
16 section: __text
17 type: S_REGULAR
18 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
19 alignment: 2
20 address: 0x0000000000000000
21 content: [ 0x00, 0xBF, 0x00, 0xBF, 0x00, 0x00, 0x00, 0x00,
22 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
23 0x03, 0x00, 0x00, 0x00, 0x00, 0xBF, 0x00, 0xBF,
24 0x00, 0xF0, 0x20, 0xE3, 0x0A, 0x00, 0x00, 0x00,
25 0x0B, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
26 0x0D, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x20, 0xE3 ]
27local-symbols:
28 - name: _foo_thumb
29 type: N_SECT
30 sect: 1
31 desc: [ N_ARM_THUMB_DEF ]
32 value: 0x0000000000000000
33 - name: _foo_arm
34 type: N_SECT
35 sect: 1
36 value: 0x0000000000000018
37dataInCode:
38 - offset: 0x00000004
39 length: 0x0004
40 kind: DICE_KIND_DATA
41 - offset: 0x00000008
42 length: 0x0004
43 kind: DICE_KIND_JUMP_TABLE32
44 - offset: 0x0000000C
45 length: 0x0004
46 kind: DICE_KIND_JUMP_TABLE16
47 - offset: 0x00000010
48 length: 0x0004
49 kind: DICE_KIND_JUMP_TABLE8
50 - offset: 0x0000001C
51 length: 0x0004
52 kind: DICE_KIND_DATA
53 - offset: 0x00000020
54 length: 0x0004
55 kind: DICE_KIND_JUMP_TABLE32
56 - offset: 0x00000024
57 length: 0x0004
58 kind: DICE_KIND_JUMP_TABLE16
59 - offset: 0x00000028
60 length: 0x0004
61 kind: DICE_KIND_JUMP_TABLE8
62...
63
64
65
66# CHECK: defined-atoms:
67# CHECK: - name: _foo_thumb
68# CHECK: references:
69# CHECK: - kind: modeThumbCode
70# CHECK: offset: 0
71# CHECK: - kind: modeData
72# CHECK: offset: 4
73# CHECK: addend: 1
74# CHECK: - kind: modeData
75# CHECK: offset: 8
76# CHECK: addend: 4
77# CHECK: - kind: modeData
78# CHECK: offset: 12
79# CHECK: addend: 3
80# CHECK: - kind: modeData
81# CHECK: offset: 16
82# CHECK: addend: 2
83# CHECK: - kind: modeThumbCode
84# CHECK: offset: 20
85# CHECK: - name: _foo_arm
86# CHECK: references:
87# CHECK: - kind: modeData
88# CHECK: offset: 4
89# CHECK: addend: 1
90# CHECK: - kind: modeData
91# CHECK: offset: 8
92# CHECK: addend: 4
93# CHECK: - kind: modeData
94# CHECK: offset: 12
95# CHECK: addend: 3
96# CHECK: - kind: modeData
97# CHECK: offset: 16
98# CHECK: addend: 2
99# CHECK: - kind: modeArmCode
100# CHECK: offset: 20
101
102
103# CHECK2: cmd LC_DATA_IN_CODE
104# CHECK2: cmdsize 16
105# CHECK2: datasize 64
106
107
108# .code 16
109# .thumb_func _foo_thumb
110#_foo_thumb:
111# nop
112# nop
113#
114# .data_region
115# .long 0
116# .end_data_region
117#
118# .data_region jt32
119# .long 1
120# .end_data_region
121#
122# .data_region jt16
123# .long 2
124# .end_data_region
125#
126# .data_region jt8
127# .long 3
128# .end_data_region
129#
130# nop
131# nop
132#
133#
134#
135# .code 32
136# .align 2
137#_foo_arm:
138# nop
139#
140# .data_region
141# .long 10
142# .end_data_region
143#
144# .data_region jt32
145# .long 11
146# .end_data_region
147#
148# .data_region jt16
149# .long 12
150# .end_data_region
151#
152# .data_region jt8
153# .long 13
154# .end_data_region
155#
156# nop
157#
deps/lld/test/mach-o/parse-data-in-code-x86.yaml created+77
......@@ -0,0 +1,77 @@
1# RUN: lld -flavor darwin -arch i386 -r -print_atoms %s -o %t | FileCheck %s \
2# RUN: && lld -flavor darwin -arch i386 -r -print_atoms %t -o %t2 | FileCheck %s
3#
4# Test parsing LC_DATA_IN_CODE
5#
6#
7
8--- !mach-o
9arch: x86
10file-type: MH_OBJECT
11flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
12sections:
13 - segment: __TEXT
14 section: __text
15 type: S_REGULAR
16 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
17 address: 0x0000000000000000
18 content: [ 0x90, 0x90, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00,
19 0x00, 0x00, 0x90, 0x90, 0x90, 0x90, 0x03, 0x00,
20 0x00, 0x00 ]
21local-symbols:
22 - name: _func1
23 type: N_SECT
24 sect: 1
25 value: 0x0000000000000000
26 - name: _func2
27 type: N_SECT
28 sect: 1
29 value: 0x000000000000000B
30dataInCode:
31 - offset: 0x00000002
32 length: 0x0008
33 kind: DICE_KIND_JUMP_TABLE32
34 - offset: 0x0000000E
35 length: 0x0004
36 kind: DICE_KIND_JUMP_TABLE32
37...
38
39
40
41# CHECK: defined-atoms:
42# CHECK: - name: _func1
43# CHECK: references:
44# CHECK: - kind: modeData
45# CHECK: offset: 2
46# CHECK: addend: 4
47# CHECK: - kind: modeCode
48# CHECK: offset: 10
49# CHECK: - name: _func2
50# CHECK: references:
51# CHECK: - kind: modeData
52# CHECK: offset: 3
53# CHECK: addend: 4
54# CHECK-NOT: - kind: modeData
55
56
57
58
59#
60#_func1:
61# nop
62# nop
63# .data_region jt32
64# .long 1
65# .long 2
66# .end_data_region
67# nop
68#
69#
70# _func2:
71# nop
72# nop
73# nop
74# .data_region jt32
75# .long 3
76# .end_data_region
77#
deps/lld/test/mach-o/parse-data-relocs-arm64.yaml created+244
......@@ -0,0 +1,244 @@
1# RUN: lld -flavor darwin -arch arm64 -r -print_atoms %s -o %t | FileCheck %s
2# RUN: lld -flavor darwin -arch arm64 -r -print_atoms %t -o %t2 | FileCheck %s
3#
4# Test parsing and writing of arm64 data relocations.
5#
6# The first step tests if the supplied mach-o file is parsed into the correct
7# set of references. The second step verifies relocations can be round-tripped
8# by writing to a new .o file, then parsing that file which should result in
9# the same references.
10#
11#_test:
12
13
14--- !mach-o
15arch: arm64
16file-type: MH_OBJECT
17flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
18sections:
19 - segment: __TEXT
20 section: __text
21 type: S_REGULAR
22 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
23 alignment: 4
24 address: 0x0000000000000000
25 content: [ 0xC0, 0x03, 0x5F, 0xD6 ]
26 - segment: __DATA
27 section: __data
28 type: S_REGULAR
29 attributes: [ ]
30 address: 0x0000000000000004
31 content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
32 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
33 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
34 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
35 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
36 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
37 0xDC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
38 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
40 0xC0, 0xFF, 0xFF, 0xFF, 0xBE, 0xFF, 0xFF, 0xFF,
41 0xB0, 0xFF, 0xFF, 0xFF ]
42 relocations:
43 - offset: 0x00000050
44 type: ARM64_RELOC_POINTER_TO_GOT
45 length: 2
46 pc-rel: true
47 extern: true
48 symbol: 2
49 - offset: 0x0000004C
50 type: ARM64_RELOC_SUBTRACTOR
51 length: 2
52 pc-rel: false
53 extern: true
54 symbol: 2
55 - offset: 0x0000004C
56 type: ARM64_RELOC_UNSIGNED
57 length: 2
58 pc-rel: false
59 extern: true
60 symbol: 2
61 - offset: 0x00000048
62 type: ARM64_RELOC_SUBTRACTOR
63 length: 2
64 pc-rel: false
65 extern: true
66 symbol: 2
67 - offset: 0x00000048
68 type: ARM64_RELOC_UNSIGNED
69 length: 2
70 pc-rel: false
71 extern: true
72 symbol: 2
73 - offset: 0x00000040
74 type: ARM64_RELOC_UNSIGNED
75 length: 3
76 pc-rel: false
77 extern: true
78 symbol: 2
79 - offset: 0x00000038
80 type: ARM64_RELOC_UNSIGNED
81 length: 3
82 pc-rel: false
83 extern: false
84 symbol: 2
85 - offset: 0x00000030
86 type: ARM64_RELOC_SUBTRACTOR
87 length: 3
88 pc-rel: false
89 extern: true
90 symbol: 2
91 - offset: 0x00000030
92 type: ARM64_RELOC_UNSIGNED
93 length: 3
94 pc-rel: false
95 extern: true
96 symbol: 2
97 - offset: 0x00000028
98 type: ARM64_RELOC_SUBTRACTOR
99 length: 3
100 pc-rel: false
101 extern: true
102 symbol: 2
103 - offset: 0x00000028
104 type: ARM64_RELOC_UNSIGNED
105 length: 3
106 pc-rel: false
107 extern: true
108 symbol: 2
109 - offset: 0x00000020
110 type: ARM64_RELOC_SUBTRACTOR
111 length: 3
112 pc-rel: false
113 extern: true
114 symbol: 2
115 - offset: 0x00000020
116 type: ARM64_RELOC_UNSIGNED
117 length: 3
118 pc-rel: false
119 extern: true
120 symbol: 2
121 - offset: 0x00000018
122 type: ARM64_RELOC_POINTER_TO_GOT
123 length: 3
124 pc-rel: false
125 extern: true
126 symbol: 2
127 - offset: 0x00000010
128 type: ARM64_RELOC_UNSIGNED
129 length: 3
130 pc-rel: false
131 extern: true
132 symbol: 2
133 - offset: 0x00000008
134 type: ARM64_RELOC_UNSIGNED
135 length: 3
136 pc-rel: false
137 extern: true
138 symbol: 2
139local-symbols:
140 - name: _v1
141 type: N_SECT
142 sect: 2
143 value: 0x000000000000000C
144global-symbols:
145 - name: _bar
146 type: N_SECT
147 scope: [ N_EXT ]
148 sect: 1
149 value: 0x0000000000000000
150undefined-symbols:
151 - name: _foo
152 type: N_UNDF
153 scope: [ N_EXT ]
154 value: 0x0000000000000000
155page-size: 0x00000000
156...
157
158# CHECK: defined-atoms:
159# CHECK: - ref-name: L000
160# CHECK: type: data
161# CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ]
162# CHECK: - name: _v1
163# CHECK: type: data
164# CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00, 08, 00, 00, 00,
165# CHECK: 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
166# CHECK: 00, 00, 00, 00, 00, 00, 00, 00, E0, FF, FF, FF,
167# CHECK: FF, FF, FF, FF, DC, FF, FF, FF, FF, FF, FF, FF,
168# CHECK: {{..}}, {{..}}, 00, 00, 00, 00, 00, 00, 04, 00, 00, 00,
169# CHECK: 00, 00, 00, 00, C0, FF, FF, FF, BE, FF, FF, FF,
170# CHECK: {{B0|B8}}, {{..}}, FF, FF ]
171# CHECK: references:
172# CHECK: - kind: pointer64
173# CHECK: offset: 0
174# CHECK: target: _foo
175# CHECK-NOT: addend:
176# CHECK: - kind: pointer64
177# CHECK: offset: 8
178# CHECK: target: _foo
179# CHECK: addend: 8
180# CHECK: - kind: pointer64ToGOT
181# CHECK: offset: 16
182# CHECK: target: _foo
183# CHECK-NOT: addend:
184# CHECK: - kind: delta64
185# CHECK: offset: 24
186# CHECK: target: _foo
187# CHECK: addend: 24
188# CHECK: - kind: delta64
189# CHECK: offset: 32
190# CHECK: target: _foo
191# CHECK-NOT: addend:
192# CHECK: - kind: delta64
193# CHECK: offset: 40
194# CHECK: target: _foo
195# CHECK: addend: 4
196# CHECK: - kind: pointer64
197# CHECK: offset: 48
198# CHECK: target: L000
199# CHECK-NOT: addend:
200# CHECK: - kind: pointer64
201# CHECK: offset: 56
202# CHECK: target: _foo
203# CHECK: addend: 4
204# CHECK: - kind: delta32
205# CHECK: offset: 64
206# CHECK: target: _foo
207# CHECK-NOT: addend:
208# CHECK: - kind: delta32
209# CHECK: offset: 68
210# CHECK: target: _foo
211# CHECK: addend: 2
212# CHECK: - kind: delta32ToGOT
213# CHECK: offset: 72
214# CHECK: target: _foo
215# CHECK-NOT: addend:
216# CHECK: - name: _bar
217# CHECK: scope: global
218# CHECK: content: [ C0, 03, 5F, D6 ]
219# CHECK: alignment: 4
220# CHECK: undefined-atoms:
221# CHECK: - name: _foo
222
223# .subsections_via_symbols
224# .text
225# .globl_foo
226# .align2
227# _foo:
228# ret
229# .data
230#Lanon:
231# .quad 0
232#_v1:
233# .quad _foo
234# .quad _foo + 8
235# .quad _foo@GOT
236# .quad _foo + 24 - .
237# .quad _foo - .
238# .quad _foo + 4 - .
239# .quad Lanon
240# .quad Lanon + 4
241# .long _foo - .
242# .long _foo +2 - .
243# .long _foo@GOT - .
244
deps/lld/test/mach-o/parse-data-relocs-x86_64.yaml created+372
......@@ -0,0 +1,372 @@
1
2# RUN: lld -flavor darwin -arch x86_64 -r %s -o %t -print_atoms | FileCheck %s \
3# RUN: && lld -flavor darwin -arch x86_64 %t -r -print_atoms -o %t2 | FileCheck %s
4#
5# Test parsing and writing of x86_64 data relocations.
6#
7# The first step tests if the supplied mach-o file is parsed into the correct
8# set of references. The second step verifies relocations can be round-tripped
9# by writing to a new .o file, then parsing that file which should result in
10# the same references.
11#
12#_foo:
13# ret
14#
15#_bar:
16# ret
17#
18# .section __DATA,__custom
19#L1:
20# .quad 0
21#
22# .data
23#_d:
24# .quad _foo
25# .quad _foo+4
26# .quad _foo - .
27# .quad L1
28# .quad L1 + 2
29# .quad _foo - .
30# .quad _foo + 4 - .
31# .quad L1 - .
32# .long _foo - .
33# .long _foo + 4 - .
34# .long L1 - .
35#
36
37--- !mach-o
38arch: x86_64
39file-type: MH_OBJECT
40flags: [ ]
41compat-version: 0.0
42current-version: 0.0
43has-UUID: false
44OS: unknown
45sections:
46 - segment: __TEXT
47 section: __text
48 type: S_REGULAR
49 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
50 address: 0x0000000000000000
51 content: [ 0xC3, 0xC3 ]
52 - segment: __DATA
53 section: __custom
54 type: S_REGULAR
55 attributes: [ ]
56 address: 0x0000000000000002
57 content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
58 - segment: __DATA
59 section: __data
60 type: S_REGULAR
61 attributes: [ ]
62 address: 0x000000000000000A
63 content: [
64# .quad _foo
65# No addend is needed here as we are referencing _foo directly and that is
66# encoded entirely in the X86_64_RELOC_UNSIGNED
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68# .quad _foo+4
69# Addend of 4 is needed here as we are referencing _foo from the
70# X86_64_RELOC_UNSIGNED, then the addend gives us 4 more.
71 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72# .quad _foo - .
73# This is the pair X86_64_RELOC_SUBTRACTOR and X86_64_RELOC_UNSIGNED.
74# The subtractor references _d which is the first nonlocal label in this
75# section. The unsigned references _foo.
76# Note the addend here is -16 because that is the offset from here back
77# to _d.
78 0xF0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
79# .quad . - _foo
80# This is the pair X86_64_RELOC_SUBTRACTOR and X86_64_RELOC_UNSIGNED.
81# The subtractor references _d which is the first nonlocal label in this
82# section. The unsigned references _foo.
83# Note the addend here is -16 because that is the offset from here back
84# to _d.
85 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86# .quad L1
87# This is a X86_64_RELOC_UNSIGNED without extern set.
88# In this case, we encode the section number for L1 in the relocation, and
89# the addend here is the absolute address of the location in that section
90# we want to reference.
91 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92# .quad L1 + 2
93# This is a X86_64_RELOC_UNSIGNED without extern set.
94# In this case, we encode the section number for L1 in the relocation, and
95# the addend here is the absolute address of the location in that section
96# we want to reference. We have a 4 because the section is at address 2
97# and we want an offset of 2 from there.
98 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
99# .quad _foo - .
100# This is the pair X86_64_RELOC_SUBTRACTOR and X86_64_RELOC_UNSIGNED.
101# The subtractor references _d which is the first nonlocal label in this
102# section. The unsigned references _foo.
103# Note the addend here is -40 because that is the offset from here back
104# to _d.
105 0xD0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
106# .quad _foo + 4 - .
107# This is the pair X86_64_RELOC_SUBTRACTOR and X86_64_RELOC_UNSIGNED.
108# The subtractor references _d which is the first nonlocal label in this
109# section. The unsigned references _foo.
110# Note the addend here is -52. It would have been -56 because that
111# would take us from the address of this relocation back to _d. But as
112# we also add 4 for the offset, we get -52.
113 0xCC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
114# .quad L1 - .
115# This is the pair X86_64_RELOC_SUBTRACTOR and X86_64_RELOC_UNSIGNED.
116# The subtractor references _d which is the first nonlocal label in this
117# section. The unsigned does not have extern set, so the relocation
118# number is the section number for L1.
119# Note the addend here is -62. Of that, -64 would be the offset from
120# this location from _d. The remaining 2 is the absolute address
121# of L1.
122 0xC2, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
123# .long _foo - .
124# This is the pair X86_64_RELOC_SUBTRACTOR and X86_64_RELOC_UNSIGNED.
125# The subtractor references _d which is the first nonlocal label in this
126# section. The unsigned references _foo.
127# Note the addend here is -72 because that is the offset from here back
128# to _d.
129 0xB8, 0xFF, 0xFF, 0xFF,
130# .long . - _foo
131# This is the pair X86_64_RELOC_SUBTRACTOR and X86_64_RELOC_UNSIGNED.
132# The subtractor references _d which is the first nonlocal label in this
133# section. The unsigned references _foo.
134# Note the addend here is -76 because that is the offset from here back
135# to _d.
136 0xB4, 0xFF, 0xFF, 0xFF,
137# .long _foo + 4 - .
138# This is the pair X86_64_RELOC_SUBTRACTOR and X86_64_RELOC_UNSIGNED.
139# The subtractor references _d which is the first nonlocal label in this
140# section. The unsigned references _foo.
141# Note the addend here is -76. It would have been -80 because that
142# would take us from the address of this relocation back to _d. But as
143# we also add 4 for the offset, we get -76.
144 0xB4, 0xFF, 0xFF, 0xFF,
145# .long L1 - .
146# This is the pair X86_64_RELOC_SUBTRACTOR and X86_64_RELOC_UNSIGNED.
147# The subtractor references _d which is the first nonlocal label in this
148# section. The unsigned does not have extern set, so the relocation
149# number is the section number for L1.
150# Note the addend here is -82. Of that, -84 would be the offset from
151# this location from _d. The remaining 2 is the absolute address
152# of L1.
153 0xAE, 0xFF, 0xFF, 0xFF ]
154 relocations:
155 - offset: 0x00000054
156 type: X86_64_RELOC_SUBTRACTOR
157 length: 2
158 pc-rel: false
159 extern: true
160 symbol: 2
161 - offset: 0x00000054
162 type: X86_64_RELOC_UNSIGNED
163 length: 2
164 pc-rel: false
165 extern: false
166 symbol: 2
167 - offset: 0x00000050
168 type: X86_64_RELOC_SUBTRACTOR
169 length: 2
170 pc-rel: false
171 extern: true
172 symbol: 2
173 - offset: 0x00000050
174 type: X86_64_RELOC_UNSIGNED
175 length: 2
176 pc-rel: false
177 extern: true
178 symbol: 0
179 - offset: 0x0000004C
180 type: X86_64_RELOC_SUBTRACTOR
181 length: 2
182 pc-rel: false
183 extern: true
184 symbol: 0
185 - offset: 0x0000004C
186 type: X86_64_RELOC_UNSIGNED
187 length: 2
188 pc-rel: false
189 extern: true
190 symbol: 2
191 - offset: 0x00000048
192 type: X86_64_RELOC_SUBTRACTOR
193 length: 2
194 pc-rel: false
195 extern: true
196 symbol: 2
197 - offset: 0x00000048
198 type: X86_64_RELOC_UNSIGNED
199 length: 2
200 pc-rel: false
201 extern: true
202 symbol: 0
203 - offset: 0x00000040
204 type: X86_64_RELOC_SUBTRACTOR
205 length: 3
206 pc-rel: false
207 extern: true
208 symbol: 2
209 - offset: 0x00000040
210 type: X86_64_RELOC_UNSIGNED
211 length: 3
212 pc-rel: false
213 extern: false
214 symbol: 2
215 - offset: 0x00000038
216 type: X86_64_RELOC_SUBTRACTOR
217 length: 3
218 pc-rel: false
219 extern: true
220 symbol: 2
221 - offset: 0x00000038
222 type: X86_64_RELOC_UNSIGNED
223 length: 3
224 pc-rel: false
225 extern: true
226 symbol: 0
227 - offset: 0x00000030
228 type: X86_64_RELOC_SUBTRACTOR
229 length: 3
230 pc-rel: false
231 extern: true
232 symbol: 2
233 - offset: 0x00000030
234 type: X86_64_RELOC_UNSIGNED
235 length: 3
236 pc-rel: false
237 extern: true
238 symbol: 0
239 - offset: 0x00000028
240 type: X86_64_RELOC_UNSIGNED
241 length: 3
242 pc-rel: false
243 extern: false
244 symbol: 2
245 - offset: 0x00000020
246 type: X86_64_RELOC_UNSIGNED
247 length: 3
248 pc-rel: false
249 extern: false
250 symbol: 2
251 - offset: 0x00000018
252 type: X86_64_RELOC_SUBTRACTOR
253 length: 3
254 pc-rel: false
255 extern: true
256 symbol: 0
257 - offset: 0x00000018
258 type: X86_64_RELOC_UNSIGNED
259 length: 3
260 pc-rel: false
261 extern: true
262 symbol: 2
263 - offset: 0x00000010
264 type: X86_64_RELOC_SUBTRACTOR
265 length: 3
266 pc-rel: false
267 extern: true
268 symbol: 2
269 - offset: 0x00000010
270 type: X86_64_RELOC_UNSIGNED
271 length: 3
272 pc-rel: false
273 extern: true
274 symbol: 0
275 - offset: 0x00000008
276 type: X86_64_RELOC_UNSIGNED
277 length: 3
278 pc-rel: false
279 extern: true
280 symbol: 0
281 - offset: 0x00000000
282 type: X86_64_RELOC_UNSIGNED
283 length: 3
284 pc-rel: false
285 extern: true
286 symbol: 0
287local-symbols:
288 - name: _foo
289 type: N_SECT
290 sect: 1
291 value: 0x0000000000000000
292 - name: _bar
293 type: N_SECT
294 sect: 1
295 value: 0x0000000000000001
296 - name: _d
297 type: N_SECT
298 sect: 3
299 value: 0x000000000000000A
300page-size: 0x00000000
301...
302
303
304# CHECK:defined-atoms:
305# CHECK: - name: _d
306# CHECK: type: data
307# CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00, 04, 00, 00, 00,
308# CHECK: 00, 00, 00, 00, F0, FF, FF, FF, FF, FF, FF, FF,
309# CHECK: 18, 00, 00, 00, 00, 00, 00, 00, {{..}}, {{..}}, 00, 00,
310# CHECK: 00, 00, 00, 00, {{..}}, {{..}}, 00, 00, 00, 00, 00, 00,
311# CHECK: D0, FF, FF, FF, FF, FF, FF, FF, CC, FF, FF, FF,
312# CHECK: FF, FF, FF, FF, {{..}}, {{..}}, {{..}}, {{..}}, {{..}}, {{..}}, {{..}}, {{..}},
313# CHECK: B8, FF, FF, FF, B4, FF, FF, FF, B4, FF, FF, FF,
314# CHECK: {{..}}, {{..}}, {{..}}, {{..}} ]
315# CHECK: dead-strip: never
316# CHECK: references:
317# CHECK: - kind: pointer64
318# CHECK: offset: 0
319# CHECK: target: _foo
320# CHECK: - kind: pointer64
321# CHECK: offset: 8
322# CHECK: target: _foo
323# CHECK: addend: 4
324# CHECK: - kind: delta64
325# CHECK: offset: 16
326# CHECK: target: _foo
327# CHECK: - kind: negDelta64
328# CHECK: offset: 24
329# CHECK: target: _foo
330# CHECK: - kind: pointer64Anon
331# CHECK: offset: 32
332# CHECK: target: L003
333# CHECK: - kind: pointer64Anon
334# CHECK: offset: 40
335# CHECK: target: L003
336# CHECK: addend: 2
337# CHECK: - kind: delta64
338# CHECK: offset: 48
339# CHECK: target: _foo
340# CHECK: - kind: delta64
341# CHECK: offset: 56
342# CHECK: target: _foo
343# CHECK: addend: 4
344# CHECK: - kind: delta64Anon
345# CHECK: offset: 64
346# CHECK: target: L003
347# CHECK: - kind: delta32
348# CHECK: offset: 72
349# CHECK: target: _foo
350# CHECK: - kind: negDelta32
351# CHECK: offset: 76
352# CHECK: target: _foo
353# CHECK: - kind: delta32
354# CHECK: offset: 80
355# CHECK: target: _foo
356# CHECK: addend: 4
357# CHECK: - kind: delta32Anon
358# CHECK: offset: 84
359# CHECK: target: L003
360# CHECK: - name: _foo
361# CHECK: content: [ C3 ]
362# CHECK: dead-strip: never
363# CHECK: - name: _bar
364# CHECK: content: [ C3 ]
365# CHECK: dead-strip: never
366# CHECK: - ref-name: L003
367# CHECK: type: unknown
368# CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ]
369# CHECK: section-choice: custom-required
370# CHECK: section-name: __DATA/__custom
371# CHECK: dead-strip: never
372
deps/lld/test/mach-o/parse-data.yaml created+119
......@@ -0,0 +1,119 @@
1# RUN: lld -flavor darwin -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s
2#
3# Test parsing of mach-o data symbols.
4#
5# long a = 0x0807060504030201;
6# int b = 0x14131211;
7# int c = 0x24232221;
8# static int s1;
9# static int s2 = 0x34333231;
10#
11#
12
13
14--- !mach-o
15arch: x86_64
16file-type: MH_OBJECT
17flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
18has-UUID: false
19OS: unknown
20sections:
21 - segment: __DATA
22 section: __data
23 type: S_REGULAR
24 attributes: [ ]
25 alignment: 8
26 address: 0x0000000000000000
27 content: [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
28 0x11, 0x12, 0x13, 0x14, 0x21, 0x22, 0x23, 0x24,
29 0x31, 0x32, 0x33, 0x34, 0x41, 0x42, 0x43, 0x44 ]
30 - segment: __CUST
31 section: __custom
32 type: S_REGULAR
33 attributes: [ ]
34 alignment: 8
35 address: 0x0000000000000018
36 content: [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ]
37 - segment: __DATA
38 section: __bss
39 type: S_ZEROFILL
40 attributes: [ ]
41 alignment: 2
42 address: 0x0000000000000020
43 size: 4
44local-symbols:
45 - name: _s1
46 type: N_SECT
47 sect: 3
48 value: 0x0000000000000020
49 - name: _s2
50 type: N_SECT
51 sect: 1
52 value: 0x0000000000000010
53global-symbols:
54 - name: _a
55 type: N_SECT
56 scope: [ N_EXT ]
57 sect: 1
58 value: 0x0000000000000000
59 - name: _b
60 type: N_SECT
61 scope: [ N_EXT ]
62 sect: 1
63 value: 0x0000000000000008
64 - name: _c
65 type: N_SECT
66 scope: [ N_EXT ]
67 sect: 1
68 value: 0x000000000000000C
69 - name: _cWeak
70 type: N_SECT
71 scope: [ N_EXT ]
72 sect: 1
73 desc: [ N_WEAK_DEF ]
74 value: 0x0000000000000014
75 - name: _kustom
76 type: N_SECT
77 scope: [ N_EXT ]
78 sect: 2
79 value: 0x0000000000000018
80...
81
82# CHECK: defined-atoms:
83
84# CHECK: - name: _a
85# CHECK: scope: global
86# CHECK: type: data
87# CHECK: content: [ 01, 02, 03, 04, 05, 06, 07, 08 ]
88
89# CHECK: - name: _b
90# CHECK: scope: global
91# CHECK: type: data
92# CHECK: content: [ 11, 12, 13, 14 ]
93
94# CHECK: - name: _c
95# CHECK: scope: global
96# CHECK: type: data
97# CHECK: content: [ 21, 22, 23, 24 ]
98
99# CHECK: - name: _s2
100# CHECK: type: data
101# CHECK: content: [ 31, 32, 33, 34 ]
102
103# CHECK: - name: _cWeak
104# CHECK: scope: global
105# CHECK: type: data
106# CHECK: content: [ 41, 42, 43, 44 ]
107# CHECK: merge: as-weak
108
109# CHECK: - name: _s1
110# CHECK: type: zero-fill
111# CHECK: size: 4
112
113# CHECK: - name: _kustom
114# CHECK: scope: global
115# CHECK: type: unknown
116# CHECK: content: [ 01, 02, 03, 04, 05, 06, 07, 08 ]
117# CHECK: section-choice: custom-required
118# CHECK: section-name: __CUST/__custom
119
deps/lld/test/mach-o/parse-eh-frame-relocs-x86_64.yaml created+176
......@@ -0,0 +1,176 @@
1# RUN: lld -flavor darwin -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s
2#
3# Test parsing of x86_64 __eh_frame (dwarf unwind) relocations.
4
5--- !mach-o
6arch: x86_64
7file-type: MH_OBJECT
8flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
9compat-version: 0.0
10current-version: 0.0
11has-UUID: false
12OS: unknown
13sections:
14 - segment: __TEXT
15 section: __text
16 type: S_REGULAR
17 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
18 alignment: 16
19 address: 0x0000000000000000
20 content: [ 0x55, 0x48, 0x89, 0xE5, 0xE8, 0x00, 0x00, 0x00,
21 0x00, 0x5D, 0xC3, 0x48, 0x89, 0xC7, 0xE8, 0x00,
22 0x00, 0x00, 0x00, 0x5D, 0xE9, 0x00, 0x00, 0x00,
23 0x00, 0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00,
24 0x55, 0x48, 0x89, 0xE5, 0x5D, 0xC3, 0x66, 0x2E,
25 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00,
26 0x55, 0x48, 0x89, 0xE5, 0xE8, 0x00, 0x00, 0x00,
27 0x00, 0x5D, 0xC3, 0x48, 0x89, 0xC7, 0xE8, 0x00,
28 0x00, 0x00, 0x00, 0x5D, 0xE9, 0x00, 0x00, 0x00,
29 0x00 ]
30 - segment: __TEXT
31 section: __gcc_except_tab
32 type: S_REGULAR
33 attributes: [ ]
34 alignment: 4
35 address: 0x000000000000004C
36 content: [ 0xFF, 0x9B, 0xA2, 0x80, 0x80, 0x00, 0x03, 0x1A,
37 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
38 0x0B, 0x00, 0x00, 0x00, 0x01, 0x09, 0x00, 0x00,
39 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
40 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
41 0xFF, 0x9B, 0xA2, 0x80, 0x80, 0x00, 0x03, 0x1A,
42 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
43 0x0B, 0x00, 0x00, 0x00, 0x01, 0x09, 0x00, 0x00,
44 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
45 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 ]
46 - segment: __TEXT
47 section: __eh_frame
48 type: S_COALESCED
49 attributes: [ ]
50 alignment: 8
51 address: 0x0000000000000100
52 content: [ 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53 0x03, 0x7A, 0x50, 0x4C, 0x52, 0x00, 0x01, 0x78,
54 0x10, 0x07, 0x9B, 0x04, 0x00, 0x00, 0x00, 0x10,
55 0x10, 0x0C, 0x07, 0x08, 0x90, 0x01, 0x00, 0x00,
56 0x2C, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00,
57 0xD8, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
58 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
59 0x08, 0x13, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
60 0xFF, 0x41, 0x0E, 0x10, 0x86, 0x02, 0x43, 0x0D,
61 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63 0x03, 0x7A, 0x52, 0x00, 0x01, 0x78, 0x10, 0x01,
64 0x10, 0x0C, 0x07, 0x08, 0x90, 0x01, 0x00, 0x00,
65 0x24, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00,
66 0xB0, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
67 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x00, 0x41, 0x0E, 0x10, 0x86, 0x02, 0x43, 0x0D,
69 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70 0x2C, 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00,
71 0x98, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
72 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
73 0x08, 0xCB, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
74 0xFF, 0x41, 0x0E, 0x10, 0x86, 0x02, 0x43, 0x0D,
75 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
76 relocations:
77 - offset: 0x00000013
78 type: X86_64_RELOC_GOT
79 length: 2
80 pc-rel: true
81 extern: true
82 symbol: 8
83local-symbols:
84 - name: GCC_except_table0
85 type: N_SECT
86 sect: 2
87 value: 0x000000000000004C
88 - name: GCC_except_table2
89 type: N_SECT
90 sect: 2
91 value: 0x0000000000000074
92global-symbols:
93 - name: _catchMyException1
94 type: N_SECT
95 scope: [ N_EXT ]
96 sect: 1
97 value: 0x0000000000000000
98 - name: _catchMyException2
99 type: N_SECT
100 scope: [ N_EXT ]
101 sect: 1
102 value: 0x0000000000000030
103 - name: _bar
104 type: N_SECT
105 scope: [ N_EXT ]
106 sect: 1
107 value: 0x0000000000000020
108undefined-symbols:
109 - name: _foo
110 type: N_UNDF
111 scope: [ N_EXT ]
112 value: 0x0000000000000000
113 - name: ___cxa_begin_catch
114 type: N_UNDF
115 scope: [ N_EXT ]
116 value: 0x0000000000000000
117 - name: ___cxa_end_catch
118 type: N_UNDF
119 scope: [ N_EXT ]
120 value: 0x0000000000000000
121 - name: ___gxx_personality_v0
122 type: N_UNDF
123 scope: [ N_EXT ]
124 value: 0x0000000000000000
125page-size: 0x00000000
126...
127
128# Check that LSDA fields are fixed up correctly, even when there are multiple
129# CIEs involved.
130#
131# (1) Check that we can relocate an LSDA at all. Requires correct interpretation
132# of augmentation data strings in CIEs and augmentation data fields of FDEs.
133#
134# CHECK: - type: unwind-cfi
135# CHECK-NOT: - type:
136# CHECK: references:
137# CHECK-NEXT: - kind: negDelta32
138# CHECK-NEXT: offset: 4
139# CHECK-NEXT: target: L002
140# CHECK-NEXT: - kind: unwindFDEToFunction
141# CHECK-NEXT: offset: 8
142# CHECK-NEXT: target: _catchMyException1
143# CHECK-NEXT: - kind: unwindFDEToFunction
144# CHECK-NEXT: offset: 25
145# CHECK-NEXT: target: GCC_except_table0
146#
147# (2) Check that we have an intervening FDE with a different CIE.
148# If the test fails here then test (3) probably isn't testing what it
149# should, and this test-case should be updated.
150#
151# CHECK: - type: unwind-cfi
152# CHECK-NOT: - type:
153# CHECK: references:
154# CHECK-NEXT: - kind: negDelta32
155# CHECK-NEXT: offset: 4
156# CHECK-NEXT: target: L001
157# CHECK-NEXT: - kind: unwindFDEToFunction
158# CHECK-NEXT: offset: 8
159# CHECK-NEXT: target: _bar
160#
161# (3) Check that we can relocate the LSDA on a second FDE that references the
162# original CIE from (1). Requires us to match this FDE up with the correct
163# CIE.
164#
165# CHECK-NEXT: - type: unwind-cfi
166# CHECK-NOT: - type:
167# CHECK: references:
168# CHECK-NEXT: - kind: negDelta32
169# CHECK-NEXT: offset: 4
170# CHECK-NEXT: target: L002
171# CHECK-NEXT: - kind: unwindFDEToFunction
172# CHECK-NEXT: offset: 8
173# CHECK-NEXT: target: _catchMyException2
174# CHECK-NEXT: - kind: unwindFDEToFunction
175# CHECK-NEXT: offset: 25
176# CHECK-NEXT: target: GCC_except_table2
deps/lld/test/mach-o/parse-eh-frame-x86-anon.yaml created+129
......@@ -0,0 +1,129 @@
1# RUN: lld -flavor darwin -arch i386 -r -print_atoms %s -o %t | FileCheck %s
2#
3# Test parsing of new __eh_frame (dwarf unwind) section that has no .eh labels
4# and no relocations.
5#
6
7--- !mach-o
8arch: x86
9file-type: MH_OBJECT
10flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
11OS: unknown
12sections:
13 - segment: __TEXT
14 section: __text
15 type: S_REGULAR
16 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
17 address: 0x0000000000000000
18 content: [ 0x55, 0x89, 0xE5, 0x56, 0x83, 0xEC, 0x14, 0xE8,
19 0x00, 0x00, 0x00, 0x00, 0x5E, 0xC7, 0x04, 0x24,
20 0x04, 0x00, 0x00, 0x00, 0xE8, 0xE7, 0xFF, 0xFF,
21 0xFF, 0xC7, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x8B,
22 0x8E, 0x38, 0x00, 0x00, 0x00, 0x89, 0x4C, 0x24,
23 0x04, 0x89, 0x04, 0x24, 0xC7, 0x44, 0x24, 0x08,
24 0x00, 0x00, 0x00, 0x00, 0xE8, 0xC7, 0xFF, 0xFF,
25 0xFF, 0x55, 0x89, 0xE5, 0x83, 0xEC, 0x08, 0xE8,
26 0xBC, 0xFF, 0xFF, 0xFF ]
27 relocations:
28 - offset: 0x00000040
29 type: GENERIC_RELOC_VANILLA
30 length: 2
31 pc-rel: true
32 extern: false
33 symbol: 1
34 - offset: 0x00000035
35 type: GENERIC_RELOC_VANILLA
36 length: 2
37 pc-rel: true
38 extern: true
39 symbol: 4
40 - offset: 0x00000021
41 scattered: true
42 type: GENERIC_RELOC_LOCAL_SECTDIFF
43 length: 2
44 pc-rel: false
45 value: 0x00000044
46 - offset: 0x00000000
47 scattered: true
48 type: GENERIC_RELOC_PAIR
49 length: 2
50 pc-rel: false
51 value: 0x0000000C
52 - offset: 0x00000015
53 type: GENERIC_RELOC_VANILLA
54 length: 2
55 pc-rel: true
56 extern: true
57 symbol: 3
58 - segment: __IMPORT
59 section: __pointers
60 type: S_NON_LAZY_SYMBOL_POINTERS
61 attributes: [ ]
62 address: 0x0000000000000044
63 content: [ 0x00, 0x00, 0x00, 0x00 ]
64 indirect-syms: [ 5 ]
65 - segment: __TEXT
66 section: __eh_frame
67 type: S_REGULAR
68 attributes: [ ]
69 alignment: 2
70 address: 0x0000000000000048
71 content: [ 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72 0x01, 0x7A, 0x52, 0x00, 0x01, 0x7C, 0x08, 0x01,
73 0x10, 0x0C, 0x05, 0x04, 0x88, 0x01, 0x00, 0x00,
74 0x18, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00,
75 0x98, 0xFF, 0xFF, 0xFF, 0x39, 0x00, 0x00, 0x00,
76 0x00, 0x41, 0x0E, 0x08, 0x84, 0x02, 0x42, 0x0D,
77 0x04, 0x44, 0x86, 0x03, 0x18, 0x00, 0x00, 0x00,
78 0x38, 0x00, 0x00, 0x00, 0xB5, 0xFF, 0xFF, 0xFF,
79 0x0B, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0E, 0x08,
80 0x84, 0x02, 0x42, 0x0D, 0x04, 0x00, 0x00, 0x00 ]
81global-symbols:
82 - name: __Z3barv
83 type: N_SECT
84 scope: [ N_EXT ]
85 sect: 1
86 value: 0x0000000000000039
87 - name: __Z3foov
88 type: N_SECT
89 scope: [ N_EXT ]
90 sect: 1
91 value: 0x0000000000000000
92undefined-symbols:
93 - name: __ZTIi
94 type: N_UNDF
95 scope: [ N_EXT ]
96 value: 0x0000000000000000
97 - name: ___cxa_allocate_exception
98 type: N_UNDF
99 scope: [ N_EXT ]
100 value: 0x0000000000000000
101 - name: ___cxa_throw
102 type: N_UNDF
103 scope: [ N_EXT ]
104 value: 0x0000000000000000
105...
106
107# CHECK: defined-atoms:
108# CHECK: - ref-name: [[CIE:L[L0-9]+]]
109# CHECK: type: unwind-cfi
110# CHECK: content:
111# CHECK: - type: unwind-cfi
112# CHECK: content:
113# CHECK: references:
114# CHECK: - kind: negDelta32
115# CHECK: offset: 4
116# CHECK: target: [[CIE]]
117# CHECK: - kind: delta32
118# CHECK: offset: 8
119# CHECK: target: __Z3foov
120# CHECK: - type: unwind-cfi
121# CHECK: content:
122# CHECK: references:
123# CHECK: - kind: negDelta32
124# CHECK: offset: 4
125# CHECK: target: [[CIE]]
126# CHECK: - kind: delta32
127# CHECK: offset: 8
128# CHECK: target: __Z3barv
129
deps/lld/test/mach-o/parse-eh-frame-x86-labeled.yaml created+193
......@@ -0,0 +1,193 @@
1# RUN: lld -flavor darwin -arch i386 -r -print_atoms %s -o %t | FileCheck %s
2#
3# Test parsing of old __eh_frame (dwarf unwind) section that has .eh labels
4# and relocations.
5#
6
7--- !mach-o
8arch: x86
9file-type: MH_OBJECT
10flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
11OS: unknown
12sections:
13 - segment: __TEXT
14 section: __text
15 type: S_REGULAR
16 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
17 address: 0x0000000000000000
18 content: [ 0x55, 0x89, 0xE5, 0x56, 0x83, 0xEC, 0x14, 0xE8,
19 0x00, 0x00, 0x00, 0x00, 0x5E, 0xC7, 0x04, 0x24,
20 0x04, 0x00, 0x00, 0x00, 0xE8, 0xE7, 0xFF, 0xFF,
21 0xFF, 0xC7, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x8B,
22 0x8E, 0x38, 0x00, 0x00, 0x00, 0x89, 0x4C, 0x24,
23 0x04, 0x89, 0x04, 0x24, 0xC7, 0x44, 0x24, 0x08,
24 0x00, 0x00, 0x00, 0x00, 0xE8, 0xC7, 0xFF, 0xFF,
25 0xFF, 0x55, 0x89, 0xE5, 0x83, 0xEC, 0x08, 0xE8,
26 0xBC, 0xFF, 0xFF, 0xFF ]
27 relocations:
28 - offset: 0x00000040
29 type: GENERIC_RELOC_VANILLA
30 length: 2
31 pc-rel: true
32 extern: false
33 symbol: 1
34 - offset: 0x00000035
35 type: GENERIC_RELOC_VANILLA
36 length: 2
37 pc-rel: true
38 extern: true
39 symbol: 7
40 - offset: 0x00000021
41 scattered: true
42 type: GENERIC_RELOC_LOCAL_SECTDIFF
43 length: 2
44 pc-rel: false
45 value: 0x00000044
46 - offset: 0x00000000
47 scattered: true
48 type: GENERIC_RELOC_PAIR
49 length: 2
50 pc-rel: false
51 value: 0x0000000C
52 - offset: 0x00000015
53 type: GENERIC_RELOC_VANILLA
54 length: 2
55 pc-rel: true
56 extern: true
57 symbol: 6
58 - segment: __IMPORT
59 section: __pointers
60 type: S_NON_LAZY_SYMBOL_POINTERS
61 attributes: [ ]
62 address: 0x0000000000000044
63 content: [ 0x00, 0x00, 0x00, 0x00 ]
64 indirect-syms: [ 5 ]
65 - segment: __TEXT
66 section: __eh_frame
67 type: S_REGULAR
68 attributes: [ ]
69 alignment: 2
70 address: 0x0000000000000048
71 content: [ 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72 0x01, 0x7A, 0x52, 0x00, 0x01, 0x7C, 0x08, 0x01,
73 0x10, 0x0C, 0x05, 0x04, 0x88, 0x01, 0x00, 0x00,
74 0x18, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00,
75 0x98, 0xFF, 0xFF, 0xFF, 0x39, 0x00, 0x00, 0x00,
76 0x00, 0x41, 0x0E, 0x08, 0x84, 0x02, 0x42, 0x0D,
77 0x04, 0x44, 0x86, 0x03, 0x18, 0x00, 0x00, 0x00,
78 0x38, 0x00, 0x00, 0x00, 0xB5, 0xFF, 0xFF, 0xFF,
79 0x0B, 0x00, 0x00, 0x00, 0x00, 0x41, 0x0E, 0x08,
80 0x84, 0x02, 0x42, 0x0D, 0x04, 0x00, 0x00, 0x00 ]
81 relocations:
82 - offset: 0x0000001C
83 scattered: true
84 type: GENERIC_RELOC_LOCAL_SECTDIFF
85 length: 2
86 pc-rel: false
87 value: 0x00000064
88 - offset: 0x00000000
89 scattered: true
90 type: GENERIC_RELOC_PAIR
91 length: 2
92 pc-rel: false
93 value: 0x00000048
94 - offset: 0x00000020
95 scattered: true
96 type: GENERIC_RELOC_SECTDIFF
97 length: 2
98 pc-rel: false
99 value: 0x00000000
100 - offset: 0x00000000
101 scattered: true
102 type: GENERIC_RELOC_PAIR
103 length: 2
104 pc-rel: false
105 value: 0x00000068
106 - offset: 0x00000038
107 scattered: true
108 type: GENERIC_RELOC_LOCAL_SECTDIFF
109 length: 2
110 pc-rel: false
111 value: 0x00000080
112 - offset: 0x00000000
113 scattered: true
114 type: GENERIC_RELOC_PAIR
115 length: 2
116 pc-rel: false
117 value: 0x00000048
118 - offset: 0x0000003C
119 scattered: true
120 type: GENERIC_RELOC_SECTDIFF
121 length: 2
122 pc-rel: false
123 value: 0x00000039
124 - offset: 0x00000000
125 scattered: true
126 type: GENERIC_RELOC_PAIR
127 length: 2
128 pc-rel: false
129 value: 0x00000084
130local-symbols:
131 - name: EH_frame0
132 type: N_SECT
133 sect: 3
134 value: 0x0000000000000048
135global-symbols:
136 - name: __Z3barv
137 type: N_SECT
138 scope: [ N_EXT ]
139 sect: 1
140 value: 0x0000000000000039
141 - name: __Z3barv.eh
142 type: N_SECT
143 scope: [ N_EXT ]
144 sect: 3
145 value: 0x000000000000007C
146 - name: __Z3foov
147 type: N_SECT
148 scope: [ N_EXT ]
149 sect: 1
150 value: 0x0000000000000000
151 - name: __Z3foov.eh
152 type: N_SECT
153 scope: [ N_EXT ]
154 sect: 3
155 value: 0x0000000000000060
156undefined-symbols:
157 - name: __ZTIi
158 type: N_UNDF
159 scope: [ N_EXT ]
160 value: 0x0000000000000000
161 - name: ___cxa_allocate_exception
162 type: N_UNDF
163 scope: [ N_EXT ]
164 value: 0x0000000000000000
165 - name: ___cxa_throw
166 type: N_UNDF
167 scope: [ N_EXT ]
168 value: 0x0000000000000000
169...
170
171# CHECK: defined-atoms:
172# CHECK: - ref-name: [[CIE:L[L0-9]+]]
173# CHECK: type: unwind-cfi
174# CHECK: content:
175# CHECK: - type: unwind-cfi
176# CHECK: content:
177# CHECK: references:
178# CHECK: - kind: negDelta32
179# CHECK: offset: 4
180# CHECK: target: [[CIE]]
181# CHECK: - kind: delta32
182# CHECK: offset: 8
183# CHECK: target: __Z3foov
184# CHECK: - type: unwind-cfi
185# CHECK: content:
186# CHECK: references:
187# CHECK: - kind: negDelta32
188# CHECK: offset: 4
189# CHECK: target: [[CIE]]
190# CHECK: - kind: delta32
191# CHECK: offset: 8
192# CHECK: target: __Z3barv
193
deps/lld/test/mach-o/parse-eh-frame.yaml created+88
......@@ -0,0 +1,88 @@
1# RUN: lld -flavor darwin -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s
2#
3# Test parsing of __eh_frame (dwarf unwind) section.
4#
5
6--- !mach-o
7arch: x86_64
8file-type: MH_OBJECT
9flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
10has-UUID: false
11OS: unknown
12sections:
13 - segment: __TEXT
14 section: __text
15 type: S_REGULAR
16 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
17 address: 0x0000000000000000
18 content: [ 0x55, 0x48, 0x89, 0xE5, 0xB8, 0x09, 0x00, 0x00,
19 0x00, 0x5D, 0xC3, 0x55, 0x48, 0x89, 0xE5, 0xB8,
20 0x0A, 0x00, 0x00, 0x00, 0x5D, 0xC3 ]
21 - segment: __TEXT
22 section: __eh_frame
23 type: S_COALESCED
24 attributes: [ ]
25 alignment: 8
26 address: 0x0000000000000058
27 content: [ 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
28 0x01, 0x7A, 0x52, 0x00, 0x01, 0x78, 0x10, 0x01,
29 0x10, 0x0C, 0x07, 0x08, 0x90, 0x01, 0x00, 0x00,
30 0x24, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00,
31 0x88, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
32 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
33 0x00, 0x41, 0x0E, 0x10, 0x86, 0x02, 0x43, 0x0D,
34 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
35 0x24, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00,
36 0x6B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
37 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
38 0x00, 0x41, 0x0E, 0x10, 0x86, 0x02, 0x43, 0x0D,
39 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
40global-symbols:
41 - name: __Z3barv
42 type: N_SECT
43 scope: [ N_EXT ]
44 sect: 1
45 value: 0x0000000000000000
46 - name: __Z3foov
47 type: N_SECT
48 scope: [ N_EXT ]
49 sect: 1
50 value: 0x000000000000000B
51...
52
53# CHECK: defined-atoms:
54# CHECK: - ref-name: [[CIE:L[0-9]+]]
55# CHECK: type: unwind-cfi
56# CHECK: content: [ 14, 00, 00, 00, 00, 00, 00, 00, 01, 7A, 52, 00,
57# CHECK: 01, 78, 10, 01, 10, 0C, 07, 08, 90, 01, 00, 00 ]
58# CHECK: - type: unwind-cfi
59# CHECK: content: [ 24, 00, 00, 00, 1C, 00, 00, 00, 88, FF, FF, FF,
60# CHECK: FF, FF, FF, FF, 0B, 00, 00, 00, 00, 00, 00, 00,
61# CHECK: 00, 41, 0E, 10, 86, 02, 43, 0D, 06, 00, 00, 00,
62# CHECK: 00, 00, 00, 00 ]
63# CHECK: references:
64# CHECK: - kind: negDelta32
65# CHECK: offset: 4
66# CHECK: target: [[CIE]]
67# CHECK: - kind: unwindFDEToFunction
68# CHECK: offset: 8
69# CHECK: target: __Z3barv
70# CHECK: - type: unwind-cfi
71# CHECK: content: [ 24, 00, 00, 00, 44, 00, 00, 00, 6B, FF, FF, FF,
72# CHECK: FF, FF, FF, FF, 0B, 00, 00, 00, 00, 00, 00, 00,
73# CHECK: 00, 41, 0E, 10, 86, 02, 43, 0D, 06, 00, 00, 00,
74# CHECK: 00, 00, 00, 00 ]
75# CHECK: references:
76# CHECK: - kind: negDelta32
77# CHECK: offset: 4
78# CHECK: target: [[CIE]]
79# CHECK: - kind: unwindFDEToFunction
80# CHECK: offset: 8
81# CHECK: target: __Z3foov
82# CHECK: - name: __Z3barv
83# CHECK: scope: global
84# CHECK: content: [ 55, 48, 89, E5, B8, 09, 00, 00, 00, 5D, C3 ]
85# CHECK: - name: __Z3foov
86# CHECK: scope: global
87# CHECK: content: [ 55, 48, 89, E5, B8, 0A, 00, 00, 00, 5D, C3 ]
88
deps/lld/test/mach-o/parse-function.yaml created+100
......@@ -0,0 +1,100 @@
1# RUN: lld -flavor darwin -arch x86_64 -r %s -o %t
2# RUN: lld -flavor darwin -arch x86_64 -r %t -print_atoms -o %t2 | FileCheck %s
3#
4# Test parsing of mach-o functions.
5#
6
7--- !mach-o
8arch: x86_64
9file-type: MH_OBJECT
10flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
11has-UUID: false
12OS: unknown
13sections:
14 - segment: __TEXT
15 section: __text
16 type: S_REGULAR
17 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
18 alignment: 4
19 address: 0x0000000000000000
20 content: [ 0xCC, 0xC3, 0x90, 0xC3, 0x90, 0x90, 0xC3, 0x90,
21 0x90, 0x90, 0xC3, 0x90, 0x90, 0x90, 0x90, 0xC3,
22 0xCC, 0x31, 0xC0, 0xC3 ]
23local-symbols:
24 - name: _myStatic
25 type: N_SECT
26 sect: 1
27 value: 0x000000000000000B
28global-symbols:
29 - name: _myGlobal
30 type: N_SECT
31 scope: [ N_EXT ]
32 sect: 1
33 value: 0x0000000000000001
34 - name: _myGlobalWeak
35 type: N_SECT
36 scope: [ N_EXT ]
37 sect: 1
38 desc: [ N_WEAK_DEF ]
39 value: 0x0000000000000002
40 - name: _myHidden
41 type: N_SECT
42 scope: [ N_EXT, N_PEXT ]
43 sect: 1
44 value: 0x0000000000000004
45 - name: _myHiddenWeak
46 type: N_SECT
47 scope: [ N_EXT, N_PEXT ]
48 sect: 1
49 desc: [ N_WEAK_DEF ]
50 value: 0x0000000000000007
51 - name: _myStripNot
52 type: N_SECT
53 scope: [ N_EXT ]
54 sect: 1
55 desc: [ N_NO_DEAD_STRIP ]
56 value: 0x0000000000000010
57 - name: _myResolver
58 type: N_SECT
59 scope: [ N_EXT ]
60 sect: 1
61 desc: [ N_SYMBOL_RESOLVER ]
62 value: 0x0000000000000011
63...
64
65# CHECK-NOT: name:
66# CHECK: content: [ CC ]
67
68# CHECK: name: _myGlobal
69# CHECK: scope: global
70# CHECK: content: [ C3 ]
71
72# CHECK: name: _myGlobalWeak
73# CHECK: scope: global
74# CHECK: content: [ 90, C3 ]
75# CHECK: merge: as-weak
76
77# CHECK: name: _myHidden
78# CHECK: scope: hidden
79# CHECK: content: [ 90, 90, C3 ]
80
81# CHECK: name: _myHiddenWeak
82# CHECK: scope: hidden
83# CHECK: content: [ 90, 90, 90, C3 ]
84# CHECK: merge: as-weak
85
86# CHECK: name: _myStatic
87# CHECK-NOT: scope: global
88# CHECK-NOT: scope: hidden
89# CHECK: content: [ 90, 90, 90, 90, C3 ]
90
91# CHECK: name: _myStripNot
92# CHECK: scope: global
93# CHECK: content: [ CC ]
94# CHECK: dead-strip: never
95
96# CHECK: name: _myResolver
97# CHECK: scope: global
98# CHECK: type: resolver
99# CHECK: content: [ 31, C0, C3 ]
100
deps/lld/test/mach-o/parse-initializers32.yaml created+84
......@@ -0,0 +1,84 @@
1# RUN: lld -flavor darwin -arch i386 -r -print_atoms %s -o %t | FileCheck %s
2#
3# Test parsing of literal sections.
4#
5
6--- !mach-o
7arch: x86
8file-type: MH_OBJECT
9flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
10has-UUID: false
11OS: unknown
12sections:
13 - segment: __TEXT
14 section: __text
15 type: S_REGULAR
16 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
17 address: 0x0000000000000000
18 content: [ 0x55, 0x89, 0xE5, 0x5D, 0xC3, 0x55, 0x89, 0xE5,
19 0x5D, 0xC3, 0x55, 0x89, 0xE5, 0x5D, 0xC3 ]
20 - segment: __DATA
21 section: __mod_init_func
22 type: S_MOD_INIT_FUNC_POINTERS
23 attributes: [ ]
24 alignment: 2
25 address: 0x0000000000000044
26 content: [ 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00 ]
27 relocations:
28 - offset: 0x00000000
29 type: GENERIC_RELOC_VANILLA
30 length: 2
31 pc-rel: false
32 extern: false
33 symbol: 1
34 - offset: 0x00000004
35 type: GENERIC_RELOC_VANILLA
36 length: 2
37 pc-rel: false
38 extern: false
39 symbol: 1
40 - segment: __DATA
41 section: __mod_term_func
42 type: S_MOD_TERM_FUNC_POINTERS
43 attributes: [ ]
44 alignment: 2
45 address: 0x0000000000000104
46 content: [ 0x0A, 0x00, 0x00, 0x00 ]
47global-symbols:
48 - name: _init
49 type: N_SECT
50 scope: [ N_EXT ]
51 sect: 1
52 value: 0x0000000000000000
53 - name: _init2
54 type: N_SECT
55 scope: [ N_EXT ]
56 sect: 1
57 value: 0x0000000000000005
58 - name: _term
59 type: N_SECT
60 scope: [ N_EXT ]
61 sect: 1
62 value: 0x000000000000000A
63...
64
65
66# CHECK:defined-atoms:
67# CHECK: - type: initializer-pointer
68# CHECK: content: [ 00, 00, 00, 00 ]
69# CHECK: dead-strip: never
70# CHECK: - type: initializer-pointer
71# CHECK: content: [ 05, 00, 00, 00 ]
72# CHECK: dead-strip: never
73# CHECK: - type: terminator-pointer
74# CHECK: content: [ 0A, 00, 00, 00 ]
75# CHECK: dead-strip: never
76# CHECK: - name: _init
77# CHECK: scope: global
78# CHECK: content: [ 55, 89, E5, 5D, C3 ]
79# CHECK: - name: _init2
80# CHECK: scope: global
81# CHECK: content: [ 55, 89, E5, 5D, C3 ]
82# CHECK: - name: _term
83# CHECK: scope: global
84# CHECK: content: [ 55, 89, E5, 5D, C3 ]
deps/lld/test/mach-o/parse-initializers64.yaml created+105
......@@ -0,0 +1,105 @@
1# RUN: lld -flavor darwin -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s
2#
3# Test parsing of literal sections.
4#
5
6--- !mach-o
7arch: x86_64
8file-type: MH_OBJECT
9flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
10has-UUID: false
11OS: unknown
12sections:
13 - segment: __TEXT
14 section: __text
15 type: S_REGULAR
16 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
17 address: 0x0000000000000000
18 content: [ 0x55, 0x48, 0x89, 0xE5, 0x5D, 0xC3, 0x55, 0x48,
19 0x89, 0xE5, 0x5D, 0xC3, 0x55, 0x48, 0x89, 0xE5,
20 0x5D, 0xC3 ]
21 - segment: __DATA
22 section: __mod_init_func
23 type: S_MOD_INIT_FUNC_POINTERS
24 attributes: [ ]
25 alignment: 1
26 address: 0x0000000000000100
27 content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
28 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
29 relocations:
30 - offset: 0x00000000
31 type: X86_64_RELOC_UNSIGNED
32 length: 3
33 pc-rel: false
34 extern: true
35 symbol: 0
36 - offset: 0x00000008
37 type: X86_64_RELOC_UNSIGNED
38 length: 3
39 pc-rel: false
40 extern: true
41 symbol: 1
42 - segment: __DATA
43 section: __mod_term_func
44 type: S_MOD_TERM_FUNC_POINTERS
45 attributes: [ ]
46 alignment: 8
47 address: 0x0000000000000108
48 content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
49 relocations:
50 - offset: 0x00000000
51 type: X86_64_RELOC_UNSIGNED
52 length: 3
53 pc-rel: false
54 extern: true
55 symbol: 2
56global-symbols:
57 - name: _init
58 type: N_SECT
59 scope: [ N_EXT ]
60 sect: 1
61 value: 0x0000000000000000
62 - name: _init2
63 type: N_SECT
64 scope: [ N_EXT ]
65 sect: 1
66 value: 0x0000000000000006
67 - name: _term
68 type: N_SECT
69 scope: [ N_EXT ]
70 sect: 1
71 value: 0x000000000000000C
72...
73
74
75# CHECK:defined-atoms:
76# CHECK: - type: initializer-pointer
77# CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ]
78# CHECK: dead-strip: never
79# CHECK: references:
80# CHECK: - kind: pointer64
81# CHECK: offset: 0
82# CHECK: target: _init
83# CHECK: - type: initializer-pointer
84# CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ]
85# CHECK: dead-strip: never
86# CHECK: references:
87# CHECK: - kind: pointer64
88# CHECK: offset: 0
89# CHECK: target: _init2
90# CHECK: - type: terminator-pointer
91# CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ]
92# CHECK: dead-strip: never
93# CHECK: references:
94# CHECK: - kind: pointer64
95# CHECK: offset: 0
96# CHECK: target: _term
97# CHECK: - name: _init
98# CHECK: scope: global
99# CHECK: content: [ 55, 48, 89, E5, 5D, C3 ]
100# CHECK: - name: _init2
101# CHECK: scope: global
102# CHECK: content: [ 55, 48, 89, E5, 5D, C3 ]
103# CHECK: - name: _term
104# CHECK: scope: global
105# CHECK: content: [ 55, 48, 89, E5, 5D, C3 ]
deps/lld/test/mach-o/parse-literals-error.yaml created+25
......@@ -0,0 +1,25 @@
1# RUN: not lld -flavor darwin -arch x86_64 -r -print_atoms %s -o %t 2> %t.err
2# RUN: FileCheck %s < %t.err
3#
4# Test for error if literal section is not correct size mulitple.
5#
6
7--- !mach-o
8arch: x86_64
9file-type: MH_OBJECT
10flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
11has-UUID: false
12OS: unknown
13sections:
14 - segment: __TEXT
15 section: __literal8
16 type: S_8BYTE_LITERALS
17 attributes: [ ]
18 alignment: 0
19 address: 0x0000000000000120
20 content: [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
21 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D ]
22...
23
24# CHECK: error:
25
deps/lld/test/mach-o/parse-literals.yaml created+93
......@@ -0,0 +1,93 @@
1# RUN: lld -flavor darwin -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s
2#
3# Test parsing of literal sections.
4#
5
6--- !mach-o
7arch: x86_64
8file-type: MH_OBJECT
9flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
10has-UUID: false
11OS: unknown
12sections:
13 - segment: __TEXT
14 section: __cstring
15 type: S_CSTRING_LITERALS
16 attributes: [ ]
17 alignment: 1
18 address: 0x0000000000000100
19 content: [ 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x00, 0x74, 0x68,
20 0x65, 0x72, 0x65, 0x00, 0x77, 0x6F, 0x72, 0x6C,
21 0x00 ]
22 - segment: __TEXT
23 section: __literal4
24 type: S_4BYTE_LITERALS
25 attributes: [ ]
26 alignment: 1
27 address: 0x0000000000000114
28 content: [ 0x01, 0x02, 0x03, 0x04, 0x11, 0x12, 0x13, 0x14,
29 0x28, 0x29, 0x2A, 0x2B ]
30 - segment: __TEXT
31 section: __literal8
32 type: S_8BYTE_LITERALS
33 attributes: [ ]
34 alignment: 1
35 address: 0x0000000000000120
36 content: [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
37 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F ]
38 - segment: __TEXT
39 section: __literal16
40 type: S_16BYTE_LITERALS
41 attributes: [ ]
42 alignment: 1
43 address: 0x0000000000000130
44 content: [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
45 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x00 ]
46 - segment: __TEXT
47 section: __ustring
48 type: S_REGULAR
49 attributes: [ ]
50 alignment: 1
51 address: 0x0000000000000100
52 content: [ 0x68, 0x00, 0x65, 0x00, 0x6C, 0x00, 0x6C, 0x00,
53 0x6F, 0x00, 0x00, 0x00, 0x74, 0x00, 0x68, 0x00,
54 0x65, 0x00, 0x72, 0x00, 0x00, 0x00 ]
55...
56
57
58# CHECK:defined-atoms:
59# CHECK: - scope: hidden
60# CHECK: type: c-string
61# CHECK: content: [ 68, 65, 6C, 6C, 6F, 00 ]
62# CHECK: - scope: hidden
63# CHECK: type: c-string
64# CHECK: content: [ 74, 68, 65, 72, 65, 00 ]
65# CHECK: - scope: hidden
66# CHECK: type: c-string
67# CHECK: content: [ 77, 6F, 72, 6C, 00 ]
68# CHECK: - scope: hidden
69# CHECK: type: utf16-string
70# CHECK: content: [ 68, 00, 65, 00, 6C, 00, 6C, 00, 6F, 00, 00, 00 ]
71# CHECK: - scope: hidden
72# CHECK: type: utf16-string
73# CHECK: content: [ 74, 00, 68, 00, 65, 00, 72, 00, 00, 00 ]
74# CHECK: - scope: hidden
75# CHECK: type: const-4-byte
76# CHECK: content: [ 01, 02, 03, 04 ]
77# CHECK: - scope: hidden
78# CHECK: type: const-4-byte
79# CHECK: content: [ 11, 12, 13, 14 ]
80# CHECK: - scope: hidden
81# CHECK: type: const-4-byte
82# CHECK: content: [ 28, 29, 2A, 2B ]
83# CHECK: - scope: hidden
84# CHECK: type: const-8-byte
85# CHECK: content: [ 01, 02, 03, 04, 05, 06, 07, 08 ]
86# CHECK: - scope: hidden
87# CHECK: type: const-8-byte
88# CHECK: content: [ 28, 29, 2A, 2B, 2C, 2D, 2E, 2F ]
89# CHECK: - scope: hidden
90# CHECK: type: const-16-byte
91# CHECK: content: [ 01, 02, 03, 04, 05, 06, 07, 08, 09, 0A, 0B, 0C,
92# CHECK: 0D, 0E, 0F, 00 ]
93
deps/lld/test/mach-o/parse-non-lazy-pointers.yaml created+98
......@@ -0,0 +1,98 @@
1# RUN: lld -flavor darwin -arch i386 -r -print_atoms %s -o %t | FileCheck %s
2#
3# Test parsing of non-lazy-pointer sections.
4#
5
6--- !mach-o
7arch: x86
8file-type: MH_OBJECT
9flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
10has-UUID: false
11OS: unknown
12sections:
13 - segment: __TEXT
14 section: __text
15 type: S_REGULAR
16 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
17 address: 0x0000000000000000
18 content: [ 0x55, 0x89, 0xE5, 0xE8, 0x00, 0x00, 0x00, 0x00,
19 0x59, 0x8D, 0x81, 0x14, 0x00, 0x00, 0x00, 0x8D,
20 0x81, 0x18, 0x00, 0x00, 0x00, 0x5D, 0xC3, 0x55,
21 0x89, 0xE5, 0x5D, 0xC3 ]
22 relocations:
23 - offset: 0x00000011
24 scattered: true
25 type: GENERIC_RELOC_LOCAL_SECTDIFF
26 length: 2
27 pc-rel: false
28 value: 0x00000020
29 - offset: 0x00000000
30 scattered: true
31 type: GENERIC_RELOC_PAIR
32 length: 2
33 pc-rel: false
34 value: 0x00000008
35 - offset: 0x0000000B
36 scattered: true
37 type: GENERIC_RELOC_LOCAL_SECTDIFF
38 length: 2
39 pc-rel: false
40 value: 0x0000001C
41 - offset: 0x00000000
42 scattered: true
43 type: GENERIC_RELOC_PAIR
44 length: 2
45 pc-rel: false
46 value: 0x00000008
47 - segment: __IMPORT
48 section: __pointers
49 type: S_NON_LAZY_SYMBOL_POINTERS
50 attributes: [ ]
51 address: 0x000000000000001C
52 content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
53 indirect-syms: [ 2, 2147483648 ]
54local-symbols:
55 - name: _foo
56 type: N_SECT
57 sect: 1
58 value: 0x0000000000000017
59global-symbols:
60 - name: _get
61 type: N_SECT
62 scope: [ N_EXT ]
63 sect: 1
64 value: 0x0000000000000000
65undefined-symbols:
66 - name: _bar
67 type: N_UNDF
68 scope: [ N_EXT ]
69 value: 0x0000000000000000
70...
71
72
73# CHECK:defined-atoms:
74# CHECK: - ref-name: [[GOT1:L[L0-9]+]]
75# CHECK: scope: hidden
76# CHECK: type: got
77# CHECK: content: [ 00, 00, 00, 00 ]
78# CHECK: merge: by-content
79# CHECK: - ref-name: [[GOT2:L[L0-9]+]]
80# CHECK: scope: hidden
81# CHECK: type: got
82# CHECK: content: [ 00, 00, 00, 00 ]
83# CHECK: merge: by-content
84# CHECK: - name: _get
85# CHECK: scope: global
86# CHECK: content: [ 55, 89, E5, E8, 00, 00, 00, 00, 59, 8D, 81, 14,
87# CHECK: 00, 00, 00, 8D, 81, 18, 00, 00, 00, 5D, C3 ]
88# CHECK: references:
89# CHECK: - kind: funcRel32
90# CHECK: offset: 11
91# CHECK: target: [[GOT1]]
92# CHECK: - kind: funcRel32
93# CHECK: offset: 17
94# CHECK: target: [[GOT2]]
95# CHECK: - name: _foo
96# CHECK: content: [ 55, 89, E5, 5D, C3 ]
97
98
deps/lld/test/mach-o/parse-relocs-x86.yaml created+296
......@@ -0,0 +1,296 @@
1# RUN: lld -flavor darwin -arch i386 -r -print_atoms %s -o %t | FileCheck %s \
2# RUN: && lld -flavor darwin -arch i386 -r -print_atoms %t -o %t2 | FileCheck %s
3#
4# Test parsing and writing of x86 relocations.
5#
6# The first step tests if the supplied mach-o file is parsed into the correct
7# set of references. The second step verifies relocations can be round-tripped
8# by writing to a new .o file, then parsing that file which should result in
9# the same references.
10#
11# .text
12#_test:
13# call _undef
14# call _undef+2
15# call _foo
16# call _foo+2
17# callw _undef
18# callw _foo
19# callw _foo+2
20#L1:
21# movl _undef, %eax
22# movl _x, %eax
23# movl _x+4, %eax
24# movl _x-L1(%eax), %eax
25# movl _x+4-L1(%eax), %eax
26#
27#_foo:
28# ret
29#
30# .data
31#_x:
32# .long _undef
33# .long _undef+7
34# .long _foo
35# .long _foo+3
36# .long _test - .
37# .long _test+3 - .
38#
39
40--- !mach-o
41arch: x86
42file-type: MH_OBJECT
43flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
44OS: unknown
45sections:
46 - segment: __TEXT
47 section: __text
48 type: S_REGULAR
49 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
50 address: 0x0000000000000000
51 content: [ 0xE8, 0xFB, 0xFF, 0xFF, 0xFF, 0xE8, 0xF8, 0xFF,
52 0xFF, 0xFF, 0xE8, 0x2C, 0x00, 0x00, 0x00, 0xE8,
53 0x29, 0x00, 0x00, 0x00, 0x66, 0xE8, 0xE8, 0xFF,
54 0x66, 0xE8, 0x1F, 0x00, 0x66, 0xE8, 0x1D, 0x00,
55 0xA1, 0x00, 0x00, 0x00, 0x00, 0xA1, 0x3C, 0x00,
56 0x00, 0x00, 0xA1, 0x40, 0x00, 0x00, 0x00, 0x8B,
57 0x80, 0x1C, 0x00, 0x00, 0x00, 0x8B, 0x80, 0x20,
58 0x00, 0x00, 0x00, 0xC3 ]
59 relocations:
60 - offset: 0x00000037
61 scattered: true
62 type: GENERIC_RELOC_LOCAL_SECTDIFF
63 length: 2
64 pc-rel: false
65 value: 0x0000003C
66 - offset: 0x00000000
67 scattered: true
68 type: GENERIC_RELOC_PAIR
69 length: 2
70 pc-rel: false
71 value: 0x00000020
72 - offset: 0x00000031
73 scattered: true
74 type: GENERIC_RELOC_LOCAL_SECTDIFF
75 length: 2
76 pc-rel: false
77 value: 0x0000003C
78 - offset: 0x00000000
79 scattered: true
80 type: GENERIC_RELOC_PAIR
81 length: 2
82 pc-rel: false
83 value: 0x00000020
84 - offset: 0x0000002B
85 scattered: true
86 type: GENERIC_RELOC_VANILLA
87 length: 2
88 pc-rel: false
89 value: 0x0000003C
90 - offset: 0x00000026
91 type: GENERIC_RELOC_VANILLA
92 length: 2
93 pc-rel: false
94 extern: false
95 symbol: 2
96 - offset: 0x00000021
97 type: GENERIC_RELOC_VANILLA
98 length: 2
99 pc-rel: false
100 extern: true
101 symbol: 3
102 - offset: 0x0000001E
103 scattered: true
104 type: GENERIC_RELOC_VANILLA
105 length: 1
106 pc-rel: true
107 value: 0x0000003B
108 - offset: 0x0000001A
109 type: GENERIC_RELOC_VANILLA
110 length: 1
111 pc-rel: true
112 extern: false
113 symbol: 1
114 - offset: 0x00000016
115 type: GENERIC_RELOC_VANILLA
116 length: 1
117 pc-rel: true
118 extern: true
119 symbol: 3
120 - offset: 0x00000010
121 scattered: true
122 type: GENERIC_RELOC_VANILLA
123 length: 2
124 pc-rel: true
125 value: 0x0000003B
126 - offset: 0x0000000B
127 type: GENERIC_RELOC_VANILLA
128 length: 2
129 pc-rel: true
130 extern: false
131 symbol: 1
132 - offset: 0x00000006
133 type: GENERIC_RELOC_VANILLA
134 length: 2
135 pc-rel: true
136 extern: true
137 symbol: 3
138 - offset: 0x00000001
139 type: GENERIC_RELOC_VANILLA
140 length: 2
141 pc-rel: true
142 extern: true
143 symbol: 3
144 - segment: __DATA
145 section: __data
146 type: S_REGULAR
147 attributes: [ ]
148 address: 0x000000000000003C
149 content: [ 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
150 0x3B, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00,
151 0xB4, 0xFF, 0xFF, 0xFF, 0xB3, 0xFF, 0xFF, 0xFF ]
152 relocations:
153 - offset: 0x00000014
154 scattered: true
155 type: GENERIC_RELOC_LOCAL_SECTDIFF
156 length: 2
157 pc-rel: false
158 value: 0x00000000
159 - offset: 0x00000000
160 scattered: true
161 type: GENERIC_RELOC_PAIR
162 length: 2
163 pc-rel: false
164 value: 0x00000050
165 - offset: 0x00000010
166 scattered: true
167 type: GENERIC_RELOC_LOCAL_SECTDIFF
168 length: 2
169 pc-rel: false
170 value: 0x00000000
171 - offset: 0x00000000
172 scattered: true
173 type: GENERIC_RELOC_PAIR
174 length: 2
175 pc-rel: false
176 value: 0x0000004C
177 - offset: 0x0000000C
178 scattered: true
179 type: GENERIC_RELOC_VANILLA
180 length: 2
181 pc-rel: false
182 value: 0x0000003B
183 - offset: 0x00000008
184 type: GENERIC_RELOC_VANILLA
185 length: 2
186 pc-rel: false
187 extern: false
188 symbol: 1
189 - offset: 0x00000004
190 type: GENERIC_RELOC_VANILLA
191 length: 2
192 pc-rel: false
193 extern: true
194 symbol: 3
195 - offset: 0x00000000
196 type: GENERIC_RELOC_VANILLA
197 length: 2
198 pc-rel: false
199 extern: true
200 symbol: 3
201local-symbols:
202 - name: _test
203 type: N_SECT
204 sect: 1
205 value: 0x0000000000000000
206 - name: _foo
207 type: N_SECT
208 sect: 1
209 value: 0x000000000000003B
210 - name: _x
211 type: N_SECT
212 sect: 2
213 value: 0x000000000000003C
214undefined-symbols:
215 - name: _undef
216 type: N_UNDF
217 scope: [ N_EXT ]
218 value: 0x0000000000000000
219...
220
221# CHECK: defined-atoms:
222# CHECK: - name: _x
223# CHECK: type: data
224# CHECK: references:
225# CHECK: - kind: pointer32
226# CHECK: offset: 0
227# CHECK: target: _undef
228# CHECK-NOT: addend:
229# CHECK: - kind: pointer32
230# CHECK: offset: 4
231# CHECK: target: _undef
232# CHECK: addend: 7
233# CHECK: - kind: pointer32
234# CHECK: offset: 8
235# CHECK: target: _foo
236# CHECK-NOT: addend:
237# CHECK: - kind: pointer32
238# CHECK: offset: 12
239# CHECK: target: _foo
240# CHECK: addend: 3
241# CHECK: - kind: delta32
242# CHECK: offset: 16
243# CHECK: target: _test
244# CHECK: - kind: delta32
245# CHECK: offset: 20
246# CHECK: target: _test
247# CHECK: addend: 3
248# CHECK: - name: _test
249# CHECK: references:
250# CHECK: - kind: branch32
251# CHECK: offset: 1
252# CHECK: target: _undef
253# CHECK-NOT: addend:
254# CHECK: - kind: branch32
255# CHECK: offset: 6
256# CHECK: target: _undef
257# CHECK: addend: 2
258# CHECK: - kind: branch32
259# CHECK: offset: 11
260# CHECK: target: _foo
261# CHECK-NOT: addend:
262# CHECK: - kind: branch32
263# CHECK: offset: 16
264# CHECK: target: _foo
265# CHECK: addend: 2
266# CHECK: - kind: branch16
267# CHECK: offset: 22
268# CHECK: target: _undef
269# CHECK-NOT: addend:
270# CHECK: - kind: branch16
271# CHECK: offset: 26
272# CHECK: target: _foo
273# CHECK-NOT: addend:
274# CHECK: - kind: branch16
275# CHECK: offset: 30
276# CHECK: target: _foo
277# CHECK: addend: 2
278# CHECK: - kind: abs32
279# CHECK: offset: 33
280# CHECK: target: _undef
281# CHECK: - kind: abs32
282# CHECK: offset: 38
283# CHECK: target: _x
284# CHECK: - kind: abs32
285# CHECK: offset: 43
286# CHECK: target: _x
287# CHECK: addend: 4
288# CHECK: - kind: funcRel32
289# CHECK: offset: 49
290# CHECK: target: _x
291# CHECK: addend: -32
292# CHECK: - kind: funcRel32
293# CHECK: offset: 55
294# CHECK: target: _x
295# CHECK: addend: -28
296
deps/lld/test/mach-o/parse-section-no-symbol.yaml created+23
......@@ -0,0 +1,23 @@
1# RUN: lld -flavor darwin -arch x86_64 -r %s -print_atoms -o %t2 | FileCheck %s
2#
3# Test parsing of mach-o functions with no symbols at all.
4#
5
6--- !mach-o
7arch: x86_64
8file-type: MH_OBJECT
9flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
10has-UUID: false
11OS: unknown
12sections:
13 - segment: __TEXT
14 section: __text
15 type: S_REGULAR
16 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
17 alignment: 4
18 address: 0x0000000000000000
19 content: [ 0xCC ]
20...
21
22# CHECK-NOT: name:
23# CHECK: content: [ CC ]
deps/lld/test/mach-o/parse-tentative-defs.yaml created+88
......@@ -0,0 +1,88 @@
1# RUN: lld -flavor darwin -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s
2#
3# Test parsing of tentative definitions, including size, scope, and alignment.
4#
5#
6# int tent4;
7# long tent8;
8# __attribute__((visibility("hidden"))) int tentHidden;
9# __attribute__((aligned(16))) int tent4_16;
10# __attribute__((aligned(32))) long tent64_32[8];
11#
12
13--- !mach-o
14arch: x86_64
15file-type: MH_OBJECT
16flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
17has-UUID: false
18OS: unknown
19sections:
20 - segment: __TEXT
21 section: __tex
22 type: S_REGULAR
23 attributes: [ S_ATTR_PURE_INSTRUCTIONS ]
24 address: 0x0000000000000000
25undefined-symbols:
26 - name: _tent4
27 type: N_UNDF
28 scope: [ N_EXT ]
29 desc: 0x0200
30 value: 0x0000000000000004
31 - name: _tent4_16
32 type: N_UNDF
33 scope: [ N_EXT ]
34 desc: 0x0400
35 value: 0x0000000000000004
36 - name: _tent64_32
37 type: N_UNDF
38 scope: [ N_EXT ]
39 desc: 0x0500
40 value: 0x0000000000000040
41 - name: _tent8
42 type: N_UNDF
43 scope: [ N_EXT ]
44 desc: 0x0300
45 value: 0x0000000000000008
46 - name: _tentHidden
47 type: N_UNDF
48 scope: [ N_EXT, N_PEXT ]
49 desc: 0x0200
50 value: 0x0000000000000004
51...
52
53
54# CHECK: defined-atoms:
55# CHECK: name: _tent4
56# CHECK: scope: global
57# CHECK: type: zero-fill
58# CHECK: size: 4
59# CHECK: merge: as-tentative
60# CHECK: alignment: 4
61
62# CHECK: name: _tent4_16
63# CHECK: scope: global
64# CHECK: type: zero-fill
65# CHECK: size: 4
66# CHECK: merge: as-tentative
67# CHECK: alignment: 16
68
69# CHECK: name: _tent64_32
70# CHECK: scope: global
71# CHECK: type: zero-fill
72# CHECK: size: 64
73# CHECK: merge: as-tentative
74# CHECK: alignment: 32
75
76# CHECK: name: _tent8
77# CHECK: scope: global
78# CHECK: type: zero-fill
79# CHECK: size: 8
80# CHECK: merge: as-tentative
81# CHECK: alignment: 8
82
83# CHECK: name: _tentHidden
84# CHECK: scope: hidden
85# CHECK: type: zero-fill
86# CHECK: size: 4
87# CHECK: merge: as-tentative
88# CHECK: alignment: 4
deps/lld/test/mach-o/parse-text-relocs-arm64.yaml created+237
......@@ -0,0 +1,237 @@
1# RUN: lld -flavor darwin -arch arm64 -r -print_atoms %s -o %t | FileCheck %s \
2# RUN: && lld -flavor darwin -arch arm64 -r -print_atoms %t -o %t2 | FileCheck %s
3#
4# Test parsing and writing of arm64 text relocations.
5#
6# The first step tests if the supplied mach-o file is parsed into the correct
7# set of references. The second step verifies relocations can be round-tripped
8# by writing to a new .o file, then parsing that file which should result in
9# the same references.
10#
11#_test:
12
13
14--- !mach-o
15arch: arm64
16file-type: MH_OBJECT
17flags: [ ]
18has-UUID: false
19OS: unknown
20sections:
21 - segment: __TEXT
22 section: __text
23 type: S_REGULAR
24 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
25 address: 0x0000000000000000
26 content: [ 0x00, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x94,
27 0x01, 0x00, 0x00, 0x90, 0x20, 0x00, 0x40, 0x39,
28 0x20, 0x00, 0x40, 0x79, 0x20, 0x00, 0x40, 0xB9,
29 0x20, 0x00, 0x40, 0xF9, 0x20, 0x00, 0xC0, 0x3D,
30 0x01, 0x00, 0x00, 0x90, 0x20, 0x00, 0x40, 0xB9,
31 0x01, 0x00, 0x00, 0x90, 0x20, 0x00, 0x40, 0xF9,
32 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x40, 0xF9 ]
33 relocations:
34 - offset: 0x00000034
35 type: ARM64_RELOC_TLVP_LOAD_PAGEOFF12
36 length: 2
37 pc-rel: false
38 extern: true
39 symbol: 5
40 - offset: 0x00000030
41 type: ARM64_RELOC_TLVP_LOAD_PAGE21
42 length: 2
43 pc-rel: true
44 extern: true
45 symbol: 5
46 - offset: 0x0000002C
47 type: ARM64_RELOC_GOT_LOAD_PAGEOFF12
48 length: 2
49 pc-rel: false
50 extern: true
51 symbol: 6
52 - offset: 0x00000028
53 type: ARM64_RELOC_GOT_LOAD_PAGE21
54 length: 2
55 pc-rel: true
56 extern: true
57 symbol: 6
58 - offset: 0x00000024
59 type: ARM64_RELOC_ADDEND
60 length: 2
61 pc-rel: false
62 extern: false
63 symbol: 16
64 - offset: 0x00000024
65 type: ARM64_RELOC_PAGEOFF12
66 length: 2
67 pc-rel: false
68 extern: true
69 symbol: 2
70 - offset: 0x00000020
71 type: ARM64_RELOC_ADDEND
72 length: 2
73 pc-rel: false
74 extern: false
75 symbol: 16
76 - offset: 0x00000020
77 type: ARM64_RELOC_PAGE21
78 length: 2
79 pc-rel: true
80 extern: true
81 symbol: 2
82 - offset: 0x0000001C
83 type: ARM64_RELOC_PAGEOFF12
84 length: 2
85 pc-rel: false
86 extern: true
87 symbol: 2
88 - offset: 0x00000018
89 type: ARM64_RELOC_PAGEOFF12
90 length: 2
91 pc-rel: false
92 extern: true
93 symbol: 2
94 - offset: 0x00000014
95 type: ARM64_RELOC_PAGEOFF12
96 length: 2
97 pc-rel: false
98 extern: true
99 symbol: 2
100 - offset: 0x00000010
101 type: ARM64_RELOC_PAGEOFF12
102 length: 2
103 pc-rel: false
104 extern: true
105 symbol: 2
106 - offset: 0x0000000C
107 type: ARM64_RELOC_PAGEOFF12
108 length: 2
109 pc-rel: false
110 extern: true
111 symbol: 2
112 - offset: 0x00000008
113 type: ARM64_RELOC_PAGE21
114 length: 2
115 pc-rel: true
116 extern: true
117 symbol: 2
118 - offset: 0x00000004
119 type: ARM64_RELOC_ADDEND
120 length: 2
121 pc-rel: false
122 extern: false
123 symbol: 8
124 - offset: 0x00000004
125 type: ARM64_RELOC_BRANCH26
126 length: 2
127 pc-rel: true
128 extern: true
129 symbol: 4
130 - offset: 0x00000000
131 type: ARM64_RELOC_BRANCH26
132 length: 2
133 pc-rel: true
134 extern: true
135 symbol: 4
136 - segment: __DATA
137 section: __data
138 type: S_REGULAR
139 attributes: [ ]
140 alignment: 2
141 address: 0x0000000000000038
142 content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
144local-symbols:
145 - name: ltmp0
146 type: N_SECT
147 sect: 1
148 value: 0x0000000000000000
149 - name: _func
150 type: N_SECT
151 sect: 1
152 value: 0x0000000000000000
153 - name: _v1
154 type: N_SECT
155 sect: 2
156 value: 0x0000000000000038
157 - name: ltmp1
158 type: N_SECT
159 sect: 2
160 value: 0x0000000000000038
161undefined-symbols:
162 - name: _foo
163 type: N_UNDF
164 scope: [ N_EXT ]
165 value: 0x0000000000000000
166 - name: _tlv
167 type: N_UNDF
168 scope: [ N_EXT ]
169 value: 0x0000000000000000
170 - name: _v2
171 type: N_UNDF
172 scope: [ N_EXT ]
173 value: 0x0000000000000000
174...
175
176# CHECK: defined-atoms:
177# CHECK: - name: _v1
178# CHECK: type: data
179# CHECK: content: [ 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,
180# CHECK: 00, 00, 00, 00 ]
181# CHECK: - name: _func
182# CHECK: content: [ 00, 00, 00, 94, 00, 00, 00, 94, 01, 00, 00, 90,
183# CHECK: 20, 00, 40, 39, 20, 00, 40, 79, 20, 00, 40, B9,
184# CHECK: 20, 00, 40, F9, 20, 00, C0, 3D, 01, 00, 00, 90,
185# CHECK: 20, 00, 40, B9, 01, 00, 00, 90, 20, 00, 40, F9,
186# CHECK: 00, 00, 00, 90, 00, 00, 40, F9 ]
187# CHECK: references:
188# CHECK: - kind: branch26
189# CHECK: offset: 0
190# CHECK: target: _foo
191# CHECK: - kind: branch26
192# CHECK: offset: 4
193# CHECK: target: _foo
194# CHECK: addend: 8
195# CHECK: - kind: page21
196# CHECK: offset: 8
197# CHECK: target: _v1
198# CHECK: - kind: offset12
199# CHECK: offset: 12
200# CHECK: target: _v1
201# CHECK: - kind: offset12scale2
202# CHECK: offset: 16
203# CHECK: target: _v1
204# CHECK: - kind: offset12scale4
205# CHECK: offset: 20
206# CHECK: target: _v1
207# CHECK: - kind: offset12scale8
208# CHECK: offset: 24
209# CHECK: target: _v1
210# CHECK: - kind: offset12scale16
211# CHECK: offset: 28
212# CHECK: target: _v1
213# CHECK: - kind: page21
214# CHECK: offset: 32
215# CHECK: target: _v1
216# CHECK: addend: 16
217# CHECK: - kind: offset12scale4
218# CHECK: offset: 36
219# CHECK: target: _v1
220# CHECK: addend: 16
221# CHECK: - kind: gotPage21
222# CHECK: offset: 40
223# CHECK: target: _v2
224# CHECK: - kind: gotOffset12
225# CHECK: offset: 44
226# CHECK: target: _v2
227# CHECK: - kind: tlvPage21
228# CHECK: offset: 48
229# CHECK: target: _tlv
230# CHECK: - kind: tlvOffset12
231# CHECK: offset: 52
232# CHECK: target: _tlv
233# CHECK: undefined-atoms:
234# CHECK: - name: _foo
235# CHECK: - name: _tlv
236# CHECK: - name: _v2
237
deps/lld/test/mach-o/parse-text-relocs-x86_64.yaml created+204
......@@ -0,0 +1,204 @@
1# RUN: lld -flavor darwin -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s \
2# RUN: && lld -flavor darwin -arch x86_64 -r -print_atoms %t -o %t2 | FileCheck %s
3#
4# Test parsing and writing of x86_64 text relocations.
5#
6# The first step tests if the supplied mach-o file is parsed into the correct
7# set of references. The second step verifies relocations can be round-tripped
8# by writing to a new .o file, then parsing that file which should result in
9# the same references.
10#
11#_test:
12# call _foo
13# call _foo+4
14# movq _foo@GOTPCREL(%rip), %rax
15# pushq _foo@GOTPCREL(%rip)
16# movl _foo(%rip), %eax
17# movl _foo+4(%rip), %eax
18# movb $0x12, _foo(%rip)
19# movw $0x1234, _foo(%rip)
20# movl $0x12345678, _foo(%rip)
21# movl L2(%rip), %eax
22# movb $0x12, L2(%rip)
23# movw $0x1234, L2(%rip)
24# movl $0x12345678, L2(%rip)
25#
26# .data
27#L2: .long 0
28
29
30--- !mach-o
31arch: x86_64
32file-type: MH_OBJECT
33flags: [ ]
34sections:
35 - segment: __TEXT
36 section: __text
37 type: S_REGULAR
38 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
39 address: 0x0000000000000000
40 content: [ 0xE8, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x04, 0x00,
41 0x00, 0x00, 0x48, 0x8B, 0x05, 0x04, 0x00, 0x00,
42 0x00, 0xFF, 0x35, 0x04, 0x00, 0x00, 0x00, 0x8B,
43 0x05, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x05, 0x04,
44 0x00, 0x00, 0x00, 0xC6, 0x05, 0xFF, 0xFF, 0xFF,
45 0xFF, 0x12, 0x66, 0xC7, 0x05, 0xFE, 0xFF, 0xFF,
46 0xFF, 0x34, 0x12, 0xC7, 0x05, 0xFC, 0xFF, 0xFF,
47 0xFF, 0x78, 0x56, 0x34, 0x12, 0x8B, 0x05, 0x1A,
48 0x00, 0x00, 0x00, 0xc6, 0x05, 0x13, 0x00, 0x00,
49 0x00, 0x12, 0x66, 0xc7, 0x05, 0x0a, 0x00, 0x00,
50 0x00, 0x34, 0x12, 0xc7, 0x05, 0x00, 0x00, 0x00,
51 0x00, 0x78, 0x56, 0x34, 0x12 ]
52 relocations:
53 - offset: 0x00000055
54 type: X86_64_RELOC_SIGNED_4
55 length: 2
56 pc-rel: true
57 extern: false
58 symbol: 2
59 - offset: 0x0000004d
60 type: X86_64_RELOC_SIGNED_2
61 length: 2
62 pc-rel: true
63 extern: false
64 symbol: 2
65 - offset: 0x00000045
66 type: X86_64_RELOC_SIGNED_1
67 length: 2
68 pc-rel: true
69 extern: false
70 symbol: 2
71 - offset: 0x0000003F
72 type: X86_64_RELOC_SIGNED
73 length: 2
74 pc-rel: true
75 extern: false
76 symbol: 2
77 - offset: 0x00000035
78 type: X86_64_RELOC_SIGNED_4
79 length: 2
80 pc-rel: true
81 extern: true
82 symbol: 1
83 - offset: 0x0000002D
84 type: X86_64_RELOC_SIGNED_2
85 length: 2
86 pc-rel: true
87 extern: true
88 symbol: 1
89 - offset: 0x00000025
90 type: X86_64_RELOC_SIGNED_1
91 length: 2
92 pc-rel: true
93 extern: true
94 symbol: 1
95 - offset: 0x0000001F
96 type: X86_64_RELOC_SIGNED
97 length: 2
98 pc-rel: true
99 extern: true
100 symbol: 1
101 - offset: 0x00000019
102 type: X86_64_RELOC_SIGNED
103 length: 2
104 pc-rel: true
105 extern: true
106 symbol: 1
107 - offset: 0x00000013
108 type: X86_64_RELOC_GOT
109 length: 2
110 pc-rel: true
111 extern: true
112 symbol: 1
113 - offset: 0x0000000D
114 type: X86_64_RELOC_GOT_LOAD
115 length: 2
116 pc-rel: true
117 extern: true
118 symbol: 1
119 - offset: 0x00000006
120 type: X86_64_RELOC_BRANCH
121 length: 2
122 pc-rel: true
123 extern: true
124 symbol: 1
125 - offset: 0x00000001
126 type: X86_64_RELOC_BRANCH
127 length: 2
128 pc-rel: true
129 extern: true
130 symbol: 1
131 - segment: __DATA
132 section: __data
133 type: S_REGULAR
134 attributes: [ ]
135 address: 0x000000000000005D
136 content: [ 0x00, 0x00, 0x00, 0x00 ]
137local-symbols:
138 - name: _test
139 type: N_SECT
140 sect: 1
141 value: 0x0000000000000000
142undefined-symbols:
143 - name: _foo
144 type: N_UNDF
145 scope: [ N_EXT ]
146 value: 0x0000000000000000
147...
148
149# CHECK: defined-atoms:
150# CHECK: - ref-name: [[LABEL:L[0-9]+]]
151# CHECK: type: data
152# CHECK: content: [ 00, 00, 00, 00 ]
153# CHECK: - name: _test
154# CHECK: references:
155# CHECK: - kind: branch32
156# CHECK: offset: 1
157# CHECK: target: _foo
158# CHECK: - kind: branch32
159# CHECK: offset: 6
160# CHECK: target: _foo
161# CHECK: addend: 4
162# CHECK: - kind: ripRel32GotLoad
163# CHECK: offset: 13
164# CHECK: target: _foo
165# CHECK: addend: 4
166# CHECK: - kind: ripRel32Got
167# CHECK: offset: 19
168# CHECK: target: _foo
169# CHECK: addend: 4
170# CHECK: - kind: ripRel32
171# CHECK: offset: 25
172# CHECK: target: _foo
173# CHECK: - kind: ripRel32
174# CHECK: offset: 31
175# CHECK: target: _foo
176# CHECK: addend: 4
177# CHECK: - kind: ripRel32Minus1
178# CHECK: offset: 37
179# CHECK: target: _foo
180# CHECK-NOT: addend:
181# CHECK: - kind: ripRel32Minus2
182# CHECK: offset: 45
183# CHECK: target: _foo
184# CHECK-NOT: addend:
185# CHECK: - kind: ripRel32Minus4
186# CHECK: offset: 53
187# CHECK: target: _foo
188# CHECK-NOT: addend:
189# CHECK: - kind: ripRel32Anon
190# CHECK: offset: 63
191# CHECK: target: [[LABEL]]
192# CHECK-NOT: addend:
193# CHECK: - kind: ripRel32Minus1Anon
194# CHECK: offset: 69
195# CHECK: target: [[LABEL]]
196# CHECK-NOT: addend:
197# CHECK: - kind: ripRel32Minus2Anon
198# CHECK: offset: 77
199# CHECK: target: [[LABEL]]
200# CHECK-NOT: addend:
201# CHECK: - kind: ripRel32Minus4Anon
202# CHECK: offset: 85
203# CHECK: target: [[LABEL]]
204# CHECK-NOT: addend:
deps/lld/test/mach-o/parse-tlv-relocs-x86-64.yaml created+100
......@@ -0,0 +1,100 @@
1# RUN: lld -flavor darwin -arch x86_64 -r -print_atoms %s -o %t | FileCheck %s \
2# RUN: && lld -flavor darwin -arch x86_64 -r -print_atoms %t -o %t2 | FileCheck %s
3#
4# Test parsing of x86_64 tlv relocations.
5
6--- !mach-o
7arch: x86_64
8file-type: MH_OBJECT
9flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
10compat-version: 0.0
11current-version: 0.0
12has-UUID: false
13OS: unknown
14sections:
15 - segment: __TEXT
16 section: __text
17 type: S_REGULAR
18 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
19 alignment: 16
20 address: 0x0000000000000000
21 content: [ 0x55, 0x48, 0x89, 0xE5, 0x48, 0x8B, 0x3D, 0x00,
22 0x00, 0x00, 0x00, 0xFF, 0x17, 0x8B, 0x00, 0x5D,
23 0xC3 ]
24 relocations:
25 - offset: 0x00000007
26 type: X86_64_RELOC_TLV
27 length: 2
28 pc-rel: true
29 extern: true
30 symbol: 2
31 - segment: __DATA
32 section: __thread_data
33 type: S_THREAD_LOCAL_REGULAR
34 attributes: [ ]
35 alignment: 4
36 address: 0x0000000000000014
37 content: [ 0x07, 0x00, 0x00, 0x00 ]
38 - segment: __DATA
39 section: __thread_vars
40 type: S_THREAD_LOCAL_VARIABLES
41 attributes: [ ]
42 address: 0x0000000000000018
43 content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
44 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
45 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
46 relocations:
47 - offset: 0x00000010
48 type: X86_64_RELOC_UNSIGNED
49 length: 3
50 pc-rel: false
51 extern: true
52 symbol: 0
53 - offset: 0x00000000
54 type: X86_64_RELOC_UNSIGNED
55 length: 3
56 pc-rel: false
57 extern: true
58 symbol: 3
59local-symbols:
60 - name: '_x$tlv$init'
61 type: N_SECT
62 sect: 2
63 value: 0x0000000000000014
64global-symbols:
65 - name: _main
66 type: N_SECT
67 scope: [ N_EXT ]
68 sect: 1
69 value: 0x0000000000000000
70 - name: _x
71 type: N_SECT
72 scope: [ N_EXT ]
73 sect: 3
74 value: 0x0000000000000018
75undefined-symbols:
76 - name: __tlv_bootstrap
77 type: N_UNDF
78 scope: [ N_EXT ]
79 value: 0x0000000000000000
80page-size: 0x00000000
81...
82
83# CHECK: - name: _x
84# CHECK-NEXT: scope: global
85# CHECK-NEXT: type: tlv-thunk
86# CHECK-NOT: - name:
87# CHECK: references:
88# CHECK-NEXT: - kind: pointer64
89# CHECK-NEXT: offset: 0
90# CHECK-NEXT: target: __tlv_bootstrap
91# CHECK-NEXT: - kind: tlvInitSectionOffset
92# CHECK-NEXT: offset: 16
93# CHECK-NEXT: target: '_x$tlv$init'
94# CHECK: - name: _main
95# CHECK-NOT: - name:
96# CHECK-NEXT: scope: global
97# CHECK: references:
98# CHECK-NEXT: - kind: ripRel32Tlv
99# CHECK-NEXT: offset: 7
100# CHECK-NEXT: target: _x
deps/lld/test/mach-o/re-exported-dylib-ordinal.yaml created+46
......@@ -0,0 +1,46 @@
1# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s \
2# RUN: %p/Inputs/re-exported-dylib-ordinal.yaml \
3# RUN: %p/Inputs/re-exported-dylib-ordinal2.yaml \
4# RUN: %p/Inputs/re-exported-dylib-ordinal3.yaml -dylib -o %t \
5# RUN: && llvm-nm -m %t | FileCheck %s
6#
7# Test that when one dylib A re-exports dylib B that using a symbol from B
8# gets recorded as coming from A.
9#
10
11--- !mach-o
12arch: x86_64
13file-type: MH_OBJECT
14flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
15has-UUID: false
16OS: unknown
17sections:
18 - segment: __TEXT
19 section: __text
20 type: S_REGULAR
21 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
22 address: 0x0000000000000000
23 content: [ 0x55, 0x48, 0x89, 0xE5, 0x31, 0xC0, 0x5D, 0xE9,
24 0x00, 0x00, 0x00, 0x00 ]
25 relocations:
26 - offset: 0x00000008
27 type: X86_64_RELOC_BRANCH
28 length: 2
29 pc-rel: true
30 extern: true
31 symbol: 1
32global-symbols:
33 - name: _test
34 type: N_SECT
35 scope: [ N_EXT ]
36 sect: 1
37 value: 0x0000000000000000
38undefined-symbols:
39 - name: _bar
40 type: N_UNDF
41 scope: [ N_EXT ]
42 value: 0x0000000000000000
43...
44
45# CHECK: (undefined) external _bar (from libfoo)
46# CHECK: (undefined) external dyld_stub_binder (from libSystem)
deps/lld/test/mach-o/rpath.yaml created+38
......@@ -0,0 +1,38 @@
1# Check we handle -rpath correctly:
2# RUN: lld -flavor darwin -arch x86_64 -rpath @loader_path/../Frameworks \
3# RUN: %p/Inputs/x86_64/libSystem.yaml %s -o %t
4# RUN: llvm-objdump -private-headers %t | FileCheck %s --check-prefix=CHECK-BINARY-WRITE
5
6--- !mach-o
7arch: x86_64
8file-type: MH_OBJECT
9flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
10has-UUID: false
11OS: unknown
12sections:
13 - segment: __TEXT
14 section: __text
15 type: S_REGULAR
16 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
17 alignment: 4
18 address: 0x0000000000000000
19 content: [ 0xCC, 0xC3, 0x90, 0xC3, 0x90, 0x90, 0xC3, 0x90,
20 0x90, 0x90, 0xC3, 0x90, 0x90, 0x90, 0x90, 0xC3,
21 0x31, 0xC0, 0xC3 ]
22local-symbols:
23 - name: _myStatic
24 type: N_SECT
25 sect: 1
26 value: 0x000000000000000B
27global-symbols:
28 - name: _main
29 type: N_SECT
30 scope: [ N_EXT ]
31 sect: 1
32 value: 0x0000000000000001
33...
34
35
36# CHECK-BINARY-WRITE: cmd LC_RPATH
37# CHECK-BINARY-WRITE-NEXT: cmdsize 40
38# CHECK-BINARY-WRITE-NEXT: path @loader_path/../Frameworks (offset 12)
deps/lld/test/mach-o/run-tlv-pass-x86-64.yaml created+144
......@@ -0,0 +1,144 @@
1# RUN: lld -flavor darwin -macosx_version_min 10.7 -arch x86_64 -print_atoms %s -o %t | FileCheck %s
2# RUN: not lld -flavor darwin -macosx_version_min 10.6 -arch x86_64 -o %t %s 2> %t2
3# RUN: FileCheck < %t2 %s --check-prefix=CHECK-ERROR
4# RUN: llvm-objdump -macho -private-headers %t | FileCheck %s --check-prefix=CHECK-LOADCMDS
5#
6# Test parsing of x86_64 tlv relocations.
7
8--- !mach-o
9arch: x86_64
10file-type: MH_OBJECT
11flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
12compat-version: 0.0
13current-version: 0.0
14has-UUID: false
15OS: unknown
16sections:
17 - segment: __TEXT
18 section: __text
19 type: S_REGULAR
20 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
21 alignment: 16
22 address: 0x0000000000000000
23 content: [ 0x55, 0x48, 0x89, 0xE5, 0x48, 0x8B, 0x3D, 0x00,
24 0x00, 0x00, 0x00, 0xFF, 0x17, 0x8B, 0x00, 0x5D,
25 0xC3 ]
26 relocations:
27 - offset: 0x00000007
28 type: X86_64_RELOC_TLV
29 length: 2
30 pc-rel: true
31 extern: true
32 symbol: 2
33 - segment: __DATA
34 section: __thread_bss
35 type: S_THREAD_LOCAL_ZEROFILL
36 attributes: [ ]
37 alignment: 4
38 address: 0x0000000000000014
39 size: 4
40 - segment: __DATA
41 section: __thread_vars
42 type: S_THREAD_LOCAL_VARIABLES
43 attributes: [ ]
44 address: 0x0000000000000018
45 content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
48 relocations:
49 - offset: 0x00000010
50 type: X86_64_RELOC_UNSIGNED
51 length: 3
52 pc-rel: false
53 extern: true
54 symbol: 0
55 - offset: 0x00000000
56 type: X86_64_RELOC_UNSIGNED
57 length: 3
58 pc-rel: false
59 extern: true
60 symbol: 3
61 - segment: __DATA
62 section: __dummy
63 type: S_REGULAR
64 attributes: [ ]
65 alignment: 8
66 address: 0x00000000000000C0
67 content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
70local-symbols:
71 - name: '_x$tlv$init'
72 type: N_SECT
73 sect: 2
74 value: 0x0000000000000014
75global-symbols:
76 - name: _main
77 type: N_SECT
78 scope: [ N_EXT ]
79 sect: 1
80 value: 0x0000000000000000
81 - name: _x
82 type: N_SECT
83 scope: [ N_EXT ]
84 sect: 3
85 value: 0x0000000000000018
86 - name: '__tlv_bootstrap'
87 type: N_SECT
88 scope: [ N_EXT ]
89 sect: 4
90 value: 0x00000000000000C0
91 - name: 'dyld_stub_binder'
92 type: N_SECT
93 scope: [ N_EXT ]
94 sect: 4
95 value: 0x00000000000000C8
96 - name: 'start'
97 type: N_SECT
98 scope: [ N_EXT ]
99 sect: 4
100 value: 0x00000000000000D0
101page-size: 0x00000000
102...
103
104# CHECK: - name: _x
105# CHECK-NEXT: scope: global
106# CHECK-NEXT: type: tlv-thunk
107# CHECK-NOT: - name:
108# CHECK: references:
109# CHECK-NEXT: - kind: pointer64
110# CHECK-NEXT: offset: 0
111# CHECK-NEXT: target: __tlv_bootstrap
112# CHECK-NEXT: - kind: tlvInitSectionOffset
113# CHECK-NEXT: offset: 16
114# CHECK-NEXT: target: '_x$tlv$init'
115# CHECK: - name: '_x$tlv$init'
116# CHECK-NEXT: type: tlv-zero-fill
117# CHECK: - name: _main
118# CHECK-NOT: - name:
119# CHECK: references:
120# CHECK-NEXT: - kind: ripRel32
121# CHECK-NEXT: offset: 7
122# CHECK-NEXT: target: L[[ID:[0-9]+]]
123# CHECK: - ref-name: L[[ID]]
124# CHECK-NEXT: scope: hidden
125# CHECK-NEXT: type: tlv-initializer-ptr
126# CHECK-NEXT: content: [ 00, 00, 00, 00, 00, 00, 00, 00 ]
127# CHECK-NEXT: alignment: 8
128# CHECK-NEXT: permissions: rw-
129# CHECK-NEXT: references:
130# CHECK-NEXT: - kind: pointer64
131# CHECK-NEXT: offset: 0
132# CHECK-NEXT: target: _x
133
134# CHECK-ERROR: targeted OS version does not support use of thread local variables in _main for architecture x86_64
135
136# CHECK-LOADCMDS: sectname __thread_bss
137# CHECK-LOADCMDS: segname __DATA
138# CHECK-LOADCMDS: addr 0x{{[0-9A-F]*}}
139# CHECK-LOADCMDS: size 0x0000000000000004
140# CHECK-LOADCMDS: offset 0
141# CHECK-LOADCMDS: align 2^2 (4)
142# CHECK-LOADCMDS: reloff 0
143# CHECK-LOADCMDS: nreloc 0
144# CHECK-LOADCMDS: type S_THREAD_LOCAL_ZEROFILL
deps/lld/test/mach-o/sdk-version-error.yaml created+22
......@@ -0,0 +1,22 @@
1# RUN: not lld -flavor darwin -arch x86_64 -sdk_version 10.blah %s -o %t 2>&1 | FileCheck %s --check-prefix=ERROR
2
3--- !mach-o
4arch: x86_64
5file-type: MH_OBJECT
6flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
7sections:
8 - segment: __TEXT
9 section: __text
10 type: S_REGULAR
11 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
12 address: 0x0000000000000000
13 content: [ 0x00, 0x00, 0x00, 0x00 ]
14global-symbols:
15 - name: _main
16 type: N_SECT
17 scope: [ N_EXT ]
18 sect: 1
19 value: 0x0000000000000000
20...
21
22# ERROR: malformed sdkVersion value
\ No newline at end of file
deps/lld/test/mach-o/sectalign.yaml created+80
......@@ -0,0 +1,80 @@
1# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -dylib \
2# RUN: -sectalign __DATA __custom 0x800 -sectalign __TEXT __text 0x400 \
3# RUN: %p/Inputs/x86_64/libSystem.yaml -o %t \
4# RUN: && llvm-readobj -sections %t | FileCheck %s
5#
6# Test -sectalign option on __text and a custom section.
7#
8
9--- !mach-o
10arch: x86_64
11file-type: MH_OBJECT
12flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
13sections:
14 - segment: __TEXT
15 section: __text
16 type: S_REGULAR
17 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
18 address: 0x0000000000000000
19 content: [ 0x55, 0x48, 0x89, 0xE5, 0x8B, 0x05, 0x00, 0x00,
20 0x00, 0x00, 0x03, 0x05, 0x00, 0x00, 0x00, 0x00,
21 0x5D, 0xC3 ]
22 relocations:
23 - offset: 0x0000000C
24 type: X86_64_RELOC_SIGNED
25 length: 2
26 pc-rel: true
27 extern: true
28 symbol: 1
29 - offset: 0x00000006
30 type: X86_64_RELOC_SIGNED
31 length: 2
32 pc-rel: true
33 extern: true
34 symbol: 2
35 - segment: __DATA
36 section: __data
37 type: S_REGULAR
38 attributes: [ ]
39 alignment: 2
40 address: 0x0000000000000014
41 content: [ 0x0A, 0x00, 0x00, 0x00 ]
42 - segment: __DATA
43 section: __custom
44 type: S_REGULAR
45 attributes: [ ]
46 alignment: 2
47 address: 0x0000000000000018
48 content: [ 0x0A, 0x00, 0x00, 0x00 ]
49global-symbols:
50 - name: _a
51 type: N_SECT
52 scope: [ N_EXT ]
53 sect: 2
54 value: 0x0000000000000014
55 - name: _b
56 type: N_SECT
57 scope: [ N_EXT ]
58 sect: 3
59 value: 0x0000000000000018
60 - name: _get
61 type: N_SECT
62 scope: [ N_EXT ]
63 sect: 1
64 value: 0x0000000000000000
65
66...
67
68
69# CHECK: Name: __text (5F 5F 74 65 78 74 00 00 00 00 00 00 00 00 00 00)
70# CHECK: Segment: __TEXT (5F 5F 54 45 58 54 00 00 00 00 00 00 00 00 00 00)
71# CHECK: Address: 0xC00
72
73# CHECK: Name: __data (5F 5F 64 61 74 61 00 00 00 00 00 00 00 00 00 00)
74# CHECK: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
75# CHECK: Address: 0x1000
76
77# CHECK: Name: __custom (5F 5F 63 75 73 74 6F 6D 00 00 00 00 00 00 00 00)
78# CHECK: Segment: __DATA (5F 5F 44 41 54 41 00 00 00 00 00 00 00 00 00 00)
79# CHECK: Address: 0x1800
80
deps/lld/test/mach-o/sectattrs.yaml created+30
......@@ -0,0 +1,30 @@
1# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -dylib \
2# RUN: %p/Inputs/x86_64/libSystem.yaml -o %t \
3# RUN: && llvm-objdump -private-headers %t | FileCheck %s
4#
5
6--- !mach-o
7arch: x86_64
8file-type: MH_OBJECT
9flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
10sections:
11 - segment: __TEXT
12 section: __text
13 type: S_REGULAR
14 attributes: [ ]
15 address: 0x0000000000000000
16 content: [ 0x55, 0x48, 0x89, 0xE5, 0x8B, 0x05, 0x00, 0x00,
17 0x00, 0x00, 0x03, 0x05, 0x00, 0x00, 0x00, 0x00,
18 0x5D, 0xC3 ]
19global-symbols:
20 - name: _get
21 type: N_SECT
22 scope: [ N_EXT ]
23 sect: 1
24 value: 0x0000000000000000
25
26...
27
28
29# CHECK: PURE_INSTRUCTIONS SOME_INSTRUCTIONS
30
deps/lld/test/mach-o/sectcreate.yaml created+12
......@@ -0,0 +1,12 @@
1# RUN: lld -flavor darwin -r -arch x86_64 -o %t -sectcreate __DATA __data \
2# RUN: %p/Inputs/hw.raw_bytes -print_atoms | FileCheck %s
3
4# CHECK: --- !native
5# CHECK: path: '<linker-internal>'
6# CHECK: defined-atoms:
7# CHECK: - scope: global
8# CHECK: type: sectcreate
9# CHECK: content: [ 68, 65, 6C, 6C, 6F, 0A ]
10# CHECK: section-choice: custom-required
11# CHECK: section-name: __DATA/__data
12# CHECK: dead-strip: never
deps/lld/test/mach-o/seg-protection-arm64.yaml created+78
......@@ -0,0 +1,78 @@
1# RUN: lld -flavor darwin -arch arm64 %s %p/Inputs/hello-world-arm64.yaml -o %t && llvm-objdump -private-headers %t | FileCheck %s
2
3--- !mach-o
4arch: arm64
5file-type: MH_OBJECT
6flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
7has-UUID: false
8OS: unknown
9sections:
10 - segment: __TEXT
11 section: __text
12 type: S_REGULAR
13 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
14 address: 0x0000000000000000
15 content: [ 0x00, 0x00 ]
16global-symbols:
17 - name: _main
18 type: N_SECT
19 scope: [ N_EXT ]
20 sect: 1
21 value: 0x0000000000000000
22 - name: start
23 type: N_SECT
24 scope: [ N_EXT ]
25 sect: 1
26 value: 0x0000000000000001
27
28...
29
30# CHECK: Load command 0
31# CHECK: cmd LC_SEGMENT_64
32# CHECK: cmdsize 72
33# CHECK: segname __PAGEZERO
34# CHECK: vmaddr
35# CHECK: vmsize
36# CHECK: fileoff
37# CHECK: filesize
38# CHECK: maxprot ---
39# CHECK: initprot ---
40# CHECK: nsects 0
41# CHECK: flags (none)
42# CHECK: Load command 1
43# CHECK: cmd LC_SEGMENT_64
44# CHECK: cmdsize 152
45# CHECK: segname __TEXT
46# CHECK: vmaddr
47# CHECK: vmsize
48# CHECK: fileoff
49# CHECK: filesize
50# CHECK: maxprot r-x
51# CHECK: initprot r-x
52# CHECK: nsects 1
53# CHECK: flags (none)
54# CHECK: Section
55# CHECK: sectname __text
56# CHECK: segname __TEXT
57# CHECK: addr
58# CHECK: size
59# CHECK: offset
60# CHECK: align 2^0 (1)
61# CHECK: reloff 0
62# CHECK: nreloc 0
63# CHECK: type S_REGULAR
64# CHECK: attributes PURE_INSTRUCTIONS SOME_INSTRUCTIONS
65# CHECK: reserved1 0
66# CHECK: reserved2 0
67# CHECK: Load command 2
68# CHECK: cmd LC_SEGMENT_64
69# CHECK: cmdsize 72
70# CHECK: segname __LINKEDIT
71# CHECK: vmaddr
72# CHECK: vmsize
73# CHECK: fileoff
74# CHECK: filesize
75# CHECK: maxprot r--
76# CHECK: initprot r--
77# CHECK: nsects 0
78# CHECK: flags (none)
deps/lld/test/mach-o/seg-protection-x86_64.yaml created+78
......@@ -0,0 +1,78 @@
1# RUN: lld -flavor darwin -arch x86_64 %s %p/Inputs/hello-world-x86_64.yaml -o %t && llvm-objdump -private-headers %t | FileCheck %s
2
3--- !mach-o
4arch: x86_64
5file-type: MH_OBJECT
6flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
7has-UUID: false
8OS: unknown
9sections:
10 - segment: __TEXT
11 section: __text
12 type: S_REGULAR
13 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
14 address: 0x0000000000000000
15 content: [ 0x00, 0x00 ]
16global-symbols:
17 - name: _main
18 type: N_SECT
19 scope: [ N_EXT ]
20 sect: 1
21 value: 0x0000000000000000
22 - name: start
23 type: N_SECT
24 scope: [ N_EXT ]
25 sect: 1
26 value: 0x0000000000000001
27
28...
29
30# CHECK: Load command 0
31# CHECK: cmd LC_SEGMENT_64
32# CHECK: cmdsize 72
33# CHECK: segname __PAGEZERO
34# CHECK: vmaddr
35# CHECK: vmsize
36# CHECK: fileoff
37# CHECK: filesize
38# CHECK: maxprot ---
39# CHECK: initprot ---
40# CHECK: nsects 0
41# CHECK: flags (none)
42# CHECK: Load command 1
43# CHECK: cmd LC_SEGMENT_64
44# CHECK: cmdsize 152
45# CHECK: segname __TEXT
46# CHECK: vmaddr
47# CHECK: vmsize
48# CHECK: fileoff
49# CHECK: filesize
50# CHECK: maxprot rwx
51# CHECK: initprot r-x
52# CHECK: nsects 1
53# CHECK: flags (none)
54# CHECK: Section
55# CHECK: sectname __text
56# CHECK: segname __TEXT
57# CHECK: addr
58# CHECK: size
59# CHECK: offset
60# CHECK: align 2^0 (1)
61# CHECK: reloff 0
62# CHECK: nreloc 0
63# CHECK: type S_REGULAR
64# CHECK: attributes PURE_INSTRUCTIONS SOME_INSTRUCTIONS
65# CHECK: reserved1 0
66# CHECK: reserved2 0
67# CHECK: Load command 2
68# CHECK: cmd LC_SEGMENT_64
69# CHECK: cmdsize 72
70# CHECK: segname __LINKEDIT
71# CHECK: vmaddr
72# CHECK: vmsize
73# CHECK: fileoff
74# CHECK: filesize
75# CHECK: maxprot rwx
76# CHECK: initprot r--
77# CHECK: nsects 0
78# CHECK: flags (none)
deps/lld/test/mach-o/source-version.yaml created+28
......@@ -0,0 +1,28 @@
1# RUN: not lld -flavor darwin -arch x86_64 -source_version 10.blah %s -o %t 2>&1 | FileCheck %s --check-prefix=ERROR
2# RUN: lld -flavor darwin -arch x86_64 -source_version 10.1.2.3.4 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml && llvm-objdump -private-headers %t | FileCheck %s
3
4--- !mach-o
5arch: x86_64
6file-type: MH_OBJECT
7flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
8sections:
9 - segment: __TEXT
10 section: __text
11 type: S_REGULAR
12 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
13 address: 0x0000000000000000
14 content: [ 0x00, 0x00, 0x00, 0x00 ]
15global-symbols:
16 - name: _main
17 type: N_SECT
18 scope: [ N_EXT ]
19 sect: 1
20 value: 0x0000000000000000
21...
22
23# ERROR: malformed source_version value
24
25# CHECK: Load command {{[0-9]*}}
26# CHECK: cmd LC_SOURCE_VERSION
27# CHECK: cmdsize 16
28# CHECK: version 10.1.2.3.4
\ No newline at end of file
deps/lld/test/mach-o/stack-size.yaml created+24
......@@ -0,0 +1,24 @@
1# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.9 %s -o %t %p/Inputs/x86_64/libSystem.yaml
2# RUN: llvm-objdump -private-headers %t | FileCheck --check-prefix=CHECK-DEFAULT %s
3# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.9 %s -o %t -stack_size 31415926000 %p/Inputs/x86_64/libSystem.yaml
4# RUN: llvm-objdump -private-headers %t | FileCheck --check-prefix=CHECK-EXPLICIT %s
5# RUN: not lld -flavor darwin -arch x86_64 -stack_size 0x31415926530 %s >/dev/null 2> %t
6# RUN: FileCheck < %t %s --check-prefix=CHECK-ERROR-MISPAGED
7# RUN: not lld -flavor darwin -arch x86_64 -stack_size hithere %s >/dev/null 2> %t
8# RUN: FileCheck < %t %s --check-prefix=CHECK-ERROR-NOTHEX
9
10--- !native
11defined-atoms:
12 - name: _main
13 scope: global
14 content: []
15
16# CHECK-DEFAULT: cmd LC_MAIN
17# CHECK-DEFAULT: stacksize 0
18
19# CHECK-EXPLICIT: cmd LC_MAIN
20# CHECK-EXPLICIT: stacksize 3384796143616
21
22# CHECK-ERROR-MISPAGED: error: stack_size must be a multiple of page size (0x1000)
23
24# CHECK-ERROR-NOTHEX: error: stack_size expects a hex number
deps/lld/test/mach-o/string-table.yaml created+66
......@@ -0,0 +1,66 @@
1# RUN: lld -flavor darwin -arch i386 %s %p/Inputs/hello-world-x86.yaml -o %t
2# RUN: obj2yaml %t | FileCheck %s
3#
4# Test that the string table contains a ' ' as its first symbol
5#
6
7--- !mach-o
8arch: x86
9file-type: MH_OBJECT
10flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
11sections:
12 - segment: __TEXT
13 section: __text
14 type: S_REGULAR
15 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
16 address: 0x0000000000000000
17 content: [ 0x55, 0x89, 0xE5, 0x83, 0xEC, 0x08, 0xE8, 0x00,
18 0x00, 0x00, 0x00, 0x58, 0x8D, 0x80, 0x16, 0x00,
19 0x00, 0x00, 0x89, 0x04, 0x24, 0xE8, 0xE6, 0xFF,
20 0xFF, 0xFF, 0x31, 0xC0, 0x83, 0xC4, 0x08, 0x5D,
21 0xC3 ]
22 relocations:
23 - offset: 0x00000016
24 type: GENERIC_RELOC_VANILLA
25 length: 2
26 pc-rel: true
27 extern: true
28 symbol: 1
29 - offset: 0x0000000E
30 scattered: true
31 type: GENERIC_RELOC_LOCAL_SECTDIFF
32 length: 2
33 pc-rel: false
34 value: 0x00000021
35 - offset: 0x00000000
36 scattered: true
37 type: GENERIC_RELOC_PAIR
38 length: 2
39 pc-rel: false
40 value: 0x0000000B
41 - segment: __TEXT
42 section: __cstring
43 type: S_CSTRING_LITERALS
44 attributes: [ ]
45 address: 0x0000000000000021
46 content: [ 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x00 ]
47global-symbols:
48 - name: _main
49 type: N_SECT
50 scope: [ N_EXT ]
51 sect: 1
52 value: 0x0000000000000000
53undefined-symbols:
54 - name: _printf
55 type: N_UNDF
56 scope: [ N_EXT ]
57 value: 0x0000000000000000
58...
59
60# CHECK: StringTable:
61# CHECK-NEXT: - ' '
62# CHECK-NEXT: - __mh_execute_header
63# CHECK-NEXT: - _main
64# CHECK-NEXT: - _printf
65# CHECK-NEXT: - dyld_stub_binder
66# CHECK-NEXT: - ''
deps/lld/test/mach-o/subsections-via-symbols-default.yaml created+28
......@@ -0,0 +1,28 @@
1# RUN: lld -flavor darwin -ios_simulator_version_min 5.0 -arch x86_64 -r %s -o %t
2# RUN: llvm-readobj -file-headers %t | FileCheck %s
3
4# Make sure that we have an objc image info in the output. It should have
5# been generated by the objc pass.
6
7--- !mach-o
8arch: x86_64
9file-type: MH_OBJECT
10flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
11compat-version: 0.0
12current-version: 0.0
13has-UUID: false
14OS: unknown
15sections:
16 - segment: __DATA
17 section: __objc_imageinfo
18 type: S_REGULAR
19 attributes: [ S_ATTR_NO_DEAD_STRIP ]
20 address: 0x0000000000000100
21 content: [ 0x00, 0x00, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00 ]
22...
23
24# The ObjC pass creates a new image info in a new MachoFile internal to the pass.
25# Make sure that we still have MH_SUBSECTIONS_VIA_SYMBOLS in the output file, even
26# though that file in the ObjCPass didn't get it set from being parsed.
27
28# CHECK: MH_SUBSECTIONS_VIA_SYMBOLS
\ No newline at end of file
deps/lld/test/mach-o/twolevel_namespace_undef_dynamic_lookup.yaml created+17
......@@ -0,0 +1,17 @@
1# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.9 -twolevel_namespace -undefined dynamic_lookup %s -o %t %p/Inputs/x86_64/libSystem.yaml
2#
3# Sanity check '-twolevel_namespace -undefined dynamic_lookup'.
4# This should pass without error, even though '_bar' is undefined.
5
6--- !native
7defined-atoms:
8 - name: _main
9 scope: global
10 content: [ E9, 00, 00, 00, 00 ]
11 alignment: 16
12 references:
13 - kind: branch32
14 offset: 1
15 target: _bar
16undefined-atoms:
17 - name: _bar
deps/lld/test/mach-o/twolevel_namespace_undef_warning_suppress.yaml created+23
......@@ -0,0 +1,23 @@
1# RUN: not lld -flavor darwin -arch x86_64 -macosx_version_min 10.9 -twolevel_namespace -undefined warning %s -o %t %p/Inputs/x86_64/libSystem.yaml 2>&1 | \
2# RUN: FileCheck --check-prefix=CHECK-WARNING %s
3# RUN: not lld -flavor darwin -arch x86_64 -macosx_version_min 10.9 -twolevel_namespace -undefined suppress %s -o %t %p/Inputs/x86_64/libSystem.yaml 2>&1 | \
4# RUN: FileCheck --check-prefix=CHECK-SUPPRESS %s
5
6--- !native
7defined-atoms:
8 - name: _main
9 scope: global
10 content: [ E9, 00, 00, 00, 00 ]
11 alignment: 16
12 references:
13 - kind: branch32
14 offset: 1
15 target: _bar
16undefined-atoms:
17 - name: _bar
18
19# Make sure that the driver issues an error diagnostic about this combination
20# being invalid.
21#
22# CHECK-WARNING: can't use -undefined warning or suppress with -twolevel_namespace
23# CHECK-SUPPRESS: can't use -undefined warning or suppress with -twolevel_namespace
\ No newline at end of file
deps/lld/test/mach-o/unwind-info-simple-arm64.yaml created+267
......@@ -0,0 +1,267 @@
1# RUN: lld -flavor darwin -arch arm64 -o %t %s \
2# RUN: %p/Inputs/unwind-info-simple-arm64.yaml -e _main %p/Inputs/arm64/libSystem.yaml
3# RUN: llvm-objdump -unwind-info %t | FileCheck %s
4
5--- !mach-o
6arch: arm64
7file-type: MH_OBJECT
8flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
9sections:
10 - segment: __TEXT
11 section: __text
12 type: S_REGULAR
13 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
14 alignment: 2
15 address: 0x0000000000000000
16 content: [ 0xFD, 0x7B, 0xBF, 0xA9, 0xFD, 0x03, 0x00, 0x91,
17 0xE0, 0x03, 0x1E, 0x32, 0x00, 0x00, 0x00, 0x94,
18 0x48, 0x01, 0x80, 0x52, 0x08, 0x00, 0x00, 0xB9,
19 0x02, 0x00, 0x80, 0xD2, 0x01, 0x00, 0x00, 0x90,
20 0x21, 0x00, 0x40, 0xF9, 0x00, 0x00, 0x00, 0x94,
21 0xFD, 0x7B, 0xBF, 0xA9, 0xFD, 0x03, 0x00, 0x91,
22 0xE0, 0x03, 0x1E, 0x32, 0x00, 0x00, 0x00, 0x94,
23 0x48, 0x01, 0x80, 0x52, 0x08, 0x00, 0x00, 0xB9,
24 0x02, 0x00, 0x80, 0xD2, 0x01, 0x00, 0x00, 0x90,
25 0x21, 0x00, 0x40, 0xF9, 0x00, 0x00, 0x00, 0x94,
26 0x3F, 0x04, 0x00, 0x71, 0x81, 0x00, 0x00, 0x54,
27 0x00, 0x00, 0x00, 0x94, 0xFD, 0x7B, 0xC1, 0xA8,
28 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x94,
29 0xFD, 0x7B, 0xBF, 0xA9, 0xFD, 0x03, 0x00, 0x91,
30 0x00, 0x00, 0x00, 0x94 ]
31 relocations:
32 - offset: 0x00000070
33 type: ARM64_RELOC_BRANCH26
34 length: 2
35 pc-rel: true
36 extern: true
37 symbol: 5
38 - offset: 0x00000064
39 type: ARM64_RELOC_BRANCH26
40 length: 2
41 pc-rel: true
42 extern: true
43 symbol: 7
44 - offset: 0x00000060
45 type: ARM64_RELOC_BRANCH26
46 length: 2
47 pc-rel: true
48 extern: true
49 symbol: 12
50 - offset: 0x00000058
51 type: ARM64_RELOC_BRANCH26
52 length: 2
53 pc-rel: true
54 extern: true
55 symbol: 11
56 - offset: 0x0000004C
57 type: ARM64_RELOC_BRANCH26
58 length: 2
59 pc-rel: true
60 extern: true
61 symbol: 13
62 - offset: 0x00000048
63 type: ARM64_RELOC_GOT_LOAD_PAGEOFF12
64 length: 2
65 pc-rel: false
66 extern: true
67 symbol: 8
68 - offset: 0x00000044
69 type: ARM64_RELOC_GOT_LOAD_PAGE21
70 length: 2
71 pc-rel: true
72 extern: true
73 symbol: 8
74 - offset: 0x00000034
75 type: ARM64_RELOC_BRANCH26
76 length: 2
77 pc-rel: true
78 extern: true
79 symbol: 10
80 - offset: 0x00000024
81 type: ARM64_RELOC_BRANCH26
82 length: 2
83 pc-rel: true
84 extern: true
85 symbol: 13
86 - offset: 0x00000020
87 type: ARM64_RELOC_GOT_LOAD_PAGEOFF12
88 length: 2
89 pc-rel: false
90 extern: true
91 symbol: 8
92 - offset: 0x0000001C
93 type: ARM64_RELOC_GOT_LOAD_PAGE21
94 length: 2
95 pc-rel: true
96 extern: true
97 symbol: 8
98 - offset: 0x0000000C
99 type: ARM64_RELOC_BRANCH26
100 length: 2
101 pc-rel: true
102 extern: true
103 symbol: 10
104 - segment: __TEXT
105 section: __gcc_except_tab
106 type: S_REGULAR
107 attributes: [ ]
108 alignment: 2
109 address: 0x0000000000000074
110 content: [ 0xFF, 0x9B, 0xAF, 0x80, 0x00, 0x03, 0x27, 0x00,
111 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00,
112 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
113 0x10, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00,
114 0x01, 0x28, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00,
115 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
116 0xD0, 0xFF, 0xFF, 0xFF ]
117 relocations:
118 - offset: 0x00000030
119 type: ARM64_RELOC_POINTER_TO_GOT
120 length: 2
121 pc-rel: true
122 extern: true
123 symbol: 9
124 - segment: __LD
125 section: __compact_unwind
126 type: S_REGULAR
127 attributes: [ ]
128 alignment: 8
129 address: 0x00000000000000A8
130 content: [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
131 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
132 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
133 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
134 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
135 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
136 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
137 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
138 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
139 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04,
140 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
141 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
142 relocations:
143 - offset: 0x00000040
144 type: ARM64_RELOC_UNSIGNED
145 length: 3
146 pc-rel: false
147 extern: false
148 symbol: 1
149 - offset: 0x00000038
150 type: ARM64_RELOC_UNSIGNED
151 length: 3
152 pc-rel: false
153 extern: false
154 symbol: 2
155 - offset: 0x00000030
156 type: ARM64_RELOC_UNSIGNED
157 length: 3
158 pc-rel: false
159 extern: true
160 symbol: 14
161 - offset: 0x00000020
162 type: ARM64_RELOC_UNSIGNED
163 length: 3
164 pc-rel: false
165 extern: false
166 symbol: 1
167 - offset: 0x00000000
168 type: ARM64_RELOC_UNSIGNED
169 length: 3
170 pc-rel: false
171 extern: false
172 symbol: 1
173local-symbols:
174 - name: ltmp0
175 type: N_SECT
176 sect: 1
177 value: 0x0000000000000000
178 - name: ltmp14
179 type: N_SECT
180 sect: 2
181 value: 0x0000000000000074
182 - name: GCC_except_table1
183 type: N_SECT
184 sect: 2
185 value: 0x0000000000000074
186 - name: ltmp21
187 type: N_SECT
188 sect: 3
189 value: 0x00000000000000A8
190global-symbols:
191 - name: __Z3barv
192 type: N_SECT
193 scope: [ N_EXT ]
194 sect: 1
195 value: 0x0000000000000028
196 - name: __Z3foov
197 type: N_SECT
198 scope: [ N_EXT ]
199 sect: 1
200 value: 0x0000000000000000
201 - name: _main
202 type: N_SECT
203 scope: [ N_EXT ]
204 sect: 1
205 value: 0x0000000000000068
206undefined-symbols:
207 - name: __Unwind_Resume
208 type: N_UNDF
209 scope: [ N_EXT ]
210 value: 0x0000000000000000
211 - name: __ZTIi
212 type: N_UNDF
213 scope: [ N_EXT ]
214 value: 0x0000000000000000
215 - name: __ZTIl
216 type: N_UNDF
217 scope: [ N_EXT ]
218 value: 0x0000000000000000
219 - name: ___cxa_allocate_exception
220 type: N_UNDF
221 scope: [ N_EXT ]
222 value: 0x0000000000000000
223 - name: ___cxa_begin_catch
224 type: N_UNDF
225 scope: [ N_EXT ]
226 value: 0x0000000000000000
227 - name: ___cxa_end_catch
228 type: N_UNDF
229 scope: [ N_EXT ]
230 value: 0x0000000000000000
231 - name: ___cxa_throw
232 type: N_UNDF
233 scope: [ N_EXT ]
234 value: 0x0000000000000000
235 - name: ___gxx_personality_v0
236 type: N_UNDF
237 scope: [ N_EXT ]
238 value: 0x0000000000000000
239
240...
241
242
243# CHECK: Contents of __unwind_info section:
244# CHECK: Version: 0x1
245# CHECK: Common encodings array section offset: 0x1c
246# CHECK: Number of common encodings in array: 0x0
247# CHECK: Personality function array section offset: 0x1c
248# CHECK: Number of personality functions in array: 0x1
249# CHECK: Index array section offset: 0x20
250# CHECK: Number of indices in array: 0x2
251# CHECK: Common encodings: (count = 0)
252# CHECK: Personality functions: (count = 1)
253# CHECK: personality[1]: 0x00004020
254# CHECK: Top level indices: (count = 2)
255# CHECK: [0]: function offset=0x00003e68, 2nd level page offset=0x00000040, LSDA offset=0x00000038
256# CHECK: [1]: function offset=0x00003edc, 2nd level page offset=0x00000000, LSDA offset=0x00000040
257# CHECK: LSDA descriptors:
258# CHECK: [0]: function offset=0x00003e90, LSDA offset=0x00003f6c
259# CHECK: Second level indices:
260# CHECK: Second level index[0]: offset in section=0x00000040, base function offset=0x00003e68
261# CHECK: [0]: function offset=0x00003e68, encoding=0x04000000
262# CHECK: [1]: function offset=0x00003e90, encoding=0x54000000
263# CHECK: [2]: function offset=0x00003ed0, encoding=0x04000000
264# CHECK-NOT: Contents of __compact_unwind section
265
266
267
deps/lld/test/mach-o/unwind-info-simple-x86_64.yaml created+133
......@@ -0,0 +1,133 @@
1# RUN: lld -flavor darwin -arch x86_64 %s -o %t -e _main %p/Inputs/x86_64/libSystem.yaml
2# RUN: llvm-objdump -unwind-info %t | FileCheck %s
3
4# CHECK: Contents of __unwind_info section:
5# CHECK: Version: 0x1
6# CHECK: Common encodings array section offset: 0x1c
7# CHECK: Number of common encodings in array: 0x0
8# CHECK: Personality function array section offset: 0x1c
9# CHECK: Number of personality functions in array: 0x1
10# CHECK: Index array section offset: 0x20
11# CHECK: Number of indices in array: 0x2
12# CHECK: Common encodings: (count = 0)
13# CHECK: Personality functions: (count = 1)
14# CHECK: personality[1]: 0x00001000
15# CHECK: Top level indices: (count = 2)
16# CHECK: [0]: function offset=0x00000efb, 2nd level page offset=0x00000040, LSDA offset=0x00000038
17# CHECK: [1]: function offset=0x00000f00, 2nd level page offset=0x00000000, LSDA offset=0x00000040
18# CHECK: LSDA descriptors:
19# CHECK: [0]: function offset=0x00000efb, LSDA offset=0x00000f00
20# CHECK: Second level indices:
21# CHECK: Second level index[0]: offset in section=0x00000040, base function offset=0x00000efb
22# CHECK: [0]: function offset=0x00000efb, encoding=0x51000000
23# CHECK: [1]: function offset=0x00000efc, encoding=0x01000000
24# CHECK: [2]: function offset=0x00000efd, encoding=0x04000018
25# CHECK: [3]: function offset=0x00000efe, encoding=0x04000040
26# CHECK: [4]: function offset=0x00000eff, encoding=0x00000000
27# CHECK-NOT: Contents of __compact_unwind section
28
29--- !native
30path: '<linker-internal>'
31defined-atoms:
32 - name: GCC_except_table1
33 type: unwind-lsda
34 content: [ FF, 9B, A2, 80, 80, 00, 03, 1A, 08, 00, 00, 00,
35 05, 00, 00, 00, 1A, 00, 00, 00, 01, 0D, 00, 00,
36 00, 64, 00, 00, 00, 00, 00, 00, 00, 00, 01, 00,
37 04, 00, 00, 00 ]
38 - type: compact-unwind
39 content: [ 40, 00, 00, 00, 00, 00, 00, 00, 01, 00, 00, 00,
40 00, 00, 00, 41, 00, 00, 00, 00, 00, 00, 00, 00,
41 E0, 00, 00, 00, 00, 00, 00, 00 ]
42 references:
43 - kind: pointer64Anon
44 offset: 0
45 target: __Z3barv
46 - kind: pointer64
47 offset: 16
48 target: ___gxx_personality_v0
49 - kind: pointer64Anon
50 offset: 24
51 target: GCC_except_table1
52 - type: compact-unwind
53 content: [ C0, 00, 00, 00, 00, 00, 00, 00, 01, 00, 00, 00,
54 00, 00, 00, 01, 00, 00, 00, 00, 00, 00, 00, 00,
55 00, 00, 00, 00, 00, 00, 00, 00 ]
56 references:
57 - kind: pointer64Anon
58 offset: 0
59 target: _main
60 - type: compact-unwind
61 content: [ C1, 00, 00, 00, 00, 00, 00, 00, 01, 00, 00, 00,
62 00, 00, 00, 04, 00, 00, 00, 00, 00, 00, 00, 00,
63 00, 00, 00, 00, 00, 00, 00, 00 ]
64 references:
65 - kind: pointer64Anon
66 offset: 0
67 target: _needsDwarfButNoCompactUnwind
68
69# Generic x86_64 CIE:
70 - name: LCIE
71 type: unwind-cfi
72 content: [ 14, 00, 00, 00, 00, 00, 00, 00, 01, 7A, 52, 00,
73 01, 78, 10, 01, 10, 0C, 07, 08, 90, 01, 00, 00 ]
74
75 - type: unwind-cfi
76 content: [ 24, 00, 00, 00, 1C, 00, 00, 00, C8, FE, FF, FF,
77 FF, FF, FF, FF, 01, 00, 00, 00, 00, 00, 00, 00,
78 00, 41, 0E, 10, 86, 02, 43, 0D, 06, 00, 00, 00,
79 00, 00, 00, 00 ]
80 references:
81 - kind: unwindFDEToFunction
82 offset: 8
83 target: _needsDwarfButNoCompactUnwind
84 - kind: negDelta32
85 offset: 4
86 target: LCIE
87
88 - type: unwind-cfi
89 content: [ 24, 00, 00, 00, 44, 00, 00, 00, C8, FE, FF, FF,
90 FF, FF, FF, FF, 01, 00, 00, 00, 00, 00, 00, 00,
91 00, 41, 0E, 10, 86, 02, 43, 0D, 06, 00, 00, 00,
92 00, 00, 00, 00 ]
93 references:
94 - kind: unwindFDEToFunction
95 offset: 8
96 target: _needsDwarfSaysCompactUnwind
97 - kind: negDelta32
98 offset: 4
99 target: LCIE
100
101 - type: unwind-cfi
102 content: [ 24, 00, 00, 00, 6C, 00, 00, 00, C8, FE, FF, FF,
103 FF, FF, FF, FF, 01, 00, 00, 00, 00, 00, 00, 00,
104 00, 41, 0E, 10, 86, 02, 43, 0D, 06, 00, 00, 00,
105 00, 00, 00, 00 ]
106 references:
107 - kind: unwindFDEToFunction
108 offset: 8
109 target: _main
110 - kind: negDelta32
111 offset: 4
112 target: LCIE
113
114 - name: __Z3barv
115 scope: global
116 content: [ C3 ]
117 - name: _main
118 scope: global
119 content: [ C3 ]
120 - name: _needsDwarfButNoCompactUnwind
121 scope: global
122 content: [ C3 ]
123 - name: _needsDwarfSaysCompactUnwind
124 scope: global
125 content: [ C3 ]
126 - name: _noUnwindData
127 scope: global
128 content: [ C3 ]
129
130shared-library-atoms:
131 - name: ___gxx_personality_v0
132 load-name: '/usr/lib/libc++abi.dylib'
133 type: unknown
deps/lld/test/mach-o/upward-dylib-load-command.yaml created+48
......@@ -0,0 +1,48 @@
1# RUN: lld -flavor darwin -arch x86_64 -dylib %p/Inputs/bar.yaml \
2# RUN: -install_name /usr/lib/libbar.dylib %p/Inputs/x86_64/libSystem.yaml -o %t1.dylib
3# RUN: lld -flavor darwin -arch x86_64 -dylib %s -upward_library %t1.dylib \
4# RUN: -install_name /usr/lib/libfoo.dylib %p/Inputs/x86_64/libSystem.yaml -o %t
5# RUN: llvm-objdump -private-headers %t | FileCheck %s
6#
7#
8# Test upward linking: 1) build libbar.dylib, 2) build libfoo.dylib and upward
9# like with libbar.dylib, 3) dump load commands of libfoo and verify upward link.
10#
11
12--- !mach-o
13arch: x86_64
14file-type: MH_OBJECT
15flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
16sections:
17 - segment: __TEXT
18 section: __text
19 type: S_REGULAR
20 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
21 address: 0x0000000000000000
22 content: [ 0x55, 0x48, 0x89, 0xE5, 0x31, 0xC0, 0x5D, 0xE9,
23 0x00, 0x00, 0x00, 0x00 ]
24 relocations:
25 - offset: 0x00000008
26 type: X86_64_RELOC_BRANCH
27 length: 2
28 pc-rel: true
29 extern: true
30 symbol: 1
31global-symbols:
32 - name: _foo
33 type: N_SECT
34 scope: [ N_EXT ]
35 sect: 1
36 value: 0x0000000000000000
37undefined-symbols:
38 - name: _bar
39 type: N_UNDF
40 scope: [ N_EXT ]
41 value: 0x0000000000000000
42
43...
44
45
46# CHECK: cmd LC_LOAD_UPWARD_DYLIB
47# CHECK-NEXT: cmdsize 48
48# CHECK-NEXT: name /usr/lib/libbar.dylib (offset 24)
deps/lld/test/mach-o/upward-dylib-paths.yaml created+18
......@@ -0,0 +1,18 @@
1#
2#
3# RUN: lld -flavor darwin -arch x86_64 -r -test_file_usage -v \
4# RUN: -path_exists /Custom/Frameworks \
5# RUN: -path_exists /Custom/Frameworks/Bar.framework/Bar \
6# RUN: -path_exists /usr/lib \
7# RUN: -path_exists /usr/lib/libfoo.dylib \
8# RUN: -path_exists /opt/stuff/libstuff.dylib \
9# RUN: -F/Custom/Frameworks \
10# RUN: -upward_framework Bar \
11# RUN: -upward-lfoo \
12# RUN: -upward_library /opt/stuff/libstuff.dylib \
13# RUN: 2>&1 | FileCheck %s
14
15# CHECK: Found upward framework /Custom/Frameworks/Bar.framework/Bar
16# CHECK: Found upward library /usr/lib/libfoo.dylib
17
18
deps/lld/test/mach-o/usage.yaml created+8
......@@ -0,0 +1,8 @@
1# RUN: not lld -flavor darwin | FileCheck %s
2#
3# Test that running darwin linker with no option prints out usage message.
4#
5
6
7# CHECK: USAGE:
8# CHECK: -arch
deps/lld/test/mach-o/use-dylib.yaml created+39
......@@ -0,0 +1,39 @@
1# RUN: lld -flavor darwin -arch x86_64 %s \
2# RUN: %p/Inputs/use-simple-dylib.yaml %p/Inputs/x86_64/libSystem.yaml -dylib -o %t.dylib
3# RUN: llvm-objdump -private-headers %t.dylib | FileCheck %s
4
5# This test ensures that we have a LC_LOAD_DYLIB for libspecial.dylib even though we don't
6# use any atoms from it. This matches the ld64 behaviour.
7--- !mach-o
8arch: x86_64
9file-type: MH_OBJECT
10flags: [ ]
11has-UUID: false
12OS: unknown
13sections:
14 - segment: __TEXT
15 section: __text
16 type: S_REGULAR
17 attributes: [ S_ATTR_PURE_INSTRUCTIONS ]
18 address: 0x0000000000000000
19 content: [ 0x55, 0x48, 0x89, 0xE5, 0xE8, 0x00, 0x00, 0x00,
20 0x00, 0xE8, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x00,
21 0x00, 0x00, 0x00, 0xE8, 0x00, 0x00, 0x00, 0x00,
22 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0xE9, 0x00,
23 0x00, 0x00, 0x00 ]
24global-symbols:
25 - name: _foo
26 type: N_SECT
27 scope: [ N_EXT ]
28 sect: 1
29 value: 0x0000000000000000
30
31
32# CHECK: cmd LC_LOAD_DYLIB
33# CHECK: name libspecial.dylib (offset 24)
34# CHECK: current version 1.0.0
35# CHECK: compatibility version 1.0.0
36# CHECK: cmd LC_LOAD_DYLIB
37# CHECK: name /usr/lib/libSystem.B.dylib (offset 24)
38# CHECK: current version 1.0.0
39# CHECK: compatibility version 1.0.0
deps/lld/test/mach-o/use-simple-dylib.yaml created+73
......@@ -0,0 +1,73 @@
1# RUN: lld -flavor darwin -arch x86_64 -print_atoms -r %s \
2# RUN: %p/Inputs/use-simple-dylib.yaml -o %t | FileCheck %s
3
4
5--- !mach-o
6arch: x86_64
7file-type: MH_OBJECT
8flags: [ ]
9has-UUID: false
10OS: unknown
11sections:
12 - segment: __TEXT
13 section: __text
14 type: S_REGULAR
15 attributes: [ S_ATTR_PURE_INSTRUCTIONS ]
16 address: 0x0000000000000000
17 content: [ 0x55, 0x48, 0x89, 0xE5, 0xE8, 0x00, 0x00, 0x00,
18 0x00, 0xE8, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x00,
19 0x00, 0x00, 0x00, 0xE8, 0x00, 0x00, 0x00, 0x00,
20 0xE8, 0x00, 0x00, 0x00, 0x00, 0x5D, 0xE9, 0x00,
21 0x00, 0x00, 0x00 ]
22global-symbols:
23 - name: _foo
24 type: N_SECT
25 scope: [ N_EXT ]
26 sect: 1
27 value: 0x0000000000000000
28undefined-symbols:
29 - name: _myGlobal
30 type: N_UNDF
31 scope: [ N_EXT ]
32 value: 0x0000000000000000
33 - name: _myGlobalWeak
34 type: N_UNDF
35 scope: [ N_EXT ]
36 value: 0x0000000000000000
37 - name: _myHidden
38 type: N_UNDF
39 scope: [ N_EXT ]
40 value: 0x0000000000000000
41 - name: _myHiddenWeak
42 type: N_UNDF
43 scope: [ N_EXT ]
44 value: 0x0000000000000000
45 - name: _myResolver
46 type: N_UNDF
47 scope: [ N_EXT ]
48 value: 0x0000000000000000
49 - name: _myStatic
50 type: N_UNDF
51 scope: [ N_EXT ]
52 value: 0x0000000000000000
53 - name: _myVariablePreviouslyKnownAsPrivateExtern
54 type: N_UNDF
55 scope: [ N_EXT ]
56 value: 0x0000000000000000
57...
58
59
60# CHECK: undefined-atoms:
61# CHECK: - name: _myStatic
62# CHECK: - name: _myVariablePreviouslyKnownAsPrivateExtern
63# CHECK: shared-library-atoms:
64# CHECK: - name: _myGlobal
65# CHECK: load-name: libspecial.dylib
66# CHECK: - name: _myGlobalWeak
67# CHECK: load-name: libspecial.dylib
68# CHECK: - name: _myHidden
69# CHECK: load-name: libspecial.dylib
70# CHECK: - name: _myHiddenWeak
71# CHECK: load-name: libspecial.dylib
72# CHECK: - name: _myResolver
73# CHECK: load-name: libspecial.dylib
deps/lld/test/mach-o/version-min-load-command-object.yaml created+35
......@@ -0,0 +1,35 @@
1# RUN: lld -flavor darwin -arch x86_64 %s -o %t -r -macosx_version_min 10.8 && llvm-objdump -private-headers %t | FileCheck %s
2# RUN: lld -flavor darwin -arch x86_64 %s -o %t -r && llvm-objdump -private-headers %t | FileCheck %s
3# RUN: lld -flavor darwin -arch x86_64 %s -o %t -r %p/Inputs/no-version-min-load-command-object.yaml && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_VERSION_MIN
4
5# If we are emitting an object file, then we only emit a min version load command if the source object file(s) all have
6# version(s) and either known platforms or contain min version load commands themselves.
7
8--- !mach-o
9arch: x86_64
10file-type: MH_OBJECT
11flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
12min-os-version-kind: LC_VERSION_MIN_MACOSX
13min-os-version: 10.8
14sections:
15 - segment: __TEXT
16 section: __text
17 type: S_REGULAR
18 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
19 address: 0x0000000000000000
20 content: [ 0x00, 0x00, 0x00, 0x00 ]
21global-symbols:
22 - name: _main
23 type: N_SECT
24 scope: [ N_EXT ]
25 sect: 1
26 value: 0x0000000000000000
27...
28
29# CHECK: Load command {{[0-9]*}}
30# CHECK: cmd LC_VERSION_MIN_MACOSX
31# CHECK: cmdsize 16
32# CHECK: version 10.8
33# CHECK: sdk n/a
34
35# NO_VERSION_MIN-NOT: LC_VERSION_MIN_MACOSX
\ No newline at end of file
deps/lld/test/mach-o/version-min-load-command.yaml created+43
......@@ -0,0 +1,43 @@
1# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml && llvm-objdump -private-headers %t | FileCheck %s
2# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml 2>&1 | FileCheck %s --check-prefix=WARNING
3# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -static -version_load_command && llvm-objdump -private-headers %t | FileCheck %s
4# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -no_version_load_command && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_VERSION_MIN
5# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -static -version_load_command -no_version_load_command && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_VERSION_MIN
6# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml -static && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=NO_VERSION_MIN
7
8# RUN: lld -flavor darwin -arch x86_64 -macosx_version_min 10.8 -sdk_version 10.9 %s -o %t -dylib %p/Inputs/x86_64/libSystem.yaml && llvm-objdump -private-headers %t | FileCheck %s --check-prefix=SDK_VERSION
9
10--- !mach-o
11arch: x86_64
12file-type: MH_OBJECT
13flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]
14sections:
15 - segment: __TEXT
16 section: __text
17 type: S_REGULAR
18 attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
19 address: 0x0000000000000000
20 content: [ 0x00, 0x00, 0x00, 0x00 ]
21global-symbols:
22 - name: _main
23 type: N_SECT
24 scope: [ N_EXT ]
25 sect: 1
26 value: 0x0000000000000000
27...
28
29# CHECK: Load command {{[0-9]*}}
30# CHECK: cmd LC_VERSION_MIN_MACOSX
31# CHECK: cmdsize 16
32# CHECK: version 10.8
33# CHECK: sdk 10.8
34
35# SDK_VERSION: Load command {{[0-9]*}}
36# SDK_VERSION: cmd LC_VERSION_MIN_MACOSX
37# SDK_VERSION: cmdsize 16
38# SDK_VERSION: version 10.8
39# SDK_VERSION: sdk 10.9
40
41# WARNING: warning: -sdk_version is required when emitting min version load command. Setting sdk version to match provided min version
42
43# NO_VERSION_MIN-NOT: LC_VERSION_MIN_MACOSX
deps/lld/test/mach-o/write-final-sections.yaml created+165
......@@ -0,0 +1,165 @@
1# RUN: lld -flavor darwin -arch x86_64 %s %p/Inputs/write-final-sections.yaml \
2# RUN: -o %t -e _foo
3# RUN: llvm-readobj -sections -section-data %t | FileCheck %s
4
5--- !native
6defined-atoms:
7# For __TEXT, __text (with typeCode)
8 - name: _foo
9 scope: global
10 content: [ 55 ]
11# CHECK: Name: __text
12# CHECK: Segment: __TEXT
13# CHECK: SectionData (
14# CHECK-NEXT: 0000: 55
15# CHECK-NEXT: )
16
17# For __TEXT, __const (with typeConstant),
18 - type: constant
19 content: [ 01, 00, 00, 00 ]
20# From __TEXT, __literal4, (with typeLiteral4)
21 - scope: hidden
22 type: const-4-byte
23 content: [ 02, 00, 00, 00 ]
24# From __TEXT, __literal8, (with typeLiteral8)
25 - scope: hidden
26 type: const-8-byte
27 content: [ 03, 00, 00, 00, 00, 00, 00, 00 ]
28# From __TEXT, __literal16, (with typeLiteral16)
29 - scope: hidden
30 type: const-16-byte
31 content: [ 04, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00 ]
32# CHECK: Name: __const
33# CHECK: Segment: __TEXT
34# CHECK: SectionData (
35# CHECK-NEXT: 0000: 01000000 02000000 03000000 00000000
36# CHECK-NEXT: 0010: 04000000 00000000 00000000 00000000
37# CHECK-NEXT: )
38
39# For __TEXT, __cstring (with typeCString)
40 - scope: hidden
41 type: c-string
42 content: [ 57, 69, 62, 62, 6C, 65, 00 ]
43 merge: by-content
44# CHECK: Name: __cstring
45# CHECK: Segment: __TEXT
46# CHECK: SectionData (
47# CHECK-NEXT: 0000: 57696262 6C6500
48# CHECK-NEXT: )
49
50# For __TEXT, __ustring (with typeUTF16String)
51 - scope: hidden
52 type: utf16-string
53 content: [ 05, 00 ]
54 merge: by-content
55# CHECK: Name: __ustring
56# CHECK: Segment: __TEXT
57# CHECK: SectionData (
58# CHECK-NEXT: 0000: 0500
59# CHECK-NEXT: )
60
61# For __TEXT, __gcc_except_tab, (with typeLSDA)
62 - name: GCC_except_table0
63 type: unwind-lsda
64 content: [ 06, 00 ]
65# CHECK: Name: __gcc_except_tab
66# CHECK: Segment: __TEXT
67# CHECK: SectionData (
68# CHECK-NEXT: 0000: 0600
69# CHECK-NEXT: )
70
71# For __TEXT, __eh_frame, (with typeCFI)
72 - name: LCIE
73 type: unwind-cfi
74 content: [ 14, 00, 00, 00, 00, 00, 00, 00, 01, 7A, 52, 00,
75 01, 78, 10, 01, 10, 0C, 07, 08, 90, 01, 00, 00 ]
76
77 - type: unwind-cfi
78 content: [ 24, 00, 00, 00, 1C, 00, 00, 00, C8, FE, FF, FF,
79 FF, FF, FF, FF, 01, 00, 00, 00, 00, 00, 00, 00,
80 00, 41, 0E, 10, 86, 02, 43, 0D, 06, 00, 00, 00,
81 00, 00, 00, 00 ]
82 references:
83 - kind: unwindFDEToFunction
84 offset: 8
85 target: _foo
86 - kind: negDelta32
87 offset: 4
88 target: LCIE
89
90# CHECK: Name: __eh_frame
91# CHECK: Segment: __TEXT
92# CHECK: SectionData (
93# CHECK-NEXT: 0000: 14000000 00000000 017A5200 01781001
94# CHECK-NEXT: 0010: 100C0708 90010000 24000000 1C000000
95# CHECK-NEXT: 0020: 70FFFFFF FFFFFFFF 01000000 00000000
96# CHECK-NEXT: 0030: 00410E10 8602430D 06000000 00000000
97# CHECK-NEXT: )
98
99# For __DATA, __data, (with typeData)
100 - name: var
101 type: data
102 content: [ 08 ]
103# CHECK: Name: __data
104# CHECK: Segment: __DATA
105# CHECK: SectionData (
106# CHECK-NEXT: 0000: 08
107# CHECK-NEXT: )
108
109# For __DATA, __bss (with typeZeroFill)
110# FIXME: Attributes & tags of __bss are mostly broken. Should be at end of
111# __DATA, should have size, should have S_ZEROFILL flag.
112 - type: zero-fill
113 size: 8
114# CHECK: Name: __bss
115# CHECK: Segment: __DATA
116
117# For __DATA, __const, (with typeConstData)
118 - type: const-data
119 content: [ 09, 00, 00, 00 ]
120# CHECK: Name: __const
121# CHECK: Segment: __DATA
122# CHECK: SectionData (
123# CHECK-NEXT: 0000: 09000000
124# CHECK-NEXT: )
125
126# For __DATA, __cfstring, (with typeCFString)
127 - type: cfstring
128 content: [ 0A, 00 ]
129# CHECK: Name: __cfstring
130# CHECK: Segment: __DATA
131# CHECK: SectionData (
132# CHECK-NEXT: 0000: 0A00
133# CHECK-NEXT: )
134
135# For __DATA, __got (with typeGOT)
136 - type: got
137 content: [ 0B, 00, 00, 00, 00, 00, 00, 00 ]
138# CHECK: Name: __got
139# CHECK: Segment: __DATA
140# CHECK: SectionData (
141# CHECK-NEXT: 0000: 0B000000 00000000
142# CHECK-NEXT: )
143
144
145# For __DATA, __mod_init_func (with typeInitializerPtr)
146 - type: initializer-pointer
147 content: [ 0C, 00, 00, 00, 00, 00, 00, 00 ]
148# CHECK: Name: __mod_init_func
149# CHECK: Segment: __DATA
150# CHECK: SectionData (
151# CHECK-NEXT: 0000: 0C000000 00000000
152# CHECK-NEXT: )
153
154# For __DATA, __mod_term_func (with typeTerminatorPointer)
155 - type: terminator-pointer
156 content: [ 0D, 00, 00, 00, 00, 00, 00, 00 ]
157# CHECK: Name: __mod_term_func
158# CHECK: Segment: __DATA
159# CHECK: SectionData (
160# CHECK-NEXT: 0000: 0D000000 00000000
161# CHECK-NEXT: )
162
163 - type: compact-unwind
164 content: [ 0E, 00, 00, 00, 00, 00, 00, 00 ]
165# CHECK-NOT: Name: __compact_unwind
deps/lld/test/mach-o/wrong-arch-error.yaml created+28
......@@ -0,0 +1,28 @@
1# RUN: not lld -flavor darwin -arch x86_64 -r %s \
2# RUN: %p/Inputs/wrong-arch-error.yaml 2> %t.err
3# RUN: FileCheck %s < %t.err
4
5--- !mach-o
6arch: x86_64
7file-type: MH_OBJECT
8flags: [ ]
9has-UUID: false
10OS: unknown
11sections:
12 - segment: __TEXT
13 section: __text
14 type: S_REGULAR
15 attributes: [ S_ATTR_PURE_INSTRUCTIONS ]
16 address: 0x0000000000000000
17 content: [ 0xCC ]
18
19global-symbols:
20 - name: _foo
21 type: N_SECT
22 scope: [ N_EXT ]
23 sect: 1
24 value: 0x0000000000000000
25...
26
27
28# CHECK: wrong architecture
deps/lld/tools/lld/CMakeLists.txt created+24
......@@ -0,0 +1,24 @@
1set(LLVM_LINK_COMPONENTS
2 Support
3 )
4
5add_lld_tool(lld
6 lld.cpp
7 )
8
9target_link_libraries(lld
10 lldDriver
11 lldCOFF
12 lldELF
13 )
14
15install(TARGETS lld
16 RUNTIME DESTINATION bin)
17
18if(NOT LLD_SYMLINKS_TO_CREATE)
19 set(LLD_SYMLINKS_TO_CREATE lld-link ld.lld)
20endif()
21
22foreach(link ${LLD_SYMLINKS_TO_CREATE})
23 add_lld_symlink(${link} lld)
24endforeach()
deps/lld/tools/lld/lld.cpp created+113
......@@ -0,0 +1,113 @@
1//===- tools/lld/lld.cpp - Linker Driver Dispatcher -----------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This is the entry point to the lld driver. This is a thin wrapper which
11// dispatches to the given platform specific driver.
12//
13// If there is -flavor option, it is dispatched according to the arguments.
14// If the flavor parameter is not present, then it is dispatched according
15// to argv[0].
16//
17//===----------------------------------------------------------------------===//
18
19#include "lld/Driver/Driver.h"
20#include "llvm/ADT/STLExtras.h"
21#include "llvm/ADT/StringSwitch.h"
22#include "llvm/ADT/Twine.h"
23#include "llvm/Support/ManagedStatic.h"
24#include "llvm/Support/Path.h"
25#include "llvm/Support/PrettyStackTrace.h"
26#include "llvm/Support/Signals.h"
27
28using namespace lld;
29using namespace llvm;
30using namespace llvm::sys;
31
32enum Flavor {
33 Invalid,
34 Gnu, // -flavor gnu
35 WinLink, // -flavor link
36 Darwin, // -flavor darwin
37};
38
39LLVM_ATTRIBUTE_NORETURN static void die(const Twine &S) {
40 errs() << S << "\n";
41 exit(1);
42}
43
44static Flavor getFlavor(StringRef S) {
45 return StringSwitch<Flavor>(S)
46 .CasesLower("ld", "ld.lld", "gnu", Gnu)
47 .CaseLower("link", WinLink)
48 .CaseLower("darwin", Darwin)
49 .Default(Invalid);
50}
51
52static Flavor parseProgname(StringRef Progname) {
53#if __APPLE__
54 // Use Darwin driver for "ld" on Darwin.
55 if (Progname == "ld")
56 return Darwin;
57#endif
58
59#if LLVM_ON_UNIX
60 // Use GNU driver for "ld" on other Unix-like system.
61 if (Progname == "ld")
62 return Gnu;
63#endif
64
65 // Progname may be something like "lld-gnu". Parse it.
66 SmallVector<StringRef, 3> V;
67 Progname.split(V, "-");
68 for (StringRef S : V)
69 if (Flavor F = getFlavor(S))
70 return F;
71 return Invalid;
72}
73
74static Flavor parseFlavor(std::vector<const char *> &V) {
75 // Parse -flavor option.
76 if (V.size() > 1 && V[1] == StringRef("-flavor")) {
77 if (V.size() <= 2)
78 die("missing arg value for '-flavor'");
79 Flavor F = getFlavor(V[2]);
80 if (F == Invalid)
81 die("Unknown flavor: " + StringRef(V[2]));
82 V.erase(V.begin() + 1, V.begin() + 3);
83 return F;
84 }
85
86 // Deduct the flavor from argv[0].
87 StringRef Arg0 = path::filename(V[0]);
88 if (Arg0.endswith_lower(".exe"))
89 Arg0 = Arg0.drop_back(4);
90 return parseProgname(Arg0);
91}
92
93/// Universal linker main(). This linker emulates the gnu, darwin, or
94/// windows linker based on the argv[0] or -flavor option.
95int main(int Argc, const char **Argv) {
96 // Standard set up, so program fails gracefully.
97 sys::PrintStackTraceOnErrorSignal(Argv[0]);
98 PrettyStackTraceProgram StackPrinter(Argc, Argv);
99 llvm_shutdown_obj Shutdown;
100
101 std::vector<const char *> Args(Argv, Argv + Argc);
102 switch (parseFlavor(Args)) {
103 case Gnu:
104 return !elf::link(Args, true);
105 case WinLink:
106 return !coff::link(Args);
107 case Darwin:
108 return !mach_o::link(Args);
109 default:
110 die("lld is a generic driver.\n"
111 "Invoke ld.lld (Unix), ld (macOS) or lld-link (Windows) instead.");
112 }
113}
deps/lld/unittests/CMakeLists.txt created+16
......@@ -0,0 +1,16 @@
1add_custom_target(LLDUnitTests)
2set_target_properties(LLDUnitTests PROPERTIES FOLDER "lld tests")
3
4set(CMAKE_BUILD_WITH_INSTALL_RPATH OFF)
5
6# add_lld_unittest(test_dirname file1.cpp file2.cpp)
7#
8# Will compile the list of files together and link against lld
9# Produces a binary named 'basename(test_dirname)'.
10function(add_lld_unittest test_dirname)
11 add_unittest(LLDUnitTests ${test_dirname} ${ARGN})
12 target_link_libraries(${test_dirname} ${LLVM_COMMON_LIBS})
13endfunction()
14
15add_subdirectory(DriverTests)
16add_subdirectory(MachOTests)
deps/lld/unittests/DriverTests/CMakeLists.txt created+8
......@@ -0,0 +1,8 @@
1add_lld_unittest(DriverTests
2 DarwinLdDriverTest.cpp
3 )
4
5target_link_libraries(DriverTests
6 lldDriver
7 lldMachO
8 )
deps/lld/unittests/DriverTests/DarwinLdDriverTest.cpp created+267
......@@ -0,0 +1,267 @@
1//===- lld/unittest/DarwinLdDriverTest.cpp --------------------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9///
10/// \file
11/// \brief Darwin's ld driver tests.
12///
13//===----------------------------------------------------------------------===//
14
15#include "lld/Driver/Driver.h"
16#include "lld/ReaderWriter/MachOLinkingContext.h"
17#include "llvm/BinaryFormat/MachO.h"
18#include "llvm/Support/raw_ostream.h"
19#include "gtest/gtest.h"
20
21using namespace llvm;
22using namespace lld;
23
24namespace lld {
25namespace mach_o {
26bool parse(llvm::ArrayRef<const char *> args, MachOLinkingContext &ctx,
27 raw_ostream &diagnostics);
28}
29}
30
31namespace {
32class DarwinLdParserTest : public testing::Test {
33protected:
34 int inputFileCount() { return _ctx.getNodes().size(); }
35
36 std::string inputFile(int index) {
37 Node &node = *_ctx.getNodes()[index];
38 if (node.kind() == Node::Kind::File)
39 return cast<FileNode>(&node)->getFile()->path();
40 llvm_unreachable("not handling other types of input files");
41 }
42
43 bool parse(std::vector<const char *> args) {
44 args.insert(args.begin(), "ld");
45 std::string errorMessage;
46 raw_string_ostream os(errorMessage);
47 return mach_o::parse(args, _ctx, os);
48 }
49
50 MachOLinkingContext _ctx;
51};
52}
53
54TEST_F(DarwinLdParserTest, Basic) {
55 EXPECT_TRUE(parse({"foo.o", "bar.o", "-arch", "i386"}));
56 EXPECT_FALSE(_ctx.allowRemainingUndefines());
57 EXPECT_FALSE(_ctx.deadStrip());
58 EXPECT_EQ(2, inputFileCount());
59 EXPECT_EQ("foo.o", inputFile(0));
60 EXPECT_EQ("bar.o", inputFile(1));
61}
62
63TEST_F(DarwinLdParserTest, Output) {
64 EXPECT_TRUE(parse({"-o", "my.out", "foo.o", "-arch", "i386"}));
65 EXPECT_EQ("my.out", _ctx.outputPath());
66}
67
68TEST_F(DarwinLdParserTest, Dylib) {
69 EXPECT_TRUE(parse({"-dylib", "foo.o", "-arch", "i386"}));
70 EXPECT_EQ(llvm::MachO::MH_DYLIB, _ctx.outputMachOType());
71}
72
73TEST_F(DarwinLdParserTest, Relocatable) {
74 EXPECT_TRUE(parse({"-r", "foo.o", "-arch", "i386"}));
75 EXPECT_EQ(llvm::MachO::MH_OBJECT, _ctx.outputMachOType());
76}
77
78TEST_F(DarwinLdParserTest, Bundle) {
79 EXPECT_TRUE(parse({"-bundle", "foo.o", "-arch", "i386"}));
80 EXPECT_EQ(llvm::MachO::MH_BUNDLE, _ctx.outputMachOType());
81}
82
83TEST_F(DarwinLdParserTest, Preload) {
84 EXPECT_TRUE(parse({"-preload", "foo.o", "-arch", "i386"}));
85 EXPECT_EQ(llvm::MachO::MH_PRELOAD, _ctx.outputMachOType());
86}
87
88TEST_F(DarwinLdParserTest, Static) {
89 EXPECT_TRUE(parse({"-static", "foo.o", "-arch", "i386"}));
90 EXPECT_EQ(llvm::MachO::MH_EXECUTE, _ctx.outputMachOType());
91}
92
93TEST_F(DarwinLdParserTest, Entry) {
94 EXPECT_TRUE(parse({"-e", "entryFunc", "foo.o", "-arch", "i386"}));
95 EXPECT_EQ("entryFunc", _ctx.entrySymbolName());
96}
97
98TEST_F(DarwinLdParserTest, DeadStrip) {
99 EXPECT_TRUE(parse({"-arch", "x86_64", "-dead_strip", "foo.o"}));
100 EXPECT_TRUE(_ctx.deadStrip());
101}
102
103TEST_F(DarwinLdParserTest, DeadStripRootsExe) {
104 EXPECT_TRUE(parse({"-arch", "x86_64", "-dead_strip", "foo.o"}));
105 EXPECT_FALSE(_ctx.globalsAreDeadStripRoots());
106}
107
108TEST_F(DarwinLdParserTest, DeadStripRootsDylib) {
109 EXPECT_TRUE(parse({"-arch", "x86_64", "-dylib", "-dead_strip", "foo.o"}));
110 EXPECT_FALSE(_ctx.globalsAreDeadStripRoots());
111}
112
113TEST_F(DarwinLdParserTest, DeadStripRootsRelocatable) {
114 EXPECT_TRUE(parse({"-arch", "x86_64", "-r", "-dead_strip", "foo.o"}));
115 EXPECT_FALSE(_ctx.globalsAreDeadStripRoots());
116}
117
118TEST_F(DarwinLdParserTest, DeadStripRootsExportDynamicExe) {
119 EXPECT_TRUE(
120 parse({"-arch", "x86_64", "-dead_strip", "-export_dynamic", "foo.o"}));
121 EXPECT_TRUE(_ctx.globalsAreDeadStripRoots());
122}
123
124TEST_F(DarwinLdParserTest, DeadStripRootsExportDynamicDylib) {
125 EXPECT_TRUE(parse({"-arch", "x86_64", "-dylib", "-dead_strip",
126 "-export_dynamic", "foo.o"}));
127 EXPECT_TRUE(_ctx.globalsAreDeadStripRoots());
128}
129
130TEST_F(DarwinLdParserTest, DeadStripRootsExportDynamicRelocatable) {
131 EXPECT_TRUE(parse(
132 {"-arch", "x86_64", "-r", "-dead_strip", "-export_dynamic", "foo.o"}));
133 EXPECT_FALSE(_ctx.globalsAreDeadStripRoots());
134}
135
136TEST_F(DarwinLdParserTest, Arch) {
137 EXPECT_TRUE(parse({"-arch", "x86_64", "foo.o"}));
138 EXPECT_EQ(MachOLinkingContext::arch_x86_64, _ctx.arch());
139 EXPECT_EQ((uint32_t)llvm::MachO::CPU_TYPE_X86_64, _ctx.getCPUType());
140 EXPECT_EQ(llvm::MachO::CPU_SUBTYPE_X86_64_ALL, _ctx.getCPUSubType());
141}
142
143TEST_F(DarwinLdParserTest, Arch_x86) {
144 EXPECT_TRUE(parse({"-arch", "i386", "foo.o"}));
145 EXPECT_EQ(MachOLinkingContext::arch_x86, _ctx.arch());
146 EXPECT_EQ((uint32_t)llvm::MachO::CPU_TYPE_I386, _ctx.getCPUType());
147 EXPECT_EQ(llvm::MachO::CPU_SUBTYPE_X86_ALL, _ctx.getCPUSubType());
148}
149
150TEST_F(DarwinLdParserTest, Arch_armv6) {
151 EXPECT_TRUE(parse({"-arch", "armv6", "foo.o"}));
152 EXPECT_EQ(MachOLinkingContext::arch_armv6, _ctx.arch());
153 EXPECT_EQ((uint32_t)llvm::MachO::CPU_TYPE_ARM, _ctx.getCPUType());
154 EXPECT_EQ(llvm::MachO::CPU_SUBTYPE_ARM_V6, _ctx.getCPUSubType());
155}
156
157TEST_F(DarwinLdParserTest, Arch_armv7) {
158 EXPECT_TRUE(parse({"-arch", "armv7", "foo.o"}));
159 EXPECT_EQ(MachOLinkingContext::arch_armv7, _ctx.arch());
160 EXPECT_EQ((uint32_t)llvm::MachO::CPU_TYPE_ARM, _ctx.getCPUType());
161 EXPECT_EQ(llvm::MachO::CPU_SUBTYPE_ARM_V7, _ctx.getCPUSubType());
162}
163
164TEST_F(DarwinLdParserTest, Arch_armv7s) {
165 EXPECT_TRUE(parse({"-arch", "armv7s", "foo.o"}));
166 EXPECT_EQ(MachOLinkingContext::arch_armv7s, _ctx.arch());
167 EXPECT_EQ((uint32_t)llvm::MachO::CPU_TYPE_ARM, _ctx.getCPUType());
168 EXPECT_EQ(llvm::MachO::CPU_SUBTYPE_ARM_V7S, _ctx.getCPUSubType());
169}
170
171TEST_F(DarwinLdParserTest, MinMacOSX10_7) {
172 EXPECT_TRUE(
173 parse({"-macosx_version_min", "10.7", "foo.o", "-arch", "x86_64"}));
174 EXPECT_EQ(MachOLinkingContext::OS::macOSX, _ctx.os());
175 EXPECT_TRUE(_ctx.minOS("10.7", ""));
176 EXPECT_FALSE(_ctx.minOS("10.8", ""));
177}
178
179TEST_F(DarwinLdParserTest, MinMacOSX10_8) {
180 EXPECT_TRUE(
181 parse({"-macosx_version_min", "10.8.3", "foo.o", "-arch", "x86_64"}));
182 EXPECT_EQ(MachOLinkingContext::OS::macOSX, _ctx.os());
183 EXPECT_TRUE(_ctx.minOS("10.7", ""));
184 EXPECT_TRUE(_ctx.minOS("10.8", ""));
185}
186
187TEST_F(DarwinLdParserTest, iOS5) {
188 EXPECT_TRUE(parse({"-ios_version_min", "5.0", "foo.o", "-arch", "armv7"}));
189 EXPECT_EQ(MachOLinkingContext::OS::iOS, _ctx.os());
190 EXPECT_TRUE(_ctx.minOS("", "5.0"));
191 EXPECT_FALSE(_ctx.minOS("", "6.0"));
192}
193
194TEST_F(DarwinLdParserTest, iOS6) {
195 EXPECT_TRUE(parse({"-ios_version_min", "6.0", "foo.o", "-arch", "armv7"}));
196 EXPECT_EQ(MachOLinkingContext::OS::iOS, _ctx.os());
197 EXPECT_TRUE(_ctx.minOS("", "5.0"));
198 EXPECT_TRUE(_ctx.minOS("", "6.0"));
199}
200
201TEST_F(DarwinLdParserTest, iOS_Simulator5) {
202 EXPECT_TRUE(
203 parse({"-ios_simulator_version_min", "5.0", "a.o", "-arch", "i386"}));
204 EXPECT_EQ(MachOLinkingContext::OS::iOS_simulator, _ctx.os());
205 EXPECT_TRUE(_ctx.minOS("", "5.0"));
206 EXPECT_FALSE(_ctx.minOS("", "6.0"));
207}
208
209TEST_F(DarwinLdParserTest, iOS_Simulator6) {
210 EXPECT_TRUE(
211 parse({"-ios_simulator_version_min", "6.0", "a.o", "-arch", "i386"}));
212 EXPECT_EQ(MachOLinkingContext::OS::iOS_simulator, _ctx.os());
213 EXPECT_TRUE(_ctx.minOS("", "5.0"));
214 EXPECT_TRUE(_ctx.minOS("", "6.0"));
215}
216
217TEST_F(DarwinLdParserTest, compatibilityVersion) {
218 EXPECT_TRUE(parse(
219 {"-dylib", "-compatibility_version", "1.2.3", "a.o", "-arch", "i386"}));
220 EXPECT_EQ(_ctx.compatibilityVersion(), 0x10203U);
221}
222
223TEST_F(DarwinLdParserTest, compatibilityVersionInvalidType) {
224 EXPECT_FALSE(parse(
225 {"-bundle", "-compatibility_version", "1.2.3", "a.o", "-arch", "i386"}));
226}
227
228TEST_F(DarwinLdParserTest, compatibilityVersionInvalidValue) {
229 EXPECT_FALSE(parse(
230 {"-bundle", "-compatibility_version", "1,2,3", "a.o", "-arch", "i386"}));
231}
232
233TEST_F(DarwinLdParserTest, currentVersion) {
234 EXPECT_TRUE(
235 parse({"-dylib", "-current_version", "1.2.3", "a.o", "-arch", "i386"}));
236 EXPECT_EQ(_ctx.currentVersion(), 0x10203U);
237}
238
239TEST_F(DarwinLdParserTest, currentVersionInvalidType) {
240 EXPECT_FALSE(
241 parse({"-bundle", "-current_version", "1.2.3", "a.o", "-arch", "i386"}));
242}
243
244TEST_F(DarwinLdParserTest, currentVersionInvalidValue) {
245 EXPECT_FALSE(
246 parse({"-bundle", "-current_version", "1,2,3", "a.o", "-arch", "i386"}));
247}
248
249TEST_F(DarwinLdParserTest, bundleLoader) {
250 EXPECT_TRUE(
251 parse({"-bundle", "-bundle_loader", "/bin/ls", "a.o", "-arch", "i386"}));
252 EXPECT_EQ(_ctx.bundleLoader(), "/bin/ls");
253}
254
255TEST_F(DarwinLdParserTest, bundleLoaderInvalidType) {
256 EXPECT_FALSE(parse({"-bundle_loader", "/bin/ls", "a.o", "-arch", "i386"}));
257}
258
259TEST_F(DarwinLdParserTest, deadStrippableDylib) {
260 EXPECT_TRUE(
261 parse({"-dylib", "-mark_dead_strippable_dylib", "a.o", "-arch", "i386"}));
262 EXPECT_EQ(true, _ctx.deadStrippableDylib());
263}
264
265TEST_F(DarwinLdParserTest, deadStrippableDylibInvalidType) {
266 EXPECT_FALSE(parse({"-mark_dead_strippable_dylib", "a.o", "-arch", "i386"}));
267}
deps/lld/unittests/MachOTests/CMakeLists.txt created+13
......@@ -0,0 +1,13 @@
1
2add_lld_unittest(lldMachOTests
3 MachONormalizedFileBinaryReaderTests.cpp
4 MachONormalizedFileBinaryWriterTests.cpp
5 MachONormalizedFileToAtomsTests.cpp
6 MachONormalizedFileYAMLTests.cpp
7 )
8
9target_link_libraries(lldMachOTests
10 lldDriver
11 lldMachO
12 lldYAML
13 )
deps/lld/unittests/MachOTests/MachONormalizedFileBinaryReaderTests.cpp created+749
......@@ -0,0 +1,749 @@
1//===- lld/unittest/MachOTests/MachONormalizedFileBinaryReaderTests.cpp ---===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "../../lib/ReaderWriter/MachO/MachONormalizedFile.h"
11#include "lld/ReaderWriter/MachOLinkingContext.h"
12#include "llvm/ADT/StringRef.h"
13#include "llvm/BinaryFormat/MachO.h"
14#include "llvm/Support/Error.h"
15#include "llvm/Support/MemoryBuffer.h"
16#include "llvm/Support/YAMLTraits.h"
17#include "gtest/gtest.h"
18#include <cstdint>
19#include <memory>
20
21using llvm::StringRef;
22using llvm::MemoryBuffer;
23
24using namespace lld::mach_o::normalized;
25using namespace llvm::MachO;
26
27static std::unique_ptr<NormalizedFile>
28fromBinary(const uint8_t bytes[], unsigned length, StringRef archStr) {
29 StringRef sr((const char*)bytes, length);
30 std::unique_ptr<MemoryBuffer> mb(MemoryBuffer::getMemBuffer(sr, "", false));
31 llvm::Expected<std::unique_ptr<NormalizedFile>> r =
32 lld::mach_o::normalized::readBinary(
33 mb, lld::MachOLinkingContext::archFromName(archStr));
34 EXPECT_FALSE(!r);
35 return std::move(*r);
36}
37
38// The Mach-O object reader uses functions such as read32 or read64
39// which don't allow unaligned access. Our in-memory object file
40// needs to be aligned to a larger boundary than uint8_t's.
41#if _MSC_VER
42#define FILEBYTES __declspec(align(64)) const uint8_t fileBytes[]
43#else
44#define FILEBYTES const uint8_t fileBytes[] __attribute__((aligned(64)))
45#endif
46
47TEST(BinaryReaderTest, empty_obj_x86_64) {
48 FILEBYTES = {
49 0xcf, 0xfa, 0xed, 0xfe, 0x07, 0x00, 0x00, 0x01,
50 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
51 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
52 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53 0x19, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
54 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
55 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
56 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
59 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
60 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
61 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62 0x5f, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x00, 0x00,
63 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64 0x5f, 0x5f, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00,
65 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
71 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
72 std::unique_ptr<NormalizedFile> f =
73 fromBinary(fileBytes, sizeof(fileBytes), "x86_64");
74 EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_x86_64);
75 EXPECT_EQ((int)(f->fileType), MH_OBJECT);
76 EXPECT_EQ((int)(f->flags), MH_SUBSECTIONS_VIA_SYMBOLS);
77 EXPECT_TRUE(f->localSymbols.empty());
78 EXPECT_TRUE(f->globalSymbols.empty());
79 EXPECT_TRUE(f->undefinedSymbols.empty());
80}
81
82TEST(BinaryReaderTest, empty_obj_x86) {
83 FILEBYTES = {
84 0xce, 0xfa, 0xed, 0xfe, 0x07, 0x00, 0x00, 0x00,
85 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
86 0x01, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00,
87 0x00, 0x20, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
88 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
89 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
90 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
91 0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
92 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
93 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
94 0x00, 0x00, 0x00, 0x00, 0x5f, 0x5f, 0x74, 0x65,
95 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
96 0x00, 0x00, 0x00, 0x00, 0x5f, 0x5f, 0x54, 0x45,
97 0x58, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
98 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
99 0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
100 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
101 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
102 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
103 std::unique_ptr<NormalizedFile> f =
104 fromBinary(fileBytes, sizeof(fileBytes), "i386");
105 EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_x86);
106 EXPECT_EQ((int)(f->fileType), MH_OBJECT);
107 EXPECT_EQ((int)(f->flags), MH_SUBSECTIONS_VIA_SYMBOLS);
108 EXPECT_TRUE(f->localSymbols.empty());
109 EXPECT_TRUE(f->globalSymbols.empty());
110 EXPECT_TRUE(f->undefinedSymbols.empty());
111}
112
113TEST(BinaryReaderTest, empty_obj_ppc) {
114 FILEBYTES = {
115 0xfe, 0xed, 0xfa, 0xce, 0x00, 0x00, 0x00, 0x12,
116 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
117 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7c,
118 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x01,
119 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00,
120 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
121 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
122 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
123 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
124 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01,
125 0x00, 0x00, 0x00, 0x00, 0x5f, 0x5f, 0x74, 0x65,
126 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
127 0x00, 0x00, 0x00, 0x00, 0x5f, 0x5f, 0x54, 0x45,
128 0x58, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
129 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
130 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
131 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
132 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00,
133 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
134 std::unique_ptr<NormalizedFile> f =
135 fromBinary(fileBytes, sizeof(fileBytes), "ppc");
136 EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_ppc);
137 EXPECT_EQ((int)(f->fileType), MH_OBJECT);
138 EXPECT_EQ((int)(f->flags), MH_SUBSECTIONS_VIA_SYMBOLS);
139 EXPECT_TRUE(f->localSymbols.empty());
140 EXPECT_TRUE(f->globalSymbols.empty());
141 EXPECT_TRUE(f->undefinedSymbols.empty());
142}
143
144TEST(BinaryReaderTest, empty_obj_armv7) {
145 FILEBYTES = {
146 0xce, 0xfa, 0xed, 0xfe, 0x0c, 0x00, 0x00, 0x00,
147 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
148 0x01, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00,
149 0x00, 0x20, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
150 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
151 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
152 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
153 0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
154 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
155 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
156 0x00, 0x00, 0x00, 0x00, 0x5f, 0x5f, 0x74, 0x65,
157 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
158 0x00, 0x00, 0x00, 0x00, 0x5f, 0x5f, 0x54, 0x45,
159 0x58, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
160 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
161 0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
162 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
163 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
164 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
165 std::unique_ptr<NormalizedFile> f =
166 fromBinary(fileBytes, sizeof(fileBytes), "armv7");
167 EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_armv7);
168 EXPECT_EQ((int)(f->fileType), MH_OBJECT);
169 EXPECT_EQ((int)(f->flags), MH_SUBSECTIONS_VIA_SYMBOLS);
170 EXPECT_TRUE(f->localSymbols.empty());
171 EXPECT_TRUE(f->globalSymbols.empty());
172 EXPECT_TRUE(f->undefinedSymbols.empty());
173}
174
175TEST(BinaryReaderTest, empty_obj_x86_64_arm7) {
176 FILEBYTES = {
177#include "empty_obj_x86_armv7.txt"
178 };
179 std::unique_ptr<NormalizedFile> f =
180 fromBinary(fileBytes, sizeof(fileBytes), "x86_64");
181 EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_x86_64);
182 EXPECT_EQ((int)(f->fileType), MH_OBJECT);
183 EXPECT_EQ((int)(f->flags), MH_SUBSECTIONS_VIA_SYMBOLS);
184 EXPECT_TRUE(f->localSymbols.empty());
185 EXPECT_TRUE(f->globalSymbols.empty());
186 EXPECT_TRUE(f->undefinedSymbols.empty());
187
188 std::unique_ptr<NormalizedFile> f2 =
189 fromBinary(fileBytes, sizeof(fileBytes), "armv7");
190 EXPECT_EQ(f2->arch, lld::MachOLinkingContext::arch_armv7);
191 EXPECT_EQ((int)(f2->fileType), MH_OBJECT);
192 EXPECT_EQ((int)(f2->flags), MH_SUBSECTIONS_VIA_SYMBOLS);
193 EXPECT_TRUE(f2->localSymbols.empty());
194 EXPECT_TRUE(f2->globalSymbols.empty());
195 EXPECT_TRUE(f2->undefinedSymbols.empty());
196}
197
198TEST(BinaryReaderTest, hello_obj_x86_64) {
199 FILEBYTES = {
200 0xCF, 0xFA, 0xED, 0xFE, 0x07, 0x00, 0x00, 0x01,
201 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
202 0x03, 0x00, 0x00, 0x00, 0x50, 0x01, 0x00, 0x00,
203 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
204 0x19, 0x00, 0x00, 0x00, 0xE8, 0x00, 0x00, 0x00,
205 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
206 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
207 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
208 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
209 0x70, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
210 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
211 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
212 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
213 0x5F, 0x5F, 0x74, 0x65, 0x78, 0x74, 0x00, 0x00,
214 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
215 0x5F, 0x5F, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00,
216 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
217 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
218 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
219 0x70, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
220 0xA4, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
221 0x00, 0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00,
222 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
223 0x5F, 0x5F, 0x63, 0x73, 0x74, 0x72, 0x69, 0x6E,
224 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
225 0x5F, 0x5F, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00,
226 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
227 0x2D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
228 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
229 0x9D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
230 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
231 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
232 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
233 0x02, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
234 0xB4, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
235 0xE4, 0x01, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00,
236 0x0B, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00,
237 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
238 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
239 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
240 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
241 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
242 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
243 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
244 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
245 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
246 0x55, 0x48, 0x89, 0xE5, 0x48, 0x83, 0xEC, 0x10,
247 0x48, 0x8D, 0x3D, 0x00, 0x00, 0x00, 0x00, 0xC7,
248 0x45, 0xFC, 0x00, 0x00, 0x00, 0x00, 0xB0, 0x00,
249 0xE8, 0x00, 0x00, 0x00, 0x00, 0xB9, 0x00, 0x00,
250 0x00, 0x00, 0x89, 0x45, 0xF8, 0x89, 0xC8, 0x48,
251 0x83, 0xC4, 0x10, 0x5D, 0xC3, 0x68, 0x65, 0x6C,
252 0x6C, 0x6F, 0x0A, 0x00, 0x19, 0x00, 0x00, 0x00,
253 0x02, 0x00, 0x00, 0x2D, 0x0B, 0x00, 0x00, 0x00,
254 0x00, 0x00, 0x00, 0x1D, 0x0F, 0x00, 0x00, 0x00,
255 0x0E, 0x02, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00,
256 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
257 0x0F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
258 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
259 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
260 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x6D, 0x61,
261 0x69, 0x6E, 0x00, 0x5F, 0x70, 0x72, 0x69, 0x6E,
262 0x74, 0x66, 0x00, 0x4C, 0x5F, 0x2E, 0x73, 0x74,
263 0x72, 0x00, 0x00, 0x00 };
264 std::unique_ptr<NormalizedFile> f =
265 fromBinary(fileBytes, sizeof(fileBytes), "x86_64");
266
267 EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_x86_64);
268 EXPECT_EQ((int)(f->fileType), MH_OBJECT);
269 EXPECT_EQ((int)(f->flags), MH_SUBSECTIONS_VIA_SYMBOLS);
270 EXPECT_EQ(f->sections.size(), 2UL);
271 const Section& text = f->sections[0];
272 EXPECT_TRUE(text.segmentName.equals("__TEXT"));
273 EXPECT_TRUE(text.sectionName.equals("__text"));
274 EXPECT_EQ(text.type, S_REGULAR);
275 EXPECT_EQ(text.attributes,SectionAttr(S_ATTR_PURE_INSTRUCTIONS
276 | S_ATTR_SOME_INSTRUCTIONS));
277 EXPECT_EQ((uint16_t)text.alignment, 16U);
278 EXPECT_EQ(text.address, Hex64(0x0));
279 EXPECT_EQ(text.content.size(), 45UL);
280 EXPECT_EQ((int)(text.content[0]), 0x55);
281 EXPECT_EQ((int)(text.content[1]), 0x48);
282 EXPECT_TRUE(text.indirectSymbols.empty());
283 EXPECT_EQ(text.relocations.size(), 2UL);
284 const Relocation& call = text.relocations[0];
285 EXPECT_EQ(call.offset, Hex32(0x19));
286 EXPECT_EQ(call.type, X86_64_RELOC_BRANCH);
287 EXPECT_EQ(call.length, 2);
288 EXPECT_EQ(call.isExtern, true);
289 EXPECT_EQ(call.symbol, 2U);
290 const Relocation& str = text.relocations[1];
291 EXPECT_EQ(str.offset, Hex32(0xB));
292 EXPECT_EQ(str.type, X86_64_RELOC_SIGNED);
293 EXPECT_EQ(str.length, 2);
294 EXPECT_EQ(str.isExtern, true);
295 EXPECT_EQ(str.symbol, 0U);
296
297 const Section& cstring = f->sections[1];
298 EXPECT_TRUE(cstring.segmentName.equals("__TEXT"));
299 EXPECT_TRUE(cstring.sectionName.equals("__cstring"));
300 EXPECT_EQ(cstring.type, S_CSTRING_LITERALS);
301 EXPECT_EQ(cstring.attributes, SectionAttr(0));
302 EXPECT_EQ((uint16_t)cstring.alignment, 1U);
303 EXPECT_EQ(cstring.address, Hex64(0x02D));
304 EXPECT_EQ(cstring.content.size(), 7UL);
305 EXPECT_EQ((int)(cstring.content[0]), 0x68);
306 EXPECT_EQ((int)(cstring.content[1]), 0x65);
307 EXPECT_EQ((int)(cstring.content[2]), 0x6c);
308 EXPECT_TRUE(cstring.indirectSymbols.empty());
309 EXPECT_TRUE(cstring.relocations.empty());
310
311 EXPECT_EQ(f->localSymbols.size(), 1UL);
312 const Symbol& strLabel = f->localSymbols[0];
313 EXPECT_EQ(strLabel.type, N_SECT);
314 EXPECT_EQ(strLabel.sect, 2);
315 EXPECT_EQ(strLabel.value, Hex64(0x2D));
316 EXPECT_EQ(f->globalSymbols.size(), 1UL);
317 const Symbol& mainLabel = f->globalSymbols[0];
318 EXPECT_TRUE(mainLabel.name.equals("_main"));
319 EXPECT_EQ(mainLabel.type, N_SECT);
320 EXPECT_EQ(mainLabel.sect, 1);
321 EXPECT_EQ(mainLabel.scope, SymbolScope(N_EXT));
322 EXPECT_EQ(mainLabel.value, Hex64(0x0));
323 EXPECT_EQ(f->undefinedSymbols.size(), 1UL);
324 const Symbol& printfLabel = f->undefinedSymbols[0];
325 EXPECT_TRUE(printfLabel.name.equals("_printf"));
326 EXPECT_EQ(printfLabel.type, N_UNDF);
327 EXPECT_EQ(printfLabel.scope, SymbolScope(N_EXT));
328}
329
330TEST(BinaryReaderTest, hello_obj_x86) {
331 FILEBYTES = {
332 0xCE, 0xFA, 0xED, 0xFE, 0x07, 0x00, 0x00, 0x00,
333 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
334 0x03, 0x00, 0x00, 0x00, 0x28, 0x01, 0x00, 0x00,
335 0x00, 0x20, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
336 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
337 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
338 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
339 0x37, 0x00, 0x00, 0x00, 0x44, 0x01, 0x00, 0x00,
340 0x37, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
341 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
342 0x00, 0x00, 0x00, 0x00, 0x5F, 0x5F, 0x74, 0x65,
343 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
344 0x00, 0x00, 0x00, 0x00, 0x5F, 0x5F, 0x54, 0x45,
345 0x58, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
346 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
347 0x30, 0x00, 0x00, 0x00, 0x44, 0x01, 0x00, 0x00,
348 0x04, 0x00, 0x00, 0x00, 0x7C, 0x01, 0x00, 0x00,
349 0x03, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x80,
350 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
351 0x5F, 0x5F, 0x63, 0x73, 0x74, 0x72, 0x69, 0x6E,
352 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
353 0x5F, 0x5F, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00,
354 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
355 0x30, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
356 0x74, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
357 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
358 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
359 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
360 0x18, 0x00, 0x00, 0x00, 0x94, 0x01, 0x00, 0x00,
361 0x02, 0x00, 0x00, 0x00, 0xAC, 0x01, 0x00, 0x00,
362 0x10, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
363 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
364 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
365 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
366 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
367 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
368 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
369 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
370 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
371 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
372 0x00, 0x00, 0x00, 0x00, 0x55, 0x89, 0xE5, 0x83,
373 0xEC, 0x18, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x58,
374 0x8D, 0x80, 0x25, 0x00, 0x00, 0x00, 0xC7, 0x45,
375 0xFC, 0x00, 0x00, 0x00, 0x00, 0x89, 0x04, 0x24,
376 0xE8, 0xDF, 0xFF, 0xFF, 0xFF, 0xB9, 0x00, 0x00,
377 0x00, 0x00, 0x89, 0x45, 0xF8, 0x89, 0xC8, 0x83,
378 0xC4, 0x18, 0x5D, 0xC3, 0x68, 0x65, 0x6C, 0x6C,
379 0x6F, 0x0A, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00,
380 0x01, 0x00, 0x00, 0x0D, 0x0E, 0x00, 0x00, 0xA4,
381 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA1,
382 0x0B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
383 0x0F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
384 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
385 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x6D, 0x61,
386 0x69, 0x6E, 0x00, 0x5F, 0x70, 0x72, 0x69, 0x6E,
387 0x74, 0x66, 0x00, 0x00
388 };
389 std::unique_ptr<NormalizedFile> f =
390 fromBinary(fileBytes, sizeof(fileBytes), "i386");
391
392 EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_x86);
393 EXPECT_EQ((int)(f->fileType), MH_OBJECT);
394 EXPECT_EQ((int)(f->flags), MH_SUBSECTIONS_VIA_SYMBOLS);
395 EXPECT_EQ(f->sections.size(), 2UL);
396 const Section& text = f->sections[0];
397 EXPECT_TRUE(text.segmentName.equals("__TEXT"));
398 EXPECT_TRUE(text.sectionName.equals("__text"));
399 EXPECT_EQ(text.type, S_REGULAR);
400 EXPECT_EQ(text.attributes,SectionAttr(S_ATTR_PURE_INSTRUCTIONS
401 | S_ATTR_SOME_INSTRUCTIONS));
402 EXPECT_EQ((uint16_t)text.alignment, 16U);
403 EXPECT_EQ(text.address, Hex64(0x0));
404 EXPECT_EQ(text.content.size(), 48UL);
405 EXPECT_EQ((int)(text.content[0]), 0x55);
406 EXPECT_EQ((int)(text.content[1]), 0x89);
407 EXPECT_TRUE(text.indirectSymbols.empty());
408 EXPECT_EQ(text.relocations.size(), 3UL);
409 const Relocation& call = text.relocations[0];
410 EXPECT_EQ(call.offset, Hex32(0x1D));
411 EXPECT_EQ(call.scattered, false);
412 EXPECT_EQ(call.type, GENERIC_RELOC_VANILLA);
413 EXPECT_EQ(call.pcRel, true);
414 EXPECT_EQ(call.length, 2);
415 EXPECT_EQ(call.isExtern, true);
416 EXPECT_EQ(call.symbol, 1U);
417 const Relocation& sectDiff = text.relocations[1];
418 EXPECT_EQ(sectDiff.offset, Hex32(0xE));
419 EXPECT_EQ(sectDiff.scattered, true);
420 EXPECT_EQ(sectDiff.type, GENERIC_RELOC_LOCAL_SECTDIFF);
421 EXPECT_EQ(sectDiff.pcRel, false);
422 EXPECT_EQ(sectDiff.length, 2);
423 EXPECT_EQ(sectDiff.value, 0x30U);
424 const Relocation& pair = text.relocations[2];
425 EXPECT_EQ(pair.offset, Hex32(0x0));
426 EXPECT_EQ(pair.scattered, true);
427 EXPECT_EQ(pair.type, GENERIC_RELOC_PAIR);
428 EXPECT_EQ(pair.pcRel, false);
429 EXPECT_EQ(pair.length, 2);
430 EXPECT_EQ(pair.value, 0x0BU);
431
432 const Section& cstring = f->sections[1];
433 EXPECT_TRUE(cstring.segmentName.equals("__TEXT"));
434 EXPECT_TRUE(cstring.sectionName.equals("__cstring"));
435 EXPECT_EQ(cstring.type, S_CSTRING_LITERALS);
436 EXPECT_EQ(cstring.attributes, SectionAttr(0));
437 EXPECT_EQ((uint16_t)cstring.alignment, 1U);
438 EXPECT_EQ(cstring.address, Hex64(0x030));
439 EXPECT_EQ(cstring.content.size(), 7UL);
440 EXPECT_EQ((int)(cstring.content[0]), 0x68);
441 EXPECT_EQ((int)(cstring.content[1]), 0x65);
442 EXPECT_EQ((int)(cstring.content[2]), 0x6c);
443 EXPECT_TRUE(cstring.indirectSymbols.empty());
444 EXPECT_TRUE(cstring.relocations.empty());
445
446 EXPECT_EQ(f->localSymbols.size(), 0UL);
447 EXPECT_EQ(f->globalSymbols.size(), 1UL);
448 const Symbol& mainLabel = f->globalSymbols[0];
449 EXPECT_TRUE(mainLabel.name.equals("_main"));
450 EXPECT_EQ(mainLabel.type, N_SECT);
451 EXPECT_EQ(mainLabel.sect, 1);
452 EXPECT_EQ(mainLabel.scope, SymbolScope(N_EXT));
453 EXPECT_EQ(mainLabel.value, Hex64(0x0));
454 EXPECT_EQ(f->undefinedSymbols.size(), 1UL);
455 const Symbol& printfLabel = f->undefinedSymbols[0];
456 EXPECT_TRUE(printfLabel.name.equals("_printf"));
457 EXPECT_EQ(printfLabel.type, N_UNDF);
458 EXPECT_EQ(printfLabel.scope, SymbolScope(N_EXT));
459}
460
461TEST(BinaryReaderTest, hello_obj_armv7) {
462 FILEBYTES = {
463 0xCE, 0xFA, 0xED, 0xFE, 0x0C, 0x00, 0x00, 0x00,
464 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
465 0x03, 0x00, 0x00, 0x00, 0x28, 0x01, 0x00, 0x00,
466 0x00, 0x20, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
467 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
468 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
469 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
470 0x31, 0x00, 0x00, 0x00, 0x44, 0x01, 0x00, 0x00,
471 0x31, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
472 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
473 0x00, 0x00, 0x00, 0x00, 0x5F, 0x5F, 0x74, 0x65,
474 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
475 0x00, 0x00, 0x00, 0x00, 0x5F, 0x5F, 0x54, 0x45,
476 0x58, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
477 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
478 0x2A, 0x00, 0x00, 0x00, 0x44, 0x01, 0x00, 0x00,
479 0x02, 0x00, 0x00, 0x00, 0x78, 0x01, 0x00, 0x00,
480 0x05, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x80,
481 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
482 0x5F, 0x5F, 0x63, 0x73, 0x74, 0x72, 0x69, 0x6E,
483 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
484 0x5F, 0x5F, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00,
485 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
486 0x2A, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
487 0x6E, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
488 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
489 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
490 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
491 0x18, 0x00, 0x00, 0x00, 0xA0, 0x01, 0x00, 0x00,
492 0x02, 0x00, 0x00, 0x00, 0xB8, 0x01, 0x00, 0x00,
493 0x10, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00,
494 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
495 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
496 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
497 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
498 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
499 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
500 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
501 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
502 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
503 0x00, 0x00, 0x00, 0x00, 0x80, 0xB5, 0x6F, 0x46,
504 0x82, 0xB0, 0x40, 0xF2, 0x18, 0x00, 0xC0, 0xF2,
505 0x00, 0x00, 0x78, 0x44, 0x00, 0x21, 0xC0, 0xF2,
506 0x00, 0x01, 0x01, 0x91, 0xFF, 0xF7, 0xF2, 0xFF,
507 0x00, 0x21, 0xC0, 0xF2, 0x00, 0x01, 0x00, 0x90,
508 0x08, 0x46, 0x02, 0xB0, 0x80, 0xBD, 0x68, 0x65,
509 0x6C, 0x6C, 0x6F, 0x0A, 0x00, 0x00, 0x00, 0x00,
510 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x6D,
511 0x0A, 0x00, 0x00, 0xB9, 0x2A, 0x00, 0x00, 0x00,
512 0x18, 0x00, 0x00, 0xB1, 0x0E, 0x00, 0x00, 0x00,
513 0x06, 0x00, 0x00, 0xA9, 0x2A, 0x00, 0x00, 0x00,
514 0x00, 0x00, 0x00, 0xA1, 0x0E, 0x00, 0x00, 0x00,
515 0x01, 0x00, 0x00, 0x00, 0x0F, 0x01, 0x08, 0x00,
516 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
517 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
518 0x00, 0x5F, 0x6D, 0x61, 0x69, 0x6E, 0x00, 0x5F,
519 0x70, 0x72, 0x69, 0x6E, 0x74, 0x66, 0x00, 0x00
520 };
521 std::unique_ptr<NormalizedFile> f =
522 fromBinary(fileBytes, sizeof(fileBytes), "armv7");
523
524 EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_armv7);
525 EXPECT_EQ((int)(f->fileType), MH_OBJECT);
526 EXPECT_EQ((int)(f->flags), MH_SUBSECTIONS_VIA_SYMBOLS);
527 EXPECT_EQ(f->sections.size(), 2UL);
528 const Section& text = f->sections[0];
529 EXPECT_TRUE(text.segmentName.equals("__TEXT"));
530 EXPECT_TRUE(text.sectionName.equals("__text"));
531 EXPECT_EQ(text.type, S_REGULAR);
532 EXPECT_EQ(text.attributes,SectionAttr(S_ATTR_PURE_INSTRUCTIONS
533 | S_ATTR_SOME_INSTRUCTIONS));
534 EXPECT_EQ((uint16_t)text.alignment, 4U);
535 EXPECT_EQ(text.address, Hex64(0x0));
536 EXPECT_EQ(text.content.size(), 42UL);
537 EXPECT_EQ((int)(text.content[0]), 0x80);
538 EXPECT_EQ((int)(text.content[1]), 0xB5);
539 EXPECT_TRUE(text.indirectSymbols.empty());
540 EXPECT_EQ(text.relocations.size(), 5UL);
541 const Relocation& call = text.relocations[0];
542 EXPECT_EQ(call.offset, Hex32(0x18));
543 EXPECT_EQ(call.scattered, false);
544 EXPECT_EQ(call.type, ARM_THUMB_RELOC_BR22);
545 EXPECT_EQ(call.length, 2);
546 EXPECT_EQ(call.isExtern, true);
547 EXPECT_EQ(call.symbol, 1U);
548 const Relocation& movt = text.relocations[1];
549 EXPECT_EQ(movt.offset, Hex32(0xA));
550 EXPECT_EQ(movt.scattered, true);
551 EXPECT_EQ(movt.type, ARM_RELOC_HALF_SECTDIFF);
552 EXPECT_EQ(movt.length, 3);
553 EXPECT_EQ(movt.value, Hex32(0x2A));
554 const Relocation& movtPair = text.relocations[2];
555 EXPECT_EQ(movtPair.offset, Hex32(0x18));
556 EXPECT_EQ(movtPair.scattered, true);
557 EXPECT_EQ(movtPair.type, ARM_RELOC_PAIR);
558 EXPECT_EQ(movtPair.length, 3);
559 EXPECT_EQ(movtPair.value, Hex32(0xE));
560 const Relocation& movw = text.relocations[3];
561 EXPECT_EQ(movw.offset, Hex32(0x6));
562 EXPECT_EQ(movw.scattered, true);
563 EXPECT_EQ(movw.type, ARM_RELOC_HALF_SECTDIFF);
564 EXPECT_EQ(movw.length, 2);
565 EXPECT_EQ(movw.value, Hex32(0x2A));
566 const Relocation& movwPair = text.relocations[4];
567 EXPECT_EQ(movwPair.offset, Hex32(0x0));
568 EXPECT_EQ(movwPair.scattered, true);
569 EXPECT_EQ(movwPair.type, ARM_RELOC_PAIR);
570 EXPECT_EQ(movwPair.length, 2);
571 EXPECT_EQ(movwPair.value, Hex32(0xE));
572
573 const Section& cstring = f->sections[1];
574 EXPECT_TRUE(cstring.segmentName.equals("__TEXT"));
575 EXPECT_TRUE(cstring.sectionName.equals("__cstring"));
576 EXPECT_EQ(cstring.type, S_CSTRING_LITERALS);
577 EXPECT_EQ(cstring.attributes, SectionAttr(0));
578 EXPECT_EQ((uint16_t)cstring.alignment, 1U);
579 EXPECT_EQ(cstring.address, Hex64(0x02A));
580 EXPECT_EQ(cstring.content.size(), 7UL);
581 EXPECT_EQ((int)(cstring.content[0]), 0x68);
582 EXPECT_EQ((int)(cstring.content[1]), 0x65);
583 EXPECT_EQ((int)(cstring.content[2]), 0x6c);
584 EXPECT_TRUE(cstring.indirectSymbols.empty());
585 EXPECT_TRUE(cstring.relocations.empty());
586
587 EXPECT_EQ(f->localSymbols.size(), 0UL);
588 EXPECT_EQ(f->globalSymbols.size(), 1UL);
589 const Symbol& mainLabel = f->globalSymbols[0];
590 EXPECT_TRUE(mainLabel.name.equals("_main"));
591 EXPECT_EQ(mainLabel.type, N_SECT);
592 EXPECT_EQ(mainLabel.sect, 1);
593 EXPECT_EQ(mainLabel.scope, SymbolScope(N_EXT));
594 EXPECT_EQ(mainLabel.value, Hex64(0x0));
595 EXPECT_EQ(f->undefinedSymbols.size(), 1UL);
596 const Symbol& printfLabel = f->undefinedSymbols[0];
597 EXPECT_TRUE(printfLabel.name.equals("_printf"));
598 EXPECT_EQ(printfLabel.type, N_UNDF);
599 EXPECT_EQ(printfLabel.scope, SymbolScope(N_EXT));
600}
601
602TEST(BinaryReaderTest, hello_obj_ppc) {
603 FILEBYTES = {
604 0xFE, 0xED, 0xFA, 0xCE, 0x00, 0x00, 0x00, 0x12,
605 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
606 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x01, 0x28,
607 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x01,
608 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00,
609 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
610 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
611 0x00, 0x00, 0x00, 0x4B, 0x00, 0x00, 0x01, 0x44,
612 0x00, 0x00, 0x00, 0x4B, 0x00, 0x00, 0x00, 0x07,
613 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02,
614 0x00, 0x00, 0x00, 0x00, 0x5F, 0x5F, 0x74, 0x65,
615 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
616 0x00, 0x00, 0x00, 0x00, 0x5F, 0x5F, 0x54, 0x45,
617 0x58, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
618 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
619 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x01, 0x44,
620 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0x90,
621 0x00, 0x00, 0x00, 0x05, 0x80, 0x00, 0x04, 0x00,
622 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
623 0x5F, 0x5F, 0x63, 0x73, 0x74, 0x72, 0x69, 0x6E,
624 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
625 0x5F, 0x5F, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00,
626 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
627 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x07,
628 0x00, 0x00, 0x01, 0x88, 0x00, 0x00, 0x00, 0x02,
629 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
630 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
631 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
632 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x01, 0xB8,
633 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x01, 0xD0,
634 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x0B,
635 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00,
636 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
637 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01,
638 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
639 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
640 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
641 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
642 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
643 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
644 0x00, 0x00, 0x00, 0x00, 0x7C, 0x08, 0x02, 0xA6,
645 0xBF, 0xC1, 0xFF, 0xF8, 0x90, 0x01, 0x00, 0x08,
646 0x94, 0x21, 0xFF, 0xB0, 0x7C, 0x3E, 0x0B, 0x78,
647 0x42, 0x9F, 0x00, 0x05, 0x7F, 0xE8, 0x02, 0xA6,
648 0x3C, 0x5F, 0x00, 0x00, 0x38, 0x62, 0x00, 0x2C,
649 0x4B, 0xFF, 0xFF, 0xDD, 0x38, 0x00, 0x00, 0x00,
650 0x7C, 0x03, 0x03, 0x78, 0x80, 0x21, 0x00, 0x00,
651 0x80, 0x01, 0x00, 0x08, 0x7C, 0x08, 0x03, 0xA6,
652 0xBB, 0xC1, 0xFF, 0xF8, 0x4E, 0x80, 0x00, 0x20,
653 0x68, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x00, 0x00,
654 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x01, 0xD3,
655 0xAB, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x44,
656 0xA1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
657 0xAC, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x44,
658 0xA1, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x18,
659 0x00, 0x00, 0x00, 0x01, 0x0F, 0x01, 0x00, 0x00,
660 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
661 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
662 0x00, 0x5F, 0x6D, 0x61, 0x69, 0x6E, 0x00, 0x5F,
663 0x70, 0x72, 0x69, 0x6E, 0x74, 0x66, 0x00, 0x00
664 };
665 std::unique_ptr<NormalizedFile> f =
666 fromBinary(fileBytes, sizeof(fileBytes), "ppc");
667
668 EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_ppc);
669 EXPECT_EQ((int)(f->fileType), MH_OBJECT);
670 EXPECT_EQ((int)(f->flags), MH_SUBSECTIONS_VIA_SYMBOLS);
671 EXPECT_EQ(f->sections.size(), 2UL);
672 const Section& text = f->sections[0];
673 EXPECT_TRUE(text.segmentName.equals("__TEXT"));
674 EXPECT_TRUE(text.sectionName.equals("__text"));
675 EXPECT_EQ(text.type, S_REGULAR);
676 EXPECT_EQ(text.attributes,SectionAttr(S_ATTR_PURE_INSTRUCTIONS
677 | S_ATTR_SOME_INSTRUCTIONS));
678 EXPECT_EQ((uint16_t)text.alignment, 4U);
679 EXPECT_EQ(text.address, Hex64(0x0));
680 EXPECT_EQ(text.content.size(), 68UL);
681 EXPECT_EQ((int)(text.content[0]), 0x7C);
682 EXPECT_EQ((int)(text.content[1]), 0x08);
683 EXPECT_TRUE(text.indirectSymbols.empty());
684 EXPECT_EQ(text.relocations.size(), 5UL);
685 const Relocation& bl = text.relocations[0];
686 EXPECT_EQ(bl.offset, Hex32(0x24));
687 EXPECT_EQ(bl.type, PPC_RELOC_BR24);
688 EXPECT_EQ(bl.length, 2);
689 EXPECT_EQ(bl.isExtern, true);
690 EXPECT_EQ(bl.symbol, 1U);
691 const Relocation& lo = text.relocations[1];
692 EXPECT_EQ(lo.offset, Hex32(0x20));
693 EXPECT_EQ(lo.scattered, true);
694 EXPECT_EQ(lo.type, PPC_RELOC_LO16_SECTDIFF);
695 EXPECT_EQ(lo.length, 2);
696 EXPECT_EQ(lo.value, Hex32(0x44));
697 const Relocation& loPair = text.relocations[2];
698 EXPECT_EQ(loPair.offset, Hex32(0x0));
699 EXPECT_EQ(loPair.scattered, true);
700 EXPECT_EQ(loPair.type, PPC_RELOC_PAIR);
701 EXPECT_EQ(loPair.length, 2);
702 EXPECT_EQ(loPair.value, Hex32(0x18));
703 const Relocation& ha = text.relocations[3];
704 EXPECT_EQ(ha.offset, Hex32(0x1C));
705 EXPECT_EQ(ha.scattered, true);
706 EXPECT_EQ(ha.type, PPC_RELOC_HA16_SECTDIFF);
707 EXPECT_EQ(ha.length, 2);
708 EXPECT_EQ(ha.value, Hex32(0x44));
709 const Relocation& haPair = text.relocations[4];
710 EXPECT_EQ(haPair.offset, Hex32(0x2c));
711 EXPECT_EQ(haPair.scattered, true);
712 EXPECT_EQ(haPair.type, PPC_RELOC_PAIR);
713 EXPECT_EQ(haPair.length, 2);
714 EXPECT_EQ(haPair.value, Hex32(0x18));
715
716 const Section& cstring = f->sections[1];
717 EXPECT_TRUE(cstring.segmentName.equals("__TEXT"));
718 EXPECT_TRUE(cstring.sectionName.equals("__cstring"));
719 EXPECT_EQ(cstring.type, S_CSTRING_LITERALS);
720 EXPECT_EQ(cstring.attributes, SectionAttr(0));
721 EXPECT_EQ((uint16_t)cstring.alignment, 4U);
722 EXPECT_EQ(cstring.address, Hex64(0x044));
723 EXPECT_EQ(cstring.content.size(), 7UL);
724 EXPECT_EQ((int)(cstring.content[0]), 0x68);
725 EXPECT_EQ((int)(cstring.content[1]), 0x65);
726 EXPECT_EQ((int)(cstring.content[2]), 0x6c);
727 EXPECT_TRUE(cstring.indirectSymbols.empty());
728 EXPECT_TRUE(cstring.relocations.empty());
729
730 EXPECT_EQ(f->localSymbols.size(), 0UL);
731 EXPECT_EQ(f->globalSymbols.size(), 1UL);
732 const Symbol& mainLabel = f->globalSymbols[0];
733 EXPECT_TRUE(mainLabel.name.equals("_main"));
734 EXPECT_EQ(mainLabel.type, N_SECT);
735 EXPECT_EQ(mainLabel.sect, 1);
736 EXPECT_EQ(mainLabel.scope, SymbolScope(N_EXT));
737 EXPECT_EQ(mainLabel.value, Hex64(0x0));
738 EXPECT_EQ(f->undefinedSymbols.size(), 1UL);
739 const Symbol& printfLabel = f->undefinedSymbols[0];
740 EXPECT_TRUE(printfLabel.name.equals("_printf"));
741 EXPECT_EQ(printfLabel.type, N_UNDF);
742 EXPECT_EQ(printfLabel.scope, SymbolScope(N_EXT));
743
744 auto ec = writeBinary(*f, "/tmp/foo.o");
745 // FIXME: We want to do EXPECT_FALSE(ec) but that fails on some Windows bots,
746 // probably due to /tmp not being available.
747 // For now just consume the error without checking it.
748 consumeError(std::move(ec));
749}
deps/lld/unittests/MachOTests/MachONormalizedFileBinaryWriterTests.cpp created+696
......@@ -0,0 +1,696 @@
1//===- lld/unittest/MachOTests/MachONormalizedFileBinaryWriterTests.cpp ---===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "../../lib/ReaderWriter/MachO/MachONormalizedFile.h"
11#include "llvm/ADT/Twine.h"
12#include "llvm/BinaryFormat/MachO.h"
13#include "llvm/Support/FileSystem.h"
14#include "gtest/gtest.h"
15#include <cassert>
16#include <memory>
17#include <system_error>
18#include <vector>
19
20using llvm::StringRef;
21using llvm::MemoryBuffer;
22using llvm::SmallString;
23using llvm::Twine;
24using llvm::ErrorOr;
25using namespace llvm::MachO;
26using namespace lld::mach_o::normalized;
27
28// Parses binary mach-o file at specified path and returns
29// ownership of buffer to mb parameter and ownership of
30// Normalized file to nf parameter.
31static void fromBinary(StringRef path, std::unique_ptr<MemoryBuffer> &mb,
32 std::unique_ptr<NormalizedFile> &nf, StringRef archStr) {
33 ErrorOr<std::unique_ptr<MemoryBuffer>> mbOrErr = MemoryBuffer::getFile(path);
34 std::error_code ec = mbOrErr.getError();
35 EXPECT_FALSE(ec);
36 mb = std::move(mbOrErr.get());
37
38 llvm::Expected<std::unique_ptr<NormalizedFile>> r =
39 lld::mach_o::normalized::readBinary(
40 mb, lld::MachOLinkingContext::archFromName(archStr));
41 EXPECT_FALSE(!r);
42 nf.reset(r->release());
43}
44
45static Relocation
46makeReloc(unsigned addr, bool rel, bool ext, RelocationInfoType type,
47 unsigned sym) {
48 Relocation result;
49 result.offset = addr;
50 result.scattered = false;
51 result.type = type;
52 result.length = 2;
53 result.pcRel = rel;
54 result.isExtern = ext;
55 result.value = 0;
56 result.symbol = sym;
57 return result;
58}
59
60static Relocation
61makeScatReloc(unsigned addr, RelocationInfoType type, unsigned value) {
62 Relocation result;
63 result.offset = addr;
64 result.scattered = true;
65 result.type = type;
66 result.length = 2;
67 result.pcRel = false;
68 result.isExtern = true;
69 result.value = value;
70 result.symbol = 0;
71 return result;
72}
73
74static Symbol
75makeUndefSymbol(StringRef name) {
76 Symbol sym;
77 sym.name = name;
78 sym.type = N_UNDF;
79 sym.scope = N_EXT;
80 sym.sect = NO_SECT;
81 sym.desc = 0;
82 sym.value = 0;
83 return sym;
84}
85
86
87static Symbol
88makeSymbol(StringRef name, unsigned addr) {
89 Symbol sym;
90 sym.name = name;
91 sym.type = N_SECT;
92 sym.scope = N_EXT;
93 sym.sect = 1;
94 sym.desc = 0;
95 sym.value = addr;
96 return sym;
97}
98
99static Symbol
100makeThumbSymbol(StringRef name, unsigned addr) {
101 Symbol sym;
102 sym.name = name;
103 sym.type = N_SECT;
104 sym.scope = N_EXT;
105 sym.sect = 1;
106 sym.desc = N_ARM_THUMB_DEF;
107 sym.value = addr;
108 return sym;
109}
110
111TEST(BinaryWriterTest, obj_relocs_x86_64) {
112 SmallString<128> tmpFl;
113 {
114 NormalizedFile f;
115 f.arch = lld::MachOLinkingContext::arch_x86_64;
116 f.fileType = MH_OBJECT;
117 f.flags = MH_SUBSECTIONS_VIA_SYMBOLS;
118 f.os = lld::MachOLinkingContext::OS::macOSX;
119 f.sections.resize(1);
120 Section& text = f.sections.front();
121 text.segmentName = "__TEXT";
122 text.sectionName = "__text";
123 text.type = S_REGULAR;
124 text.attributes = SectionAttr(S_ATTR_PURE_INSTRUCTIONS
125 | S_ATTR_SOME_INSTRUCTIONS);
126 text.alignment = 16;
127 text.address = 0;
128 const uint8_t textBytes[] = {
129 0xe8, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8b, 0x05,
130 0x00, 0x00, 0x00, 0x00, 0xff, 0x35, 0x00, 0x00,
131 0x00, 0x00, 0x8b, 0x05, 0x00, 0x00, 0x00, 0x00,
132 0xc6, 0x05, 0xff, 0xff, 0xff, 0xff, 0x12, 0xc7,
133 0x05, 0xfc, 0xff, 0xff, 0xff, 0x78, 0x56, 0x34,
134 0x12, 0x48, 0x8b, 0x3d, 0x00, 0x00, 0x00, 0x00 };
135
136 text.content = llvm::makeArrayRef(textBytes, sizeof(textBytes));
137 text.relocations.push_back(makeReloc(0x01, false, true, X86_64_RELOC_BRANCH, 1));
138 text.relocations.push_back(makeReloc(0x08, false, true, X86_64_RELOC_GOT_LOAD, 1));
139 text.relocations.push_back(makeReloc(0x0E, false, true, X86_64_RELOC_GOT, 1));
140 text.relocations.push_back(makeReloc(0x14, false, true, X86_64_RELOC_SIGNED, 1));
141 text.relocations.push_back(makeReloc(0x1A, false, true, X86_64_RELOC_SIGNED_1, 1));
142 text.relocations.push_back(makeReloc(0x21, false, true, X86_64_RELOC_SIGNED_4, 1));
143 text.relocations.push_back(makeReloc(0x2C, false, true, X86_64_RELOC_TLV, 2));
144
145 f.undefinedSymbols.push_back(makeUndefSymbol("_bar"));
146 f.undefinedSymbols.push_back(makeUndefSymbol("_tbar"));
147
148 std::error_code ec =
149 llvm::sys::fs::createTemporaryFile(Twine("xx"), "o", tmpFl);
150 EXPECT_FALSE(ec);
151 llvm::Error ec2 = writeBinary(f, tmpFl);
152 EXPECT_FALSE(ec2);
153 }
154
155 std::unique_ptr<MemoryBuffer> bufferOwner;
156 std::unique_ptr<NormalizedFile> f2;
157 fromBinary(tmpFl, bufferOwner, f2, "x86_64");
158
159 EXPECT_EQ(lld::MachOLinkingContext::arch_x86_64, f2->arch);
160 EXPECT_EQ(MH_OBJECT, f2->fileType);
161 EXPECT_EQ(FileFlags(MH_SUBSECTIONS_VIA_SYMBOLS), f2->flags);
162
163 EXPECT_TRUE(f2->localSymbols.empty());
164 EXPECT_TRUE(f2->globalSymbols.empty());
165 EXPECT_EQ(2UL, f2->undefinedSymbols.size());
166 const Symbol& barUndef = f2->undefinedSymbols[0];
167 EXPECT_TRUE(barUndef.name.equals("_bar"));
168 EXPECT_EQ(N_UNDF, barUndef.type);
169 EXPECT_EQ(SymbolScope(N_EXT), barUndef.scope);
170 const Symbol& tbarUndef = f2->undefinedSymbols[1];
171 EXPECT_TRUE(tbarUndef.name.equals("_tbar"));
172 EXPECT_EQ(N_UNDF, tbarUndef.type);
173 EXPECT_EQ(SymbolScope(N_EXT), tbarUndef.scope);
174
175 EXPECT_EQ(1UL, f2->sections.size());
176 const Section& text = f2->sections[0];
177 EXPECT_TRUE(text.segmentName.equals("__TEXT"));
178 EXPECT_TRUE(text.sectionName.equals("__text"));
179 EXPECT_EQ(S_REGULAR, text.type);
180 EXPECT_EQ(text.attributes,SectionAttr(S_ATTR_PURE_INSTRUCTIONS
181 | S_ATTR_SOME_INSTRUCTIONS));
182 EXPECT_EQ((uint16_t)text.alignment, 16U);
183 EXPECT_EQ(text.address, Hex64(0x0));
184 EXPECT_EQ(48UL, text.content.size());
185 const Relocation& call = text.relocations[0];
186 EXPECT_EQ(call.offset, Hex32(0x1));
187 EXPECT_EQ(call.type, X86_64_RELOC_BRANCH);
188 EXPECT_EQ(call.length, 2);
189 EXPECT_EQ(call.isExtern, true);
190 EXPECT_EQ(call.symbol, 1U);
191 const Relocation& gotLoad = text.relocations[1];
192 EXPECT_EQ(gotLoad.offset, Hex32(0x8));
193 EXPECT_EQ(gotLoad.type, X86_64_RELOC_GOT_LOAD);
194 EXPECT_EQ(gotLoad.length, 2);
195 EXPECT_EQ(gotLoad.isExtern, true);
196 EXPECT_EQ(gotLoad.symbol, 1U);
197 const Relocation& gotUse = text.relocations[2];
198 EXPECT_EQ(gotUse.offset, Hex32(0xE));
199 EXPECT_EQ(gotUse.type, X86_64_RELOC_GOT);
200 EXPECT_EQ(gotUse.length, 2);
201 EXPECT_EQ(gotUse.isExtern, true);
202 EXPECT_EQ(gotUse.symbol, 1U);
203 const Relocation& signed0 = text.relocations[3];
204 EXPECT_EQ(signed0.offset, Hex32(0x14));
205 EXPECT_EQ(signed0.type, X86_64_RELOC_SIGNED);
206 EXPECT_EQ(signed0.length, 2);
207 EXPECT_EQ(signed0.isExtern, true);
208 EXPECT_EQ(signed0.symbol, 1U);
209 const Relocation& signed1 = text.relocations[4];
210 EXPECT_EQ(signed1.offset, Hex32(0x1A));
211 EXPECT_EQ(signed1.type, X86_64_RELOC_SIGNED_1);
212 EXPECT_EQ(signed1.length, 2);
213 EXPECT_EQ(signed1.isExtern, true);
214 EXPECT_EQ(signed1.symbol, 1U);
215 const Relocation& signed4 = text.relocations[5];
216 EXPECT_EQ(signed4.offset, Hex32(0x21));
217 EXPECT_EQ(signed4.type, X86_64_RELOC_SIGNED_4);
218 EXPECT_EQ(signed4.length, 2);
219 EXPECT_EQ(signed4.isExtern, true);
220 EXPECT_EQ(signed4.symbol, 1U);
221
222 bufferOwner.reset(nullptr);
223 std::error_code ec = llvm::sys::fs::remove(Twine(tmpFl));
224 EXPECT_FALSE(ec);
225}
226
227
228
229TEST(BinaryWriterTest, obj_relocs_x86) {
230 SmallString<128> tmpFl;
231 {
232 NormalizedFile f;
233 f.arch = lld::MachOLinkingContext::arch_x86;
234 f.fileType = MH_OBJECT;
235 f.flags = MH_SUBSECTIONS_VIA_SYMBOLS;
236 f.os = lld::MachOLinkingContext::OS::macOSX;
237 f.sections.resize(1);
238 Section& text = f.sections.front();
239 text.segmentName = "__TEXT";
240 text.sectionName = "__text";
241 text.type = S_REGULAR;
242 text.attributes = SectionAttr(S_ATTR_PURE_INSTRUCTIONS
243 | S_ATTR_SOME_INSTRUCTIONS);
244 text.alignment = 16;
245 text.address = 0;
246 const uint8_t textBytes[] = {
247 0xe8, 0xfb, 0xff, 0xff, 0xff, 0xa1, 0x00, 0x00,
248 0x00, 0x00, 0x8b, 0xb0, 0xfb, 0xff, 0xff, 0xff,
249 0x8b, 0x80, 0x11, 0x00, 0x00, 0x00 };
250
251 text.content = llvm::makeArrayRef(textBytes, sizeof(textBytes));
252 text.relocations.push_back(makeReloc(0x01, true, true, GENERIC_RELOC_VANILLA, 0));
253 text.relocations.push_back(makeReloc(0x06, false, true, GENERIC_RELOC_VANILLA, 0));
254 text.relocations.push_back(makeScatReloc(0x0c, GENERIC_RELOC_LOCAL_SECTDIFF, 0));
255 text.relocations.push_back(makeScatReloc(0x0, GENERIC_RELOC_PAIR, 5));
256 text.relocations.push_back(makeReloc(0x12, true, true, GENERIC_RELOC_TLV, 1));
257
258 f.undefinedSymbols.push_back(makeUndefSymbol("_bar"));
259 f.undefinedSymbols.push_back(makeUndefSymbol("_tbar"));
260
261 std::error_code ec =
262 llvm::sys::fs::createTemporaryFile(Twine("xx"), "o", tmpFl);
263 EXPECT_FALSE(ec);
264 llvm::Error ec2 = writeBinary(f, tmpFl);
265 EXPECT_FALSE(ec2);
266 }
267 std::unique_ptr<MemoryBuffer> bufferOwner;
268 std::unique_ptr<NormalizedFile> f2;
269 fromBinary(tmpFl, bufferOwner, f2, "i386");
270
271 EXPECT_EQ(lld::MachOLinkingContext::arch_x86, f2->arch);
272 EXPECT_EQ(MH_OBJECT, f2->fileType);
273 EXPECT_EQ(FileFlags(MH_SUBSECTIONS_VIA_SYMBOLS), f2->flags);
274
275 EXPECT_TRUE(f2->localSymbols.empty());
276 EXPECT_TRUE(f2->globalSymbols.empty());
277 EXPECT_EQ(2UL, f2->undefinedSymbols.size());
278 const Symbol& barUndef = f2->undefinedSymbols[0];
279 EXPECT_TRUE(barUndef.name.equals("_bar"));
280 EXPECT_EQ(N_UNDF, barUndef.type);
281 EXPECT_EQ(SymbolScope(N_EXT), barUndef.scope);
282 const Symbol& tbarUndef = f2->undefinedSymbols[1];
283 EXPECT_TRUE(tbarUndef.name.equals("_tbar"));
284 EXPECT_EQ(N_UNDF, tbarUndef.type);
285 EXPECT_EQ(SymbolScope(N_EXT), tbarUndef.scope);
286
287 EXPECT_EQ(1UL, f2->sections.size());
288 const Section& text = f2->sections[0];
289 EXPECT_TRUE(text.segmentName.equals("__TEXT"));
290 EXPECT_TRUE(text.sectionName.equals("__text"));
291 EXPECT_EQ(S_REGULAR, text.type);
292 EXPECT_EQ(text.attributes,SectionAttr(S_ATTR_PURE_INSTRUCTIONS
293 | S_ATTR_SOME_INSTRUCTIONS));
294 EXPECT_EQ((uint16_t)text.alignment, 16U);
295 EXPECT_EQ(text.address, Hex64(0x0));
296 EXPECT_EQ(22UL, text.content.size());
297 const Relocation& call = text.relocations[0];
298 EXPECT_EQ(call.offset, Hex32(0x1));
299 EXPECT_EQ(call.scattered, false);
300 EXPECT_EQ(call.type, GENERIC_RELOC_VANILLA);
301 EXPECT_EQ(call.pcRel, true);
302 EXPECT_EQ(call.length, 2);
303 EXPECT_EQ(call.isExtern, true);
304 EXPECT_EQ(call.symbol, 0U);
305 const Relocation& absLoad = text.relocations[1];
306 EXPECT_EQ(absLoad.offset, Hex32(0x6));
307 EXPECT_EQ(absLoad.scattered, false);
308 EXPECT_EQ(absLoad.type, GENERIC_RELOC_VANILLA);
309 EXPECT_EQ(absLoad.pcRel, false);
310 EXPECT_EQ(absLoad.length, 2);
311 EXPECT_EQ(absLoad.isExtern, true);
312 EXPECT_EQ(absLoad.symbol,0U);
313 const Relocation& pic1 = text.relocations[2];
314 EXPECT_EQ(pic1.offset, Hex32(0xc));
315 EXPECT_EQ(pic1.scattered, true);
316 EXPECT_EQ(pic1.type, GENERIC_RELOC_LOCAL_SECTDIFF);
317 EXPECT_EQ(pic1.length, 2);
318 EXPECT_EQ(pic1.value, 0U);
319 const Relocation& pic2 = text.relocations[3];
320 EXPECT_EQ(pic2.offset, Hex32(0x0));
321 EXPECT_EQ(pic1.scattered, true);
322 EXPECT_EQ(pic2.type, GENERIC_RELOC_PAIR);
323 EXPECT_EQ(pic2.length, 2);
324 EXPECT_EQ(pic2.value, 5U);
325 const Relocation& tlv = text.relocations[4];
326 EXPECT_EQ(tlv.offset, Hex32(0x12));
327 EXPECT_EQ(tlv.type, GENERIC_RELOC_TLV);
328 EXPECT_EQ(tlv.length, 2);
329 EXPECT_EQ(tlv.isExtern, true);
330 EXPECT_EQ(tlv.symbol, 1U);
331
332 //llvm::errs() << "temp = " << tmpFl << "\n";
333 bufferOwner.reset(nullptr);
334 std::error_code ec = llvm::sys::fs::remove(Twine(tmpFl));
335 EXPECT_FALSE(ec);
336}
337
338
339
340TEST(BinaryWriterTest, obj_relocs_armv7) {
341 SmallString<128> tmpFl;
342 {
343 NormalizedFile f;
344 f.arch = lld::MachOLinkingContext::arch_armv7;
345 f.fileType = MH_OBJECT;
346 f.flags = MH_SUBSECTIONS_VIA_SYMBOLS;
347 f.os = lld::MachOLinkingContext::OS::macOSX;
348 f.sections.resize(1);
349 Section& text = f.sections.front();
350 text.segmentName = "__TEXT";
351 text.sectionName = "__text";
352 text.type = S_REGULAR;
353 text.attributes = SectionAttr(S_ATTR_PURE_INSTRUCTIONS
354 | S_ATTR_SOME_INSTRUCTIONS);
355 text.alignment = 4;
356 text.address = 0;
357 const uint8_t textBytes[] = {
358 0xff, 0xf7, 0xfe, 0xef, 0x40, 0xf2, 0x05, 0x01,
359 0xc0, 0xf2, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
360 0x00, 0xbf };
361
362 text.content = llvm::makeArrayRef(textBytes, sizeof(textBytes));
363 text.relocations.push_back(makeReloc(0x00, true, true,
364 ARM_THUMB_RELOC_BR22, 2));
365 text.relocations.push_back(makeScatReloc(0x04,
366 ARM_RELOC_HALF_SECTDIFF, 0x10));
367 text.relocations.push_back(makeScatReloc(0x00,
368 ARM_RELOC_PAIR, 0xC));
369 text.relocations.push_back(makeScatReloc(0x08,
370 ARM_RELOC_HALF_SECTDIFF, 0x10));
371 text.relocations.push_back(makeScatReloc(0x00,
372 ARM_RELOC_PAIR, 0xC));
373 text.relocations.push_back(makeReloc(0x0C, false, true,
374 ARM_RELOC_VANILLA, 2));
375
376 f.globalSymbols.push_back(makeThumbSymbol("_foo", 0x00));
377 f.globalSymbols.push_back(makeThumbSymbol("_foo2", 0x10));
378 f.undefinedSymbols.push_back(makeUndefSymbol("_bar"));
379
380 std::error_code ec =
381 llvm::sys::fs::createTemporaryFile(Twine("xx"), "o", tmpFl);
382 EXPECT_FALSE(ec);
383 llvm::Error ec2 = writeBinary(f, tmpFl);
384 EXPECT_FALSE(ec2);
385 }
386 std::unique_ptr<MemoryBuffer> bufferOwner;
387 std::unique_ptr<NormalizedFile> f2;
388 fromBinary(tmpFl, bufferOwner, f2, "armv7");
389
390 EXPECT_EQ(lld::MachOLinkingContext::arch_armv7, f2->arch);
391 EXPECT_EQ(MH_OBJECT, f2->fileType);
392 EXPECT_EQ(FileFlags(MH_SUBSECTIONS_VIA_SYMBOLS), f2->flags);
393
394 EXPECT_TRUE(f2->localSymbols.empty());
395 EXPECT_EQ(2UL, f2->globalSymbols.size());
396 const Symbol& fooDef = f2->globalSymbols[0];
397 EXPECT_TRUE(fooDef.name.equals("_foo"));
398 EXPECT_EQ(N_SECT, fooDef.type);
399 EXPECT_EQ(1, fooDef.sect);
400 EXPECT_EQ(SymbolScope(N_EXT), fooDef.scope);
401 const Symbol& foo2Def = f2->globalSymbols[1];
402 EXPECT_TRUE(foo2Def.name.equals("_foo2"));
403 EXPECT_EQ(N_SECT, foo2Def.type);
404 EXPECT_EQ(1, foo2Def.sect);
405 EXPECT_EQ(SymbolScope(N_EXT), foo2Def.scope);
406
407 EXPECT_EQ(1UL, f2->undefinedSymbols.size());
408 const Symbol& barUndef = f2->undefinedSymbols[0];
409 EXPECT_TRUE(barUndef.name.equals("_bar"));
410 EXPECT_EQ(N_UNDF, barUndef.type);
411 EXPECT_EQ(SymbolScope(N_EXT), barUndef.scope);
412
413 EXPECT_EQ(1UL, f2->sections.size());
414 const Section& text = f2->sections[0];
415 EXPECT_TRUE(text.segmentName.equals("__TEXT"));
416 EXPECT_TRUE(text.sectionName.equals("__text"));
417 EXPECT_EQ(S_REGULAR, text.type);
418 EXPECT_EQ(text.attributes,SectionAttr(S_ATTR_PURE_INSTRUCTIONS
419 | S_ATTR_SOME_INSTRUCTIONS));
420 EXPECT_EQ((uint16_t)text.alignment, 4U);
421 EXPECT_EQ(text.address, Hex64(0x0));
422 EXPECT_EQ(18UL, text.content.size());
423 const Relocation& blx = text.relocations[0];
424 EXPECT_EQ(blx.offset, Hex32(0x0));
425 EXPECT_EQ(blx.scattered, false);
426 EXPECT_EQ(blx.type, ARM_THUMB_RELOC_BR22);
427 EXPECT_EQ(blx.pcRel, true);
428 EXPECT_EQ(blx.length, 2);
429 EXPECT_EQ(blx.isExtern, true);
430 EXPECT_EQ(blx.symbol, 2U);
431 const Relocation& movw1 = text.relocations[1];
432 EXPECT_EQ(movw1.offset, Hex32(0x4));
433 EXPECT_EQ(movw1.scattered, true);
434 EXPECT_EQ(movw1.type, ARM_RELOC_HALF_SECTDIFF);
435 EXPECT_EQ(movw1.length, 2);
436 EXPECT_EQ(movw1.value, 0x10U);
437 const Relocation& movw2 = text.relocations[2];
438 EXPECT_EQ(movw2.offset, Hex32(0x0));
439 EXPECT_EQ(movw2.scattered, true);
440 EXPECT_EQ(movw2.type, ARM_RELOC_PAIR);
441 EXPECT_EQ(movw2.length, 2);
442 EXPECT_EQ(movw2.value, Hex32(0xC));
443 const Relocation& movt1 = text.relocations[3];
444 EXPECT_EQ(movt1.offset, Hex32(0x8));
445 EXPECT_EQ(movt1.scattered, true);
446 EXPECT_EQ(movt1.type, ARM_RELOC_HALF_SECTDIFF);
447 EXPECT_EQ(movt1.length, 2);
448 EXPECT_EQ(movt1.value, Hex32(0x10));
449 const Relocation& movt2 = text.relocations[4];
450 EXPECT_EQ(movt2.offset, Hex32(0x0));
451 EXPECT_EQ(movt2.scattered, true);
452 EXPECT_EQ(movt2.type, ARM_RELOC_PAIR);
453 EXPECT_EQ(movt2.length, 2);
454 EXPECT_EQ(movt2.value, Hex32(0xC));
455 const Relocation& absPointer = text.relocations[5];
456 EXPECT_EQ(absPointer.offset, Hex32(0xC));
457 EXPECT_EQ(absPointer.type, ARM_RELOC_VANILLA);
458 EXPECT_EQ(absPointer.length, 2);
459 EXPECT_EQ(absPointer.isExtern, true);
460 EXPECT_EQ(absPointer.symbol, 2U);
461
462 //llvm::errs() << "temp = " << tmpFl << "\n";
463 bufferOwner.reset(nullptr);
464 std::error_code ec = llvm::sys::fs::remove(Twine(tmpFl));
465 EXPECT_FALSE(ec);
466}
467
468
469
470TEST(BinaryWriterTest, obj_relocs_ppc) {
471 SmallString<128> tmpFl;
472 {
473 NormalizedFile f;
474 f.arch = lld::MachOLinkingContext::arch_ppc;
475 f.fileType = MH_OBJECT;
476 f.flags = MH_SUBSECTIONS_VIA_SYMBOLS;
477 f.os = lld::MachOLinkingContext::OS::macOSX;
478 f.sections.resize(1);
479 Section& text = f.sections.front();
480 text.segmentName = "__TEXT";
481 text.sectionName = "__text";
482 text.type = S_REGULAR;
483 text.attributes = SectionAttr(S_ATTR_PURE_INSTRUCTIONS
484 | S_ATTR_SOME_INSTRUCTIONS);
485 text.alignment = 4;
486 text.address = 0;
487 const uint8_t textBytes[] = {
488 0x48, 0x00, 0x00, 0x01, 0x40, 0x82, 0xff, 0xfc,
489 0x3c, 0x62, 0x00, 0x00, 0x3c, 0x62, 0x00, 0x00,
490 0x80, 0x63, 0x00, 0x24, 0x80, 0x63, 0x00, 0x24,
491 0x3c, 0x40, 0x00, 0x00, 0x3c, 0x60, 0x00, 0x00,
492 0x80, 0x42, 0x00, 0x28, 0x80, 0x63, 0x00, 0x28,
493 0x60, 0x00, 0x00, 0x00 };
494
495 text.content = llvm::makeArrayRef(textBytes, sizeof(textBytes));
496 text.relocations.push_back(makeReloc(0x00, true, true,
497 PPC_RELOC_BR24, 2));
498 text.relocations.push_back(makeReloc(0x04, true, true,
499 PPC_RELOC_BR14, 2));
500 text.relocations.push_back(makeScatReloc(0x08,
501 PPC_RELOC_HI16_SECTDIFF, 0x28));
502 text.relocations.push_back(makeScatReloc(0x24,
503 PPC_RELOC_PAIR, 0x4));
504 text.relocations.push_back(makeScatReloc(0x0C,
505 PPC_RELOC_HA16_SECTDIFF, 0x28));
506 text.relocations.push_back(makeScatReloc(0x24,
507 PPC_RELOC_PAIR, 0x4));
508 text.relocations.push_back(makeScatReloc(0x10,
509 PPC_RELOC_LO16_SECTDIFF, 0x28));
510 text.relocations.push_back(makeScatReloc(0x00,
511 PPC_RELOC_PAIR, 0x4));
512 text.relocations.push_back(makeScatReloc(0x14,
513 PPC_RELOC_LO14_SECTDIFF, 0x28));
514 text.relocations.push_back(makeScatReloc(0x00,
515 PPC_RELOC_PAIR, 0x4));
516 text.relocations.push_back(makeReloc(0x18, false, false,
517 PPC_RELOC_HI16, 1));
518 text.relocations.push_back(makeReloc(0x28, false, false,
519 PPC_RELOC_PAIR, 0));
520 text.relocations.push_back(makeReloc(0x1C, false, false,
521 PPC_RELOC_HA16, 1));
522 text.relocations.push_back(makeReloc(0x28, false, false,
523 PPC_RELOC_PAIR, 0));
524 text.relocations.push_back(makeReloc(0x20, false, false,
525 PPC_RELOC_LO16, 1));
526 text.relocations.push_back(makeReloc(0x00, false, false,
527 PPC_RELOC_PAIR, 0));
528 text.relocations.push_back(makeReloc(0x24, false, false,
529 PPC_RELOC_LO14, 1));
530 text.relocations.push_back(makeReloc(0x00, false, false,
531 PPC_RELOC_PAIR, 0));
532
533 f.globalSymbols.push_back(makeSymbol("_foo", 0x00));
534 f.globalSymbols.push_back(makeSymbol("_foo2", 0x28));
535 f.undefinedSymbols.push_back(makeUndefSymbol("_bar"));
536
537 std::error_code ec =
538 llvm::sys::fs::createTemporaryFile(Twine("xx"), "o", tmpFl);
539 EXPECT_FALSE(ec);
540 llvm::Error ec2 = writeBinary(f, tmpFl);
541 EXPECT_FALSE(ec2);
542 }
543 std::unique_ptr<MemoryBuffer> bufferOwner;
544 std::unique_ptr<NormalizedFile> f2;
545 fromBinary(tmpFl, bufferOwner, f2, "ppc");
546
547 EXPECT_EQ(lld::MachOLinkingContext::arch_ppc, f2->arch);
548 EXPECT_EQ(MH_OBJECT, f2->fileType);
549 EXPECT_EQ(FileFlags(MH_SUBSECTIONS_VIA_SYMBOLS), f2->flags);
550
551 EXPECT_TRUE(f2->localSymbols.empty());
552 EXPECT_EQ(2UL, f2->globalSymbols.size());
553 const Symbol& fooDef = f2->globalSymbols[0];
554 EXPECT_TRUE(fooDef.name.equals("_foo"));
555 EXPECT_EQ(N_SECT, fooDef.type);
556 EXPECT_EQ(1, fooDef.sect);
557 EXPECT_EQ(SymbolScope(N_EXT), fooDef.scope);
558 const Symbol& foo2Def = f2->globalSymbols[1];
559 EXPECT_TRUE(foo2Def.name.equals("_foo2"));
560 EXPECT_EQ(N_SECT, foo2Def.type);
561 EXPECT_EQ(1, foo2Def.sect);
562 EXPECT_EQ(SymbolScope(N_EXT), foo2Def.scope);
563
564 EXPECT_EQ(1UL, f2->undefinedSymbols.size());
565 const Symbol& barUndef = f2->undefinedSymbols[0];
566 EXPECT_TRUE(barUndef.name.equals("_bar"));
567 EXPECT_EQ(N_UNDF, barUndef.type);
568 EXPECT_EQ(SymbolScope(N_EXT), barUndef.scope);
569
570 EXPECT_EQ(1UL, f2->sections.size());
571 const Section& text = f2->sections[0];
572 EXPECT_TRUE(text.segmentName.equals("__TEXT"));
573 EXPECT_TRUE(text.sectionName.equals("__text"));
574 EXPECT_EQ(S_REGULAR, text.type);
575 EXPECT_EQ(text.attributes,SectionAttr(S_ATTR_PURE_INSTRUCTIONS
576 | S_ATTR_SOME_INSTRUCTIONS));
577 EXPECT_EQ((uint16_t)text.alignment, 4U);
578 EXPECT_EQ(text.address, Hex64(0x0));
579 EXPECT_EQ(44UL, text.content.size());
580 const Relocation& br24 = text.relocations[0];
581 EXPECT_EQ(br24.offset, Hex32(0x0));
582 EXPECT_EQ(br24.scattered, false);
583 EXPECT_EQ(br24.type, PPC_RELOC_BR24);
584 EXPECT_EQ(br24.pcRel, true);
585 EXPECT_EQ(br24.length, 2);
586 EXPECT_EQ(br24.isExtern, true);
587 EXPECT_EQ(br24.symbol, 2U);
588 const Relocation& br14 = text.relocations[1];
589 EXPECT_EQ(br14.offset, Hex32(0x4));
590 EXPECT_EQ(br14.scattered, false);
591 EXPECT_EQ(br14.type, PPC_RELOC_BR14);
592 EXPECT_EQ(br14.pcRel, true);
593 EXPECT_EQ(br14.length, 2);
594 EXPECT_EQ(br14.isExtern, true);
595 EXPECT_EQ(br14.symbol, 2U);
596 const Relocation& pichi1 = text.relocations[2];
597 EXPECT_EQ(pichi1.offset, Hex32(0x8));
598 EXPECT_EQ(pichi1.scattered, true);
599 EXPECT_EQ(pichi1.type, PPC_RELOC_HI16_SECTDIFF);
600 EXPECT_EQ(pichi1.length, 2);
601 EXPECT_EQ(pichi1.value, 0x28U);
602 const Relocation& pichi2 = text.relocations[3];
603 EXPECT_EQ(pichi2.offset, Hex32(0x24));
604 EXPECT_EQ(pichi2.scattered, true);
605 EXPECT_EQ(pichi2.type, PPC_RELOC_PAIR);
606 EXPECT_EQ(pichi2.length, 2);
607 EXPECT_EQ(pichi2.value, 0x4U);
608 const Relocation& picha1 = text.relocations[4];
609 EXPECT_EQ(picha1.offset, Hex32(0xC));
610 EXPECT_EQ(picha1.scattered, true);
611 EXPECT_EQ(picha1.type, PPC_RELOC_HA16_SECTDIFF);
612 EXPECT_EQ(picha1.length, 2);
613 EXPECT_EQ(picha1.value, 0x28U);
614 const Relocation& picha2 = text.relocations[5];
615 EXPECT_EQ(picha2.offset, Hex32(0x24));
616 EXPECT_EQ(picha2.scattered, true);
617 EXPECT_EQ(picha2.type, PPC_RELOC_PAIR);
618 EXPECT_EQ(picha2.length, 2);
619 EXPECT_EQ(picha2.value, 0x4U);
620 const Relocation& piclo1 = text.relocations[6];
621 EXPECT_EQ(piclo1.offset, Hex32(0x10));
622 EXPECT_EQ(piclo1.scattered, true);
623 EXPECT_EQ(piclo1.type, PPC_RELOC_LO16_SECTDIFF);
624 EXPECT_EQ(piclo1.length, 2);
625 EXPECT_EQ(piclo1.value, 0x28U);
626 const Relocation& piclo2 = text.relocations[7];
627 EXPECT_EQ(piclo2.offset, Hex32(0x0));
628 EXPECT_EQ(piclo2.scattered, true);
629 EXPECT_EQ(piclo2.type, PPC_RELOC_PAIR);
630 EXPECT_EQ(piclo2.length, 2);
631 EXPECT_EQ(piclo2.value, 0x4U);
632 const Relocation& picloa1 = text.relocations[8];
633 EXPECT_EQ(picloa1.offset, Hex32(0x14));
634 EXPECT_EQ(picloa1.scattered, true);
635 EXPECT_EQ(picloa1.type, PPC_RELOC_LO14_SECTDIFF);
636 EXPECT_EQ(picloa1.length, 2);
637 EXPECT_EQ(picloa1.value, 0x28U);
638 const Relocation& picloa2 = text.relocations[9];
639 EXPECT_EQ(picloa2.offset, Hex32(0x0));
640 EXPECT_EQ(picloa2.scattered, true);
641 EXPECT_EQ(picloa2.type, PPC_RELOC_PAIR);
642 EXPECT_EQ(picloa2.length, 2);
643 EXPECT_EQ(picloa2.value, 0x4U);
644 const Relocation& abshi1 = text.relocations[10];
645 EXPECT_EQ(abshi1.offset, Hex32(0x18));
646 EXPECT_EQ(abshi1.scattered, false);
647 EXPECT_EQ(abshi1.type, PPC_RELOC_HI16);
648 EXPECT_EQ(abshi1.length, 2);
649 EXPECT_EQ(abshi1.symbol, 1U);
650 const Relocation& abshi2 = text.relocations[11];
651 EXPECT_EQ(abshi2.offset, Hex32(0x28));
652 EXPECT_EQ(abshi2.scattered, false);
653 EXPECT_EQ(abshi2.type, PPC_RELOC_PAIR);
654 EXPECT_EQ(abshi2.length, 2);
655 EXPECT_EQ(abshi2.symbol, 0U);
656 const Relocation& absha1 = text.relocations[12];
657 EXPECT_EQ(absha1.offset, Hex32(0x1C));
658 EXPECT_EQ(absha1.scattered, false);
659 EXPECT_EQ(absha1.type, PPC_RELOC_HA16);
660 EXPECT_EQ(absha1.length, 2);
661 EXPECT_EQ(absha1.symbol, 1U);
662 const Relocation& absha2 = text.relocations[13];
663 EXPECT_EQ(absha2.offset, Hex32(0x28));
664 EXPECT_EQ(absha2.scattered, false);
665 EXPECT_EQ(absha2.type, PPC_RELOC_PAIR);
666 EXPECT_EQ(absha2.length, 2);
667 EXPECT_EQ(absha2.symbol, 0U);
668 const Relocation& abslo1 = text.relocations[14];
669 EXPECT_EQ(abslo1.offset, Hex32(0x20));
670 EXPECT_EQ(abslo1.scattered, false);
671 EXPECT_EQ(abslo1.type, PPC_RELOC_LO16);
672 EXPECT_EQ(abslo1.length, 2);
673 EXPECT_EQ(abslo1.symbol, 1U);
674 const Relocation& abslo2 = text.relocations[15];
675 EXPECT_EQ(abslo2.offset, Hex32(0x00));
676 EXPECT_EQ(abslo2.scattered, false);
677 EXPECT_EQ(abslo2.type, PPC_RELOC_PAIR);
678 EXPECT_EQ(abslo2.length, 2);
679 EXPECT_EQ(abslo2.symbol, 0U);
680 const Relocation& absloa1 = text.relocations[16];
681 EXPECT_EQ(absloa1.offset, Hex32(0x24));
682 EXPECT_EQ(absloa1.scattered, false);
683 EXPECT_EQ(absloa1.type, PPC_RELOC_LO14);
684 EXPECT_EQ(absloa1.length, 2);
685 EXPECT_EQ(absloa1.symbol, 1U);
686 const Relocation& absloa2 = text.relocations[17];
687 EXPECT_EQ(absloa2.offset, Hex32(0x00));
688 EXPECT_EQ(absloa2.scattered, false);
689 EXPECT_EQ(absloa2.type, PPC_RELOC_PAIR);
690 EXPECT_EQ(absloa2.length, 2);
691 EXPECT_EQ(absloa2.symbol, 0U);
692
693 bufferOwner.reset(nullptr);
694 std::error_code ec = llvm::sys::fs::remove(Twine(tmpFl));
695 EXPECT_FALSE(ec);
696}
deps/lld/unittests/MachOTests/MachONormalizedFileToAtomsTests.cpp created+100
......@@ -0,0 +1,100 @@
1//===- lld/unittest/MachOTests/MachONormalizedFileToAtomsTests.cpp --------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "../../lib/ReaderWriter/MachO/MachONormalizedFile.h"
11#include "lld/Core/Atom.h"
12#include "lld/Core/DefinedAtom.h"
13#include "lld/Core/File.h"
14#include "lld/Core/UndefinedAtom.h"
15#include "lld/ReaderWriter/MachOLinkingContext.h"
16#include "llvm/ADT/ArrayRef.h"
17#include "llvm/BinaryFormat/MachO.h"
18#include "llvm/Support/Error.h"
19#include "llvm/Support/YAMLTraits.h"
20#include "gtest/gtest.h"
21#include <cstdint>
22#include <memory>
23
24using namespace lld::mach_o::normalized;
25using namespace llvm::MachO;
26
27TEST(ToAtomsTest, empty_obj_x86_64) {
28 NormalizedFile f;
29 f.arch = lld::MachOLinkingContext::arch_x86_64;
30 llvm::Expected<std::unique_ptr<const lld::File>> atom_f =
31 normalizedToAtoms(f, "", false);
32 EXPECT_FALSE(!atom_f);
33 EXPECT_EQ(0U, (*atom_f)->defined().size());
34}
35
36TEST(ToAtomsTest, basic_obj_x86_64) {
37 NormalizedFile f;
38 f.arch = lld::MachOLinkingContext::arch_x86_64;
39 Section textSection;
40 static const uint8_t contentBytes[] = { 0x90, 0xC3, 0xC3, 0xC4 };
41 const unsigned contentSize = sizeof(contentBytes) / sizeof(contentBytes[0]);
42 textSection.content = llvm::makeArrayRef(contentBytes, contentSize);
43 f.sections.push_back(textSection);
44 Symbol fooSymbol;
45 fooSymbol.name = "_foo";
46 fooSymbol.type = N_SECT;
47 fooSymbol.scope = N_EXT;
48 fooSymbol.sect = 1;
49 fooSymbol.value = 0;
50 f.globalSymbols.push_back(fooSymbol);
51 Symbol barSymbol;
52 barSymbol.name = "_bar";
53 barSymbol.type = N_SECT;
54 barSymbol.scope = N_EXT;
55 barSymbol.sect = 1;
56 barSymbol.value = 2;
57 f.globalSymbols.push_back(barSymbol);
58 Symbol undefSym;
59 undefSym.name = "_undef";
60 undefSym.type = N_UNDF;
61 f.undefinedSymbols.push_back(undefSym);
62 Symbol bazSymbol;
63 bazSymbol.name = "_baz";
64 bazSymbol.type = N_SECT;
65 bazSymbol.scope = N_EXT | N_PEXT;
66 bazSymbol.sect = 1;
67 bazSymbol.value = 3;
68 f.localSymbols.push_back(bazSymbol);
69
70 llvm::Expected<std::unique_ptr<const lld::File>> atom_f =
71 normalizedToAtoms(f, "", false);
72 EXPECT_FALSE(!atom_f);
73 const lld::File &file = **atom_f;
74 EXPECT_EQ(3U, file.defined().size());
75 auto it = file.defined().begin();
76 const lld::DefinedAtom *atom1 = *it;
77 ++it;
78 const lld::DefinedAtom *atom2 = *it;
79 ++it;
80 const lld::DefinedAtom *atom3 = *it;
81 const lld::UndefinedAtom *atom4 = *file.undefined().begin();
82 EXPECT_TRUE(atom1->name().equals("_foo"));
83 EXPECT_EQ(2U, atom1->rawContent().size());
84 EXPECT_EQ(0x90, atom1->rawContent()[0]);
85 EXPECT_EQ(0xC3, atom1->rawContent()[1]);
86 EXPECT_EQ(lld::Atom::scopeGlobal, atom1->scope());
87
88 EXPECT_TRUE(atom2->name().equals("_bar"));
89 EXPECT_EQ(1U, atom2->rawContent().size());
90 EXPECT_EQ(0xC3, atom2->rawContent()[0]);
91 EXPECT_EQ(lld::Atom::scopeGlobal, atom2->scope());
92
93 EXPECT_TRUE(atom3->name().equals("_baz"));
94 EXPECT_EQ(1U, atom3->rawContent().size());
95 EXPECT_EQ(0xC4, atom3->rawContent()[0]);
96 EXPECT_EQ(lld::Atom::scopeLinkageUnit, atom3->scope());
97
98 EXPECT_TRUE(atom4->name().equals("_undef"));
99 EXPECT_EQ(lld::Atom::definitionUndefined, atom4->definition());
100}
deps/lld/unittests/MachOTests/MachONormalizedFileYAMLTests.cpp created+763
......@@ -0,0 +1,763 @@
1//===- lld/unittest/MachOTests/MachONormalizedFileYAMLTests.cpp -----------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "../../lib/ReaderWriter/MachO/MachONormalizedFile.h"
11#include "lld/ReaderWriter/MachOLinkingContext.h"
12#include "llvm/ADT/StringRef.h"
13#include "llvm/BinaryFormat/MachO.h"
14#include "llvm/Support/Error.h"
15#include "llvm/Support/MemoryBuffer.h"
16#include "llvm/Support/raw_ostream.h"
17#include "gtest/gtest.h"
18#include <cstdint>
19#include <memory>
20#include <string>
21#include <system_error>
22
23using llvm::StringRef;
24using llvm::MemoryBuffer;
25using lld::mach_o::normalized::NormalizedFile;
26using lld::mach_o::normalized::Symbol;
27using lld::mach_o::normalized::Section;
28using lld::mach_o::normalized::Relocation;
29
30static std::unique_ptr<NormalizedFile> fromYAML(StringRef str) {
31 std::unique_ptr<MemoryBuffer> mb(MemoryBuffer::getMemBuffer(str));
32 llvm::Expected<std::unique_ptr<NormalizedFile>> r
33 = lld::mach_o::normalized::readYaml(mb);
34 EXPECT_FALSE(!r);
35 return std::move(*r);
36}
37
38static void toYAML(const NormalizedFile &f, std::string &out) {
39 llvm::raw_string_ostream ostr(out);
40 std::error_code ec = lld::mach_o::normalized::writeYaml(f, ostr);
41 EXPECT_TRUE(!ec);
42}
43
44// ppc is no longer supported, but it is here to test endianness handling.
45TEST(ObjectFileYAML, empty_ppc) {
46 std::unique_ptr<NormalizedFile> f = fromYAML(
47 "---\n"
48 "arch: ppc\n"
49 "file-type: MH_OBJECT\n"
50 "flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]\n"
51 "...\n");
52 EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_ppc);
53 EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);
54 EXPECT_EQ((int)(f->flags), llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);
55 EXPECT_TRUE(f->sections.empty());
56 EXPECT_TRUE(f->localSymbols.empty());
57 EXPECT_TRUE(f->globalSymbols.empty());
58 EXPECT_TRUE(f->undefinedSymbols.empty());
59}
60
61TEST(ObjectFileYAML, empty_x86_64) {
62 std::unique_ptr<NormalizedFile> f = fromYAML(
63 "---\n"
64 "arch: x86_64\n"
65 "file-type: MH_OBJECT\n"
66 "flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]\n"
67 "...\n");
68 EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_x86_64);
69 EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);
70 EXPECT_EQ((int)(f->flags), llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);
71 EXPECT_TRUE(f->sections.empty());
72 EXPECT_TRUE(f->localSymbols.empty());
73 EXPECT_TRUE(f->globalSymbols.empty());
74 EXPECT_TRUE(f->undefinedSymbols.empty());
75}
76
77TEST(ObjectFileYAML, empty_x86) {
78 std::unique_ptr<NormalizedFile> f = fromYAML(
79 "---\n"
80 "arch: x86\n"
81 "file-type: MH_OBJECT\n"
82 "flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]\n"
83 "...\n");
84 EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_x86);
85 EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);
86 EXPECT_EQ((int)(f->flags), llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);
87 EXPECT_TRUE(f->sections.empty());
88 EXPECT_TRUE(f->localSymbols.empty());
89 EXPECT_TRUE(f->globalSymbols.empty());
90 EXPECT_TRUE(f->undefinedSymbols.empty());
91}
92
93TEST(ObjectFileYAML, empty_armv6) {
94 std::unique_ptr<NormalizedFile> f = fromYAML(
95 "---\n"
96 "arch: armv6\n"
97 "file-type: MH_OBJECT\n"
98 "flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]\n"
99 "...\n");
100 EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_armv6);
101 EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);
102 EXPECT_EQ((int)(f->flags), llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);
103 EXPECT_TRUE(f->sections.empty());
104 EXPECT_TRUE(f->localSymbols.empty());
105 EXPECT_TRUE(f->globalSymbols.empty());
106 EXPECT_TRUE(f->undefinedSymbols.empty());
107}
108
109TEST(ObjectFileYAML, empty_armv7) {
110 std::unique_ptr<NormalizedFile> f = fromYAML(
111 "---\n"
112 "arch: armv7\n"
113 "file-type: MH_OBJECT\n"
114 "flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]\n"
115 "...\n");
116 EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_armv7);
117 EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);
118 EXPECT_EQ((int)(f->flags), llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);
119 EXPECT_TRUE(f->sections.empty());
120 EXPECT_TRUE(f->localSymbols.empty());
121 EXPECT_TRUE(f->globalSymbols.empty());
122 EXPECT_TRUE(f->undefinedSymbols.empty());
123}
124
125TEST(ObjectFileYAML, empty_armv7s) {
126 std::unique_ptr<NormalizedFile> f = fromYAML(
127 "---\n"
128 "arch: armv7s\n"
129 "file-type: MH_OBJECT\n"
130 "flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]\n"
131 "...\n");
132 EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_armv7s);
133 EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);
134 EXPECT_EQ((int)(f->flags), llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);
135 EXPECT_TRUE(f->sections.empty());
136 EXPECT_TRUE(f->localSymbols.empty());
137 EXPECT_TRUE(f->globalSymbols.empty());
138 EXPECT_TRUE(f->undefinedSymbols.empty());
139}
140
141TEST(ObjectFileYAML, roundTrip) {
142 std::string intermediate;
143 {
144 NormalizedFile f;
145 f.arch = lld::MachOLinkingContext::arch_x86_64;
146 f.fileType = llvm::MachO::MH_OBJECT;
147 f.flags = llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS;
148 f.os = lld::MachOLinkingContext::OS::macOSX;
149 toYAML(f, intermediate);
150 }
151 {
152 std::unique_ptr<NormalizedFile> f2 = fromYAML(intermediate);
153 EXPECT_EQ(f2->arch, lld::MachOLinkingContext::arch_x86_64);
154 EXPECT_EQ((int)(f2->fileType), llvm::MachO::MH_OBJECT);
155 EXPECT_EQ((int)(f2->flags), llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);
156 EXPECT_TRUE(f2->sections.empty());
157 EXPECT_TRUE(f2->localSymbols.empty());
158 EXPECT_TRUE(f2->globalSymbols.empty());
159 EXPECT_TRUE(f2->undefinedSymbols.empty());
160 }
161}
162
163TEST(ObjectFileYAML, oneSymbol) {
164 std::unique_ptr<NormalizedFile> f = fromYAML(
165 "---\n"
166 "arch: x86_64\n"
167 "file-type: MH_OBJECT\n"
168 "global-symbols:\n"
169 " - name: _main\n"
170 " type: N_SECT\n"
171 " scope: [ N_EXT ]\n"
172 " sect: 1\n"
173 " desc: [ ]\n"
174 " value: 0x100\n"
175 "...\n");
176 EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_x86_64);
177 EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);
178 EXPECT_TRUE(f->sections.empty());
179 EXPECT_TRUE(f->localSymbols.empty());
180 EXPECT_TRUE(f->undefinedSymbols.empty());
181 EXPECT_EQ(f->globalSymbols.size(), 1UL);
182 const Symbol& sym = f->globalSymbols[0];
183 EXPECT_TRUE(sym.name.equals("_main"));
184 EXPECT_EQ((int)(sym.type), llvm::MachO::N_SECT);
185 EXPECT_EQ((int)(sym.scope), llvm::MachO::N_EXT);
186 EXPECT_EQ(sym.sect, 1);
187 EXPECT_EQ((int)(sym.desc), 0);
188 EXPECT_EQ((uint64_t)sym.value, 0x100ULL);
189}
190
191TEST(ObjectFileYAML, oneSection) {
192 std::unique_ptr<NormalizedFile> f = fromYAML(
193 "---\n"
194 "arch: x86_64\n"
195 "file-type: MH_OBJECT\n"
196 "sections:\n"
197 " - segment: __TEXT\n"
198 " section: __text\n"
199 " type: S_REGULAR\n"
200 " attributes: [ S_ATTR_PURE_INSTRUCTIONS ]\n"
201 " alignment: 2\n"
202 " address: 0x12345678\n"
203 " content: [ 0x90, 0x90 ]\n"
204 "...\n");
205 EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_x86_64);
206 EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);
207 EXPECT_TRUE(f->localSymbols.empty());
208 EXPECT_TRUE(f->globalSymbols.empty());
209 EXPECT_TRUE(f->undefinedSymbols.empty());
210 EXPECT_EQ(f->sections.size(), 1UL);
211 const Section& sect = f->sections[0];
212 EXPECT_TRUE(sect.segmentName.equals("__TEXT"));
213 EXPECT_TRUE(sect.sectionName.equals("__text"));
214 EXPECT_EQ((uint32_t)(sect.type), (uint32_t)(llvm::MachO::S_REGULAR));
215 EXPECT_EQ((uint32_t)(sect.attributes),
216 (uint32_t)(llvm::MachO::S_ATTR_PURE_INSTRUCTIONS));
217 EXPECT_EQ((uint16_t)sect.alignment, 2U);
218 EXPECT_EQ((uint64_t)sect.address, 0x12345678ULL);
219 EXPECT_EQ(sect.content.size(), 2UL);
220 EXPECT_EQ((int)(sect.content[0]), 0x90);
221 EXPECT_EQ((int)(sect.content[1]), 0x90);
222}
223
224TEST(ObjectFileYAML, hello_x86_64) {
225 std::unique_ptr<NormalizedFile> f = fromYAML(
226 "---\n"
227 "arch: x86_64\n"
228 "file-type: MH_OBJECT\n"
229 "flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]\n"
230 "sections:\n"
231 " - segment: __TEXT\n"
232 " section: __text\n"
233 " type: S_REGULAR\n"
234 " attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS]\n"
235 " alignment: 1\n"
236 " address: 0x0000\n"
237 " content: [ 0x55, 0x48, 0x89, 0xe5, 0x48, 0x8d, 0x3d, 0x00,\n"
238 " 0x00, 0x00, 0x00, 0x30, 0xc0, 0xe8, 0x00, 0x00,\n"
239 " 0x00, 0x00, 0x31, 0xc0, 0x5d, 0xc3 ]\n"
240 " relocations:\n"
241 " - offset: 0x0e\n"
242 " type: X86_64_RELOC_BRANCH\n"
243 " length: 2\n"
244 " pc-rel: true\n"
245 " extern: true\n"
246 " symbol: 2\n"
247 " - offset: 0x07\n"
248 " type: X86_64_RELOC_SIGNED\n"
249 " length: 2\n"
250 " pc-rel: true\n"
251 " extern: true\n"
252 " symbol: 1\n"
253 " - segment: __TEXT\n"
254 " section: __cstring\n"
255 " type: S_CSTRING_LITERALS\n"
256 " attributes: [ ]\n"
257 " alignment: 1\n"
258 " address: 0x0016\n"
259 " content: [ 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x0a, 0x00 ]\n"
260 "global-symbols:\n"
261 " - name: _main\n"
262 " type: N_SECT\n"
263 " scope: [ N_EXT ]\n"
264 " sect: 1\n"
265 " value: 0x0\n"
266 "local-symbols:\n"
267 " - name: L_.str\n"
268 " type: N_SECT\n"
269 " scope: [ ]\n"
270 " sect: 2\n"
271 " value: 0x16\n"
272 "undefined-symbols:\n"
273 " - name: _printf\n"
274 " type: N_UNDF\n"
275 " value: 0x0\n"
276 "...\n");
277 EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_x86_64);
278 EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);
279 EXPECT_EQ((int)(f->flags), llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);
280 EXPECT_EQ(f->sections.size(), 2UL);
281
282 const Section& sect1 = f->sections[0];
283 EXPECT_TRUE(sect1.segmentName.equals("__TEXT"));
284 EXPECT_TRUE(sect1.sectionName.equals("__text"));
285 EXPECT_EQ((uint32_t)(sect1.type), (uint32_t)(llvm::MachO::S_REGULAR));
286 EXPECT_EQ((uint32_t)(sect1.attributes),
287 (uint32_t)(llvm::MachO::S_ATTR_PURE_INSTRUCTIONS
288 | llvm::MachO::S_ATTR_SOME_INSTRUCTIONS));
289 EXPECT_EQ((uint16_t)sect1.alignment, 1U);
290 EXPECT_EQ((uint64_t)sect1.address, 0x0ULL);
291 EXPECT_EQ(sect1.content.size(), 22UL);
292 EXPECT_EQ((int)(sect1.content[0]), 0x55);
293 EXPECT_EQ((int)(sect1.content[1]), 0x48);
294 EXPECT_EQ(sect1.relocations.size(), 2UL);
295 const Relocation& reloc1 = sect1.relocations[0];
296 EXPECT_EQ(reloc1.offset, 0x0eU);
297 EXPECT_FALSE(reloc1.scattered);
298 EXPECT_EQ((int)reloc1.type, (int)llvm::MachO::X86_64_RELOC_BRANCH);
299 EXPECT_EQ(reloc1.length, 2);
300 EXPECT_TRUE(reloc1.pcRel);
301 EXPECT_TRUE(reloc1.isExtern);
302 EXPECT_EQ(reloc1.symbol, 2U);
303 EXPECT_EQ((int)(reloc1.value), 0);
304 const Relocation& reloc2 = sect1.relocations[1];
305 EXPECT_EQ(reloc2.offset, 0x07U);
306 EXPECT_FALSE(reloc2.scattered);
307 EXPECT_EQ((int)reloc2.type, (int)llvm::MachO::X86_64_RELOC_SIGNED);
308 EXPECT_EQ(reloc2.length, 2);
309 EXPECT_TRUE(reloc2.pcRel);
310 EXPECT_TRUE(reloc2.isExtern);
311 EXPECT_EQ(reloc2.symbol, 1U);
312 EXPECT_EQ((int)(reloc2.value), 0);
313
314 const Section& sect2 = f->sections[1];
315 EXPECT_TRUE(sect2.segmentName.equals("__TEXT"));
316 EXPECT_TRUE(sect2.sectionName.equals("__cstring"));
317 EXPECT_EQ((uint32_t)(sect2.type), (uint32_t)(llvm::MachO::S_CSTRING_LITERALS));
318 EXPECT_EQ((uint32_t)(sect2.attributes), 0U);
319 EXPECT_EQ((uint16_t)sect2.alignment, 1U);
320 EXPECT_EQ((uint64_t)sect2.address, 0x016ULL);
321 EXPECT_EQ(sect2.content.size(), 7UL);
322 EXPECT_EQ((int)(sect2.content[0]), 0x68);
323 EXPECT_EQ((int)(sect2.content[1]), 0x65);
324 EXPECT_EQ((int)(sect2.content[2]), 0x6c);
325
326 EXPECT_EQ(f->globalSymbols.size(), 1UL);
327 const Symbol& sym1 = f->globalSymbols[0];
328 EXPECT_TRUE(sym1.name.equals("_main"));
329 EXPECT_EQ((int)(sym1.type), llvm::MachO::N_SECT);
330 EXPECT_EQ((int)(sym1.scope), llvm::MachO::N_EXT);
331 EXPECT_EQ(sym1.sect, 1);
332 EXPECT_EQ((int)(sym1.desc), 0);
333 EXPECT_EQ((uint64_t)sym1.value, 0x0ULL);
334 EXPECT_EQ(f->localSymbols.size(), 1UL);
335 const Symbol& sym2 = f->localSymbols[0];
336 EXPECT_TRUE(sym2.name.equals("L_.str"));
337 EXPECT_EQ((int)(sym2.type), llvm::MachO::N_SECT);
338 EXPECT_EQ((int)(sym2.scope), 0);
339 EXPECT_EQ(sym2.sect, 2);
340 EXPECT_EQ((int)(sym2.desc), 0);
341 EXPECT_EQ((uint64_t)sym2.value, 0x16ULL);
342 EXPECT_EQ(f->undefinedSymbols.size(), 1UL);
343 const Symbol& sym3 = f->undefinedSymbols[0];
344 EXPECT_TRUE(sym3.name.equals("_printf"));
345 EXPECT_EQ((int)(sym3.type), llvm::MachO::N_UNDF);
346 EXPECT_EQ((int)(sym3.scope), 0);
347 EXPECT_EQ(sym3.sect, 0);
348 EXPECT_EQ((int)(sym3.desc), 0);
349 EXPECT_EQ((uint64_t)sym3.value, 0x0ULL);
350}
351
352TEST(ObjectFileYAML, hello_x86) {
353 std::unique_ptr<NormalizedFile> f = fromYAML(
354 "---\n"
355 "arch: x86\n"
356 "file-type: MH_OBJECT\n"
357 "flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]\n"
358 "sections:\n"
359 " - segment: __TEXT\n"
360 " section: __text\n"
361 " type: S_REGULAR\n"
362 " attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS]\n"
363 " alignment: 1\n"
364 " address: 0x0000\n"
365 " content: [ 0x55, 0x89, 0xe5, 0x83, 0xec, 0x08, 0xe8, 0x00,\n"
366 " 0x00, 0x00, 0x00, 0x58, 0x8d, 0x80, 0x16, 0x00,\n"
367 " 0x00, 0x00, 0x89, 0x04, 0x24, 0xe8, 0xe6, 0xff,\n"
368 " 0xff, 0xff, 0x31, 0xc0, 0x83, 0xc4, 0x08, 0x5d,\n"
369 " 0xc3 ]\n"
370 " relocations:\n"
371 " - offset: 0x16\n"
372 " type: GENERIC_RELOC_VANILLA\n"
373 " length: 2\n"
374 " pc-rel: true\n"
375 " extern: true\n"
376 " symbol: 1\n"
377 " - offset: 0x0e\n"
378 " scattered: true\n"
379 " type: GENERIC_RELOC_LOCAL_SECTDIFF\n"
380 " length: 2\n"
381 " pc-rel: false\n"
382 " value: 0x21\n"
383 " - offset: 0x0\n"
384 " scattered: true\n"
385 " type: GENERIC_RELOC_PAIR\n"
386 " length: 2\n"
387 " pc-rel: false\n"
388 " value: 0xb\n"
389 " - segment: __TEXT\n"
390 " section: __cstring\n"
391 " type: S_CSTRING_LITERALS\n"
392 " attributes: [ ]\n"
393 " alignment: 1\n"
394 " address: 0x0021\n"
395 " content: [ 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x0a, 0x00 ]\n"
396 "global-symbols:\n"
397 " - name: _main\n"
398 " type: N_SECT\n"
399 " scope: [ N_EXT ]\n"
400 " sect: 1\n"
401 " value: 0x0\n"
402 "undefined-symbols:\n"
403 " - name: _printf\n"
404 " type: N_UNDF\n"
405 " value: 0x0\n"
406 "...\n");
407 EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_x86);
408 EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);
409 EXPECT_EQ((int)(f->flags), llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);
410 EXPECT_EQ(f->sections.size(), 2UL);
411
412 const Section& sect1 = f->sections[0];
413 EXPECT_TRUE(sect1.segmentName.equals("__TEXT"));
414 EXPECT_TRUE(sect1.sectionName.equals("__text"));
415 EXPECT_EQ((uint32_t)(sect1.type), (uint32_t)(llvm::MachO::S_REGULAR));
416 EXPECT_EQ((uint32_t)(sect1.attributes),
417 (uint32_t)(llvm::MachO::S_ATTR_PURE_INSTRUCTIONS
418 | llvm::MachO::S_ATTR_SOME_INSTRUCTIONS));
419 EXPECT_EQ((uint16_t)sect1.alignment, 1U);
420 EXPECT_EQ((uint64_t)sect1.address, 0x0ULL);
421 EXPECT_EQ(sect1.content.size(), 33UL);
422 EXPECT_EQ((int)(sect1.content[0]), 0x55);
423 EXPECT_EQ((int)(sect1.content[1]), 0x89);
424 EXPECT_EQ(sect1.relocations.size(), 3UL);
425 const Relocation& reloc1 = sect1.relocations[0];
426 EXPECT_EQ(reloc1.offset, 0x16U);
427 EXPECT_FALSE(reloc1.scattered);
428 EXPECT_EQ((int)reloc1.type, (int)llvm::MachO::GENERIC_RELOC_VANILLA);
429 EXPECT_EQ(reloc1.length, 2);
430 EXPECT_TRUE(reloc1.pcRel);
431 EXPECT_TRUE(reloc1.isExtern);
432 EXPECT_EQ(reloc1.symbol, 1U);
433 EXPECT_EQ((int)(reloc1.value), 0);
434 const Relocation& reloc2 = sect1.relocations[1];
435 EXPECT_EQ(reloc2.offset, 0x0eU);
436 EXPECT_TRUE(reloc2.scattered);
437 EXPECT_EQ((int)reloc2.type, (int)llvm::MachO::GENERIC_RELOC_LOCAL_SECTDIFF);
438 EXPECT_EQ(reloc2.length, 2);
439 EXPECT_FALSE(reloc2.pcRel);
440 EXPECT_EQ(reloc2.symbol, 0U);
441 EXPECT_EQ((int)(reloc2.value), 0x21);
442 const Relocation& reloc3 = sect1.relocations[2];
443 EXPECT_EQ(reloc3.offset, 0U);
444 EXPECT_TRUE(reloc3.scattered);
445 EXPECT_EQ((int)reloc3.type, (int)llvm::MachO::GENERIC_RELOC_PAIR);
446 EXPECT_EQ(reloc3.length, 2);
447 EXPECT_FALSE(reloc3.pcRel);
448 EXPECT_EQ(reloc3.symbol, 0U);
449 EXPECT_EQ((int)(reloc3.value), 0xb);
450
451 const Section& sect2 = f->sections[1];
452 EXPECT_TRUE(sect2.segmentName.equals("__TEXT"));
453 EXPECT_TRUE(sect2.sectionName.equals("__cstring"));
454 EXPECT_EQ((uint32_t)(sect2.type), (uint32_t)(llvm::MachO::S_CSTRING_LITERALS));
455 EXPECT_EQ((uint32_t)(sect2.attributes), 0U);
456 EXPECT_EQ((uint16_t)sect2.alignment, 1U);
457 EXPECT_EQ((uint64_t)sect2.address, 0x021ULL);
458 EXPECT_EQ(sect2.content.size(), 7UL);
459 EXPECT_EQ((int)(sect2.content[0]), 0x68);
460 EXPECT_EQ((int)(sect2.content[1]), 0x65);
461 EXPECT_EQ((int)(sect2.content[2]), 0x6c);
462
463 EXPECT_EQ(f->globalSymbols.size(), 1UL);
464 const Symbol& sym1 = f->globalSymbols[0];
465 EXPECT_TRUE(sym1.name.equals("_main"));
466 EXPECT_EQ((int)(sym1.type), llvm::MachO::N_SECT);
467 EXPECT_EQ((int)(sym1.scope), llvm::MachO::N_EXT);
468 EXPECT_EQ(sym1.sect, 1);
469 EXPECT_EQ((int)(sym1.desc), 0);
470 EXPECT_EQ((uint64_t)sym1.value, 0x0ULL);
471 EXPECT_EQ(f->undefinedSymbols.size(), 1UL);
472 const Symbol& sym2 = f->undefinedSymbols[0];
473 EXPECT_TRUE(sym2.name.equals("_printf"));
474 EXPECT_EQ((int)(sym2.type), llvm::MachO::N_UNDF);
475 EXPECT_EQ((int)(sym2.scope), 0);
476 EXPECT_EQ(sym2.sect, 0);
477 EXPECT_EQ((int)(sym2.desc), 0);
478 EXPECT_EQ((uint64_t)sym2.value, 0x0ULL);
479}
480
481TEST(ObjectFileYAML, hello_armv6) {
482 std::unique_ptr<NormalizedFile> f = fromYAML(
483 "---\n"
484 "arch: armv6\n"
485 "file-type: MH_OBJECT\n"
486 "flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]\n"
487 "sections:\n"
488 " - segment: __TEXT\n"
489 " section: __text\n"
490 " type: S_REGULAR\n"
491 " attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS]\n"
492 " alignment: 4\n"
493 " address: 0x0000\n"
494 " content: [ 0x80, 0x40, 0x2d, 0xe9, 0x10, 0x00, 0x9f, 0xe5,\n"
495 " 0x0d, 0x70, 0xa0, 0xe1, 0x00, 0x00, 0x8f, 0xe0,\n"
496 " 0xfa, 0xff, 0xff, 0xeb, 0x00, 0x00, 0xa0, 0xe3,\n"
497 " 0x80, 0x80, 0xbd, 0xe8, 0x0c, 0x00, 0x00, 0x00 ]\n"
498 " relocations:\n"
499 " - offset: 0x1c\n"
500 " scattered: true\n"
501 " type: ARM_RELOC_SECTDIFF\n"
502 " length: 2\n"
503 " pc-rel: false\n"
504 " value: 0x20\n"
505 " - offset: 0x0\n"
506 " scattered: true\n"
507 " type: ARM_RELOC_PAIR\n"
508 " length: 2\n"
509 " pc-rel: false\n"
510 " value: 0xc\n"
511 " - offset: 0x10\n"
512 " type: ARM_RELOC_BR24\n"
513 " length: 2\n"
514 " pc-rel: true\n"
515 " extern: true\n"
516 " symbol: 1\n"
517 " - segment: __TEXT\n"
518 " section: __cstring\n"
519 " type: S_CSTRING_LITERALS\n"
520 " attributes: [ ]\n"
521 " alignment: 1\n"
522 " address: 0x0020\n"
523 " content: [ 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x0a, 0x00 ]\n"
524 "global-symbols:\n"
525 " - name: _main\n"
526 " type: N_SECT\n"
527 " scope: [ N_EXT ]\n"
528 " sect: 1\n"
529 " value: 0x0\n"
530 "undefined-symbols:\n"
531 " - name: _printf\n"
532 " type: N_UNDF\n"
533 " value: 0x0\n"
534 "...\n");
535 EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_armv6);
536 EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);
537 EXPECT_EQ((int)(f->flags), llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);
538 EXPECT_EQ(f->sections.size(), 2UL);
539
540 const Section& sect1 = f->sections[0];
541 EXPECT_TRUE(sect1.segmentName.equals("__TEXT"));
542 EXPECT_TRUE(sect1.sectionName.equals("__text"));
543 EXPECT_EQ((uint32_t)(sect1.type), (uint32_t)(llvm::MachO::S_REGULAR));
544 EXPECT_EQ((uint32_t)(sect1.attributes),
545 (uint32_t)(llvm::MachO::S_ATTR_PURE_INSTRUCTIONS
546 | llvm::MachO::S_ATTR_SOME_INSTRUCTIONS));
547 EXPECT_EQ((uint16_t)sect1.alignment, 4U);
548 EXPECT_EQ((uint64_t)sect1.address, 0x0ULL);
549 EXPECT_EQ(sect1.content.size(), 32UL);
550 EXPECT_EQ((int)(sect1.content[0]), 0x80);
551 EXPECT_EQ((int)(sect1.content[1]), 0x40);
552 EXPECT_EQ(sect1.relocations.size(), 3UL);
553 const Relocation& reloc1 = sect1.relocations[0];
554 EXPECT_EQ(reloc1.offset, 0x1cU);
555 EXPECT_TRUE(reloc1.scattered);
556 EXPECT_EQ((int)reloc1.type, (int)llvm::MachO::ARM_RELOC_SECTDIFF);
557 EXPECT_EQ(reloc1.length, 2);
558 EXPECT_FALSE(reloc1.pcRel);
559 EXPECT_EQ(reloc1.symbol, 0U);
560 EXPECT_EQ((int)(reloc1.value), 0x20);
561 const Relocation& reloc2 = sect1.relocations[1];
562 EXPECT_EQ(reloc2.offset, 0x0U);
563 EXPECT_TRUE(reloc2.scattered);
564 EXPECT_EQ((int)reloc2.type, (int)llvm::MachO::ARM_RELOC_PAIR);
565 EXPECT_EQ(reloc2.length, 2);
566 EXPECT_FALSE(reloc2.pcRel);
567 EXPECT_EQ(reloc2.symbol, 0U);
568 EXPECT_EQ((int)(reloc2.value), 0xc);
569 const Relocation& reloc3 = sect1.relocations[2];
570 EXPECT_EQ(reloc3.offset, 0x10U);
571 EXPECT_FALSE(reloc3.scattered);
572 EXPECT_EQ((int)reloc3.type, (int)llvm::MachO::ARM_RELOC_BR24);
573 EXPECT_EQ(reloc3.length, 2);
574 EXPECT_TRUE(reloc3.pcRel);
575 EXPECT_TRUE(reloc3.isExtern);
576 EXPECT_EQ(reloc3.symbol, 1U);
577 EXPECT_EQ((int)(reloc3.value), 0);
578
579 const Section& sect2 = f->sections[1];
580 EXPECT_TRUE(sect2.segmentName.equals("__TEXT"));
581 EXPECT_TRUE(sect2.sectionName.equals("__cstring"));
582 EXPECT_EQ((uint32_t)(sect2.type), (uint32_t)(llvm::MachO::S_CSTRING_LITERALS));
583 EXPECT_EQ((uint32_t)(sect2.attributes), 0U);
584 EXPECT_EQ((uint16_t)sect2.alignment, 1U);
585 EXPECT_EQ((uint64_t)sect2.address, 0x020ULL);
586 EXPECT_EQ(sect2.content.size(), 7UL);
587 EXPECT_EQ((int)(sect2.content[0]), 0x68);
588 EXPECT_EQ((int)(sect2.content[1]), 0x65);
589 EXPECT_EQ((int)(sect2.content[2]), 0x6c);
590
591 EXPECT_EQ(f->globalSymbols.size(), 1UL);
592 const Symbol& sym1 = f->globalSymbols[0];
593 EXPECT_TRUE(sym1.name.equals("_main"));
594 EXPECT_EQ((int)(sym1.type), llvm::MachO::N_SECT);
595 EXPECT_EQ((int)(sym1.scope), llvm::MachO::N_EXT);
596 EXPECT_EQ(sym1.sect, 1);
597 EXPECT_EQ((int)(sym1.desc), 0);
598 EXPECT_EQ((uint64_t)sym1.value, 0x0ULL);
599 EXPECT_EQ(f->undefinedSymbols.size(), 1UL);
600 const Symbol& sym2 = f->undefinedSymbols[0];
601 EXPECT_TRUE(sym2.name.equals("_printf"));
602 EXPECT_EQ((int)(sym2.type), llvm::MachO::N_UNDF);
603 EXPECT_EQ((int)(sym2.scope), 0);
604 EXPECT_EQ(sym2.sect, 0);
605 EXPECT_EQ((int)(sym2.desc), 0);
606 EXPECT_EQ((uint64_t)sym2.value, 0x0ULL);
607}
608
609TEST(ObjectFileYAML, hello_armv7) {
610 std::unique_ptr<NormalizedFile> f = fromYAML(
611 "---\n"
612 "arch: armv7\n"
613 "file-type: MH_OBJECT\n"
614 "flags: [ MH_SUBSECTIONS_VIA_SYMBOLS ]\n"
615 "sections:\n"
616 " - segment: __TEXT\n"
617 " section: __text\n"
618 " type: S_REGULAR\n"
619 " attributes: [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS]\n"
620 " alignment: 2\n"
621 " address: 0x0000\n"
622 " content: [ 0x80, 0xb5, 0x40, 0xf2, 0x06, 0x00, 0x6f, 0x46,\n"
623 " 0xc0, 0xf2, 0x00, 0x00, 0x78, 0x44, 0xff, 0xf7,\n"
624 " 0xf8, 0xef, 0x00, 0x20, 0x80, 0xbd ]\n"
625 " relocations:\n"
626 " - offset: 0x0e\n"
627 " type: ARM_THUMB_RELOC_BR22\n"
628 " length: 2\n"
629 " pc-rel: true\n"
630 " extern: true\n"
631 " symbol: 1\n"
632 " - offset: 0x08\n"
633 " scattered: true\n"
634 " type: ARM_RELOC_HALF_SECTDIFF\n"
635 " length: 3\n"
636 " pc-rel: false\n"
637 " value: 0x16\n"
638 " - offset: 0x06\n"
639 " scattered: true\n"
640 " type: ARM_RELOC_PAIR\n"
641 " length: 3\n"
642 " pc-rel: false\n"
643 " value: 0xc\n"
644 " - offset: 0x02\n"
645 " scattered: true\n"
646 " type: ARM_RELOC_HALF_SECTDIFF\n"
647 " length: 2\n"
648 " pc-rel: false\n"
649 " value: 0x16\n"
650 " - offset: 0x0\n"
651 " scattered: true\n"
652 " type: ARM_RELOC_PAIR\n"
653 " length: 2\n"
654 " pc-rel: false\n"
655 " value: 0xc\n"
656 " - segment: __TEXT\n"
657 " section: __cstring\n"
658 " type: S_CSTRING_LITERALS\n"
659 " attributes: [ ]\n"
660 " alignment: 1\n"
661 " address: 0x0016\n"
662 " content: [ 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x0a, 0x00 ]\n"
663 "global-symbols:\n"
664 " - name: _main\n"
665 " type: N_SECT\n"
666 " scope: [ N_EXT ]\n"
667 " sect: 1\n"
668 " desc: [ N_ARM_THUMB_DEF ]\n"
669 " value: 0x0\n"
670 "undefined-symbols:\n"
671 " - name: _printf\n"
672 " type: N_UNDF\n"
673 " value: 0x0\n"
674 "...\n");
675 EXPECT_EQ(f->arch, lld::MachOLinkingContext::arch_armv7);
676 EXPECT_EQ(f->fileType, llvm::MachO::MH_OBJECT);
677 EXPECT_EQ((int)(f->flags), llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS);
678 EXPECT_EQ(f->sections.size(), 2UL);
679
680 const Section& sect1 = f->sections[0];
681 EXPECT_TRUE(sect1.segmentName.equals("__TEXT"));
682 EXPECT_TRUE(sect1.sectionName.equals("__text"));
683 EXPECT_EQ((uint32_t)(sect1.type), (uint32_t)(llvm::MachO::S_REGULAR));
684 EXPECT_EQ((uint32_t)(sect1.attributes),
685 (uint32_t)(llvm::MachO::S_ATTR_PURE_INSTRUCTIONS
686 | llvm::MachO::S_ATTR_SOME_INSTRUCTIONS));
687 EXPECT_EQ((uint16_t)sect1.alignment, 2U);
688 EXPECT_EQ((uint64_t)sect1.address, 0x0ULL);
689 EXPECT_EQ(sect1.content.size(), 22UL);
690 EXPECT_EQ((int)(sect1.content[0]), 0x80);
691 EXPECT_EQ((int)(sect1.content[1]), 0xb5);
692 EXPECT_EQ(sect1.relocations.size(), 5UL);
693 const Relocation& reloc1 = sect1.relocations[0];
694 EXPECT_EQ(reloc1.offset, 0x0eU);
695 EXPECT_FALSE(reloc1.scattered);
696 EXPECT_EQ((int)reloc1.type, (int)llvm::MachO::ARM_THUMB_RELOC_BR22);
697 EXPECT_EQ(reloc1.length, 2);
698 EXPECT_TRUE(reloc1.pcRel);
699 EXPECT_TRUE(reloc1.isExtern);
700 EXPECT_EQ(reloc1.symbol, 1U);
701 EXPECT_EQ((int)(reloc1.value), 0);
702 const Relocation& reloc2 = sect1.relocations[1];
703 EXPECT_EQ(reloc2.offset, 0x8U);
704 EXPECT_TRUE(reloc2.scattered);
705 EXPECT_EQ((int)reloc2.type, (int)llvm::MachO::ARM_RELOC_HALF_SECTDIFF);
706 EXPECT_EQ(reloc2.length, 3);
707 EXPECT_FALSE(reloc2.pcRel);
708 EXPECT_EQ(reloc2.symbol, 0U);
709 EXPECT_EQ((int)(reloc2.value), 0x16);
710 const Relocation& reloc3 = sect1.relocations[2];
711 EXPECT_EQ(reloc3.offset, 0x6U);
712 EXPECT_TRUE(reloc3.scattered);
713 EXPECT_EQ((int)reloc3.type, (int)llvm::MachO::ARM_RELOC_PAIR);
714 EXPECT_EQ(reloc3.length, 3);
715 EXPECT_FALSE(reloc3.pcRel);
716 EXPECT_EQ(reloc3.symbol, 0U);
717 EXPECT_EQ((int)(reloc3.value), 0xc);
718 const Relocation& reloc4 = sect1.relocations[3];
719 EXPECT_EQ(reloc4.offset, 0x2U);
720 EXPECT_TRUE(reloc4.scattered);
721 EXPECT_EQ((int)reloc4.type, (int)llvm::MachO::ARM_RELOC_HALF_SECTDIFF);
722 EXPECT_EQ(reloc4.length, 2);
723 EXPECT_FALSE(reloc4.pcRel);
724 EXPECT_EQ(reloc4.symbol, 0U);
725 EXPECT_EQ((int)(reloc4.value), 0x16);
726 const Relocation& reloc5 = sect1.relocations[4];
727 EXPECT_EQ(reloc5.offset, 0x0U);
728 EXPECT_TRUE(reloc5.scattered);
729 EXPECT_EQ((int)reloc5.type, (int)llvm::MachO::ARM_RELOC_PAIR);
730 EXPECT_EQ(reloc5.length, 2);
731 EXPECT_FALSE(reloc5.pcRel);
732 EXPECT_EQ(reloc5.symbol, 0U);
733 EXPECT_EQ((int)(reloc5.value), 0xc);
734
735 const Section& sect2 = f->sections[1];
736 EXPECT_TRUE(sect2.segmentName.equals("__TEXT"));
737 EXPECT_TRUE(sect2.sectionName.equals("__cstring"));
738 EXPECT_EQ((uint32_t)(sect2.type), (uint32_t)(llvm::MachO::S_CSTRING_LITERALS));
739 EXPECT_EQ((uint32_t)(sect2.attributes), 0U);
740 EXPECT_EQ((uint16_t)sect2.alignment, 1U);
741 EXPECT_EQ((uint64_t)sect2.address, 0x016ULL);
742 EXPECT_EQ(sect2.content.size(), 7UL);
743 EXPECT_EQ((int)(sect2.content[0]), 0x68);
744 EXPECT_EQ((int)(sect2.content[1]), 0x65);
745 EXPECT_EQ((int)(sect2.content[2]), 0x6c);
746
747 EXPECT_EQ(f->globalSymbols.size(), 1UL);
748 const Symbol& sym1 = f->globalSymbols[0];
749 EXPECT_TRUE(sym1.name.equals("_main"));
750 EXPECT_EQ((int)(sym1.type), llvm::MachO::N_SECT);
751 EXPECT_EQ((int)(sym1.scope), llvm::MachO::N_EXT);
752 EXPECT_EQ(sym1.sect, 1);
753 EXPECT_EQ((int)(sym1.desc), (int)(llvm::MachO::N_ARM_THUMB_DEF));
754 EXPECT_EQ((uint64_t)sym1.value, 0x0ULL);
755 EXPECT_EQ(f->undefinedSymbols.size(), 1UL);
756 const Symbol& sym2 = f->undefinedSymbols[0];
757 EXPECT_TRUE(sym2.name.equals("_printf"));
758 EXPECT_EQ((int)(sym2.type), llvm::MachO::N_UNDF);
759 EXPECT_EQ((int)(sym2.scope), 0);
760 EXPECT_EQ(sym2.sect, 0);
761 EXPECT_EQ((int)(sym2.desc), 0);
762 EXPECT_EQ((uint64_t)sym2.value, 0x0ULL);
763}
deps/lld/unittests/MachOTests/empty_obj_x86_armv7.txt created+1272
......@@ -0,0 +1,1272 @@
10xca, 0xfe, 0xba, 0xbe, 0x00, 0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x07, 0x00,
20x00, 0x00, 0x03, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00,
30x00, 0x0c, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x40,
40x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00,
50x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
60x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
90x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
100x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
120x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
130x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
140x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
150x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
160x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
170x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
180x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
190x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
200x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
210x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
220x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
230x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
240x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
250x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
260x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
280x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
290x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
300x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
310x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
320x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
330x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
340x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
360x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
370x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
380x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
390x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
400x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
410x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
420x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
440x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
450x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
460x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
470x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
480x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
490x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
500x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
520x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
530x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
540x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
550x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
560x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
570x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
580x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
590x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
600x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
610x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
620x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
630x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
640x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
650x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
660x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
670x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
680x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
690x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
700x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
710x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
720x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
730x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
740x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
760x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
770x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
780x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
790x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
800x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
810x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
820x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
840x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
850x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
860x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
870x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
880x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
890x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
900x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
910x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
920x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
930x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
940x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
950x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
960x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
970x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
980x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
990x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1000x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1010x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1020x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1030x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1040x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1050x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1060x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1070x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1080x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1090x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1100x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1120x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1130x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1140x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1150x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1160x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1170x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1180x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1190x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1200x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1210x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1220x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1230x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1240x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1250x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1260x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1280x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1290x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1300x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1310x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1320x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1330x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1340x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1360x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1370x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1380x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1390x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1400x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1410x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1420x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1440x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1450x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1460x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1470x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1480x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1490x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1500x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1520x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1530x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1540x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1550x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1560x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1570x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1580x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1590x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1600x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1610x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1620x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1630x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1640x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1650x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1660x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1670x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1680x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1690x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1700x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1710x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1720x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1730x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1740x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1760x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1770x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1780x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1790x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1800x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1810x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1820x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1840x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1850x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1860x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1870x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1880x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1890x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1900x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1910x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1920x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1930x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1940x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1950x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1960x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1970x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1980x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1990x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2000x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2010x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2020x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2030x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2040x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2050x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2060x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2070x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2080x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2090x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2100x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2120x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2130x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2140x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2150x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2160x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2170x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2180x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2190x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2200x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2210x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2220x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2230x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2240x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2250x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2260x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2280x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2290x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2300x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2310x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2320x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2330x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2340x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2360x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2370x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2380x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2390x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2400x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2410x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2420x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2440x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2450x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2460x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2470x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2480x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2490x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2500x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2520x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2530x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2540x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2550x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2560x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2570x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2580x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2590x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2600x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2610x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2620x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2630x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2640x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2650x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2660x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2670x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2680x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2690x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2700x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2710x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2720x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2730x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2740x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2760x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2770x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2780x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2790x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2800x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2810x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2820x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2840x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2850x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2860x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2870x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2880x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2890x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2900x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2910x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2920x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2930x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2940x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2950x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2960x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2970x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2980x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2990x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3000x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3010x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3020x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3030x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3040x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3050x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3060x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3070x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3080x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3090x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3100x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3120x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3130x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3140x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3150x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3160x00, 0xcf, 0xfa, 0xed, 0xfe, 0x07, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00,
3170x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x00,
3180x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x98, 0x00,
3190x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3200x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3210x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x00,
3220x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00,
3230x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3240x00, 0x5f, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3250x00, 0x00, 0x00, 0x00, 0x5f, 0x5f, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00, 0x00,
3260x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, 0x00, 0x00,
3280x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3290x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3300x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3310x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3320x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3330x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3340x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3360x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3370x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3380x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3390x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3400x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3410x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3420x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3440x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3450x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3460x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3470x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3480x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3490x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3500x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3520x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3530x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3540x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3550x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3560x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3570x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3580x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3590x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3600x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3610x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3620x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3630x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3640x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3650x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3660x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3670x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3680x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3690x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3700x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3710x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3720x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3730x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3740x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3760x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3770x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3780x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3790x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3800x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3810x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3820x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3840x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3850x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3860x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3870x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3880x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3890x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3900x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3910x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3920x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3930x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3940x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3950x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3960x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3970x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3980x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3990x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4000x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4010x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4020x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4030x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4040x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4050x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4060x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4070x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4080x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4090x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4100x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4120x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4130x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4140x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4150x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4160x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4170x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4180x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4190x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4200x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4210x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4220x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4230x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4240x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4250x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4260x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4280x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4290x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4300x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4310x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4320x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4330x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4340x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4360x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4370x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4380x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4390x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4400x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4410x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4420x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4440x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4450x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4460x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4470x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4480x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4490x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4500x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4520x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4530x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4540x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4550x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4560x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4570x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4580x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4590x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4600x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4610x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4620x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4630x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4640x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4650x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4660x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4670x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4680x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4690x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4700x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4710x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4720x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4730x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4740x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4760x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4770x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4780x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4790x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4800x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4810x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4820x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4840x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4850x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4860x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4870x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4880x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4890x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4900x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4910x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4920x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4930x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4940x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4950x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4960x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4970x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4980x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
4990x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5000x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5010x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5020x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5030x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5040x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5050x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5060x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5070x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5080x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5090x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5100x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5120x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5130x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5140x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5150x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5160x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5170x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5180x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5190x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5200x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5210x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5220x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5230x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5240x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5250x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5260x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5280x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5290x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5300x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5310x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5320x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5330x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5340x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5360x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5370x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5380x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5390x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5400x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5410x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5420x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5440x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5450x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5460x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5470x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5480x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5490x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5500x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5520x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5530x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5540x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5550x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5560x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5570x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5580x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5590x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5600x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5610x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5620x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5630x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5640x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5650x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5660x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5670x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5680x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5690x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5700x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5710x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5720x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5730x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5740x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5760x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5770x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5780x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5790x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5800x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5810x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5820x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5840x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5850x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5860x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5870x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5880x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5890x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5900x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5910x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5920x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5930x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5940x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5950x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5960x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5970x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5980x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5990x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6000x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6010x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6020x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6030x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6040x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6050x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6060x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6070x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6080x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6090x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6100x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6120x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6130x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6140x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6150x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6160x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6170x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6180x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6190x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6200x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6210x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6220x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6230x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6240x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6250x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6260x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6280x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6290x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6300x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6310x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6320x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6330x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6340x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6360x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6370x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6380x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6390x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6400x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6410x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6420x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6440x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6450x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6460x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6470x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6480x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6490x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6500x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6520x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6530x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6540x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6550x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6560x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6570x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6580x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6590x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6600x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6610x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6620x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6630x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6640x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6650x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6660x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6670x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6680x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6690x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6700x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6710x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6720x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6730x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6740x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6760x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6770x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6780x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6790x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6800x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6810x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6820x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6840x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6850x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6860x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6870x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6880x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6890x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6900x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6910x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6920x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6930x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6940x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6950x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6960x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6970x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6980x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6990x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7000x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7010x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7020x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7030x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7040x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7050x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7060x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7070x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7080x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7090x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7100x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7120x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7130x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7140x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7150x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7160x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7170x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7180x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7190x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7200x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7210x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7220x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7230x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7240x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7250x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7260x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7280x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7290x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7300x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7310x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7320x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7330x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7340x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7360x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7370x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7380x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7390x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7400x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7410x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7420x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7440x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7450x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7460x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7470x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7480x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7490x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7500x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7520x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7530x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7540x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7550x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7560x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7570x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7580x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7590x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7600x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7610x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7620x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7630x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7640x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7650x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7660x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7670x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7680x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7690x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7700x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7710x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7720x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7730x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7740x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7760x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7770x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7780x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7790x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7800x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7810x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7820x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7840x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7850x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7860x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7870x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7880x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7890x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7900x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7910x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7920x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7930x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7940x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7950x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7960x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7970x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7980x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7990x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8000x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8010x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8020x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8030x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8040x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8050x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8060x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8070x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8080x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8090x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8100x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8120x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8130x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8140x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8150x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8160x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8170x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8180x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8190x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8200x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8210x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8220x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8230x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8240x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8250x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8260x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8280x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8290x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8300x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8310x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8320x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8330x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8340x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8360x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8370x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8380x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8390x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8400x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8410x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8420x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8440x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8450x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8460x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8470x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8480x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8490x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8500x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8520x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8530x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8540x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8550x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8560x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8570x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8580x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8590x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8600x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8610x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8620x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8630x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8640x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8650x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8660x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8670x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8680x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8690x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8700x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8710x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8720x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8730x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8740x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8760x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8770x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8780x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8790x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8800x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8810x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8820x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8840x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8850x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8860x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8870x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8880x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8890x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8900x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8910x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8920x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8930x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8940x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8950x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8960x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8970x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8980x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8990x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9000x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9010x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9020x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9030x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9040x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9050x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9060x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9070x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9080x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9090x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9100x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9120x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9130x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9140x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9150x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9160x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9170x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9180x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9190x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9200x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9210x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9220x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9230x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9240x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9250x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9260x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9280x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9290x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9300x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9310x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9320x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9330x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9340x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9360x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9370x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9380x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9390x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9400x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9410x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9420x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9440x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9450x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9460x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9470x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9480x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9490x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9500x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9520x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9530x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9540x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9550x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9560x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9570x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9580x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9590x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9600x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9610x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9620x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9630x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9640x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9650x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9660x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9670x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9680x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9690x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9700x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9710x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9720x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9730x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9740x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9760x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9770x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9780x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9790x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9800x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9810x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9820x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9840x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9850x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9860x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9870x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9880x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9890x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9900x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9910x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9920x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9930x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9940x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9950x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9960x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9970x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9980x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
9990x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10000x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10010x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10020x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10030x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10040x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10050x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10060x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10070x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10080x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10090x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10100x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10120x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10130x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10140x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10150x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10160x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10170x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10180x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10190x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10200x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10210x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10220x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10230x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10240x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10250x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10260x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10280x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10290x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10300x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10310x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10320x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10330x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10340x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10360x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10370x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10380x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10390x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10400x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10410x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10420x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10440x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10450x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10460x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10470x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10480x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10490x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10500x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10520x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10530x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10540x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10550x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10560x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10570x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10580x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10590x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10600x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10610x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10620x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10630x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10640x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10650x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10660x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10670x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10680x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10690x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10700x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10710x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10720x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10730x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10740x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10760x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10770x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10780x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10790x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10800x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10810x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10820x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10840x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10850x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10860x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10870x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10880x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10890x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10900x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10910x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10920x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10930x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10940x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10950x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10960x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10970x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10980x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
10990x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11000x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11010x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11020x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11030x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11040x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11050x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11060x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11070x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11080x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11090x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11100x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11120x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11130x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11140x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11150x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11160x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11170x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11180x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11190x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11200x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11210x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11220x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11230x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11240x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11250x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11260x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11280x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11290x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11300x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11310x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11320x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11330x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11340x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11360x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11370x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11380x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11390x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11400x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11410x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11420x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11440x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11450x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11460x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11470x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11480x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11490x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11500x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11520x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11530x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11540x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11550x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11560x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11570x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11580x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11590x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11600x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11610x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11620x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11630x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11640x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11650x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11660x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11670x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11680x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11690x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11700x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11710x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11720x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11730x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11740x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11750x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11760x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11770x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11780x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11790x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11800x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11810x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11820x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11830x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11840x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11850x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11860x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11870x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11880x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11890x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11900x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11910x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11920x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11930x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11940x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11950x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11960x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11970x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11980x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
11990x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12000x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12010x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12020x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12030x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12040x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12050x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12060x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12070x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12080x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12090x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12100x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12110x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12120x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12130x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12140x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12150x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12160x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12170x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12180x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12190x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12200x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12210x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12220x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12230x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12240x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12250x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12260x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12270x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12280x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12290x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12300x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12310x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12320x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12330x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12340x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12350x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12360x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12370x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12380x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12390x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12400x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12410x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12420x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12430x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12440x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12450x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12460x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12470x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12480x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12490x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12500x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12510x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12520x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12530x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12540x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12550x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12560x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12570x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12580x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12590x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12600x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12610x00, 0x00, 0x00, 0x00, 0xce, 0xfa, 0xed, 0xfe, 0x0c, 0x00, 0x00, 0x00, 0x09,
12620x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7c, 0x00,
12630x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00,
12640x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12650x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98,
12660x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00,
12670x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x5f, 0x74,
12680x65, 0x78, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12690x5f, 0x5f, 0x54, 0x45, 0x58, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12700x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x00,
12710x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
12720x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
example/mix_o_files/test.c+1-1
......@@ -8,7 +8,7 @@ int main(int argc, char **argv) {
88 const char *encoded = "YWxsIHlvdXIgYmFzZSBhcmUgYmVsb25nIHRvIHVz";
99 char buf[200];
1010
11 size_t len = decode_base_64(buf, 200, encoded, strlen(encoded));
11 size_t len = decode_base_64((uint8_t *)buf, 200, (uint8_t *)encoded, strlen(encoded));
1212 buf[len] = 0;
1313 assert(strcmp(buf, "all your base are belong to us") == 0);
1414
src/all_types.hpp-1
......@@ -1469,7 +1469,6 @@ struct CodeGen {
14691469 bool windows_subsystem_windows;
14701470 bool windows_subsystem_console;
14711471 bool windows_linker_unicode;
1472 Buf *darwin_linker_version;
14731472 Buf *mmacosx_version_min;
14741473 Buf *mios_version_min;
14751474 bool linker_rdynamic;
src/analyze.cpp+5-1
......@@ -1995,7 +1995,7 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) {
19951995 if (buf_eql_str(&fn_table_entry->symbol_name, "main")) {
19961996 g->main_fn = fn_table_entry;
19971997
1998 if (g->libc_link_lib == nullptr && tld_fn->base.visib_mod != VisibModExport) {
1998 if (tld_fn->base.visib_mod != VisibModExport) {
19991999 TypeTableEntry *err_void = get_error_type(g, g->builtin_types.entry_void);
20002000 TypeTableEntry *actual_return_type = fn_table_entry->type_entry->data.fn.fn_type_id.return_type;
20012001 if (actual_return_type != err_void) {
......@@ -2918,6 +2918,10 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {
29182918}
29192919
29202920static void add_symbols_from_import(CodeGen *g, AstNode *src_use_node, AstNode *dst_use_node) {
2921 if (src_use_node->data.use.resolution == TldResolutionUnresolved) {
2922 preview_use_decl(g, src_use_node);
2923 }
2924
29212925 IrInstruction *use_target_value = src_use_node->data.use.value;
29222926 if (use_target_value->value.type->id == TypeTableEntryIdInvalid) {
29232927 dst_use_node->owner->any_imports_failed = true;
src/codegen.cpp+4-8
......@@ -108,7 +108,6 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out
108108 g->libc_lib_dir = buf_create_from_str("");
109109 g->libc_static_lib_dir = buf_create_from_str("");
110110 g->libc_include_dir = buf_create_from_str("");
111 g->darwin_linker_version = buf_create_from_str("");
112111 g->each_lib_rpath = false;
113112 } else {
114113 // native compilation, we can rely on the configuration stuff
......@@ -119,7 +118,6 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out
119118 g->libc_lib_dir = buf_create_from_str(ZIG_LIBC_LIB_DIR);
120119 g->libc_static_lib_dir = buf_create_from_str(ZIG_LIBC_STATIC_LIB_DIR);
121120 g->libc_include_dir = buf_create_from_str(ZIG_LIBC_INCLUDE_DIR);
122 g->darwin_linker_version = buf_create_from_str(ZIG_HOST_LINK_VERSION);
123121#ifdef ZIG_EACH_LIB_RPATH
124122 g->each_lib_rpath = true;
125123#endif
......@@ -139,6 +137,7 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out
139137 g->zig_target.os == ZigLLVM_IOS)
140138 {
141139 g->libc_link_lib = create_link_lib(buf_create_from_str("c"));
140 g->link_libs_list.append(g->libc_link_lib);
142141 }
143142
144143 return g;
......@@ -250,10 +249,6 @@ void codegen_set_windows_unicode(CodeGen *g, bool municode) {
250249 g->windows_linker_unicode = municode;
251250}
252251
253void codegen_set_mlinker_version(CodeGen *g, Buf *darwin_linker_version) {
254 g->darwin_linker_version = darwin_linker_version;
255}
256
257252void codegen_set_mmacosx_version_min(CodeGen *g, Buf *mmacosx_version_min) {
258253 g->mmacosx_version_min = mmacosx_version_min;
259254}
......@@ -733,8 +728,8 @@ static LLVMValueRef get_panic_msg_ptr_val(CodeGen *g, PanicMsgId msg_id) {
733728 ConstExprValue *array_val = create_const_str_lit(g, buf_msg);
734729 init_const_slice(g, val, array_val, 0, buf_len(buf_msg), true);
735730
736 render_const_val_global(g, val, "");
737731 render_const_val(g, val);
732 render_const_val_global(g, val, "");
738733
739734 assert(val->global_refs->llvm_global);
740735 return val->global_refs->llvm_global;
......@@ -3651,7 +3646,8 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
36513646 fields[type_struct_field->gen_index] = gen_const_val(g, &const_val->data.x_struct.fields[i]);
36523647 }
36533648 }
3654 return LLVMConstNamedStruct(type_entry->type_ref, fields, type_entry->data.structure.gen_field_count);
3649 return LLVMConstStruct(fields, type_entry->data.structure.gen_field_count,
3650 type_entry->data.structure.layout == ContainerLayoutPacked);
36553651 }
36563652 case TypeTableEntryIdUnion:
36573653 {
src/codegen.hpp-1
......@@ -36,7 +36,6 @@ void codegen_add_lib_dir(CodeGen *codegen, const char *dir);
3636LinkLib *codegen_add_link_lib(CodeGen *codegen, Buf *lib);
3737void codegen_add_framework(CodeGen *codegen, const char *name);
3838void codegen_add_rpath(CodeGen *codegen, const char *name);
39void codegen_set_mlinker_version(CodeGen *g, Buf *darwin_linker_version);
4039void codegen_set_rdynamic(CodeGen *g, bool rdynamic);
4140void codegen_set_mmacosx_version_min(CodeGen *g, Buf *mmacosx_version_min);
4241void codegen_set_mios_version_min(CodeGen *g, Buf *mios_version_min);
src/config.h.in-1
......@@ -19,7 +19,6 @@
1919#define ZIG_LIBC_LIB_DIR "@ZIG_LIBC_LIB_DIR@"
2020#define ZIG_LIBC_STATIC_LIB_DIR "@ZIG_LIBC_STATIC_LIB_DIR@"
2121#define ZIG_DYNAMIC_LINKER "@ZIG_DYNAMIC_LINKER@"
22#define ZIG_HOST_LINK_VERSION "@ZIG_HOST_LINK_VERSION@"
2322
2423#cmakedefine ZIG_EACH_LIB_RPATH
2524#cmakedefine ZIG_LLVM_OLD_CXX_ABI
src/link.cpp+76-18
......@@ -325,6 +325,10 @@ static void construct_linker_job_elf(LinkJob *lj) {
325325 lj->args.append(get_libc_static_file(g, "crtend.o"));
326326 lj->args.append(get_libc_file(g, "crtn.o"));
327327 }
328
329 if (!g->is_native_target) {
330 lj->args.append("--allow-shlib-undefined");
331 }
328332}
329333
330334static bool is_target_cyg_mingw(const ZigTarget *target) {
......@@ -437,12 +441,26 @@ static void construct_linker_job_coff(LinkJob *lj) {
437441 }
438442 }
439443 if (buf_len(def_contents) != 0) {
440 Buf *dll_path = buf_alloc();
441 os_path_join(g->cache_dir, buf_create_from_str("all.dll"), dll_path);
442 ZigLLDDefToLib(def_contents, dll_path);
444 Buf *def_path = buf_alloc();
445 os_path_join(g->cache_dir, buf_create_from_str("all.def"), def_path);
446 os_write_file(def_path, def_contents);
443447
444448 Buf *all_lib_path = buf_alloc();
445449 os_path_join(g->cache_dir, buf_create_from_str("all.lib"), all_lib_path);
450
451 //Buf *dll_path = buf_alloc();
452 //os_path_join(g->cache_dir, buf_create_from_str("all.dll"), dll_path);
453
454 ZigList<const char *> args = {0};
455 args.append("link");
456 args.append(buf_ptr(buf_sprintf("-DEF:%s", buf_ptr(def_path))));
457 args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(all_lib_path))));
458 Buf diag = BUF_INIT;
459 if (!ZigLLDLink(g->zig_target.oformat, args.items, args.length, &diag)) {
460 fprintf(stderr, "%s\n", buf_ptr(&diag));
461 exit(1);
462 }
463
446464 lj->args.append(buf_ptr(all_lib_path));
447465 }
448466
......@@ -556,7 +574,7 @@ static void get_darwin_platform(LinkJob *lj, DarwinPlatform *platform) {
556574 } else if (g->mios_version_min) {
557575 platform->kind = IPhoneOS;
558576 } else {
559 zig_panic("unable to infer -macosx-version-min or -mios-version-min");
577 zig_panic("unable to infer -mmacosx-version-min or -mios-version-min");
560578 }
561579
562580 bool had_extra;
......@@ -616,7 +634,29 @@ static void construct_linker_job_macho(LinkJob *lj) {
616634 }
617635
618636 if (is_lib) {
619 zig_panic("TODO linker args on darwin for making a library");
637 if (!g->is_static) {
638 lj->args.append("-dylib");
639
640 Buf *compat_vers = buf_sprintf("%" ZIG_PRI_usize ".0.0", g->version_major);
641 lj->args.append("-compatibility_version");
642 lj->args.append(buf_ptr(compat_vers));
643
644 Buf *cur_vers = buf_sprintf("%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".%" ZIG_PRI_usize,
645 g->version_major, g->version_minor, g->version_patch);
646 lj->args.append("-current_version");
647 lj->args.append(buf_ptr(cur_vers));
648
649 // TODO getting an error when running an executable when doing this rpath thing
650 //Buf *dylib_install_name = buf_sprintf("@rpath/lib%s.%" ZIG_PRI_usize ".dylib",
651 // buf_ptr(g->root_out_name), g->version_major);
652 //lj->args.append("-install_name");
653 //lj->args.append(buf_ptr(dylib_install_name));
654
655 if (buf_len(&lj->out_file) == 0) {
656 buf_appendf(&lj->out_file, "lib%s.%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".%" ZIG_PRI_usize ".dylib",
657 buf_ptr(g->root_out_name), g->version_major, g->version_minor, g->version_patch);
658 }
659 }
620660 }
621661
622662 lj->args.append("-arch");
......@@ -649,8 +689,14 @@ static void construct_linker_job_macho(LinkJob *lj) {
649689 lj->args.append("-o");
650690 lj->args.append(buf_ptr(&lj->out_file));
651691
692 for (size_t i = 0; i < g->rpath_list.length; i += 1) {
693 Buf *rpath = g->rpath_list.at(i);
694 add_rpath(lj, rpath);
695 }
696 add_rpath(lj, &lj->out_file);
697
652698 if (shared) {
653 zig_panic("TODO");
699 lj->args.append("-headerpad_max_install_names");
654700 } else if (g->is_static) {
655701 lj->args.append("-lcrt0.o");
656702 } else {
......@@ -689,20 +735,30 @@ static void construct_linker_job_macho(LinkJob *lj) {
689735 lj->args.append((const char *)buf_ptr(g->link_objects.at(i)));
690736 }
691737
692 for (size_t i = 0; i < g->link_libs_list.length; i += 1) {
693 LinkLib *link_lib = g->link_libs_list.at(i);
694 if (buf_eql_str(link_lib->name, "c")) {
695 continue;
696 }
697 Buf *arg = buf_sprintf("-l%s", buf_ptr(link_lib->name));
698 lj->args.append(buf_ptr(arg));
738 // compiler_rt on darwin is missing some stuff, so we still build it and rely on LinkOnce
739 if (g->out_type == OutTypeExe || g->out_type == OutTypeLib) {
740 Buf *compiler_rt_o_path = build_compiler_rt(g);
741 lj->args.append(buf_ptr(compiler_rt_o_path));
699742 }
700743
701 // on Darwin, libSystem has libc in it, but also you have to use it
702 // to make syscalls because the syscall numbers are not documented
703 // and change between versions.
704 // so we always link against libSystem
705 lj->args.append("-lSystem");
744 if (g->is_native_target) {
745 for (size_t lib_i = 0; lib_i < g->link_libs_list.length; lib_i += 1) {
746 LinkLib *link_lib = g->link_libs_list.at(lib_i);
747 if (buf_eql_str(link_lib->name, "c")) {
748 // on Darwin, libSystem has libc in it, but also you have to use it
749 // to make syscalls because the syscall numbers are not documented
750 // and change between versions.
751 // so we always link against libSystem
752 lj->args.append("-lSystem");
753 } else {
754 Buf *arg = buf_sprintf("-l%s", buf_ptr(link_lib->name));
755 lj->args.append(buf_ptr(arg));
756 }
757 }
758 } else {
759 lj->args.append("-undefined");
760 lj->args.append("dynamic_lookup");
761 }
706762
707763 if (platform.kind == MacOS) {
708764 if (darwin_version_lt(&platform, 10, 5)) {
......@@ -732,6 +788,8 @@ static void construct_linker_job(LinkJob *lj) {
732788 return construct_linker_job_elf(lj);
733789 case ZigLLVM_MachO:
734790 return construct_linker_job_macho(lj);
791 case ZigLLVM_Wasm:
792 zig_panic("TODO link wasm");
735793 }
736794}
737795
src/main.cpp-7
......@@ -68,7 +68,6 @@ static int usage(const char *arg0) {
6868 " -municode (windows) link with unicode\n"
6969 " -framework [name] (darwin) link against framework\n"
7070 " -mios-version-min [ver] (darwin) set iOS deployment target\n"
71 " -mlinker-version [ver] (darwin) override linker version\n"
7271 " -mmacosx-version-min [ver] (darwin) set Mac OS X deployment target\n"
7372 " --ver-major [ver] dynamic library semver major version\n"
7473 " --ver-minor [ver] dynamic library semver minor version\n"
......@@ -199,7 +198,6 @@ int main(int argc, char **argv) {
199198 bool mwindows = false;
200199 bool mconsole = false;
201200 bool municode = false;
202 const char *mlinker_version = nullptr;
203201 bool rdynamic = false;
204202 const char *mmacosx_version_min = nullptr;
205203 const char *mios_version_min = nullptr;
......@@ -433,8 +431,6 @@ int main(int argc, char **argv) {
433431 target_os = argv[i];
434432 } else if (strcmp(arg, "--target-environ") == 0) {
435433 target_environ = argv[i];
436 } else if (strcmp(arg, "-mlinker-version") == 0) {
437 mlinker_version = argv[i];
438434 } else if (strcmp(arg, "-mmacosx-version-min") == 0) {
439435 mmacosx_version_min = argv[i];
440436 } else if (strcmp(arg, "-mios-version-min") == 0) {
......@@ -632,9 +628,6 @@ int main(int argc, char **argv) {
632628 codegen_set_windows_subsystem(g, mwindows, mconsole);
633629 codegen_set_windows_unicode(g, municode);
634630 codegen_set_rdynamic(g, rdynamic);
635 if (mlinker_version) {
636 codegen_set_mlinker_version(g, buf_create_from_str(mlinker_version));
637 }
638631 if (mmacosx_version_min && mios_version_min) {
639632 fprintf(stderr, "-mmacosx-version-min and -mios-version-min options not allowed together\n");
640633 return EXIT_FAILURE;
src/os.cpp+2-5
......@@ -709,10 +709,6 @@ int os_delete_file(Buf *path) {
709709 }
710710}
711711
712void os_init(void) {
713 srand((unsigned)time(NULL));
714}
715
716712int os_rename(Buf *src_path, Buf *dest_path) {
717713 if (rename(buf_ptr(src_path), buf_ptr(dest_path)) == -1) {
718714 return ErrorFileSystem;
......@@ -805,7 +801,8 @@ int os_make_dir(Buf *path) {
805801#endif
806802}
807803
808int zig_os_init(void) {
804int os_init(void) {
805 srand((unsigned)time(NULL));
809806#if defined(ZIG_OS_WINDOWS)
810807 unsigned __int64 frequency;
811808 if (QueryPerformanceFrequency((LARGE_INTEGER*) &frequency)) {
src/os.hpp+1-1
......@@ -27,8 +27,8 @@ struct Termination {
2727 int code;
2828};
2929
30int os_init(void);
3031
31void os_init(void);
3232void os_spawn_process(const char *exe, ZigList<const char *> &args, Termination *term);
3333int os_exec_process(const char *exe, ZigList<const char *> &args,
3434 Termination *term, Buf *out_stderr, Buf *out_stdout);
src/parseh.cpp+7-4
......@@ -341,7 +341,6 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const
341341 case BuiltinType::OCLEvent:
342342 case BuiltinType::OCLClkEvent:
343343 case BuiltinType::OCLQueue:
344 case BuiltinType::OCLNDRange:
345344 case BuiltinType::OCLReserveID:
346345 emit_warning(c, decl, "missed a builtin type");
347346 return c->codegen->builtin_types.entry_invalid;
......@@ -445,8 +444,8 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const
445444 case CC_X86Pascal: // __attribute__((pascal))
446445 emit_warning(c, decl, "function type has x86 pascal calling convention");
447446 return c->codegen->builtin_types.entry_invalid;
448 case CC_X86_64Win64: // __attribute__((ms_abi))
449 emit_warning(c, decl, "function type has x86 64win64 calling convention");
447 case CC_Win64: // __attribute__((ms_abi))
448 emit_warning(c, decl, "function type has win64 calling convention");
450449 return c->codegen->builtin_types.entry_invalid;
451450 case CC_X86_64SysV: // __attribute__((sysv_abi))
452451 emit_warning(c, decl, "function type has x86 64sysv calling convention");
......@@ -586,6 +585,7 @@ static TypeTableEntry *resolve_type_with_table(Context *c, const Type *ty, const
586585 case Type::Atomic:
587586 case Type::Pipe:
588587 case Type::ObjCTypeParam:
588 case Type::DeducedTemplateSpecialization:
589589 emit_warning(c, decl, "missed a '%s' type", ty->getTypeClassName());
590590 return c->codegen->builtin_types.entry_invalid;
591591 }
......@@ -1370,6 +1370,8 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch
13701370 bool capture_diagnostics = true;
13711371 bool user_files_are_volatile = true;
13721372 bool allow_pch_with_compiler_errors = false;
1373 bool single_file_parse = false;
1374 bool for_serialization = false;
13731375 const char *resources_path = ZIG_HEADERS_DIR;
13741376 std::unique_ptr<ASTUnit> err_unit;
13751377 std::unique_ptr<ASTUnit> ast_unit(ASTUnit::LoadFromCommandLine(
......@@ -1377,7 +1379,8 @@ int parse_h_file(ImportTableEntry *import, ZigList<ErrorMsg *> *errors, const ch
13771379 pch_container_ops, diags, resources_path,
13781380 only_local_decls, capture_diagnostics, None, true, 0, TU_Complete,
13791381 false, false, allow_pch_with_compiler_errors, skip_function_bodies,
1380 user_files_are_volatile, false, None, &err_unit));
1382 single_file_parse, user_files_are_volatile, for_serialization, None, &err_unit,
1383 nullptr));
13811384
13821385
13831386 // Early failures in LoadFromCommandLine may return with ErrUnit unset.
src/target.cpp+11
......@@ -24,6 +24,7 @@ static const ArchType arch_list[] = {
2424 {ZigLLVM_arm, ZigLLVM_ARMSubArch_v7m},
2525 {ZigLLVM_arm, ZigLLVM_ARMSubArch_v7s},
2626 {ZigLLVM_arm, ZigLLVM_ARMSubArch_v7k},
27 {ZigLLVM_arm, ZigLLVM_ARMSubArch_v7ve},
2728 {ZigLLVM_arm, ZigLLVM_ARMSubArch_v6},
2829 {ZigLLVM_arm, ZigLLVM_ARMSubArch_v6m},
2930 {ZigLLVM_arm, ZigLLVM_ARMSubArch_v6k},
......@@ -44,6 +45,7 @@ static const ArchType arch_list[] = {
4445 {ZigLLVM_mips64, ZigLLVM_NoSubArch},
4546 {ZigLLVM_mips64el, ZigLLVM_NoSubArch},
4647 {ZigLLVM_msp430, ZigLLVM_NoSubArch},
48 {ZigLLVM_nios2, ZigLLVM_NoSubArch},
4749 {ZigLLVM_ppc, ZigLLVM_NoSubArch},
4850 {ZigLLVM_ppc64, ZigLLVM_NoSubArch},
4951 {ZigLLVM_ppc64le, ZigLLVM_NoSubArch},
......@@ -100,10 +102,12 @@ static const ZigLLVM_VendorType vendor_list[] = {
100102 ZigLLVM_Myriad,
101103 ZigLLVM_AMD,
102104 ZigLLVM_Mesa,
105 ZigLLVM_SUSE,
103106};
104107
105108static const ZigLLVM_OSType os_list[] = {
106109 ZigLLVM_UnknownOS,
110 ZigLLVM_Ananas,
107111 ZigLLVM_CloudABI,
108112 ZigLLVM_Darwin,
109113 ZigLLVM_DragonFly,
......@@ -156,6 +160,7 @@ static const ZigLLVM_EnvironmentType environ_list[] = {
156160 ZigLLVM_Cygnus,
157161 ZigLLVM_AMDOpenCL,
158162 ZigLLVM_CoreCLR,
163 ZigLLVM_OpenCL,
159164};
160165
161166static const ZigLLVM_ObjectFormatType oformat_list[] = {
......@@ -163,6 +168,7 @@ static const ZigLLVM_ObjectFormatType oformat_list[] = {
163168 ZigLLVM_COFF,
164169 ZigLLVM_ELF,
165170 ZigLLVM_MachO,
171 ZigLLVM_Wasm,
166172};
167173
168174size_t target_oformat_count(void) {
......@@ -179,6 +185,7 @@ const char *get_target_oformat_name(ZigLLVM_ObjectFormatType oformat) {
179185 case ZigLLVM_COFF: return "coff";
180186 case ZigLLVM_ELF: return "elf";
181187 case ZigLLVM_MachO: return "macho";
188 case ZigLLVM_Wasm: return "wasm";
182189 }
183190 zig_unreachable();
184191}
......@@ -353,6 +360,7 @@ void resolve_target_object_format(ZigTarget *target) {
353360 case ZigLLVM_mips64el:
354361 case ZigLLVM_mipsel:
355362 case ZigLLVM_msp430:
363 case ZigLLVM_nios2:
356364 case ZigLLVM_nvptx:
357365 case ZigLLVM_nvptx64:
358366 case ZigLLVM_ppc64le:
......@@ -389,6 +397,7 @@ void resolve_target_object_format(ZigTarget *target) {
389397}
390398
391399// See lib/Support/Triple.cpp in LLVM for the source of this data.
400// getArchPointerBitWidth
392401static int get_arch_pointer_bit_width(ZigLLVM_ArchType arch) {
393402 switch (arch) {
394403 case ZigLLVM_UnknownArch:
......@@ -404,6 +413,7 @@ static int get_arch_pointer_bit_width(ZigLLVM_ArchType arch) {
404413 case ZigLLVM_le32:
405414 case ZigLLVM_mips:
406415 case ZigLLVM_mipsel:
416 case ZigLLVM_nios2:
407417 case ZigLLVM_nvptx:
408418 case ZigLLVM_ppc:
409419 case ZigLLVM_r600:
......@@ -504,6 +514,7 @@ uint32_t target_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
504514 case CIntTypeCount:
505515 zig_unreachable();
506516 }
517 case ZigLLVM_Ananas:
507518 case ZigLLVM_CloudABI:
508519 case ZigLLVM_DragonFly:
509520 case ZigLLVM_FreeBSD:
src/zig_llvm.cpp+15-166
......@@ -38,7 +38,6 @@
3838#include <llvm/Support/FileSystem.h>
3939#include <llvm/Support/TargetParser.h>
4040#include <llvm/Support/raw_ostream.h>
41#include <llvm/Support/COFF.h>
4241#include <llvm/Target/TargetMachine.h>
4342#include <llvm/Transforms/IPO.h>
4443#include <llvm/Transforms/IPO/PassManagerBuilder.h>
......@@ -105,11 +104,9 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM
105104 PMBuilder->DisableTailCalls = is_debug;
106105 PMBuilder->DisableUnitAtATime = is_debug;
107106 PMBuilder->DisableUnrollLoops = is_debug;
108 PMBuilder->BBVectorize = !is_debug;
109107 PMBuilder->SLPVectorize = !is_debug;
110108 PMBuilder->LoopVectorize = !is_debug;
111109 PMBuilder->RerollLoops = !is_debug;
112 PMBuilder->LoadCombine = !is_debug;
113110 PMBuilder->NewGVN = !is_debug;
114111 PMBuilder->DisableGVNLoadPRE = is_debug;
115112 PMBuilder->VerifyInput = assertions_on;
......@@ -125,13 +122,10 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM
125122 if (is_debug) {
126123 PMBuilder->Inliner = createAlwaysInlinerLegacyPass(false);
127124 } else {
128 PMBuilder->addExtension(PassManagerBuilder::EP_EarlyAsPossible,
129 [&](const PassManagerBuilder &, legacy::PassManagerBase &PM) {
130 target_machine->addEarlyAsPossiblePasses(PM);
131 });
125 target_machine->adjustPassManager(*PMBuilder);
132126
133127 PMBuilder->addExtension(PassManagerBuilder::EP_EarlyAsPossible, addDiscriminatorsPass);
134 PMBuilder->Inliner = createFunctionInliningPass(PMBuilder->OptLevel, PMBuilder->SizeLevel);
128 PMBuilder->Inliner = createFunctionInliningPass(PMBuilder->OptLevel, PMBuilder->SizeLevel, false);
135129 }
136130
137131 // Set up the per-function pass manager.
......@@ -182,7 +176,7 @@ LLVMValueRef ZigLLVMBuildCall(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *A
182176 CallInst *call_inst = CallInst::Create(unwrap(Fn), makeArrayRef(unwrap(Args), NumArgs), Name);
183177 call_inst->setCallingConv(CC);
184178 if (always_inline) {
185 call_inst->addAttribute(AttributeSet::FunctionIndex, Attribute::AlwaysInline);
179 call_inst->addAttribute(AttributeList::FunctionIndex, Attribute::AlwaysInline);
186180 }
187181 return wrap(unwrap(B)->Insert(call_inst));
188182}
......@@ -198,7 +192,7 @@ ZigLLVMDIType *ZigLLVMCreateDebugPointerType(ZigLLVMDIBuilder *dibuilder, ZigLLV
198192 uint64_t size_in_bits, uint64_t align_in_bits, const char *name)
199193{
200194 DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createPointerType(
201 reinterpret_cast<DIType*>(pointee_type), size_in_bits, align_in_bits, name);
195 reinterpret_cast<DIType*>(pointee_type), size_in_bits, align_in_bits, Optional<unsigned>(), name);
202196 return reinterpret_cast<ZigLLVMDIType*>(di_type);
203197}
204198
......@@ -599,23 +593,22 @@ void ZigLLVMSetFastMath(LLVMBuilderRef builder_wrapped, bool on_state) {
599593
600594void ZigLLVMAddFunctionAttr(LLVMValueRef fn_ref, const char *attr_name, const char *attr_value) {
601595 Function *func = unwrap<Function>(fn_ref);
602 const AttributeSet attr_set = func->getAttributes();
596 const AttributeList attr_set = func->getAttributes();
603597 AttrBuilder attr_builder;
604598 if (attr_value) {
605599 attr_builder.addAttribute(attr_name, attr_value);
606600 } else {
607601 attr_builder.addAttribute(attr_name);
608602 }
609 const AttributeSet new_attr_set = attr_set.addAttributes(func->getContext(),
610 AttributeSet::FunctionIndex, AttributeSet::get(func->getContext(),
611 AttributeSet::FunctionIndex, attr_builder));
603 const AttributeList new_attr_set = attr_set.addAttributes(func->getContext(),
604 AttributeList::FunctionIndex, attr_builder);
612605 func->setAttributes(new_attr_set);
613606}
614607
615608void ZigLLVMAddFunctionAttrCold(LLVMValueRef fn_ref) {
616609 Function *func = unwrap<Function>(fn_ref);
617 const AttributeSet attr_set = func->getAttributes();
618 const AttributeSet new_attr_set = attr_set.addAttribute(func->getContext(), AttributeSet::FunctionIndex,
610 const AttributeList attr_set = func->getAttributes();
611 const AttributeList new_attr_set = attr_set.addAttribute(func->getContext(), AttributeList::FunctionIndex,
619612 Attribute::Cold);
620613 func->setAttributes(new_attr_set);
621614}
......@@ -690,6 +683,8 @@ const char *ZigLLVMGetSubArchTypeName(ZigLLVM_SubArchType sub_arch) {
690683 return "v7s";
691684 case ZigLLVM_ARMSubArch_v7k:
692685 return "v7k";
686 case ZigLLVM_ARMSubArch_v7ve:
687 return "v7ve";
693688 case ZigLLVM_ARMSubArch_v6:
694689 return "v6";
695690 case ZigLLVM_ARMSubArch_v6m:
......@@ -741,8 +736,7 @@ LLVMValueRef ZigLLVMBuildCmpXchg(LLVMBuilderRef builder, LLVMValueRef ptr, LLVMV
741736 LLVMAtomicOrdering failure_ordering)
742737{
743738 return wrap(unwrap(builder)->CreateAtomicCmpXchg(unwrap(ptr), unwrap(cmp), unwrap(new_val),
744 mapFromLLVMOrdering(success_ordering), mapFromLLVMOrdering(failure_ordering),
745 CrossThread));
739 mapFromLLVMOrdering(success_ordering), mapFromLLVMOrdering(failure_ordering)));
746740}
747741
748742LLVMValueRef ZigLLVMBuildNSWShl(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS,
......@@ -802,154 +796,9 @@ bool ZigLLDLink(ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_
802796
803797 case ZigLLVM_MachO:
804798 return lld::mach_o::link(array_ref_args, diag);
799
800 case ZigLLVM_Wasm:
801 zig_panic("ZigLLDLink for Wasm");
805802 }
806803 zig_unreachable();
807804}
808
809// workaround for LLD not exposing ability to convert .def to .lib
810
811#include <set>
812
813namespace lld {
814namespace coff {
815
816class SymbolBody;
817class StringChunk;
818struct Symbol;
819
820struct Export {
821 StringRef Name; // N in /export:N or /export:E=N
822 StringRef ExtName; // E in /export:E=N
823 SymbolBody *Sym = nullptr;
824 uint16_t Ordinal = 0;
825 bool Noname = false;
826 bool Data = false;
827 bool Private = false;
828
829 // If an export is a form of /export:foo=dllname.bar, that means
830 // that foo should be exported as an alias to bar in the DLL.
831 // ForwardTo is set to "dllname.bar" part. Usually empty.
832 StringRef ForwardTo;
833 StringChunk *ForwardChunk = nullptr;
834
835 // True if this /export option was in .drectves section.
836 bool Directives = false;
837 StringRef SymbolName;
838 StringRef ExportName; // Name in DLL
839
840 bool operator==(const Export &E) {
841 return (Name == E.Name && ExtName == E.ExtName &&
842 Ordinal == E.Ordinal && Noname == E.Noname &&
843 Data == E.Data && Private == E.Private);
844 }
845};
846
847enum class DebugType {
848 None = 0x0,
849 CV = 0x1, /// CodeView
850 PData = 0x2, /// Procedure Data
851 Fixup = 0x4, /// Relocation Table
852};
853
854struct Configuration {
855 enum ManifestKind { SideBySide, Embed, No };
856 llvm::COFF::MachineTypes Machine = llvm::COFF::IMAGE_FILE_MACHINE_UNKNOWN;
857 bool Verbose = false;
858 llvm::COFF::WindowsSubsystem Subsystem = llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN;
859 SymbolBody *Entry = nullptr;
860 bool NoEntry = false;
861 std::string OutputFile;
862 bool DoGC = true;
863 bool DoICF = true;
864 bool Relocatable = true;
865 bool Force = false;
866 bool Debug = false;
867 bool WriteSymtab = true;
868 unsigned DebugTypes = static_cast<unsigned>(DebugType::None);
869 StringRef PDBPath;
870
871 // Symbols in this set are considered as live by the garbage collector.
872 std::set<SymbolBody *> GCRoot;
873
874 std::set<StringRef> NoDefaultLibs;
875 bool NoDefaultLibAll = false;
876
877 // True if we are creating a DLL.
878 bool DLL = false;
879 StringRef Implib;
880 std::vector<Export> Exports;
881 std::set<std::string> DelayLoads;
882 std::map<std::string, int> DLLOrder;
883 SymbolBody *DelayLoadHelper = nullptr;
884
885 // Used for SafeSEH.
886 Symbol *SEHTable = nullptr;
887 Symbol *SEHCount = nullptr;
888
889 // Used for /opt:lldlto=N
890 unsigned LTOOptLevel = 2;
891
892 // Used for /opt:lldltojobs=N
893 unsigned LTOJobs = 1;
894
895 // Used for /merge:from=to (e.g. /merge:.rdata=.text)
896 std::map<StringRef, StringRef> Merge;
897
898 // Used for /section=.name,{DEKPRSW} to set section attributes.
899 std::map<StringRef, uint32_t> Section;
900
901 // Options for manifest files.
902 ManifestKind Manifest = SideBySide;
903 int ManifestID = 1;
904 StringRef ManifestDependency;
905 bool ManifestUAC = true;
906 std::vector<std::string> ManifestInput;
907 StringRef ManifestLevel = "'asInvoker'";
908 StringRef ManifestUIAccess = "'false'";
909 StringRef ManifestFile;
910
911 // Used for /failifmismatch.
912 std::map<StringRef, StringRef> MustMatch;
913
914 // Used for /alternatename.
915 std::map<StringRef, StringRef> AlternateNames;
916
917 uint64_t ImageBase = -1;
918 uint64_t StackReserve = 1024 * 1024;
919 uint64_t StackCommit = 4096;
920 uint64_t HeapReserve = 1024 * 1024;
921 uint64_t HeapCommit = 4096;
922 uint32_t MajorImageVersion = 0;
923 uint32_t MinorImageVersion = 0;
924 uint32_t MajorOSVersion = 6;
925 uint32_t MinorOSVersion = 0;
926 bool DynamicBase = true;
927 bool AllowBind = true;
928 bool NxCompat = true;
929 bool AllowIsolation = true;
930 bool TerminalServerAware = true;
931 bool LargeAddressAware = false;
932 bool HighEntropyVA = false;
933
934 // This is for debugging.
935 bool DebugPdb = false;
936 bool DumpPdb = false;
937};
938
939extern Configuration *Config;
940
941void writeImportLibrary();
942void parseModuleDefs(MemoryBufferRef MB);
943
944} // namespace coff
945} // namespace lld
946
947// writes the output to dll_path with .dll replaced with .lib
948void ZigLLDDefToLib(Buf *def_contents, Buf *dll_path) {
949 lld::coff::Config = new lld::coff::Configuration;
950 auto mem_buf = MemoryBuffer::getMemBuffer(buf_ptr(def_contents));
951 MemoryBufferRef mbref(*mem_buf);
952 lld::coff::parseModuleDefs(mbref);
953 lld::coff::Config->OutputFile = buf_ptr(dll_path);
954 lld::coff::writeImportLibrary();
955}
src/zig_llvm.hpp+30-27
......@@ -188,6 +188,7 @@ enum ZigLLVM_ArchType {
188188 ZigLLVM_mips64, // MIPS64: mips64
189189 ZigLLVM_mips64el, // MIPS64EL: mips64el
190190 ZigLLVM_msp430, // MSP430: msp430
191 ZigLLVM_nios2, // NIOSII: nios2
191192 ZigLLVM_ppc, // PPC: powerpc
192193 ZigLLVM_ppc64, // PPC64: powerpc64, ppu
193194 ZigLLVM_ppc64le, // PPC64LE: powerpc64le
......@@ -228,30 +229,31 @@ enum ZigLLVM_ArchType {
228229};
229230
230231enum ZigLLVM_SubArchType {
231 ZigLLVM_NoSubArch,
232
233 ZigLLVM_ARMSubArch_v8_2a,
234 ZigLLVM_ARMSubArch_v8_1a,
235 ZigLLVM_ARMSubArch_v8,
236 ZigLLVM_ARMSubArch_v8r,
237 ZigLLVM_ARMSubArch_v8m_baseline,
238 ZigLLVM_ARMSubArch_v8m_mainline,
239 ZigLLVM_ARMSubArch_v7,
240 ZigLLVM_ARMSubArch_v7em,
241 ZigLLVM_ARMSubArch_v7m,
242 ZigLLVM_ARMSubArch_v7s,
243 ZigLLVM_ARMSubArch_v7k,
244 ZigLLVM_ARMSubArch_v6,
245 ZigLLVM_ARMSubArch_v6m,
246 ZigLLVM_ARMSubArch_v6k,
247 ZigLLVM_ARMSubArch_v6t2,
248 ZigLLVM_ARMSubArch_v5,
249 ZigLLVM_ARMSubArch_v5te,
250 ZigLLVM_ARMSubArch_v4t,
251
252 ZigLLVM_KalimbaSubArch_v3,
253 ZigLLVM_KalimbaSubArch_v4,
254 ZigLLVM_KalimbaSubArch_v5,
232 ZigLLVM_NoSubArch,
233
234 ZigLLVM_ARMSubArch_v8_2a,
235 ZigLLVM_ARMSubArch_v8_1a,
236 ZigLLVM_ARMSubArch_v8,
237 ZigLLVM_ARMSubArch_v8r,
238 ZigLLVM_ARMSubArch_v8m_baseline,
239 ZigLLVM_ARMSubArch_v8m_mainline,
240 ZigLLVM_ARMSubArch_v7,
241 ZigLLVM_ARMSubArch_v7em,
242 ZigLLVM_ARMSubArch_v7m,
243 ZigLLVM_ARMSubArch_v7s,
244 ZigLLVM_ARMSubArch_v7k,
245 ZigLLVM_ARMSubArch_v7ve,
246 ZigLLVM_ARMSubArch_v6,
247 ZigLLVM_ARMSubArch_v6m,
248 ZigLLVM_ARMSubArch_v6k,
249 ZigLLVM_ARMSubArch_v6t2,
250 ZigLLVM_ARMSubArch_v5,
251 ZigLLVM_ARMSubArch_v5te,
252 ZigLLVM_ARMSubArch_v4t,
253
254 ZigLLVM_KalimbaSubArch_v3,
255 ZigLLVM_KalimbaSubArch_v4,
256 ZigLLVM_KalimbaSubArch_v5,
255257};
256258
257259enum ZigLLVM_VendorType {
......@@ -271,13 +273,15 @@ enum ZigLLVM_VendorType {
271273 ZigLLVM_Myriad,
272274 ZigLLVM_AMD,
273275 ZigLLVM_Mesa,
276 ZigLLVM_SUSE,
274277
275 ZigLLVM_LastVendorType = ZigLLVM_Mesa
278 ZigLLVM_LastVendorType = ZigLLVM_SUSE
276279};
277280
278281enum ZigLLVM_OSType {
279282 ZigLLVM_UnknownOS,
280283
284 ZigLLVM_Ananas,
281285 ZigLLVM_CloudABI,
282286 ZigLLVM_Darwin,
283287 ZigLLVM_DragonFly,
......@@ -344,6 +348,7 @@ enum ZigLLVM_ObjectFormatType {
344348 ZigLLVM_COFF,
345349 ZigLLVM_ELF,
346350 ZigLLVM_MachO,
351 ZigLLVM_Wasm,
347352};
348353
349354const char *ZigLLVMGetArchTypeName(ZigLLVM_ArchType arch);
......@@ -363,6 +368,4 @@ void ZigLLVMGetNativeTarget(ZigLLVM_ArchType *arch_type, ZigLLVM_SubArchType *su
363368 ZigLLVM_VendorType *vendor_type, ZigLLVM_OSType *os_type, ZigLLVM_EnvironmentType *environ_type,
364369 ZigLLVM_ObjectFormatType *oformat);
365370
366void ZigLLDDefToLib(Buf *def_contents, Buf *dll_path);
367
368371#endif
std/build.zig+38-4
......@@ -784,10 +784,27 @@ pub const LibExeObjStep = struct {
784784 if (self.static) {
785785 self.out_filename = self.builder.fmt("lib{}.a", self.name);
786786 } else {
787 self.out_filename = self.builder.fmt("lib{}.so.{d}.{d}.{d}",
788 self.name, self.version.major, self.version.minor, self.version.patch);
789 self.major_only_filename = self.builder.fmt("lib{}.so.{d}", self.name, self.version.major);
790 self.name_only_filename = self.builder.fmt("lib{}.so", self.name);
787 const target_os = switch (self.target) {
788 Target.Native => builtin.os,
789 Target.Cross => |t| t.os,
790 };
791 switch (target_os) {
792 builtin.Os.darwin, builtin.Os.ios, builtin.Os.macosx => {
793 self.out_filename = self.builder.fmt("lib{}.dylib.{d}.{d}.{d}",
794 self.name, self.version.major, self.version.minor, self.version.patch);
795 self.major_only_filename = self.builder.fmt("lib{}.dylib.{d}", self.name, self.version.major);
796 self.name_only_filename = self.builder.fmt("lib{}.dylib", self.name);
797 },
798 builtin.Os.windows => {
799 self.out_filename = self.builder.fmt("lib{}.dll", self.name);
800 },
801 else => {
802 self.out_filename = self.builder.fmt("lib{}.so.{d}.{d}.{d}",
803 self.name, self.version.major, self.version.minor, self.version.patch);
804 self.major_only_filename = self.builder.fmt("lib{}.so.{d}", self.name, self.version.major);
805 self.name_only_filename = self.builder.fmt("lib{}.so", self.name);
806 },
807 }
791808 }
792809 },
793810 }
......@@ -1124,6 +1141,7 @@ pub const CLibExeObjStep = struct {
11241141 kind: Kind,
11251142 build_mode: builtin.Mode,
11261143 strip: bool,
1144 need_flat_namespace_hack: bool,
11271145
11281146 const Kind = enum {
11291147 Exe,
......@@ -1178,6 +1196,7 @@ pub const CLibExeObjStep = struct {
11781196 .object_src = undefined,
11791197 .build_mode = builtin.Mode.Debug,
11801198 .strip = false,
1199 .need_flat_namespace_hack = false,
11811200 };
11821201 clib.computeOutFileNames();
11831202 return clib;
......@@ -1223,6 +1242,7 @@ pub const CLibExeObjStep = struct {
12231242 %%self.full_path_libs.append(lib.getOutputPath());
12241243 // TODO should be some kind of isolated directory that only has this header in it
12251244 %%self.include_dirs.append(self.builder.cache_root);
1245 self.need_flat_namespace_hack = true;
12261246 }
12271247
12281248 pub fn linkSystemLibrary(self: &CLibExeObjStep, name: []const u8) {
......@@ -1448,6 +1468,20 @@ pub const CLibExeObjStep = struct {
14481468
14491469 %%cc_args.append("-rdynamic");
14501470
1471 const target_os = switch (self.target) {
1472 Target.Native => builtin.os,
1473 Target.Cross => |t| t.os,
1474 };
1475 switch (target_os) {
1476 builtin.Os.darwin, builtin.Os.ios, builtin.Os.macosx => {
1477 if (self.need_flat_namespace_hack) {
1478 %%cc_args.append("-Wl,-flat_namespace");
1479 }
1480 %%cc_args.append("-Wl,-search_paths_first");
1481 },
1482 else => {}
1483 }
1484
14511485 for (self.full_path_libs.toSliceConst()) |full_path_lib| {
14521486 %%cc_args.append(builder.pathFromRoot(full_path_lib));
14531487 }
std/c/darwin.zig+32-2
......@@ -1,4 +1,34 @@
1pub extern "c" fn getrandom(buf_ptr: &u8, buf_len: usize) -> c_int;
2fn extern "c" __error() -> &c_int;
1extern "c" fn __error() -> &c_int;
2
3pub use @import("../os/darwin_errno.zig");
34
45pub const _errno = __error;
6
7/// Renamed to Stat to not conflict with the stat function.
8pub const Stat = extern struct {
9 dev: u32,
10 mode: u16,
11 nlink: u16,
12 ino: u64,
13 uid: u32,
14 gid: u32,
15 rdev: u64,
16
17 atim: timespec,
18 mtim: timespec,
19 ctim: timespec,
20
21 size: u64,
22 blocks: u64,
23 blksize: u32,
24 flags: u32,
25 gen: u32,
26 lspare: i32,
27 qspare: [2]u64,
28
29};
30
31pub const timespec = extern struct {
32 tv_sec: isize,
33 tv_nsec: isize,
34};
std/c/index.zig+29-3
......@@ -1,4 +1,3 @@
1pub use @import("../os/errno.zig");
21const builtin = @import("builtin");
32const Os = builtin.Os;
43
......@@ -8,7 +7,34 @@ pub use switch(builtin.os) {
87 Os.darwin, Os.macosx, Os.ios => @import("darwin.zig"),
98 else => empty_import,
109};
10const empty_import = @import("../empty.zig");
1111
1212pub extern "c" fn abort() -> noreturn;
13
14const empty_import = @import("../empty.zig");
13pub extern "c" fn exit(code: c_int) -> noreturn;
14pub extern "c" fn isatty(fd: c_int) -> c_int;
15pub extern "c" fn close(fd: c_int) -> c_int;
16pub extern "c" fn fstat(fd: c_int, buf: &stat) -> c_int;
17pub extern "c" fn lseek(fd: c_int, offset: isize, whence: c_int) -> isize;
18pub extern "c" fn open(path: &const u8, oflag: c_int, ...) -> c_int;
19pub extern "c" fn raise(sig: c_int) -> c_int;
20pub extern "c" fn read(fd: c_int, buf: &c_void, nbyte: usize) -> isize;
21pub extern "c" fn stat(noalias path: &const u8, noalias buf: &Stat) -> c_int;
22pub extern "c" fn write(fd: c_int, buf: &const c_void, nbyte: usize) -> c_int;
23pub extern "c" fn mmap(addr: ?&c_void, len: usize, prot: c_int, flags: c_int,
24 fd: c_int, offset: isize) -> ?&c_void;
25pub extern "c" fn munmap(addr: &c_void, len: usize) -> c_int;
26pub extern "c" fn unlink(path: &const u8) -> c_int;
27pub extern "c" fn getcwd(buf: &u8, size: usize) -> ?&u8;
28pub extern "c" fn waitpid(pid: c_int, stat_loc: &c_int, options: c_int) -> c_int;
29pub extern "c" fn fork() -> c_int;
30pub extern "c" fn pipe(fds: &c_int) -> c_int;
31pub extern "c" fn mkdir(path: &const u8, mode: c_uint) -> c_int;
32pub extern "c" fn symlink(existing: &const u8, new: &const u8) -> c_int;
33pub extern "c" fn rename(old: &const u8, new: &const u8) -> c_int;
34pub extern "c" fn chdir(path: &const u8) -> c_int;
35pub extern "c" fn execve(path: &const u8, argv: &const ?&const u8,
36 envp: &const ?&const u8) -> c_int;
37pub extern "c" fn dup(fd: c_int) -> c_int;
38pub extern "c" fn dup2(old_fd: c_int, new_fd: c_int) -> c_int;
39pub extern "c" fn readlink(noalias path: &const u8, noalias buf: &u8, bufsize: usize) -> isize;
40pub extern "c" fn realpath(noalias file_name: &const u8, noalias resolved_name: &u8) -> ?&u8;
std/c/linux.zig+2
......@@ -1,3 +1,5 @@
1pub use @import("../os/linux_errno.zig");
2
13pub extern "c" fn getrandom(buf_ptr: &u8, buf_len: usize, flags: c_uint) -> c_int;
24extern "c" fn __errno_location() -> &c_int;
35pub const _errno = __errno_location;
std/debug.zig+5-1
......@@ -147,6 +147,9 @@ pub fn writeStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocator, tty
147147 builtin.ObjectFormat.macho => {
148148 %return out_stream.write("(stack trace unavailable for Mach-O object format)\n");
149149 },
150 builtin.ObjectFormat.wasm => {
151 %return out_stream.write("(stack trace unavailable for WASM object format)\n");
152 },
150153 builtin.ObjectFormat.unknown => {
151154 %return out_stream.write("(stack trace unavailable for unknown object format)\n");
152155 },
......@@ -718,7 +721,8 @@ fn getLineNumberInfo(st: &ElfStackTrace, compile_unit: &const CompileUnit, targe
718721 });
719722 },
720723 else => {
721 %return in_stream.seekForward(op_size - 1);
724 const fwd_amt = math.cast(isize, op_size - 1) %% return error.InvalidDebugInfo;
725 %return in_stream.seekForward(fwd_amt);
722726 },
723727 }
724728 } else if (opcode >= opcode_base) {
std/io.zig+37-29
......@@ -2,12 +2,12 @@ const builtin = @import("builtin");
22const Os = builtin.Os;
33const system = switch(builtin.os) {
44 Os.linux => @import("os/linux.zig"),
5 Os.darwin => @import("os/darwin.zig"),
5 Os.darwin, Os.macosx, Os.ios => @import("os/darwin.zig"),
66 Os.windows => @import("os/windows/index.zig"),
77 else => @compileError("Unsupported OS"),
88};
9const c = @import("c/index.zig");
910
10const errno = @import("os/errno.zig");
1111const math = @import("math/index.zig");
1212const debug = @import("debug.zig");
1313const assert = debug.assert;
......@@ -180,7 +180,11 @@ pub const OutStream = struct {
180180
181181 pub fn isTty(self: &OutStream) -> %bool {
182182 if (is_posix) {
183 return system.isatty(self.fd);
183 if (builtin.link_libc) {
184 return c.isatty(self.fd) == 0;
185 } else {
186 return system.isatty(self.fd);
187 }
184188 } else if (is_windows) {
185189 return os.windowsIsTty(%return self.getHandle());
186190 } else {
......@@ -264,11 +268,11 @@ pub const InStream = struct {
264268 const read_err = system.getErrno(amt_read);
265269 if (read_err > 0) {
266270 switch (read_err) {
267 errno.EINTR => continue,
268 errno.EINVAL => unreachable,
269 errno.EFAULT => unreachable,
270 errno.EBADF => return error.BadFd,
271 errno.EIO => return error.Io,
271 system.EINTR => continue,
272 system.EINVAL => unreachable,
273 system.EFAULT => unreachable,
274 system.EBADF => return error.BadFd,
275 system.EIO => return error.Io,
272276 else => return error.Unexpected,
273277 }
274278 }
......@@ -323,18 +327,18 @@ pub const InStream = struct {
323327 return mem.readInt(input_slice, T, is_be);
324328 }
325329
326 pub fn seekForward(is: &InStream, amount: usize) -> %void {
330 pub fn seekForward(is: &InStream, amount: isize) -> %void {
327331 switch (builtin.os) {
328332 Os.linux, Os.darwin => {
329333 const result = system.lseek(is.fd, amount, system.SEEK_CUR);
330334 const err = system.getErrno(result);
331335 if (err > 0) {
332336 return switch (err) {
333 errno.EBADF => error.BadFd,
334 errno.EINVAL => error.Unseekable,
335 errno.EOVERFLOW => error.Unseekable,
336 errno.ESPIPE => error.Unseekable,
337 errno.ENXIO => error.Unseekable,
337 system.EBADF => error.BadFd,
338 system.EINVAL => error.Unseekable,
339 system.EOVERFLOW => error.Unseekable,
340 system.ESPIPE => error.Unseekable,
341 system.ENXIO => error.Unseekable,
338342 else => error.Unexpected,
339343 };
340344 }
......@@ -346,15 +350,15 @@ pub const InStream = struct {
346350 pub fn seekTo(is: &InStream, pos: usize) -> %void {
347351 switch (builtin.os) {
348352 Os.linux, Os.darwin => {
349 const result = system.lseek(is.fd, pos, system.SEEK_SET);
353 const result = system.lseek(is.fd, @bitCast(isize, pos), system.SEEK_SET);
350354 const err = system.getErrno(result);
351355 if (err > 0) {
352356 return switch (err) {
353 errno.EBADF => error.BadFd,
354 errno.EINVAL => error.Unseekable,
355 errno.EOVERFLOW => error.Unseekable,
356 errno.ESPIPE => error.Unseekable,
357 errno.ENXIO => error.Unseekable,
357 system.EBADF => error.BadFd,
358 system.EINVAL => error.Unseekable,
359 system.EOVERFLOW => error.Unseekable,
360 system.ESPIPE => error.Unseekable,
361 system.ENXIO => error.Unseekable,
358362 else => error.Unexpected,
359363 };
360364 }
......@@ -370,11 +374,11 @@ pub const InStream = struct {
370374 const err = system.getErrno(result);
371375 if (err > 0) {
372376 return switch (err) {
373 errno.EBADF => error.BadFd,
374 errno.EINVAL => error.Unseekable,
375 errno.EOVERFLOW => error.Unseekable,
376 errno.ESPIPE => error.Unseekable,
377 errno.ENXIO => error.Unseekable,
377 system.EBADF => error.BadFd,
378 system.EINVAL => error.Unseekable,
379 system.EOVERFLOW => error.Unseekable,
380 system.ESPIPE => error.Unseekable,
381 system.ENXIO => error.Unseekable,
378382 else => error.Unexpected,
379383 };
380384 }
......@@ -385,12 +389,12 @@ pub const InStream = struct {
385389 }
386390
387391 pub fn getEndPos(is: &InStream) -> %usize {
388 var stat: system.stat = undefined;
392 var stat: system.Stat = undefined;
389393 const err = system.getErrno(system.fstat(is.fd, &stat));
390394 if (err > 0) {
391395 return switch (err) {
392 errno.EBADF => error.BadFd,
393 errno.ENOMEM => error.NoMem,
396 system.EBADF => error.BadFd,
397 system.ENOMEM => error.NoMem,
394398 else => error.Unexpected,
395399 }
396400 }
......@@ -417,7 +421,11 @@ pub const InStream = struct {
417421
418422 pub fn isTty(self: &InStream) -> %bool {
419423 if (is_posix) {
420 return system.isatty(self.fd);
424 if (builtin.link_libc) {
425 return c.isatty(self.fd) == 0;
426 } else {
427 return system.isatty(self.fd);
428 }
421429 } else if (is_windows) {
422430 return os.windowsIsTty(%return self.getHandle());
423431 } else {
std/net.zig+15-16
......@@ -1,5 +1,4 @@
11const linux = @import("os/linux.zig");
2const errno = @import("os/errno.zig");
32const assert = @import("debug.zig").assert;
43const endian = @import("endian.zig");
54
......@@ -21,10 +20,10 @@ const Connection = struct {
2120 const send_err = linux.getErrno(send_ret);
2221 switch (send_err) {
2322 0 => return send_ret,
24 errno.EINVAL => unreachable,
25 errno.EFAULT => unreachable,
26 errno.ECONNRESET => return error.ConnectionReset,
27 errno.EINTR => return error.SigInterrupt,
23 linux.EINVAL => unreachable,
24 linux.EFAULT => unreachable,
25 linux.ECONNRESET => return error.ConnectionReset,
26 linux.EINTR => return error.SigInterrupt,
2827 // TODO there are more possible errors
2928 else => return error.Unexpected,
3029 }
......@@ -35,13 +34,13 @@ const Connection = struct {
3534 const recv_err = linux.getErrno(recv_ret);
3635 switch (recv_err) {
3736 0 => return buf[0..recv_ret],
38 errno.EINVAL => unreachable,
39 errno.EFAULT => unreachable,
40 errno.ENOTSOCK => return error.NotSocket,
41 errno.EINTR => return error.SigInterrupt,
42 errno.ENOMEM => return error.NoMem,
43 errno.ECONNREFUSED => return error.ConnectionRefused,
44 errno.EBADF => return error.BadFd,
37 linux.EINVAL => unreachable,
38 linux.EFAULT => unreachable,
39 linux.ENOTSOCK => return error.NotSocket,
40 linux.EINTR => return error.SigInterrupt,
41 linux.ENOMEM => return error.NoMem,
42 linux.ECONNREFUSED => return error.ConnectionRefused,
43 linux.EBADF => return error.BadFd,
4544 // TODO more error values
4645 else => return error.Unexpected,
4746 }
......@@ -50,9 +49,9 @@ const Connection = struct {
5049 pub fn close(c: Connection) -> %void {
5150 switch (linux.getErrno(linux.close(c.socket_fd))) {
5251 0 => return,
53 errno.EBADF => unreachable,
54 errno.EINTR => return error.SigInterrupt,
55 errno.EIO => return error.Io,
52 linux.EBADF => unreachable,
53 linux.EINTR => return error.SigInterrupt,
54 linux.EIO => return error.Io,
5655 else => return error.Unexpected,
5756 }
5857 }
......@@ -119,7 +118,7 @@ pub fn connectAddr(addr: &Address, port: u16) -> %Connection {
119118 const connect_err = linux.getErrno(connect_ret);
120119 if (connect_err > 0) {
121120 switch (connect_err) {
122 errno.ETIMEDOUT => return error.TimedOut,
121 linux.ETIMEDOUT => return error.TimedOut,
123122 else => {
124123 // TODO figure out possible errors from connect()
125124 return error.Unexpected;
std/os/child_process.zig+7-35
......@@ -3,7 +3,6 @@ const os = @import("index.zig");
33const posix = os.posix;
44const mem = @import("../mem.zig");
55const Allocator = mem.Allocator;
6const errno = @import("errno.zig");
76const debug = @import("../debug.zig");
87const assert = debug.assert;
98const BufMap = @import("../buf_map.zig").BufMap;
......@@ -56,8 +55,8 @@ pub const ChildProcess = struct {
5655 const err = posix.getErrno(posix.waitpid(self.pid, &status, 0));
5756 if (err > 0) {
5857 switch (err) {
59 errno.EINVAL, errno.ECHILD => unreachable,
60 errno.EINTR => continue,
58 posix.EINVAL, posix.ECHILD => unreachable,
59 posix.EINTR => continue,
6160 else => {
6261 if (self.stdin) |*stdin| { stdin.close(); }
6362 if (self.stdout) |*stdout| { stdout.close(); }
......@@ -130,7 +129,7 @@ pub const ChildProcess = struct {
130129 const pid_err = posix.getErrno(pid);
131130 if (pid_err > 0) {
132131 return switch (pid_err) {
133 errno.EAGAIN, errno.ENOMEM, errno.ENOSYS => error.SystemResources,
132 posix.EAGAIN, posix.ENOMEM, posix.ENOSYS => error.SystemResources,
134133 else => error.Unexpected,
135134 };
136135 }
......@@ -209,7 +208,7 @@ fn makePipe() -> %[2]i32 {
209208 const err = posix.getErrno(posix.pipe(&fds));
210209 if (err > 0) {
211210 return switch (err) {
212 errno.EMFILE, errno.ENFILE => error.SystemResources,
211 posix.EMFILE, posix.ENFILE => error.SystemResources,
213212 else => error.Unexpected,
214213 }
215214 }
......@@ -229,42 +228,15 @@ fn forkChildErrReport(fd: i32, err: error) -> noreturn {
229228}
230229
231230const ErrInt = @IntType(false, @sizeOf(error) * 8);
231
232232fn writeIntFd(fd: i32, value: ErrInt) -> %void {
233233 var bytes: [@sizeOf(ErrInt)]u8 = undefined;
234234 mem.writeInt(bytes[0..], value, true);
235
236 var index: usize = 0;
237 while (index < bytes.len) {
238 const amt_written = posix.write(fd, &bytes[index], bytes.len - index);
239 const err = posix.getErrno(amt_written);
240 if (err > 0) {
241 switch (err) {
242 errno.EINTR => continue,
243 errno.EINVAL => unreachable,
244 else => return error.SystemResources,
245 }
246 }
247 index += amt_written;
248 }
235 os.posixWrite(fd, bytes[0..]) %% return error.SystemResources;
249236}
250237
251238fn readIntFd(fd: i32) -> %ErrInt {
252239 var bytes: [@sizeOf(ErrInt)]u8 = undefined;
253
254 var index: usize = 0;
255 while (index < bytes.len) {
256 const amt_written = posix.read(fd, &bytes[index], bytes.len - index);
257 const err = posix.getErrno(amt_written);
258 if (err > 0) {
259 switch (err) {
260 errno.EINTR => continue,
261 errno.EINVAL => unreachable,
262 else => return error.SystemResources,
263 }
264 }
265 index += amt_written;
266 }
267
240 os.posixRead(fd, bytes[0..]) %% return error.SystemResources;
268241 return mem.readInt(bytes[0..], ErrInt, true);
269242}
270
std/os/darwin.zig+147-42
......@@ -1,18 +1,46 @@
1const c = @import("../c/index.zig");
2const assert = @import("../debug.zig").assert;
13
2const builtin = @import("builtin");
3const arch = switch (builtin.arch) {
4 builtin.Arch.x86_64 => @import("darwin_x86_64.zig"),
5 else => @compileError("unsupported arch"),
6};
4pub use @import("darwin_errno.zig");
75
8const errno = @import("errno.zig");
6pub const PATH_MAX = 1024;
97
108pub const STDIN_FILENO = 0;
119pub const STDOUT_FILENO = 1;
1210pub const STDERR_FILENO = 2;
1311
12pub const PROT_NONE = 0x00; /// [MC2] no permissions
13pub const PROT_READ = 0x01; /// [MC2] pages can be read
14pub const PROT_WRITE = 0x02; /// [MC2] pages can be written
15pub const PROT_EXEC = 0x04; /// [MC2] pages can be executed
16
17pub const MAP_ANONYMOUS = 0x1000; /// allocated from memory, swap space
18pub const MAP_FILE = 0x0000; /// map from file (default)
19pub const MAP_FIXED = 0x0010; /// interpret addr exactly
20pub const MAP_HASSEMAPHORE = 0x0200; /// region may contain semaphores
21pub const MAP_PRIVATE = 0x0002; /// changes are private
22pub const MAP_SHARED = 0x0001; /// share changes
23pub const MAP_NOCACHE = 0x0400; /// don't cache pages for this mapping
24pub const MAP_NORESERVE = 0x0040; /// don't reserve needed swap area
25pub const MAP_FAILED = @maxValue(usize);
26
1427pub const O_LARGEFILE = 0x0000;
15pub const O_RDONLY = 0x0000;
28pub const O_PATH = 0x0000;
29
30pub const O_RDONLY = 0x0000; /// open for reading only
31pub const O_WRONLY = 0x0001; /// open for writing only
32pub const O_RDWR = 0x0002; /// open for reading and writing
33pub const O_NONBLOCK = 0x0004; /// do not block on open or for data to become available
34pub const O_APPEND = 0x0008; /// append on each write
35pub const O_CREAT = 0x0200; /// create file if it does not exist
36pub const O_TRUNC = 0x0400; /// truncate size to 0
37pub const O_EXCL = 0x0800; /// error if O_CREAT and the file exists
38pub const O_SHLOCK = 0x0010; /// atomically obtain a shared lock
39pub const O_EXLOCK = 0x0020; /// atomically obtain an exclusive lock
40pub const O_NOFOLLOW = 0x0100; /// do not follow symlinks
41pub const O_SYMLINK = 0x200000; /// allow open of symlinks
42pub const O_EVTONLY = 0x8000; /// descriptor requested for event notifications only
43pub const O_CLOEXEC = 0x1000000; /// mark as close-on-exec
1644
1745pub const SEEK_SET = 0x0;
1846pub const SEEK_CUR = 0x1;
......@@ -53,64 +81,141 @@ pub const SIGPWR = 30;
5381pub const SIGSYS = 31;
5482pub const SIGUNUSED = SIGSYS;
5583
56pub fn exit(status: usize) -> noreturn {
57 _ = arch.syscall1(arch.SYS_exit, status);
58 unreachable
59}
84fn wstatus(x: i32) -> i32 { x & 0o177 }
85const wstopped = 0o177;
86pub fn WEXITSTATUS(x: i32) -> i32 { x >> 8 }
87pub fn WTERMSIG(x: i32) -> i32 { wstatus(x) }
88pub fn WSTOPSIG(x: i32) -> i32 { x >> 8 }
89pub fn WIFEXITED(x: i32) -> bool { wstatus(x) == 0 }
90pub fn WIFSTOPPED(x: i32) -> bool { wstatus(x) == wstopped and WSTOPSIG(x) != 0x13 }
91pub fn WIFSIGNALED(x: i32) -> bool { wstatus(x) != wstopped and wstatus(x) != 0 }
6092
6193/// Get the errno from a syscall return value, or 0 for no error.
6294pub fn getErrno(r: usize) -> usize {
63 const signed_r = *@ptrCast(&const isize, &r);
95 const signed_r = @bitCast(isize, r);
6496 if (signed_r > -4096 and signed_r < 0) usize(-signed_r) else 0
6597}
6698
67pub fn write(fd: i32, buf: &const u8, count: usize) -> usize {
68 arch.syscall3(arch.SYS_write, usize(fd), usize(buf), count)
99pub fn close(fd: i32) -> usize {
100 errnoWrap(c.close(fd))
69101}
70102
71pub fn close(fd: i32) -> usize {
72 arch.syscall1(arch.SYS_close, usize(fd))
103pub fn abort() -> noreturn {
104 c.abort()
105}
106
107pub fn exit(code: i32) -> noreturn {
108 c.exit(code)
73109}
74110
75pub fn open(path: &const u8, flags: usize, perm: usize) -> usize {
76 arch.syscall3(arch.SYS_open, usize(path), flags, perm)
111pub fn isatty(fd: i32) -> bool {
112 c.isatty(fd) == 0
77113}
78114
79pub fn read(fd: i32, buf: &u8, count: usize) -> usize {
80 arch.syscall3(arch.SYS_read, usize(fd), usize(buf), count)
115pub fn fstat(fd: i32, buf: &c.stat) -> usize {
116 errnoWrap(c.fstat(fd, buf))
81117}
82118
83pub fn lseek(fd: i32, offset: usize, ref_pos: usize) -> usize {
84 arch.syscall3(arch.SYS_lseek, usize(fd), offset, ref_pos)
119pub fn lseek(fd: i32, offset: isize, whence: c_int) -> usize {
120 errnoWrap(c.lseek(fd, buf, whence))
85121}
86122
87pub const stat = arch.stat;
88pub const timespec = arch.timespec;
123pub fn open(path: &const u8, flags: u32, mode: usize) -> usize {
124 errnoWrap(c.open(path, @bitCast(c_int, flags), mode))
125}
89126
90pub fn fstat(fd: i32, stat_buf: &stat) -> usize {
91 arch.syscall2(arch.SYS_fstat, usize(fd), usize(stat_buf))
127pub fn raise(sig: i32) -> usize {
128 errnoWrap(c.raise(sig))
92129}
93130
94error Unexpected;
131pub fn read(fd: i32, buf: &u8, nbyte: usize) -> usize {
132 errnoWrap(c.read(fd, @ptrCast(&c_void, buf), nbyte))
133}
95134
96pub fn getrandom(buf: &u8, count: usize) -> usize {
97 const rr = open_c(c"/dev/urandom", O_LARGEFILE | O_RDONLY, 0);
135pub fn stat(noalias path: &const u8, noalias buf: &stat) -> usize {
136 errnoWrap(c.stat(path, buf))
137}
98138
99 if(getErrno(rr) > 0) return rr;
139pub fn write(fd: i32, buf: &const u8, nbyte: usize) -> usize {
140 errnoWrap(c.write(fd, @ptrCast(&const c_void, buf), nbyte))
141}
100142
101 var fd: i32 = i32(rr);
102 const readRes = read(fd, buf, count);
103 readRes
143pub fn mmap(address: ?&u8, length: usize, prot: usize, flags: usize, fd: i32,
144 offset: isize) -> usize
145{
146 const ptr_result = c.mmap(@ptrCast(&c_void, address), length,
147 @bitCast(c_int, c_uint(prot)), @bitCast(c_int, c_uint(flags)), fd, offset);
148 const isize_result = @bitCast(isize, @ptrToInt(ptr_result));
149 return errnoWrap(isize_result);
104150}
105151
106pub fn raise(sig: i32) -> i32 {
107 // TODO investigate whether we need to block signals before calling kill
108 // like we do in the linux version of raise
152pub fn munmap(address: &u8, length: usize) -> usize {
153 errnoWrap(c.munmap(@ptrCast(&c_void, address), length))
154}
155
156pub fn unlink(path: &const u8) -> usize {
157 errnoWrap(c.unlink(path))
158}
159
160pub fn getcwd(buf: &u8, size: usize) -> usize {
161 if (c.getcwd(buf, size) == null) @bitCast(usize, -isize(*c._errno())) else 0
162}
163
164pub fn waitpid(pid: i32, status: &i32, options: u32) -> usize {
165 comptime assert(i32.bit_count == c_int.bit_count);
166 errnoWrap(c.waitpid(pid, @ptrCast(&c_int, status), @bitCast(c_int, options)))
167}
168
169pub fn fork() -> usize {
170 errnoWrap(c.fork())
171}
172
173pub fn pipe(fds: &[2]i32) -> usize {
174 comptime assert(i32.bit_count == c_int.bit_count);
175 errnoWrap(c.pipe(@ptrCast(&c_int, &(*fds)[0])))
176}
177
178pub fn mkdir(path: &const u8, mode: u32) -> usize {
179 errnoWrap(c.mkdir(path, mode))
180}
181
182pub fn symlink(existing: &const u8, new: &const u8) -> usize {
183 errnoWrap(c.symlink(existing, new))
184}
185
186pub fn rename(old: &const u8, new: &const u8) -> usize {
187 errnoWrap(c.rename(old, new))
188}
189
190pub fn chdir(path: &const u8) -> usize {
191 errnoWrap(c.chdir(path))
192}
193
194pub fn execve(path: &const u8, argv: &const ?&const u8, envp: &const ?&const u8)
195 -> usize
196{
197 errnoWrap(c.execve(path, argv, envp))
198}
199
200pub fn dup2(old: i32, new: i32) -> usize {
201 errnoWrap(c.dup2(old, new))
202}
203
204pub fn readlink(noalias path: &const u8, noalias buf_ptr: &u8, buf_len: usize) -> usize {
205 errnoWrap(c.readlink(path, buf_ptr, buf_len))
206}
207
208pub fn realpath(noalias filename: &const u8, noalias resolved_name: &u8) -> usize {
209 if (c.realpath(filename, resolved_name) == null) @bitCast(usize, -isize(*c._errno())) else 0
210}
109211
110 //var set: sigset_t = undefined;
111 //blockAppSignals(&set);
112 const pid = i32(arch.syscall0(arch.SYS_getpid));
113 const ret = i32(arch.syscall2(arch.SYS_kill, usize(pid), usize(sig)));
114 //restoreSignals(&set);
115 return ret;
212/// Takes the return value from a syscall and formats it back in the way
213/// that the kernel represents it to libc. Errno was a mistake, let's make
214/// it go away forever.
215fn errnoWrap(value: isize) -> usize {
216 @bitCast(usize, if (value == -1) {
217 -isize(*c._errno())
218 } else {
219 value
220 })
116221}
std/os/darwin_errno.zig created+142
......@@ -0,0 +1,142 @@
1
2pub const EPERM = 1; /// Operation not permitted
3pub const ENOENT = 2; /// No such file or directory
4pub const ESRCH = 3; /// No such process
5pub const EINTR = 4; /// Interrupted system call
6pub const EIO = 5; /// Input/output error
7pub const ENXIO = 6; /// Device not configured
8pub const E2BIG = 7; /// Argument list too long
9pub const ENOEXEC = 8; /// Exec format error
10pub const EBADF = 9; /// Bad file descriptor
11pub const ECHILD = 10; /// No child processes
12pub const EDEADLK = 11; /// Resource deadlock avoided
13
14pub const ENOMEM = 12; /// Cannot allocate memory
15pub const EACCES = 13; /// Permission denied
16pub const EFAULT = 14; /// Bad address
17pub const ENOTBLK = 15; /// Block device required
18pub const EBUSY = 16; /// Device / Resource busy
19pub const EEXIST = 17; /// File exists
20pub const EXDEV = 18; /// Cross-device link
21pub const ENODEV = 19; /// Operation not supported by device
22pub const ENOTDIR = 20; /// Not a directory
23pub const EISDIR = 21; /// Is a directory
24pub const EINVAL = 22; /// Invalid argument
25pub const ENFILE = 23; /// Too many open files in system
26pub const EMFILE = 24; /// Too many open files
27pub const ENOTTY = 25; /// Inappropriate ioctl for device
28pub const ETXTBSY = 26; /// Text file busy
29pub const EFBIG = 27; /// File too large
30pub const ENOSPC = 28; /// No space left on device
31pub const ESPIPE = 29; /// Illegal seek
32pub const EROFS = 30; /// Read-only file system
33pub const EMLINK = 31; /// Too many links
34pub const EPIPE = 32; /// Broken pipe
35
36// math software
37pub const EDOM = 33; /// Numerical argument out of domain
38pub const ERANGE = 34; /// Result too large
39
40// non-blocking and interrupt i/o
41pub const EAGAIN = 35; /// Resource temporarily unavailable
42pub const EWOULDBLOCK = EAGAIN; /// Operation would block
43pub const EINPROGRESS = 36; /// Operation now in progress
44pub const EALREADY = 37; /// Operation already in progress
45
46// ipc/network software -- argument errors
47pub const ENOTSOCK = 38; /// Socket operation on non-socket
48pub const EDESTADDRREQ = 39; /// Destination address required
49pub const EMSGSIZE = 40; /// Message too long
50pub const EPROTOTYPE = 41; /// Protocol wrong type for socket
51pub const ENOPROTOOPT = 42; /// Protocol not available
52pub const EPROTONOSUPPORT = 43; /// Protocol not supported
53
54pub const ESOCKTNOSUPPORT = 44; /// Socket type not supported
55
56pub const ENOTSUP = 45; /// Operation not supported
57
58pub const EPFNOSUPPORT = 46; /// Protocol family not supported
59pub const EAFNOSUPPORT = 47; /// Address family not supported by protocol family
60pub const EADDRINUSE = 48; /// Address already in use
61pub const EADDRNOTAVAIL = 49; /// Can't assign requested address
62
63// ipc/network software -- operational errors
64pub const ENETDOWN = 50; /// Network is down
65pub const ENETUNREACH = 51; /// Network is unreachable
66pub const ENETRESET = 52; /// Network dropped connection on reset
67pub const ECONNABORTED = 53; /// Software caused connection abort
68pub const ECONNRESET = 54; /// Connection reset by peer
69pub const ENOBUFS = 55; /// No buffer space available
70pub const EISCONN = 56; /// Socket is already connected
71pub const ENOTCONN = 57; /// Socket is not connected
72
73pub const ESHUTDOWN = 58; /// Can't send after socket shutdown
74pub const ETOOMANYREFS = 59; /// Too many references: can't splice
75
76pub const ETIMEDOUT = 60; /// Operation timed out
77pub const ECONNREFUSED = 61; /// Connection refused
78
79pub const ELOOP = 62; /// Too many levels of symbolic links
80pub const ENAMETOOLONG = 63; /// File name too long
81
82pub const EHOSTDOWN = 64; /// Host is down
83pub const EHOSTUNREACH = 65; /// No route to host
84pub const ENOTEMPTY = 66; /// Directory not empty
85
86// quotas & mush
87pub const EPROCLIM = 67; /// Too many processes
88pub const EUSERS = 68; /// Too many users
89pub const EDQUOT = 69; /// Disc quota exceeded
90
91// Network File System
92pub const ESTALE = 70; /// Stale NFS file handle
93pub const EREMOTE = 71; /// Too many levels of remote in path
94pub const EBADRPC = 72; /// RPC struct is bad
95pub const ERPCMISMATCH = 73; /// RPC version wrong
96pub const EPROGUNAVAIL = 74; /// RPC prog. not avail
97pub const EPROGMISMATCH = 75; /// Program version wrong
98pub const EPROCUNAVAIL = 76; /// Bad procedure for program
99
100pub const ENOLCK = 77; /// No locks available
101pub const ENOSYS = 78; /// Function not implemented
102
103pub const EFTYPE = 79; /// Inappropriate file type or format
104pub const EAUTH = 80; /// Authentication error
105pub const ENEEDAUTH = 81; /// Need authenticator
106
107// Intelligent device errors
108pub const EPWROFF = 82; /// Device power is off
109pub const EDEVERR = 83; /// Device error, e.g. paper out
110
111pub const EOVERFLOW = 84; /// Value too large to be stored in data type
112
113// Program loading errors
114pub const EBADEXEC = 85; /// Bad executable
115pub const EBADARCH = 86; /// Bad CPU type in executable
116pub const ESHLIBVERS = 87; /// Shared library version mismatch
117pub const EBADMACHO = 88; /// Malformed Macho file
118
119pub const ECANCELED = 89; /// Operation canceled
120
121pub const EIDRM = 90; /// Identifier removed
122pub const ENOMSG = 91; /// No message of desired type
123pub const EILSEQ = 92; /// Illegal byte sequence
124pub const ENOATTR = 93; /// Attribute not found
125
126pub const EBADMSG = 94; /// Bad message
127pub const EMULTIHOP = 95; /// Reserved
128pub const ENODATA = 96; /// No message available on STREAM
129pub const ENOLINK = 97; /// Reserved
130pub const ENOSR = 98; /// No STREAM resources
131pub const ENOSTR = 99; /// Not a STREAM
132pub const EPROTO = 100; /// Protocol error
133pub const ETIME = 101; /// STREAM ioctl timeout
134
135pub const ENOPOLICY = 103; /// No such policy registered
136
137pub const ENOTRECOVERABLE = 104; /// State not recoverable
138pub const EOWNERDEAD = 105; /// Previous owner died
139
140pub const EQFULL = 106; /// Interface output queue is full
141pub const ELAST = 106; /// Must be equal largest errno
142
std/os/darwin_x86_64.zig deleted-87
......@@ -1,87 +0,0 @@
1
2pub const SYSCALL_CLASS_SHIFT = 24;
3pub const SYSCALL_CLASS_MASK = 0xFF << SYSCALL_CLASS_SHIFT;
4// pub const SYSCALL_NUMBER_MASK = ~SYSCALL_CLASS_MASK; // ~ modifier not supported yet
5
6pub const SYSCALL_CLASS_NONE = 0; // Invalid
7pub const SYSCALL_CLASS_MACH = 1; // Mach
8pub const SYSCALL_CLASS_UNIX = 2; // Unix/BSD
9pub const SYSCALL_CLASS_MDEP = 3; // Machine-dependent
10pub const SYSCALL_CLASS_DIAG = 4; // Diagnostics
11
12// TODO: use the above constants to create the below values
13
14pub const SYS_exit = 0x2000001;
15pub const SYS_read = 0x2000003;
16pub const SYS_write = 0x2000004;
17pub const SYS_open = 0x2000005;
18pub const SYS_close = 0x2000006;
19pub const SYS_kill = 0x2000025;
20pub const SYS_getpid = 0x2000030;
21pub const SYS_fstat = 0x20000BD;
22pub const SYS_lseek = 0x20000C7;
23
24pub inline fn syscall0(number: usize) -> usize {
25 asm volatile ("syscall"
26 : [ret] "={rax}" (-> usize)
27 : [number] "{rax}" (number)
28 : "rcx", "r11")
29}
30
31pub inline fn syscall1(number: usize, arg1: usize) -> usize {
32 asm volatile ("syscall"
33 : [ret] "={rax}" (-> usize)
34 : [number] "{rax}" (number),
35 [arg1] "{rdi}" (arg1)
36 : "rcx", "r11")
37}
38
39pub inline fn syscall2(number: usize, arg1: usize, arg2: usize) -> usize {
40 asm volatile ("syscall"
41 : [ret] "={rax}" (-> usize)
42 : [number] "{rax}" (number),
43 [arg1] "{rdi}" (arg1),
44 [arg2] "{rsi}" (arg2)
45 : "rcx", "r11")
46}
47
48pub inline fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) -> usize {
49 asm volatile ("syscall"
50 : [ret] "={rax}" (-> usize)
51 : [number] "{rax}" (number),
52 [arg1] "{rdi}" (arg1),
53 [arg2] "{rsi}" (arg2),
54 [arg3] "{rdx}" (arg3)
55 : "rcx", "r11")
56}
57
58
59
60
61pub const stat = extern struct {
62 dev: u32,
63 mode: u16,
64 nlink: u16,
65 ino: u64,
66 uid: u32,
67 gid: u32,
68 rdev: u64,
69
70 atim: timespec,
71 mtim: timespec,
72 ctim: timespec,
73
74 size: u64,
75 blocks: u64,
76 blksize: u32,
77 flags: u32,
78 gen: u32,
79 lspare: i32,
80 qspare: [2]u64,
81
82};
83
84pub const timespec = extern struct {
85 tv_sec: isize,
86 tv_nsec: isize,
87};
std/os/errno.zig deleted-146
......@@ -1,146 +0,0 @@
1pub const EPERM = 1; // Operation not permitted
2pub const ENOENT = 2; // No such file or directory
3pub const ESRCH = 3; // No such process
4pub const EINTR = 4; // Interrupted system call
5pub const EIO = 5; // I/O error
6pub const ENXIO = 6; // No such device or address
7pub const E2BIG = 7; // Arg list too long
8pub const ENOEXEC = 8; // Exec format error
9pub const EBADF = 9; // Bad file number
10pub const ECHILD = 10; // No child processes
11pub const EAGAIN = 11; // Try again
12pub const ENOMEM = 12; // Out of memory
13pub const EACCES = 13; // Permission denied
14pub const EFAULT = 14; // Bad address
15pub const ENOTBLK = 15; // Block device required
16pub const EBUSY = 16; // Device or resource busy
17pub const EEXIST = 17; // File exists
18pub const EXDEV = 18; // Cross-device link
19pub const ENODEV = 19; // No such device
20pub const ENOTDIR = 20; // Not a directory
21pub const EISDIR = 21; // Is a directory
22pub const EINVAL = 22; // Invalid argument
23pub const ENFILE = 23; // File table overflow
24pub const EMFILE = 24; // Too many open files
25pub const ENOTTY = 25; // Not a typewriter
26pub const ETXTBSY = 26; // Text file busy
27pub const EFBIG = 27; // File too large
28pub const ENOSPC = 28; // No space left on device
29pub const ESPIPE = 29; // Illegal seek
30pub const EROFS = 30; // Read-only file system
31pub const EMLINK = 31; // Too many links
32pub const EPIPE = 32; // Broken pipe
33pub const EDOM = 33; // Math argument out of domain of func
34pub const ERANGE = 34; // Math result not representable
35pub const EDEADLK = 35; // Resource deadlock would occur
36pub const ENAMETOOLONG = 36; // File name too long
37pub const ENOLCK = 37; // No record locks available
38pub const ENOSYS = 38; // Function not implemented
39pub const ENOTEMPTY = 39; // Directory not empty
40pub const ELOOP = 40; // Too many symbolic links encountered
41pub const EWOULDBLOCK = EAGAIN; // Operation would block
42pub const ENOMSG = 42; // No message of desired type
43pub const EIDRM = 43; // Identifier removed
44pub const ECHRNG = 44; // Channel number out of range
45pub const EL2NSYNC = 45; // Level 2 not synchronized
46pub const EL3HLT = 46; // Level 3 halted
47pub const EL3RST = 47; // Level 3 reset
48pub const ELNRNG = 48; // Link number out of range
49pub const EUNATCH = 49; // Protocol driver not attached
50pub const ENOCSI = 50; // No CSI structure available
51pub const EL2HLT = 51; // Level 2 halted
52pub const EBADE = 52; // Invalid exchange
53pub const EBADR = 53; // Invalid request descriptor
54pub const EXFULL = 54; // Exchange full
55pub const ENOANO = 55; // No anode
56pub const EBADRQC = 56; // Invalid request code
57pub const EBADSLT = 57; // Invalid slot
58
59pub const EBFONT = 59; // Bad font file format
60pub const ENOSTR = 60; // Device not a stream
61pub const ENODATA = 61; // No data available
62pub const ETIME = 62; // Timer expired
63pub const ENOSR = 63; // Out of streams resources
64pub const ENONET = 64; // Machine is not on the network
65pub const ENOPKG = 65; // Package not installed
66pub const EREMOTE = 66; // Object is remote
67pub const ENOLINK = 67; // Link has been severed
68pub const EADV = 68; // Advertise error
69pub const ESRMNT = 69; // Srmount error
70pub const ECOMM = 70; // Communication error on send
71pub const EPROTO = 71; // Protocol error
72pub const EMULTIHOP = 72; // Multihop attempted
73pub const EDOTDOT = 73; // RFS specific error
74pub const EBADMSG = 74; // Not a data message
75pub const EOVERFLOW = 75; // Value too large for defined data type
76pub const ENOTUNIQ = 76; // Name not unique on network
77pub const EBADFD = 77; // File descriptor in bad state
78pub const EREMCHG = 78; // Remote address changed
79pub const ELIBACC = 79; // Can not access a needed shared library
80pub const ELIBBAD = 80; // Accessing a corrupted shared library
81pub const ELIBSCN = 81; // .lib section in a.out corrupted
82pub const ELIBMAX = 82; // Attempting to link in too many shared libraries
83pub const ELIBEXEC = 83; // Cannot exec a shared library directly
84pub const EILSEQ = 84; // Illegal byte sequence
85pub const ERESTART = 85; // Interrupted system call should be restarted
86pub const ESTRPIPE = 86; // Streams pipe error
87pub const EUSERS = 87; // Too many users
88pub const ENOTSOCK = 88; // Socket operation on non-socket
89pub const EDESTADDRREQ = 89; // Destination address required
90pub const EMSGSIZE = 90; // Message too long
91pub const EPROTOTYPE = 91; // Protocol wrong type for socket
92pub const ENOPROTOOPT = 92; // Protocol not available
93pub const EPROTONOSUPPORT = 93; // Protocol not supported
94pub const ESOCKTNOSUPPORT = 94; // Socket type not supported
95pub const EOPNOTSUPP = 95; // Operation not supported on transport endpoint
96pub const EPFNOSUPPORT = 96; // Protocol family not supported
97pub const EAFNOSUPPORT = 97; // Address family not supported by protocol
98pub const EADDRINUSE = 98; // Address already in use
99pub const EADDRNOTAVAIL = 99; // Cannot assign requested address
100pub const ENETDOWN = 100; // Network is down
101pub const ENETUNREACH = 101; // Network is unreachable
102pub const ENETRESET = 102; // Network dropped connection because of reset
103pub const ECONNABORTED = 103; // Software caused connection abort
104pub const ECONNRESET = 104; // Connection reset by peer
105pub const ENOBUFS = 105; // No buffer space available
106pub const EISCONN = 106; // Transport endpoint is already connected
107pub const ENOTCONN = 107; // Transport endpoint is not connected
108pub const ESHUTDOWN = 108; // Cannot send after transport endpoint shutdown
109pub const ETOOMANYREFS = 109; // Too many references: cannot splice
110pub const ETIMEDOUT = 110; // Connection timed out
111pub const ECONNREFUSED = 111; // Connection refused
112pub const EHOSTDOWN = 112; // Host is down
113pub const EHOSTUNREACH = 113; // No route to host
114pub const EALREADY = 114; // Operation already in progress
115pub const EINPROGRESS = 115; // Operation now in progress
116pub const ESTALE = 116; // Stale NFS file handle
117pub const EUCLEAN = 117; // Structure needs cleaning
118pub const ENOTNAM = 118; // Not a XENIX named type file
119pub const ENAVAIL = 119; // No XENIX semaphores available
120pub const EISNAM = 120; // Is a named type file
121pub const EREMOTEIO = 121; // Remote I/O error
122pub const EDQUOT = 122; // Quota exceeded
123
124pub const ENOMEDIUM = 123; // No medium found
125pub const EMEDIUMTYPE = 124; // Wrong medium type
126
127// nameserver query return codes
128pub const ENSROK = 0; // DNS server returned answer with no data
129pub const ENSRNODATA = 160; // DNS server returned answer with no data
130pub const ENSRFORMERR = 161; // DNS server claims query was misformatted
131pub const ENSRSERVFAIL = 162; // DNS server returned general failure
132pub const ENSRNOTFOUND = 163; // Domain name not found
133pub const ENSRNOTIMP = 164; // DNS server does not implement requested operation
134pub const ENSRREFUSED = 165; // DNS server refused query
135pub const ENSRBADQUERY = 166; // Misformatted DNS query
136pub const ENSRBADNAME = 167; // Misformatted domain name
137pub const ENSRBADFAMILY = 168; // Unsupported address family
138pub const ENSRBADRESP = 169; // Misformatted DNS reply
139pub const ENSRCONNREFUSED = 170; // Could not contact DNS servers
140pub const ENSRTIMEOUT = 171; // Timeout while contacting DNS servers
141pub const ENSROF = 172; // End of file
142pub const ENSRFILE = 173; // Error reading file
143pub const ENSRNOMEM = 174; // Out of memory
144pub const ENSRDESTRUCTION = 175; // Application terminated lookup
145pub const ENSRQUERYDOMAINTOOLONG = 176; // Domain name is too long
146pub const ENSRCNAMELOOP = 177; // Domain name is too long
std/os/index.zig+178-160
......@@ -23,7 +23,6 @@ pub const page_size = 4 * 1024;
2323const debug = @import("../debug.zig");
2424const assert = debug.assert;
2525
26const errno = @import("errno.zig");
2726const c = @import("../c/index.zig");
2827
2928const mem = @import("../mem.zig");
......@@ -56,43 +55,40 @@ error WouldBlock;
5655/// appropriate OS-specific library call. Otherwise it uses the zig standard
5756/// library implementation.
5857pub fn getRandomBytes(buf: []u8) -> %void {
59 while (true) {
60 const err = switch (builtin.os) {
61 Os.linux => {
62 // TODO check libc version and potentially call c.getrandom.
63 // See #397
64 posix.getErrno(posix.getrandom(buf.ptr, buf.len, 0))
65 },
66 Os.darwin, Os.macosx, Os.ios => {
67 if (builtin.link_libc) {
68 if (posix.getrandom(buf.ptr, buf.len) == -1) *c._errno() else 0
69 } else {
70 posix.getErrno(posix.getrandom(buf.ptr, buf.len))
71 }
72 },
73 Os.windows => {
74 var hCryptProv: windows.HCRYPTPROV = undefined;
75 if (!windows.CryptAcquireContext(&hCryptProv, null, null, windows.PROV_RSA_FULL, 0)) {
76 return error.Unexpected;
58 switch (builtin.os) {
59 Os.linux => while (true) {
60 // TODO check libc version and potentially call c.getrandom.
61 // See #397
62 const err = posix.getErrno(posix.getrandom(buf.ptr, buf.len, 0));
63 if (err > 0) {
64 return switch (err) {
65 posix.EINVAL => unreachable,
66 posix.EFAULT => unreachable,
67 posix.EINTR => continue,
68 else => error.Unexpected,
7769 }
78 defer _ = windows.CryptReleaseContext(hCryptProv, 0);
70 }
71 return;
72 },
73 Os.darwin, Os.macosx, Os.ios => {
74 const fd = %return posixOpen("/dev/urandom", posix.O_RDONLY|posix.O_CLOEXEC,
75 0, null);
76 defer posixClose(fd);
7977
80 if (!windows.CryptGenRandom(hCryptProv, windows.DWORD(buf.len), buf.ptr)) {
81 return error.Unexpected;
82 }
83 return;
84 },
85 else => @compileError("Unsupported OS"),
86 };
87 if (err > 0) {
88 return switch (err) {
89 errno.EINVAL => unreachable,
90 errno.EFAULT => unreachable,
91 errno.EINTR => continue,
92 else => error.Unexpected,
78 %return posixRead(fd, buf);
79 },
80 Os.windows => {
81 var hCryptProv: windows.HCRYPTPROV = undefined;
82 if (!windows.CryptAcquireContext(&hCryptProv, null, null, windows.PROV_RSA_FULL, 0)) {
83 return error.Unexpected;
9384 }
94 }
95 return;
85 defer _ = windows.CryptReleaseContext(hCryptProv, 0);
86
87 if (!windows.CryptGenRandom(hCryptProv, windows.DWORD(buf.len), buf.ptr)) {
88 return error.Unexpected;
89 }
90 },
91 else => @compileError("Unsupported OS"),
9692 }
9793}
9894
......@@ -120,7 +116,7 @@ pub coldcc fn abort() -> noreturn {
120116pub fn posixClose(fd: i32) {
121117 while (true) {
122118 const err = posix.getErrno(posix.close(fd));
123 if (err == errno.EINTR) {
119 if (err == posix.EINTR) {
124120 continue;
125121 } else {
126122 return;
......@@ -128,12 +124,34 @@ pub fn posixClose(fd: i32) {
128124 }
129125}
130126
127/// Calls POSIX read, and keeps trying if it gets interrupted.
128pub fn posixRead(fd: i32, buf: []u8) -> %void {
129 var index: usize = 0;
130 while (index < buf.len) {
131 const amt_written = posix.read(fd, &buf[index], buf.len - index);
132 const err = posix.getErrno(amt_written);
133 if (err > 0) {
134 return switch (err) {
135 posix.EINTR => continue,
136 posix.EINVAL, posix.EFAULT => unreachable,
137 posix.EAGAIN => error.WouldBlock,
138 posix.EBADF => error.FileClosed,
139 posix.EIO => error.InputOutput,
140 posix.EISDIR => error.IsDir,
141 posix.ENOBUFS, posix.ENOMEM => error.SystemResources,
142 else => return error.Unexpected,
143 }
144 }
145 index += amt_written;
146 }
147}
148
131149error WouldBlock;
132150error FileClosed;
133151error DestinationAddressRequired;
134152error DiskQuota;
135153error FileTooBig;
136error FileSystem;
154error InputOutput;
137155error NoSpaceLeft;
138156error BrokenPipe;
139157error Unexpected;
......@@ -145,17 +163,17 @@ pub fn posixWrite(fd: i32, bytes: []const u8) -> %void {
145163 const write_err = posix.getErrno(write_ret);
146164 if (write_err > 0) {
147165 return switch (write_err) {
148 errno.EINTR => continue,
149 errno.EINVAL, errno.EFAULT => unreachable,
150 errno.EAGAIN => error.WouldBlock,
151 errno.EBADF => error.FileClosed,
152 errno.EDESTADDRREQ => error.DestinationAddressRequired,
153 errno.EDQUOT => error.DiskQuota,
154 errno.EFBIG => error.FileTooBig,
155 errno.EIO => error.FileSystem,
156 errno.ENOSPC => error.NoSpaceLeft,
157 errno.EPERM => error.AccessDenied,
158 errno.EPIPE => error.BrokenPipe,
166 posix.EINTR => continue,
167 posix.EINVAL, posix.EFAULT => unreachable,
168 posix.EAGAIN => error.WouldBlock,
169 posix.EBADF => error.FileClosed,
170 posix.EDESTADDRREQ => error.DestinationAddressRequired,
171 posix.EDQUOT => error.DiskQuota,
172 posix.EFBIG => error.FileTooBig,
173 posix.EIO => error.InputOutput,
174 posix.ENOSPC => error.NoSpaceLeft,
175 posix.EPERM => error.AccessDenied,
176 posix.EPIPE => error.BrokenPipe,
159177 else => error.Unexpected,
160178 }
161179 }
......@@ -213,7 +231,7 @@ pub fn windowsIsCygwinPty(handle: windows.HANDLE) -> bool {
213231/// otherwise if the fixed size buffer is too small, allocator is used to obtain the needed memory.
214232/// Calls POSIX open, keeps trying if it gets interrupted, and translates
215233/// the return value into zig errors.
216pub fn posixOpen(file_path: []const u8, flags: usize, perm: usize, allocator: ?&Allocator) -> %i32 {
234pub fn posixOpen(file_path: []const u8, flags: u32, perm: usize, allocator: ?&Allocator) -> %i32 {
217235 var stack_buf: [max_noalloc_path_len]u8 = undefined;
218236 var path0: []u8 = undefined;
219237 var need_free = false;
......@@ -237,23 +255,23 @@ pub fn posixOpen(file_path: []const u8, flags: usize, perm: usize, allocator: ?&
237255 const err = posix.getErrno(result);
238256 if (err > 0) {
239257 return switch (err) {
240 errno.EINTR => continue,
241
242 errno.EFAULT => unreachable,
243 errno.EINVAL => unreachable,
244 errno.EACCES => error.AccessDenied,
245 errno.EFBIG, errno.EOVERFLOW => error.FileTooBig,
246 errno.EISDIR => error.IsDir,
247 errno.ELOOP => error.SymLinkLoop,
248 errno.EMFILE => error.ProcessFdQuotaExceeded,
249 errno.ENAMETOOLONG => error.NameTooLong,
250 errno.ENFILE => error.SystemFdQuotaExceeded,
251 errno.ENODEV => error.NoDevice,
252 errno.ENOENT => error.PathNotFound,
253 errno.ENOMEM => error.SystemResources,
254 errno.ENOSPC => error.NoSpaceLeft,
255 errno.ENOTDIR => error.NotDir,
256 errno.EPERM => error.AccessDenied,
258 posix.EINTR => continue,
259
260 posix.EFAULT => unreachable,
261 posix.EINVAL => unreachable,
262 posix.EACCES => error.AccessDenied,
263 posix.EFBIG, posix.EOVERFLOW => error.FileTooBig,
264 posix.EISDIR => error.IsDir,
265 posix.ELOOP => error.SymLinkLoop,
266 posix.EMFILE => error.ProcessFdQuotaExceeded,
267 posix.ENAMETOOLONG => error.NameTooLong,
268 posix.ENFILE => error.SystemFdQuotaExceeded,
269 posix.ENODEV => error.NoDevice,
270 posix.ENOENT => error.PathNotFound,
271 posix.ENOMEM => error.SystemResources,
272 posix.ENOSPC => error.NoSpaceLeft,
273 posix.ENOTDIR => error.NotDir,
274 posix.EPERM => error.AccessDenied,
257275 else => error.Unexpected,
258276 }
259277 }
......@@ -266,9 +284,9 @@ pub fn posixDup2(old_fd: i32, new_fd: i32) -> %void {
266284 const err = posix.getErrno(posix.dup2(old_fd, new_fd));
267285 if (err > 0) {
268286 return switch (err) {
269 errno.EBUSY, errno.EINTR => continue,
270 errno.EMFILE => error.ProcessFdQuotaExceeded,
271 errno.EINVAL => unreachable,
287 posix.EBUSY, posix.EINTR => continue,
288 posix.EMFILE => error.ProcessFdQuotaExceeded,
289 posix.EINVAL => unreachable,
272290 else => error.Unexpected,
273291 };
274292 }
......@@ -362,14 +380,14 @@ pub fn posixExecve(exe_path: []const u8, argv: []const []const u8, env_map: &con
362380 path_buf[search_path.len + exe_path.len + 1] = 0;
363381 err = posix.getErrno(posix.execve(path_buf.ptr, argv_buf.ptr, envp_buf.ptr));
364382 assert(err > 0);
365 if (err == errno.EACCES) {
383 if (err == posix.EACCES) {
366384 seen_eacces = true;
367 } else if (err != errno.ENOENT) {
385 } else if (err != posix.ENOENT) {
368386 return posixExecveErrnoToErr(err);
369387 }
370388 }
371389 if (seen_eacces) {
372 err = errno.EACCES;
390 err = posix.EACCES;
373391 }
374392 return posixExecveErrnoToErr(err);
375393}
......@@ -377,15 +395,15 @@ pub fn posixExecve(exe_path: []const u8, argv: []const []const u8, env_map: &con
377395fn posixExecveErrnoToErr(err: usize) -> error {
378396 assert(err > 0);
379397 return switch (err) {
380 errno.EFAULT => unreachable,
381 errno.E2BIG, errno.EMFILE, errno.ENAMETOOLONG, errno.ENFILE, errno.ENOMEM => error.SystemResources,
382 errno.EACCES, errno.EPERM => error.AccessDenied,
383 errno.EINVAL, errno.ENOEXEC => error.InvalidExe,
384 errno.EIO, errno.ELOOP => error.FileSystem,
385 errno.EISDIR => error.IsDir,
386 errno.ENOENT => error.FileNotFound,
387 errno.ENOTDIR => error.NotDir,
388 errno.ETXTBSY => error.FileBusy,
398 posix.EFAULT => unreachable,
399 posix.E2BIG, posix.EMFILE, posix.ENAMETOOLONG, posix.ENFILE, posix.ENOMEM => error.SystemResources,
400 posix.EACCES, posix.EPERM => error.AccessDenied,
401 posix.EINVAL, posix.ENOEXEC => error.InvalidExe,
402 posix.EIO, posix.ELOOP => error.FileSystem,
403 posix.EISDIR => error.IsDir,
404 posix.ENOENT => error.FileNotFound,
405 posix.ENOTDIR => error.NotDir,
406 posix.ETXTBSY => error.FileBusy,
389407 else => error.Unexpected,
390408 };
391409}
......@@ -445,7 +463,7 @@ pub fn getCwd(allocator: &Allocator) -> %[]u8 {
445463 %defer allocator.free(buf);
446464 while (true) {
447465 const err = posix.getErrno(posix.getcwd(buf.ptr, buf.len));
448 if (err == errno.ERANGE) {
466 if (err == posix.ERANGE) {
449467 buf = %return allocator.realloc(u8, buf, buf.len * 2);
450468 continue;
451469 } else if (err > 0) {
......@@ -471,18 +489,18 @@ pub fn symLink(allocator: &Allocator, existing_path: []const u8, new_path: []con
471489 const err = posix.getErrno(posix.symlink(existing_buf.ptr, new_buf.ptr));
472490 if (err > 0) {
473491 return switch (err) {
474 errno.EFAULT, errno.EINVAL => unreachable,
475 errno.EACCES, errno.EPERM => error.AccessDenied,
476 errno.EDQUOT => error.DiskQuota,
477 errno.EEXIST => error.PathAlreadyExists,
478 errno.EIO => error.FileSystem,
479 errno.ELOOP => error.SymLinkLoop,
480 errno.ENAMETOOLONG => error.NameTooLong,
481 errno.ENOENT => error.FileNotFound,
482 errno.ENOTDIR => error.NotDir,
483 errno.ENOMEM => error.SystemResources,
484 errno.ENOSPC => error.NoSpaceLeft,
485 errno.EROFS => error.ReadOnlyFileSystem,
492 posix.EFAULT, posix.EINVAL => unreachable,
493 posix.EACCES, posix.EPERM => error.AccessDenied,
494 posix.EDQUOT => error.DiskQuota,
495 posix.EEXIST => error.PathAlreadyExists,
496 posix.EIO => error.FileSystem,
497 posix.ELOOP => error.SymLinkLoop,
498 posix.ENAMETOOLONG => error.NameTooLong,
499 posix.ENOENT => error.FileNotFound,
500 posix.ENOTDIR => error.NotDir,
501 posix.ENOMEM => error.SystemResources,
502 posix.ENOSPC => error.NoSpaceLeft,
503 posix.EROFS => error.ReadOnlyFileSystem,
486504 else => error.Unexpected,
487505 };
488506 }
......@@ -530,17 +548,17 @@ pub fn deleteFile(allocator: &Allocator, file_path: []const u8) -> %void {
530548 const err = posix.getErrno(posix.unlink(buf.ptr));
531549 if (err > 0) {
532550 return switch (err) {
533 errno.EACCES, errno.EPERM => error.AccessDenied,
534 errno.EBUSY => error.FileBusy,
535 errno.EFAULT, errno.EINVAL => unreachable,
536 errno.EIO => error.FileSystem,
537 errno.EISDIR => error.IsDir,
538 errno.ELOOP => error.SymLinkLoop,
539 errno.ENAMETOOLONG => error.NameTooLong,
540 errno.ENOENT => error.FileNotFound,
541 errno.ENOTDIR => error.NotDir,
542 errno.ENOMEM => error.SystemResources,
543 errno.EROFS => error.ReadOnlyFileSystem,
551 posix.EACCES, posix.EPERM => error.AccessDenied,
552 posix.EBUSY => error.FileBusy,
553 posix.EFAULT, posix.EINVAL => unreachable,
554 posix.EIO => error.FileSystem,
555 posix.EISDIR => error.IsDir,
556 posix.ELOOP => error.SymLinkLoop,
557 posix.ENAMETOOLONG => error.NameTooLong,
558 posix.ENOENT => error.FileNotFound,
559 posix.ENOTDIR => error.NotDir,
560 posix.ENOMEM => error.SystemResources,
561 posix.EROFS => error.ReadOnlyFileSystem,
544562 else => error.Unexpected,
545563 };
546564 }
......@@ -593,21 +611,21 @@ pub fn rename(allocator: &Allocator, old_path: []const u8, new_path: []const u8)
593611 const err = posix.getErrno(posix.rename(old_buf.ptr, new_buf.ptr));
594612 if (err > 0) {
595613 return switch (err) {
596 errno.EACCES, errno.EPERM => error.AccessDenied,
597 errno.EBUSY => error.FileBusy,
598 errno.EDQUOT => error.DiskQuota,
599 errno.EFAULT, errno.EINVAL => unreachable,
600 errno.EISDIR => error.IsDir,
601 errno.ELOOP => error.SymLinkLoop,
602 errno.EMLINK => error.LinkQuotaExceeded,
603 errno.ENAMETOOLONG => error.NameTooLong,
604 errno.ENOENT => error.FileNotFound,
605 errno.ENOTDIR => error.NotDir,
606 errno.ENOMEM => error.SystemResources,
607 errno.ENOSPC => error.NoSpaceLeft,
608 errno.EEXIST, errno.ENOTEMPTY => error.PathAlreadyExists,
609 errno.EROFS => error.ReadOnlyFileSystem,
610 errno.EXDEV => error.RenameAcrossMountPoints,
614 posix.EACCES, posix.EPERM => error.AccessDenied,
615 posix.EBUSY => error.FileBusy,
616 posix.EDQUOT => error.DiskQuota,
617 posix.EFAULT, posix.EINVAL => unreachable,
618 posix.EISDIR => error.IsDir,
619 posix.ELOOP => error.SymLinkLoop,
620 posix.EMLINK => error.LinkQuotaExceeded,
621 posix.ENAMETOOLONG => error.NameTooLong,
622 posix.ENOENT => error.FileNotFound,
623 posix.ENOTDIR => error.NotDir,
624 posix.ENOMEM => error.SystemResources,
625 posix.ENOSPC => error.NoSpaceLeft,
626 posix.EEXIST, posix.ENOTEMPTY => error.PathAlreadyExists,
627 posix.EROFS => error.ReadOnlyFileSystem,
628 posix.EXDEV => error.RenameAcrossMountPoints,
611629 else => error.Unexpected,
612630 };
613631 }
......@@ -623,18 +641,18 @@ pub fn makeDir(allocator: &Allocator, dir_path: []const u8) -> %void {
623641 const err = posix.getErrno(posix.mkdir(path_buf.ptr, 0o755));
624642 if (err > 0) {
625643 return switch (err) {
626 errno.EACCES, errno.EPERM => error.AccessDenied,
627 errno.EDQUOT => error.DiskQuota,
628 errno.EEXIST => error.PathAlreadyExists,
629 errno.EFAULT => unreachable,
630 errno.ELOOP => error.SymLinkLoop,
631 errno.EMLINK => error.LinkQuotaExceeded,
632 errno.ENAMETOOLONG => error.NameTooLong,
633 errno.ENOENT => error.FileNotFound,
634 errno.ENOMEM => error.SystemResources,
635 errno.ENOSPC => error.NoSpaceLeft,
636 errno.ENOTDIR => error.NotDir,
637 errno.EROFS => error.ReadOnlyFileSystem,
644 posix.EACCES, posix.EPERM => error.AccessDenied,
645 posix.EDQUOT => error.DiskQuota,
646 posix.EEXIST => error.PathAlreadyExists,
647 posix.EFAULT => unreachable,
648 posix.ELOOP => error.SymLinkLoop,
649 posix.EMLINK => error.LinkQuotaExceeded,
650 posix.ENAMETOOLONG => error.NameTooLong,
651 posix.ENOENT => error.FileNotFound,
652 posix.ENOMEM => error.SystemResources,
653 posix.ENOSPC => error.NoSpaceLeft,
654 posix.ENOTDIR => error.NotDir,
655 posix.EROFS => error.ReadOnlyFileSystem,
638656 else => error.Unexpected,
639657 };
640658 }
......@@ -690,16 +708,16 @@ pub fn deleteDir(allocator: &Allocator, dir_path: []const u8) -> %void {
690708 const err = posix.getErrno(posix.rmdir(path_buf.ptr));
691709 if (err > 0) {
692710 return switch (err) {
693 errno.EACCES, errno.EPERM => error.AccessDenied,
694 errno.EBUSY => error.FileBusy,
695 errno.EFAULT, errno.EINVAL => unreachable,
696 errno.ELOOP => error.SymLinkLoop,
697 errno.ENAMETOOLONG => error.NameTooLong,
698 errno.ENOENT => error.FileNotFound,
699 errno.ENOMEM => error.SystemResources,
700 errno.ENOTDIR => error.NotDir,
701 errno.EEXIST, errno.ENOTEMPTY => error.DirNotEmpty,
702 errno.EROFS => error.ReadOnlyFileSystem,
711 posix.EACCES, posix.EPERM => error.AccessDenied,
712 posix.EBUSY => error.FileBusy,
713 posix.EFAULT, posix.EINVAL => unreachable,
714 posix.ELOOP => error.SymLinkLoop,
715 posix.ENAMETOOLONG => error.NameTooLong,
716 posix.ENOENT => error.FileNotFound,
717 posix.ENOMEM => error.SystemResources,
718 posix.ENOTDIR => error.NotDir,
719 posix.EEXIST, posix.ENOTEMPTY => error.DirNotEmpty,
720 posix.EROFS => error.ReadOnlyFileSystem,
703721 else => error.Unexpected,
704722 };
705723 }
......@@ -806,8 +824,8 @@ pub const Dir = struct {
806824 const err = linux.getErrno(result);
807825 if (err > 0) {
808826 switch (err) {
809 errno.EBADF, errno.EFAULT, errno.ENOTDIR => unreachable,
810 errno.EINVAL => {
827 posix.EBADF, posix.EFAULT, posix.ENOTDIR => unreachable,
828 posix.EINVAL => {
811829 self.buf = %return self.allocator.realloc(u8, self.buf, self.buf.len * 2);
812830 continue;
813831 },
......@@ -860,14 +878,14 @@ pub fn changeCurDir(allocator: &Allocator, dir_path: []const u8) -> %void {
860878 const err = posix.getErrno(posix.chdir(path_buf.ptr));
861879 if (err > 0) {
862880 return switch (err) {
863 errno.EACCES => error.AccessDenied,
864 errno.EFAULT => unreachable,
865 errno.EIO => error.FileSystem,
866 errno.ELOOP => error.SymLinkLoop,
867 errno.ENAMETOOLONG => error.NameTooLong,
868 errno.ENOENT => error.FileNotFound,
869 errno.ENOMEM => error.SystemResources,
870 errno.ENOTDIR => error.NotDir,
881 posix.EACCES => error.AccessDenied,
882 posix.EFAULT => unreachable,
883 posix.EIO => error.FileSystem,
884 posix.ELOOP => error.SymLinkLoop,
885 posix.ENAMETOOLONG => error.NameTooLong,
886 posix.ENOENT => error.FileNotFound,
887 posix.ENOMEM => error.SystemResources,
888 posix.ENOTDIR => error.NotDir,
871889 else => error.Unexpected,
872890 };
873891 }
......@@ -888,14 +906,14 @@ pub fn readLink(allocator: &Allocator, pathname: []const u8) -> %[]u8 {
888906 const err = posix.getErrno(ret_val);
889907 if (err > 0) {
890908 return switch (err) {
891 errno.EACCES => error.AccessDenied,
892 errno.EFAULT, errno.EINVAL => unreachable,
893 errno.EIO => error.FileSystem,
894 errno.ELOOP => error.SymLinkLoop,
895 errno.ENAMETOOLONG => error.NameTooLong,
896 errno.ENOENT => error.FileNotFound,
897 errno.ENOMEM => error.SystemResources,
898 errno.ENOTDIR => error.NotDir,
909 posix.EACCES => error.AccessDenied,
910 posix.EFAULT, posix.EINVAL => unreachable,
911 posix.EIO => error.FileSystem,
912 posix.ELOOP => error.SymLinkLoop,
913 posix.ENAMETOOLONG => error.NameTooLong,
914 posix.ENOENT => error.FileNotFound,
915 posix.ENOMEM => error.SystemResources,
916 posix.ENOTDIR => error.NotDir,
899917 else => error.Unexpected,
900918 };
901919 }
std/os/linux.zig+20-17
......@@ -4,7 +4,9 @@ const arch = switch (builtin.arch) {
44 builtin.Arch.i386 => @import("linux_i386.zig"),
55 else => @compileError("unsupported arch"),
66};
7const errno = @import("errno.zig");
7pub use @import("linux_errno.zig");
8
9pub const PATH_MAX = 4096;
810
911pub const STDIN_FILENO = 0;
1012pub const STDOUT_FILENO = 1;
......@@ -309,8 +311,8 @@ pub const TIOCGPKT = 0x80045438;
309311pub const TIOCGPTLCK = 0x80045439;
310312pub const TIOCGEXCL = 0x80045440;
311313
312fn unsigned(s: i32) -> u32 { *@ptrCast(&u32, &s) }
313fn signed(s: u32) -> i32 { *@ptrCast(&i32, &s) }
314fn unsigned(s: i32) -> u32 { @bitCast(u32, s) }
315fn signed(s: u32) -> i32 { @bitCast(i32, s) }
314316pub fn WEXITSTATUS(s: i32) -> i32 { signed((unsigned(s) & 0xff00) >> 8) }
315317pub fn WTERMSIG(s: i32) -> i32 { signed(unsigned(s) & 0x7f) }
316318pub fn WSTOPSIG(s: i32) -> i32 { WEXITSTATUS(s) }
......@@ -328,7 +330,7 @@ pub const winsize = extern struct {
328330
329331/// Get the errno from a syscall return value, or 0 for no error.
330332pub fn getErrno(r: usize) -> usize {
331 const signed_r = *@ptrCast(&const isize, &r);
333 const signed_r = @bitCast(isize, r);
332334 if (signed_r > -4096 and signed_r < 0) usize(-signed_r) else 0
333335}
334336
......@@ -353,7 +355,7 @@ pub fn getcwd(buf: &u8, size: usize) -> usize {
353355}
354356
355357pub fn getdents(fd: i32, dirp: &u8, count: usize) -> usize {
356 arch.syscall3(arch.SYS_getdents, usize(fd), @ptrToInt(dirp), usize(count))
358 arch.syscall3(arch.SYS_getdents, usize(fd), @ptrToInt(dirp), count)
357359}
358360
359361pub fn isatty(fd: i32) -> bool {
......@@ -365,14 +367,15 @@ pub fn readlink(noalias path: &const u8, noalias buf_ptr: &u8, buf_len: usize) -
365367 arch.syscall3(arch.SYS_readlink, @ptrToInt(path), @ptrToInt(buf_ptr), buf_len)
366368}
367369
368pub fn mkdir(path: &const u8, mode: usize) -> usize {
370pub fn mkdir(path: &const u8, mode: u32) -> usize {
369371 arch.syscall2(arch.SYS_mkdir, @ptrToInt(path), mode)
370372}
371373
372pub fn mmap(address: ?&u8, length: usize, prot: usize, flags: usize, fd: i32, offset: usize)
374pub fn mmap(address: ?&u8, length: usize, prot: usize, flags: usize, fd: i32, offset: isize)
373375 -> usize
374376{
375 arch.syscall6(arch.SYS_mmap, @ptrToInt(address), length, prot, flags, usize(fd), offset)
377 arch.syscall6(arch.SYS_mmap, @ptrToInt(address), length, prot, flags, usize(fd),
378 @bitCast(usize, offset))
376379}
377380
378381pub fn munmap(address: &u8, length: usize) -> usize {
......@@ -415,7 +418,7 @@ pub fn rename(old: &const u8, new: &const u8) -> usize {
415418 arch.syscall2(arch.SYS_rename, @ptrToInt(old), @ptrToInt(new))
416419}
417420
418pub fn open(path: &const u8, flags: usize, perm: usize) -> usize {
421pub fn open(path: &const u8, flags: u32, perm: usize) -> usize {
419422 arch.syscall3(arch.SYS_open, @ptrToInt(path), flags, perm)
420423}
421424
......@@ -431,12 +434,12 @@ pub fn close(fd: i32) -> usize {
431434 arch.syscall1(arch.SYS_close, usize(fd))
432435}
433436
434pub fn lseek(fd: i32, offset: usize, ref_pos: usize) -> usize {
435 arch.syscall3(arch.SYS_lseek, usize(fd), offset, ref_pos)
437pub fn lseek(fd: i32, offset: isize, ref_pos: usize) -> usize {
438 arch.syscall3(arch.SYS_lseek, usize(fd), @bitCast(usize, offset), ref_pos)
436439}
437440
438441pub fn exit(status: i32) -> noreturn {
439 _ = arch.syscall1(arch.SYS_exit, usize(status));
442 _ = arch.syscall1(arch.SYS_exit, @bitCast(usize, isize(status)));
440443 unreachable
441444}
442445
......@@ -453,7 +456,7 @@ pub fn unlink(path: &const u8) -> usize {
453456}
454457
455458pub fn waitpid(pid: i32, status: &i32, options: i32) -> usize {
456 arch.syscall4(arch.SYS_wait4, usize(pid), @ptrToInt(status), usize(options), 0)
459 arch.syscall4(arch.SYS_wait4, usize(pid), @ptrToInt(status), @bitCast(usize, isize(options)), 0)
457460}
458461
459462const NSIG = 65;
......@@ -461,11 +464,11 @@ const sigset_t = [128]u8;
461464const all_mask = []u8 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, };
462465const app_mask = []u8 { 0xff, 0xff, 0xff, 0xfc, 0x7f, 0xff, 0xff, 0xff, };
463466
464pub fn raise(sig: i32) -> i32 {
467pub fn raise(sig: i32) -> usize {
465468 var set: sigset_t = undefined;
466469 blockAppSignals(&set);
467470 const tid = i32(arch.syscall0(arch.SYS_gettid));
468 const ret = i32(arch.syscall2(arch.SYS_tkill, usize(tid), usize(sig)));
471 const ret = arch.syscall2(arch.SYS_tkill, usize(tid), usize(sig));
469472 restoreSignals(&set);
470473 return ret;
471474}
......@@ -630,9 +633,9 @@ pub fn accept4(fd: i32, noalias addr: &sockaddr, noalias len: &socklen_t, flags:
630633// return ifr.ifr_ifindex;
631634// }
632635
633pub const stat = arch.stat;
636pub const Stat = arch.Stat;
634637pub const timespec = arch.timespec;
635638
636pub fn fstat(fd: i32, stat_buf: &stat) -> usize {
639pub fn fstat(fd: i32, stat_buf: &Stat) -> usize {
637640 arch.syscall2(arch.SYS_fstat, usize(fd), @ptrToInt(stat_buf))
638641}
std/os/linux_errno.zig created+146
......@@ -0,0 +1,146 @@
1pub const EPERM = 1; /// Operation not permitted
2pub const ENOENT = 2; /// No such file or directory
3pub const ESRCH = 3; /// No such process
4pub const EINTR = 4; /// Interrupted system call
5pub const EIO = 5; /// I/O error
6pub const ENXIO = 6; /// No such device or address
7pub const E2BIG = 7; /// Arg list too long
8pub const ENOEXEC = 8; /// Exec format error
9pub const EBADF = 9; /// Bad file number
10pub const ECHILD = 10; /// No child processes
11pub const EAGAIN = 11; /// Try again
12pub const ENOMEM = 12; /// Out of memory
13pub const EACCES = 13; /// Permission denied
14pub const EFAULT = 14; /// Bad address
15pub const ENOTBLK = 15; /// Block device required
16pub const EBUSY = 16; /// Device or resource busy
17pub const EEXIST = 17; /// File exists
18pub const EXDEV = 18; /// Cross-device link
19pub const ENODEV = 19; /// No such device
20pub const ENOTDIR = 20; /// Not a directory
21pub const EISDIR = 21; /// Is a directory
22pub const EINVAL = 22; /// Invalid argument
23pub const ENFILE = 23; /// File table overflow
24pub const EMFILE = 24; /// Too many open files
25pub const ENOTTY = 25; /// Not a typewriter
26pub const ETXTBSY = 26; /// Text file busy
27pub const EFBIG = 27; /// File too large
28pub const ENOSPC = 28; /// No space left on device
29pub const ESPIPE = 29; /// Illegal seek
30pub const EROFS = 30; /// Read-only file system
31pub const EMLINK = 31; /// Too many links
32pub const EPIPE = 32; /// Broken pipe
33pub const EDOM = 33; /// Math argument out of domain of func
34pub const ERANGE = 34; /// Math result not representable
35pub const EDEADLK = 35; /// Resource deadlock would occur
36pub const ENAMETOOLONG = 36; /// File name too long
37pub const ENOLCK = 37; /// No record locks available
38pub const ENOSYS = 38; /// Function not implemented
39pub const ENOTEMPTY = 39; /// Directory not empty
40pub const ELOOP = 40; /// Too many symbolic links encountered
41pub const EWOULDBLOCK = EAGAIN; /// Operation would block
42pub const ENOMSG = 42; /// No message of desired type
43pub const EIDRM = 43; /// Identifier removed
44pub const ECHRNG = 44; /// Channel number out of range
45pub const EL2NSYNC = 45; /// Level 2 not synchronized
46pub const EL3HLT = 46; /// Level 3 halted
47pub const EL3RST = 47; /// Level 3 reset
48pub const ELNRNG = 48; /// Link number out of range
49pub const EUNATCH = 49; /// Protocol driver not attached
50pub const ENOCSI = 50; /// No CSI structure available
51pub const EL2HLT = 51; /// Level 2 halted
52pub const EBADE = 52; /// Invalid exchange
53pub const EBADR = 53; /// Invalid request descriptor
54pub const EXFULL = 54; /// Exchange full
55pub const ENOANO = 55; /// No anode
56pub const EBADRQC = 56; /// Invalid request code
57pub const EBADSLT = 57; /// Invalid slot
58
59pub const EBFONT = 59; /// Bad font file format
60pub const ENOSTR = 60; /// Device not a stream
61pub const ENODATA = 61; /// No data available
62pub const ETIME = 62; /// Timer expired
63pub const ENOSR = 63; /// Out of streams resources
64pub const ENONET = 64; /// Machine is not on the network
65pub const ENOPKG = 65; /// Package not installed
66pub const EREMOTE = 66; /// Object is remote
67pub const ENOLINK = 67; /// Link has been severed
68pub const EADV = 68; /// Advertise error
69pub const ESRMNT = 69; /// Srmount error
70pub const ECOMM = 70; /// Communication error on send
71pub const EPROTO = 71; /// Protocol error
72pub const EMULTIHOP = 72; /// Multihop attempted
73pub const EDOTDOT = 73; /// RFS specific error
74pub const EBADMSG = 74; /// Not a data message
75pub const EOVERFLOW = 75; /// Value too large for defined data type
76pub const ENOTUNIQ = 76; /// Name not unique on network
77pub const EBADFD = 77; /// File descriptor in bad state
78pub const EREMCHG = 78; /// Remote address changed
79pub const ELIBACC = 79; /// Can not access a needed shared library
80pub const ELIBBAD = 80; /// Accessing a corrupted shared library
81pub const ELIBSCN = 81; /// .lib section in a.out corrupted
82pub const ELIBMAX = 82; /// Attempting to link in too many shared libraries
83pub const ELIBEXEC = 83; /// Cannot exec a shared library directly
84pub const EILSEQ = 84; /// Illegal byte sequence
85pub const ERESTART = 85; /// Interrupted system call should be restarted
86pub const ESTRPIPE = 86; /// Streams pipe error
87pub const EUSERS = 87; /// Too many users
88pub const ENOTSOCK = 88; /// Socket operation on non-socket
89pub const EDESTADDRREQ = 89; /// Destination address required
90pub const EMSGSIZE = 90; /// Message too long
91pub const EPROTOTYPE = 91; /// Protocol wrong type for socket
92pub const ENOPROTOOPT = 92; /// Protocol not available
93pub const EPROTONOSUPPORT = 93; /// Protocol not supported
94pub const ESOCKTNOSUPPORT = 94; /// Socket type not supported
95pub const EOPNOTSUPP = 95; /// Operation not supported on transport endpoint
96pub const EPFNOSUPPORT = 96; /// Protocol family not supported
97pub const EAFNOSUPPORT = 97; /// Address family not supported by protocol
98pub const EADDRINUSE = 98; /// Address already in use
99pub const EADDRNOTAVAIL = 99; /// Cannot assign requested address
100pub const ENETDOWN = 100; /// Network is down
101pub const ENETUNREACH = 101; /// Network is unreachable
102pub const ENETRESET = 102; /// Network dropped connection because of reset
103pub const ECONNABORTED = 103; /// Software caused connection abort
104pub const ECONNRESET = 104; /// Connection reset by peer
105pub const ENOBUFS = 105; /// No buffer space available
106pub const EISCONN = 106; /// Transport endpoint is already connected
107pub const ENOTCONN = 107; /// Transport endpoint is not connected
108pub const ESHUTDOWN = 108; /// Cannot send after transport endpoint shutdown
109pub const ETOOMANYREFS = 109; /// Too many references: cannot splice
110pub const ETIMEDOUT = 110; /// Connection timed out
111pub const ECONNREFUSED = 111; /// Connection refused
112pub const EHOSTDOWN = 112; /// Host is down
113pub const EHOSTUNREACH = 113; /// No route to host
114pub const EALREADY = 114; /// Operation already in progress
115pub const EINPROGRESS = 115; /// Operation now in progress
116pub const ESTALE = 116; /// Stale NFS file handle
117pub const EUCLEAN = 117; /// Structure needs cleaning
118pub const ENOTNAM = 118; /// Not a XENIX named type file
119pub const ENAVAIL = 119; /// No XENIX semaphores available
120pub const EISNAM = 120; /// Is a named type file
121pub const EREMOTEIO = 121; /// Remote I/O error
122pub const EDQUOT = 122; /// Quota exceeded
123
124pub const ENOMEDIUM = 123; /// No medium found
125pub const EMEDIUMTYPE = 124; /// Wrong medium type
126
127// nameserver query return codes
128pub const ENSROK = 0; /// DNS server returned answer with no data
129pub const ENSRNODATA = 160; /// DNS server returned answer with no data
130pub const ENSRFORMERR = 161; /// DNS server claims query was misformatted
131pub const ENSRSERVFAIL = 162; /// DNS server returned general failure
132pub const ENSRNOTFOUND = 163; /// Domain name not found
133pub const ENSRNOTIMP = 164; /// DNS server does not implement requested operation
134pub const ENSRREFUSED = 165; /// DNS server refused query
135pub const ENSRBADQUERY = 166; /// Misformatted DNS query
136pub const ENSRBADNAME = 167; /// Misformatted domain name
137pub const ENSRBADFAMILY = 168; /// Unsupported address family
138pub const ENSRBADRESP = 169; /// Misformatted DNS reply
139pub const ENSRCONNREFUSED = 170; /// Could not contact DNS servers
140pub const ENSRTIMEOUT = 171; /// Timeout while contacting DNS servers
141pub const ENSROF = 172; /// End of file
142pub const ENSRFILE = 173; /// Error reading file
143pub const ENSRNOMEM = 174; /// Out of memory
144pub const ENSRDESTRUCTION = 175; /// Application terminated lookup
145pub const ENSRQUERYDOMAINTOOLONG = 176; /// Domain name is too long
146pub const ENSRCNAMELOOP = 177; /// Domain name is too long
std/os/linux_x86_64.zig+9-8
......@@ -370,14 +370,14 @@ pub const F_GETOWN_EX = 16;
370370
371371pub const F_GETOWNER_UIDS = 17;
372372
373pub inline fn syscall0(number: usize) -> usize {
373pub fn syscall0(number: usize) -> usize {
374374 asm volatile ("syscall"
375375 : [ret] "={rax}" (-> usize)
376376 : [number] "{rax}" (number)
377377 : "rcx", "r11")
378378}
379379
380pub inline fn syscall1(number: usize, arg1: usize) -> usize {
380pub fn syscall1(number: usize, arg1: usize) -> usize {
381381 asm volatile ("syscall"
382382 : [ret] "={rax}" (-> usize)
383383 : [number] "{rax}" (number),
......@@ -385,7 +385,7 @@ pub inline fn syscall1(number: usize, arg1: usize) -> usize {
385385 : "rcx", "r11")
386386}
387387
388pub inline fn syscall2(number: usize, arg1: usize, arg2: usize) -> usize {
388pub fn syscall2(number: usize, arg1: usize, arg2: usize) -> usize {
389389 asm volatile ("syscall"
390390 : [ret] "={rax}" (-> usize)
391391 : [number] "{rax}" (number),
......@@ -394,7 +394,7 @@ pub inline fn syscall2(number: usize, arg1: usize, arg2: usize) -> usize {
394394 : "rcx", "r11")
395395}
396396
397pub inline fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) -> usize {
397pub fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) -> usize {
398398 asm volatile ("syscall"
399399 : [ret] "={rax}" (-> usize)
400400 : [number] "{rax}" (number),
......@@ -404,7 +404,7 @@ pub inline fn syscall3(number: usize, arg1: usize, arg2: usize, arg3: usize) ->
404404 : "rcx", "r11")
405405}
406406
407pub inline fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize) -> usize {
407pub fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize) -> usize {
408408 asm volatile ("syscall"
409409 : [ret] "={rax}" (-> usize)
410410 : [number] "{rax}" (number),
......@@ -415,7 +415,7 @@ pub inline fn syscall4(number: usize, arg1: usize, arg2: usize, arg3: usize, arg
415415 : "rcx", "r11")
416416}
417417
418pub inline fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) -> usize {
418pub fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize, arg5: usize) -> usize {
419419 asm volatile ("syscall"
420420 : [ret] "={rax}" (-> usize)
421421 : [number] "{rax}" (number),
......@@ -427,7 +427,7 @@ pub inline fn syscall5(number: usize, arg1: usize, arg2: usize, arg3: usize, arg
427427 : "rcx", "r11")
428428}
429429
430pub inline fn syscall6(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize,
430pub fn syscall6(number: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize,
431431 arg5: usize, arg6: usize) -> usize
432432{
433433 asm volatile ("syscall"
......@@ -454,7 +454,8 @@ pub const msghdr = extern struct {
454454 msg_flags: i32,
455455};
456456
457pub const stat = extern struct {
457/// Renamed to Stat to not conflict with the stat function.
458pub const Stat = extern struct {
458459 dev: u64,
459460 ino: u64,
460461 nlink: usize,
std/os/path.zig+52-9
......@@ -8,6 +8,8 @@ const Allocator = mem.Allocator;
88const os = @import("index.zig");
99const math = @import("../math.zig");
1010const posix = os.posix;
11const c = @import("../c/index.zig");
12const cstr = @import("../cstr.zig");
1113
1214pub const sep = switch (builtin.os) {
1315 Os.windows => '\\',
......@@ -279,19 +281,60 @@ fn testRelative(from: []const u8, to: []const u8, expected_output: []const u8) {
279281 assert(mem.eql(u8, result, expected_output));
280282}
281283
284error AccessDenied;
285error FileNotFound;
286error NotSupported;
287error NotDir;
288error NameTooLong;
289error SymLinkLoop;
290error InputOutput;
291error Unexpected;
282292/// Return the canonicalized absolute pathname.
283293/// Expands all symbolic links and resolves references to `.`, `..`, and
284294/// extra `/` characters in ::pathname.
285295/// Caller must deallocate result.
286296pub fn real(allocator: &Allocator, pathname: []const u8) -> %[]u8 {
287 if (builtin.os == builtin.Os.windows) {
288 @compileError("TODO implement os.path.real for windows");
297 switch (builtin.os) {
298 Os.windows => @compileError("TODO implement os.path.real for windows"),
299 Os.darwin, Os.macosx, Os.ios => {
300 // TODO instead of calling the libc function here, port the implementation
301 // to Zig, and then remove the NameTooLong error possibility.
302 const pathname_buf = %return allocator.alloc(u8, pathname.len + 1);
303 defer allocator.free(pathname_buf);
304
305 const result_buf = %return allocator.alloc(u8, posix.PATH_MAX);
306 %defer allocator.free(result_buf);
307
308 mem.copy(u8, pathname_buf, pathname);
309 pathname_buf[pathname.len] = 0;
310
311 const err = posix.getErrno(posix.realpath(pathname_buf.ptr, result_buf.ptr));
312 if (err > 0) {
313 return switch (err) {
314 posix.EINVAL => unreachable,
315 posix.EBADF => unreachable,
316 posix.EFAULT => unreachable,
317 posix.EACCES => error.AccessDenied,
318 posix.ENOENT => error.FileNotFound,
319 posix.ENOTSUP => error.NotSupported,
320 posix.ENOTDIR => error.NotDir,
321 posix.ENAMETOOLONG => error.NameTooLong,
322 posix.ELOOP => error.SymLinkLoop,
323 posix.EIO => error.InputOutput,
324 else => error.Unexpected,
325 };
326 }
327 return cstr.toSlice(result_buf.ptr);
328 },
329 Os.linux => {
330 const fd = %return os.posixOpen(pathname, posix.O_PATH|posix.O_NONBLOCK|posix.O_CLOEXEC, 0, allocator);
331 defer os.posixClose(fd);
332
333 var buf: ["/proc/self/fd/-2147483648".len]u8 = undefined;
334 const proc_path = fmt.bufPrint(buf[0..], "/proc/self/fd/{}", fd);
335
336 return os.readLink(allocator, proc_path);
337 },
338 else => @compileError("TODO implement os.path.real for " ++ @enumTagName(builtin.os)),
289339 }
290 const fd = %return os.posixOpen(pathname, posix.O_PATH|posix.O_NONBLOCK|posix.O_CLOEXEC, 0, allocator);
291 defer os.posixClose(fd);
292
293 var buf: ["/proc/self/fd/-2147483648".len]u8 = undefined;
294 const proc_path = fmt.bufPrint(buf[0..], "/proc/self/fd/{}", fd);
295
296 return os.readLink(allocator, proc_path);
297340}
std/special/builtin.zig+7-2
......@@ -30,16 +30,21 @@ export fn __stack_chk_fail() {
3030 @panic("stack smashing detected");
3131}
3232
33const math = @import("../math/index.zig");
34
3335export fn fmodf(x: f32, y: f32) -> f32 { generic_fmod(f32, x, y) }
3436export fn fmod(x: f64, y: f64) -> f64 { generic_fmod(f64, x, y) }
3537
36const Log2Int = @import("../math/index.zig").Log2Int;
38// TODO add intrinsics for these (and probably the double version too)
39// and have the math stuff use the intrinsic. same as @mod and @rem
40export fn floorf(x: f32) -> f32 { math.floor(x) }
41export fn ceilf(x: f32) -> f32 { math.ceil(x) }
3742
3843fn generic_fmod(comptime T: type, x: T, y: T) -> T {
3944 @setDebugSafety(this, false);
4045
4146 const uint = @IntType(false, T.bit_count);
42 const log2uint = Log2Int(uint);
47 const log2uint = math.Log2Int(uint);
4348 const digits = if (T == f32) 23 else 52;
4449 const exp_bits = if (T == f32) 9 else 12;
4550 const bits_minus_1 = T.bit_count - 1;
std/special/compiler_rt/comparetf2.zig+25-1
......@@ -18,7 +18,13 @@ const significandMask = implicitBit - 1;
1818const exponentMask = absMask ^ significandMask;
1919const infRep = exponentMask;
2020
21const builtin = @import("builtin");
22const is_test = builtin.is_test;
23
2124export fn __letf2(a: f128, b: f128) -> c_int {
25 @setDebugSafety(this, is_test);
26 @setGlobalLinkage(__letf2, builtin.GlobalLinkage.LinkOnce);
27
2228 const aInt = @bitCast(rep_t, a);
2329 const bInt = @bitCast(rep_t, b);
2430
......@@ -58,7 +64,11 @@ export fn __letf2(a: f128, b: f128) -> c_int {
5864
5965// Alias for libgcc compatibility
6066// TODO https://github.com/zig-lang/zig/issues/420
61export fn __cmptf2(a: f128, b: f128) -> c_int { __letf2(a, b) }
67export fn __cmptf2(a: f128, b: f128) -> c_int {
68 @setGlobalLinkage(__cmptf2, builtin.GlobalLinkage.LinkOnce);
69 @setDebugSafety(this, is_test);
70 return __letf2(a, b);
71}
6272
6373// TODO https://github.com/zig-lang/zig/issues/305
6474// and then make the return types of some of these functions the enum instead of c_int
......@@ -68,6 +78,9 @@ const GE_GREATER = c_int(1);
6878const GE_UNORDERED = c_int(-1); // Note: different from LE_UNORDERED
6979
7080export fn __getf2(a: f128, b: f128) -> c_int {
81 @setGlobalLinkage(__getf2, builtin.GlobalLinkage.LinkOnce);
82 @setDebugSafety(this, is_test);
83
7184 const aInt = @bitCast(srep_t, a);
7285 const bInt = @bitCast(srep_t, b);
7386 const aAbs = @bitCast(rep_t, aInt) & absMask;
......@@ -95,6 +108,9 @@ export fn __getf2(a: f128, b: f128) -> c_int {
95108}
96109
97110export fn __unordtf2(a: f128, b: f128) -> c_int {
111 @setGlobalLinkage(__unordtf2, builtin.GlobalLinkage.LinkOnce);
112 @setDebugSafety(this, is_test);
113
98114 const aAbs = @bitCast(rep_t, a) & absMask;
99115 const bAbs = @bitCast(rep_t, b) & absMask;
100116 return c_int(aAbs > infRep or bAbs > infRep);
......@@ -103,17 +119,25 @@ export fn __unordtf2(a: f128, b: f128) -> c_int {
103119// The following are alternative names for the preceding routines.
104120
105121export fn __eqtf2(a: f128, b: f128) -> c_int {
122 @setGlobalLinkage(__eqtf2, builtin.GlobalLinkage.LinkOnce);
123 @setDebugSafety(this, is_test);
106124 return __letf2(a, b);
107125}
108126
109127export fn __lttf2(a: f128, b: f128) -> c_int {
128 @setGlobalLinkage(__lttf2, builtin.GlobalLinkage.LinkOnce);
129 @setDebugSafety(this, is_test);
110130 return __letf2(a, b);
111131}
112132
113133export fn __netf2(a: f128, b: f128) -> c_int {
134 @setGlobalLinkage(__netf2, builtin.GlobalLinkage.LinkOnce);
135 @setDebugSafety(this, is_test);
114136 return __letf2(a, b);
115137}
116138
117139export fn __gttf2(a: f128, b: f128) -> c_int {
140 @setGlobalLinkage(__gttf2, builtin.GlobalLinkage.LinkOnce);
141 @setDebugSafety(this, is_test);
118142 return __getf2(a, b);
119143}
std/special/compiler_rt/fixunsdfdi.zig+1
......@@ -1,6 +1,7 @@
11const fixuint = @import("fixuint.zig").fixuint;
22
33export fn __fixunsdfdi(a: f64) -> u64 {
4 @setGlobalLinkage(__fixunsdfdi, @import("builtin").GlobalLinkage.LinkOnce);
45 return fixuint(f64, u64, a);
56}
67
std/special/compiler_rt/fixunsdfsi.zig+1
......@@ -1,6 +1,7 @@
11const fixuint = @import("fixuint.zig").fixuint;
22
33export fn __fixunsdfsi(a: f64) -> u32 {
4 @setGlobalLinkage(__fixunsdfsi, @import("builtin").GlobalLinkage.LinkOnce);
45 return fixuint(f64, u32, a);
56}
67
std/special/compiler_rt/fixunsdfti.zig+1
......@@ -1,6 +1,7 @@
11const fixuint = @import("fixuint.zig").fixuint;
22
33export fn __fixunsdfti(a: f64) -> u128 {
4 @setGlobalLinkage(__fixunsdfti, @import("builtin").GlobalLinkage.LinkOnce);
45 return fixuint(f64, u128, a);
56}
67
std/special/compiler_rt/fixunssfdi.zig+1
......@@ -1,6 +1,7 @@
11const fixuint = @import("fixuint.zig").fixuint;
22
33export fn __fixunssfdi(a: f32) -> u64 {
4 @setGlobalLinkage(__fixunssfdi, @import("builtin").GlobalLinkage.LinkOnce);
45 return fixuint(f32, u64, a);
56}
67
std/special/compiler_rt/fixunssfsi.zig+1
......@@ -1,6 +1,7 @@
11const fixuint = @import("fixuint.zig").fixuint;
22
33export fn __fixunssfsi(a: f32) -> u32 {
4 @setGlobalLinkage(__fixunssfsi, @import("builtin").GlobalLinkage.LinkOnce);
45 return fixuint(f32, u32, a);
56}
67
std/special/compiler_rt/fixunssfti.zig+1
......@@ -1,6 +1,7 @@
11const fixuint = @import("fixuint.zig").fixuint;
22
33export fn __fixunssfti(a: f32) -> u128 {
4 @setGlobalLinkage(__fixunssfti, @import("builtin").GlobalLinkage.LinkOnce);
45 return fixuint(f32, u128, a);
56}
67
std/special/compiler_rt/fixunstfdi.zig+1
......@@ -1,6 +1,7 @@
11const fixuint = @import("fixuint.zig").fixuint;
22
33export fn __fixunstfdi(a: f128) -> u64 {
4 @setGlobalLinkage(__fixunstfdi, @import("builtin").GlobalLinkage.LinkOnce);
45 return fixuint(f128, u64, a);
56}
67
std/special/compiler_rt/fixunstfsi.zig+1
......@@ -1,6 +1,7 @@
11const fixuint = @import("fixuint.zig").fixuint;
22
33export fn __fixunstfsi(a: f128) -> u32 {
4 @setGlobalLinkage(__fixunstfsi, @import("builtin").GlobalLinkage.LinkOnce);
45 return fixuint(f128, u32, a);
56}
67
std/special/compiler_rt/fixunstfti.zig+1
......@@ -1,6 +1,7 @@
11const fixuint = @import("fixuint.zig").fixuint;
22
33export fn __fixunstfti(a: f128) -> u128 {
4 @setGlobalLinkage(__fixunstfti, @import("builtin").GlobalLinkage.LinkOnce);
45 return fixuint(f128, u128, a);
56}
67
std/special/compiler_rt/index.zig+6
......@@ -23,11 +23,13 @@ const __udivmoddi4 = @import("udivmoddi4.zig").__udivmoddi4;
2323
2424export fn __udivdi3(a: u64, b: u64) -> u64 {
2525 @setDebugSafety(this, is_test);
26 @setGlobalLinkage(__udivdi3, builtin.GlobalLinkage.LinkOnce);
2627 return __udivmoddi4(a, b, null);
2728}
2829
2930export fn __umoddi3(a: u64, b: u64) -> u64 {
3031 @setDebugSafety(this, is_test);
32 @setGlobalLinkage(__umoddi3, builtin.GlobalLinkage.LinkOnce);
3133
3234 var r: u64 = undefined;
3335 _ = __udivmoddi4(a, b, &r);
......@@ -63,6 +65,7 @@ export nakedcc fn __aeabi_uidivmod() {
6365 @setDebugSafety(this, false);
6466
6567 if (comptime isArmArch()) {
68 @setGlobalLinkage(__aeabi_uidivmod, builtin.GlobalLinkage.LinkOnce);
6669 asm volatile (
6770 \\ push { lr }
6871 \\ sub sp, sp, #4
......@@ -80,6 +83,7 @@ export nakedcc fn __aeabi_uidivmod() {
8083
8184export fn __udivmodsi4(a: u32, b: u32, rem: &u32) -> u32 {
8285 @setDebugSafety(this, is_test);
86 @setGlobalLinkage(__udivmodsi4, builtin.GlobalLinkage.LinkOnce);
8387
8488 const d = __udivsi3(a, b);
8589 *rem = u32(i32(a) -% (i32(d) * i32(b)));
......@@ -92,12 +96,14 @@ export fn __udivmodsi4(a: u32, b: u32, rem: &u32) -> u32 {
9296
9397export fn __aeabi_uidiv(n: u32, d: u32) -> u32 {
9498 @setDebugSafety(this, is_test);
99 @setGlobalLinkage(__aeabi_uidiv, builtin.GlobalLinkage.LinkOnce);
95100
96101 return __udivsi3(n, d);
97102}
98103
99104export fn __udivsi3(n: u32, d: u32) -> u32 {
100105 @setDebugSafety(this, is_test);
106 @setGlobalLinkage(__udivsi3, builtin.GlobalLinkage.LinkOnce);
101107
102108 const n_uword_bits: c_uint = u32.bit_count;
103109 // special cases
std/special/compiler_rt/udivmoddi4.zig+3
......@@ -1,6 +1,9 @@
11const udivmod = @import("udivmod.zig").udivmod;
2const builtin = @import("builtin");
23
34export fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?&u64) -> u64 {
5 @setDebugSafety(this, builtin.is_test);
6 @setGlobalLinkage(__udivmoddi4, builtin.GlobalLinkage.LinkOnce);
47 return udivmod(u64, a, b, maybe_rem);
58}
69
std/special/compiler_rt/udivmodti4.zig+3
......@@ -1,6 +1,9 @@
11const udivmod = @import("udivmod.zig").udivmod;
2const builtin = @import("builtin");
23
34export fn __udivmodti4(a: u128, b: u128, maybe_rem: ?&u128) -> u128 {
5 @setDebugSafety(this, builtin.is_test);
6 @setGlobalLinkage(__udivmodti4, builtin.GlobalLinkage.LinkOnce);
47 return udivmod(u128, a, b, maybe_rem);
58}
69
std/special/compiler_rt/udivti3.zig+3
......@@ -1,5 +1,8 @@
11const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4;
2const builtin = @import("builtin");
23
34export fn __udivti3(a: u128, b: u128) -> u128 {
5 @setDebugSafety(this, builtin.is_test);
6 @setGlobalLinkage(__udivti3, builtin.GlobalLinkage.LinkOnce);
47 return __udivmodti4(a, b, null);
58}
std/special/compiler_rt/umodti3.zig+3
......@@ -1,6 +1,9 @@
11const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4;
2const builtin = @import("builtin");
23
34export fn __umodti3(a: u128, b: u128) -> u128 {
5 @setDebugSafety(this, builtin.is_test);
6 @setGlobalLinkage(__umodti3, builtin.GlobalLinkage.LinkOnce);
47 var r: u128 = undefined;
58 _ = __udivmodti4(a, b, &r);
69 return r;
test/cases/asm.zig+2-2
......@@ -2,7 +2,7 @@ const config = @import("builtin");
22const assert = @import("std").debug.assert;
33
44comptime {
5 if (config.arch == config.Arch.x86_64) {
5 if (config.arch == config.Arch.x86_64 and config.os == config.Os.linux) {
66 asm volatile (
77 \\.globl aoeu;
88 \\.type aoeu, @function;
......@@ -12,7 +12,7 @@ comptime {
1212}
1313
1414test "module level assembly" {
15 if (config.arch == config.Arch.x86_64) {
15 if (config.arch == config.Arch.x86_64 and config.os == config.Os.linux) {
1616 assert(aoeu() == 1234);
1717 }
1818}
test/cases/switch.zig+3-3
......@@ -72,7 +72,7 @@ fn nonConstSwitch(foo: SwitchStatmentFoo) {
7272 SwitchStatmentFoo.C => 3,
7373 SwitchStatmentFoo.D => 4,
7474 };
75 if (val != 3) unreachable;
75 assert(val == 3);
7676}
7777const SwitchStatmentFoo = enum {
7878 A,
......@@ -95,10 +95,10 @@ const SwitchProngWithVarEnum = enum {
9595fn switchProngWithVarFn(a: &const SwitchProngWithVarEnum) {
9696 switch(*a) {
9797 SwitchProngWithVarEnum.One => |x| {
98 if (x != 13) unreachable;
98 assert(x == 13);
9999 },
100100 SwitchProngWithVarEnum.Two => |x| {
101 if (x != 13.0) unreachable;
101 assert(x == 13.0);
102102 },
103103 SwitchProngWithVarEnum.Meh => |x| {
104104 const v: void = x;