tbb-commits
Threads by month
- ----- 2025 -----
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
July 2019
- 2 participants
- 76 discussions

[tor-browser-build/master] Merge remote-tracking branch 'boklm/bug_30585_v2'
by gk@torproject.org 31 Jul '19
by gk@torproject.org 31 Jul '19
31 Jul '19
commit 7b6444dd34d7a9e32d619c194e078464529fd5c1
Merge: 525e93a 4c2b3a9
Author: Georg Koppen <gk(a)torproject.org>
Date: Wed Jul 31 09:27:04 2019 +0000
Merge remote-tracking branch 'boklm/bug_30585_v2'
keyring/clang.gpg | Bin 0 -> 7186 bytes
projects/clang/build | 45 ++
projects/clang/config | 45 ++
projects/clang/win-patches/llvm-objcopy-1.patch | 27 +
projects/clang/win-patches/llvm-objcopy-10.patch | 28 +
projects/clang/win-patches/llvm-objcopy-11.patch | 377 +++++++++++++
projects/clang/win-patches/llvm-objcopy-12.patch | 43 ++
projects/clang/win-patches/llvm-objcopy-2.patch | 665 +++++++++++++++++++++++
projects/clang/win-patches/llvm-objcopy-3.patch | 160 ++++++
projects/clang/win-patches/llvm-objcopy-4.patch | 222 ++++++++
projects/clang/win-patches/llvm-objcopy-5.patch | 61 +++
projects/clang/win-patches/llvm-objcopy-6.patch | 242 +++++++++
projects/clang/win-patches/llvm-objcopy-7.patch | 224 ++++++++
projects/clang/win-patches/llvm-objcopy-8.patch | 330 +++++++++++
projects/clang/win-patches/llvm-objcopy-9.patch | 260 +++++++++
15 files changed, 2729 insertions(+)
1
0

[tor-browser-build/master] Bug 30585: Provide clang 8 for Tor Browser 9
by gk@torproject.org 31 Jul '19
by gk@torproject.org 31 Jul '19
31 Jul '19
commit 4c2b3a98e04605ce7fcbd1c2c7c4864c6a5125a2
Author: Georg Koppen <gk(a)torproject.org>
Date: Thu May 23 12:02:51 2019 +0000
Bug 30585: Provide clang 8 for Tor Browser 9
Adding a clang project is mainly motivated by getting our
mingw-w64/clang toolchain for Windows set up (#28716). Clang is a
separate project and will replace the llvm one (which we use in parallel
for now) as we don't want to build the clang part every time, say, the
ming-w64 commit gets updated. Moreover, we need a recent enough clang on
the host system for building at least the Stylo part in Firefox anyway.
The patches for Windows and general set up is more or less following
build/build-clang/clang-8-mingw.json on the mozilla-esr68 branch.
---
keyring/clang.gpg | Bin 0 -> 7186 bytes
projects/clang/build | 45 ++
projects/clang/config | 45 ++
projects/clang/win-patches/llvm-objcopy-1.patch | 27 +
projects/clang/win-patches/llvm-objcopy-10.patch | 28 +
projects/clang/win-patches/llvm-objcopy-11.patch | 377 +++++++++++++
projects/clang/win-patches/llvm-objcopy-12.patch | 43 ++
projects/clang/win-patches/llvm-objcopy-2.patch | 665 +++++++++++++++++++++++
projects/clang/win-patches/llvm-objcopy-3.patch | 160 ++++++
projects/clang/win-patches/llvm-objcopy-4.patch | 222 ++++++++
projects/clang/win-patches/llvm-objcopy-5.patch | 61 +++
projects/clang/win-patches/llvm-objcopy-6.patch | 242 +++++++++
projects/clang/win-patches/llvm-objcopy-7.patch | 224 ++++++++
projects/clang/win-patches/llvm-objcopy-8.patch | 330 +++++++++++
projects/clang/win-patches/llvm-objcopy-9.patch | 260 +++++++++
15 files changed, 2729 insertions(+)
diff --git a/keyring/clang.gpg b/keyring/clang.gpg
new file mode 100644
index 0000000..15f0d8a
Binary files /dev/null and b/keyring/clang.gpg differ
diff --git a/projects/clang/build b/projects/clang/build
new file mode 100644
index 0000000..50576b4
--- /dev/null
+++ b/projects/clang/build
@@ -0,0 +1,45 @@
+#!/bin/bash
+[% c("var/set_default_env") -%]
+distdir=/var/tmp/dist/[% project %]
+mkdir -p /var/tmp/dist
+tar -C /var/tmp/dist -xf [% c('input_files_by_name/cmake') %]
+export PATH="/var/tmp/dist/cmake/bin:$PATH"
+[% IF c("var/linux") %]
+ # We need a link to our GCC, otherwise the system cc gets used which points to
+ # /usr/bin/gcc.
+ [% pc('gcc', 'var/setup', { compiler_tarfile => c('input_files_by_name/gcc'),
+ hardened_gcc => 0 }) %]
+ ln -s gcc /var/tmp/dist/gcc/bin/cc
+[% END -%]
+mkdir -p /var/tmp/build
+cd /var/tmp/build
+tar -xf $rootdir/[% c('input_files_by_name/llvm') %]
+tar -xf $rootdir/[% c('input_files_by_name/cfe') %]
+tar -xf $rootdir/[% c('input_files_by_name/libcxx') %]
+tar -xf $rootdir/[% c('input_files_by_name/libcxxabi') %]
+tar -xf $rootdir/[% c('input_files_by_name/lld') %]
+tar -xf $rootdir/[% c('input_files_by_name/compiler-rt') %]
+mv llvm-* llvm
+mv cfe-* llvm/tools/clang
+mv libcxx-* llvm/projects/libcxx
+mv libcxxabi-* llvm/projects/libcxxabi
+mv lld-* llvm/tools/lld
+mv compiler-rt-* llvm/projects/compiler-rt
+[% IF c("var/windows") -%]
+ # Patch order is important here
+ for i in {1..12}
+ do git apply $rootdir/win-patches/llvm-objcopy-$i.patch
+ done
+[% END %]
+cd llvm
+export LLVM_HOME=$(pwd)
+mkdir build
+cd build
+cmake .. -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=$distdir -DCMAKE_BUILD_TYPE:STRING=Release $LLVM_HOME
+make -j[% c("buildconf/num_procs") %]
+make install
+cd /var/tmp/dist
+[% c('tar', {
+ tar_src => [ project ],
+ tar_args => '-czf ' _ dest_dir _ '/' _ c('filename'),
+ }) %]
diff --git a/projects/clang/config b/projects/clang/config
new file mode 100644
index 0000000..f439cf7
--- /dev/null
+++ b/projects/clang/config
@@ -0,0 +1,45 @@
+# vim: filetype=yaml sw=2
+version: 8.0.0
+filename: '[% project %]-[% c("version") %]-[% c("var/build_id") %].tar.gz'
+gpg_keyring: clang.gpg
+sig_ext: sig
+
+var:
+ container:
+ use_container: 1
+
+targets:
+ windows:
+ var:
+ arch_deps:
+ # We use git to apply patches
+ - git
+
+
+input_files:
+ - project: container-image
+ - name: '[% c("var/compiler") %]'
+ project: '[% c("var/compiler") %]'
+ enable: '[% c("var/linux") %]'
+ - project: cmake
+ name: cmake
+ - URL: 'https://releases.llvm.org/[% c("version") %]/llvm-[% c("version") %].src.tar.xz'
+ name: llvm
+ file_gpg_id: 1
+ - URL: 'https://releases.llvm.org/[% c("version") %]/cfe-[% c("version") %].src.tar.xz'
+ name: cfe
+ file_gpg_id: 1
+ - URL: 'https://releases.llvm.org/[% c("version") %]/libcxx-[% c("version") %].src.tar.xz'
+ name: libcxx
+ file_gpg_id: 1
+ - URL: 'https://releases.llvm.org/[% c("version") %]/libcxxabi-[% c("version") %].src.tar.xz'
+ name: libcxxabi
+ file_gpg_id: 1
+ - URL: 'https://releases.llvm.org/[% c("version") %]/lld-[% c("version") %].src.tar.xz'
+ name: lld
+ file_gpg_id: 1
+ - URL: 'https://releases.llvm.org/[% c("version") %]/compiler-rt-[% c("version") %].src.tar.xz'
+ name: compiler-rt
+ file_gpg_id: 1
+ - filename: win-patches
+ enable: '[% c("var/windows") %]'
diff --git a/projects/clang/win-patches/llvm-objcopy-1.patch b/projects/clang/win-patches/llvm-objcopy-1.patch
new file mode 100644
index 0000000..9c9f250
--- /dev/null
+++ b/projects/clang/win-patches/llvm-objcopy-1.patch
@@ -0,0 +1,27 @@
+From a495c9ae6fb3367e6b59d8d245273ed3669754f0 Mon Sep 17 00:00:00 2001
+From: Martin Storsjo <martin(a)martin.st>
+Date: Sat, 19 Jan 2019 19:42:23 +0000
+Subject: [PATCH] [llvm-objcopy] [COFF] Remove a superfluous namespace
+ qualification. NFC.
+
+git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351658 91177308-0d34-0410-b5e6-96231b3b80d8
+---
+ tools/llvm-objcopy/COFF/COFFObjcopy.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+index ceebf600b3a..437dccbd3d5 100644
+--- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+@@ -78,7 +78,7 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
+ }
+
+ void executeObjcopyOnBinary(const CopyConfig &Config,
+- object::COFFObjectFile &In, Buffer &Out) {
++ COFFObjectFile &In, Buffer &Out) {
+ COFFReader Reader(In);
+ Expected<std::unique_ptr<Object>> ObjOrErr = Reader.create();
+ if (!ObjOrErr)
+--
+2.17.1
+
diff --git a/projects/clang/win-patches/llvm-objcopy-10.patch b/projects/clang/win-patches/llvm-objcopy-10.patch
new file mode 100644
index 0000000..4aca911
--- /dev/null
+++ b/projects/clang/win-patches/llvm-objcopy-10.patch
@@ -0,0 +1,28 @@
+From 1284ee3c47bab17ec081b5169633aea4f8abfd30 Mon Sep 17 00:00:00 2001
+From: Martin Storsjo <martin(a)martin.st>
+Date: Wed, 23 Jan 2019 09:12:53 +0000
+Subject: [PATCH] [llvm-objcopy] [COFF] Clear the unwritten tail of
+ coff_section::Header::Name
+
+This should fix the add-gnu-debuglink test on all buildbots.
+
+git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351934 91177308-0d34-0410-b5e6-96231b3b80d8
+---
+ tools/llvm-objcopy/COFF/Writer.cpp | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.cpp b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
+index 05e46291c39..db897e2ff33 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Writer.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
+@@ -121,6 +121,7 @@ size_t COFFWriter::finalizeStringTable() {
+
+ for (auto &S : Obj.getMutableSections()) {
+ if (S.Name.size() > COFF::NameSize) {
++ memset(S.Header.Name, 0, sizeof(S.Header.Name));
+ snprintf(S.Header.Name, sizeof(S.Header.Name), "/%d",
+ (int)StrTabBuilder.getOffset(S.Name));
+ } else {
+--
+2.17.1
+
diff --git a/projects/clang/win-patches/llvm-objcopy-11.patch b/projects/clang/win-patches/llvm-objcopy-11.patch
new file mode 100644
index 0000000..9149b80
--- /dev/null
+++ b/projects/clang/win-patches/llvm-objcopy-11.patch
@@ -0,0 +1,377 @@
+From 74c7d422cba163635394ec32f2b243b1de502a18 Mon Sep 17 00:00:00 2001
+From: Martin Storsjo <martin(a)martin.st>
+Date: Wed, 23 Jan 2019 11:54:51 +0000
+Subject: [PATCH] [llvm-objcopy] [COFF] Fix handling of aux symbols for big
+ objects
+
+The aux symbols were stored in an opaque std::vector<uint8_t>,
+with contents interpreted according to the rest of the symbol.
+
+All aux symbol types but one fit in 18 bytes (sizeof(coff_symbol16)),
+and if written to a bigobj, two extra padding bytes are written (as
+sizeof(coff_symbol32) is 20). In the storage agnostic intermediate
+representation, store the aux symbols as a series of coff_symbol16
+sized opaque blobs. (In practice, all such aux symbols only consist
+of one aux symbol, so this is more flexible than what reality needs.)
+
+The special case is the file aux symbols, which are written in
+potentially more than one aux symbol slot, without any padding,
+as one single long string. This can't be stored in the same opaque
+vector of fixed sized aux symbol entries. The file aux symbols will
+occupy a different number of aux symbol slots depending on the type
+of output object file. As nothing in the intermediate process needs
+to have accurate raw symbol indices, updating that is moved into the
+writer class.
+
+Differential Revision: https://reviews.llvm.org/D57009
+
+git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351947 91177308-0d34-0410-b5e6-96231b3b80d8
+---
+ .../llvm-objcopy/COFF/Inputs/bigobj.o.gz | Bin 0 -> 7841 bytes
+ test/tools/llvm-objcopy/COFF/bigobj.test | 35 +++++++++++++
+ .../llvm-objcopy/ELF/auto-remove-shndx.test | 2 +-
+ .../tools/llvm-objcopy/ELF/many-sections.test | 2 +-
+ test/tools/llvm-objcopy/ELF/remove-shndx.test | 2 +-
+ .../tools/llvm-objcopy/ELF/strict-no-add.test | 2 +-
+ .../llvm-objcopy/{ELF => }/Inputs/ungzip.py | 0
+ tools/llvm-objcopy/COFF/COFFObjcopy.cpp | 6 +--
+ tools/llvm-objcopy/COFF/Object.cpp | 6 +--
+ tools/llvm-objcopy/COFF/Object.h | 18 ++++++-
+ tools/llvm-objcopy/COFF/Reader.cpp | 21 ++++++--
+ tools/llvm-objcopy/COFF/Writer.cpp | 49 +++++++++++++-----
+ tools/llvm-objcopy/COFF/Writer.h | 2 +-
+ 13 files changed, 115 insertions(+), 30 deletions(-)
+ create mode 100644 test/tools/llvm-objcopy/COFF/Inputs/bigobj.o.gz
+ create mode 100644 test/tools/llvm-objcopy/COFF/bigobj.test
+ rename test/tools/llvm-objcopy/{ELF => }/Inputs/ungzip.py (100%)
+
+diff --git a/llvm/test/tools/llvm-objcopy/COFF/Inputs/bigobj.o.gz b/llvm/test/tools/llvm-objcopy/COFF/Inputs/bigobj.o.gz
+new file mode 100644
+index 0000000000000000000000000000000000000000..6435f4785ff76e0c6bca12f3e57bc6ad8888bece
+GIT binary patch
+literal 7841
+zcmb2|=3r3v^@w3&etUMmo^zoH`-kGKM_vfJsF<z%6+Sz#g6qq)pf0Hj#_r`4B7DML
+zW(h1l`+!x)t@&W-R@I~lyKmU3Ti&1Z=iKur;uBMy1MR!_ywlsouYY&-*4H1mU!Qw=
+z`RpIDkw;!V4(WOF_)B3`(Vt|~S>?L-b)Wx@^wig`HIMAw|N8V<v65oeyETs611{)_
+zm27RwTe)ENN|7SLgM~83N6}~qjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kinXb6mk
+zz-S1JhQMeDjE2By2#kinXb6mkz-S1JhQMeDjE2By2#kgRokHNw|D97mKRo|%+Z6Ym
+z*X{Ku$4#4*Vqm}gyYR^b^Sc?_E*<<cFE#Q=*rt6OBmJeLZ=aoe_u9R>-w!^l5biDe
+p{d@nvw*mU6<NG83=jxn4_wt_G?yUy#YeOF~KhH^=cj<;Y0{~9Br>p<~
+
+literal 0
+HcmV?d00001
+
+diff --git a/llvm/test/tools/llvm-objcopy/COFF/bigobj.test b/llvm/test/tools/llvm-objcopy/COFF/bigobj.test
+new file mode 100644
+index 00000000000..17968f12b8a
+--- /dev/null
++++ b/llvm/test/tools/llvm-objcopy/COFF/bigobj.test
+@@ -0,0 +1,35 @@
++RUN: %python %p/../Inputs/ungzip.py %p/Inputs/bigobj.o.gz > %t.in.o
++
++RUN: llvm-objdump -t %t.in.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-BIG,SYMBOLS-ORIG
++
++# Do a plain copy, to check that section numbers in symbols referring
++# to sections outside of the small object format are handled correctly.
++RUN: llvm-objcopy -R '.text$4' %t.in.o %t.small.o
++RUN: llvm-objdump -t %t.in.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-BIG,SYMBOLS-ORIG
++
++# Remove a section, making the section count fit into a small object.
++RUN: llvm-objcopy -R '.text$4' %t.in.o %t.small.o
++RUN: llvm-objdump -t %t.small.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-SMALL,SYMBOLS-REMOVED-SMALL
++
++# Add a .gnu_debuglink section, forcing the object back to big format.
++RUN: llvm-objcopy --add-gnu-debuglink=%t.in.o %t.small.o %t.big.o
++ llvm-objdump -t %t.big.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-BIG,SYMBOLS-REMOVED-BIG
++
++# In big object format, the .file symbol occupies one symbol table entry for
++# the auxillary data, but needs two entries in the small format, forcing the
++# raw symbol indices of later symbols to change.
++SYMBOLS: SYMBOL TABLE:
++SYMBOLS-NEXT: [ 0]{{.*}} (nx 1) {{.*}} .text
++SYMBOLS-NEXT: AUX scnlen
++SYMBOLS-SMALL-NEXT: [ 2]{{.*}} (nx 2) {{.*}} .file
++SYMBOLS-BIG-NEXT: [ 2]{{.*}} (nx 1) {{.*}} .file
++SYMBOLS-NEXT: AUX abcdefghijklmnopqrs
++SYMBOLS-SMALL-NEXT: [ 5]{{.*}} (nx 0) {{.*}} foo
++SYMBOLS-BIG-NEXT: [ 4]{{.*}} (nx 0) {{.*}} foo
++
++# Check that the section numbers outside of signed 16 bit int range
++# are represented properly. After removing one section, the section
++# numbers decrease.
++SYMBOLS-ORIG: [ 5](sec 65280){{.*}} symbol65280
++SYMBOLS-REMOVED-SMALL: [ 6](sec 65279){{.*}} symbol65280
++SYMBOLS-REMOVED-BIG: [ 5](sec 65279){{.*}} symbol65280
+diff --git a/llvm/test/tools/llvm-objcopy/ELF/auto-remove-shndx.test b/llvm/test/tools/llvm-objcopy/ELF/auto-remove-shndx.test
+index 5a23493fa94..8e6c788bf48 100644
+--- a/llvm/test/tools/llvm-objcopy/ELF/auto-remove-shndx.test
++++ b/llvm/test/tools/llvm-objcopy/ELF/auto-remove-shndx.test
+@@ -1,4 +1,4 @@
+-# RUN: %python %p/Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t
++# RUN: %python %p/../Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t
+ # RUN: llvm-objcopy -R .text -R s0 -R s1 -R s2 -R s3 -R s4 -R s5 -R s6 %t %t2
+ # RUN: llvm-readobj --sections %t2 | FileCheck --check-prefix=SECS %s
+
+diff --git a/llvm/test/tools/llvm-objcopy/ELF/many-sections.test b/llvm/test/tools/llvm-objcopy/ELF/many-sections.test
+index 57239f32e4a..1dd41cfb10c 100644
+--- a/llvm/test/tools/llvm-objcopy/ELF/many-sections.test
++++ b/llvm/test/tools/llvm-objcopy/ELF/many-sections.test
+@@ -1,4 +1,4 @@
+-RUN: %python %p/Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t
++RUN: %python %p/../Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t
+ RUN: llvm-objcopy %t %t2
+ RUN: llvm-readobj --file-headers %t2 | FileCheck --check-prefix=EHDR %s
+ RUN: llvm-readobj --sections %t2 | FileCheck --check-prefix=SECS %s
+diff --git a/llvm/test/tools/llvm-objcopy/ELF/remove-shndx.test b/llvm/test/tools/llvm-objcopy/ELF/remove-shndx.test
+index 6cc3a1a291f..53ca8e7f220 100644
+--- a/llvm/test/tools/llvm-objcopy/ELF/remove-shndx.test
++++ b/llvm/test/tools/llvm-objcopy/ELF/remove-shndx.test
+@@ -1,6 +1,6 @@
+ # This test checks to see that a .symtab_shndx section is added to any binary
+ # that needs it, even if the original was removed.
+-RUN: %python %p/Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t
++RUN: %python %p/../Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t
+ RUN: llvm-objcopy -R .symtab_shndx %t %t2
+ RUN: llvm-readobj --sections %t2 | FileCheck %s
+
+diff --git a/llvm/test/tools/llvm-objcopy/ELF/strict-no-add.test b/llvm/test/tools/llvm-objcopy/ELF/strict-no-add.test
+index 4f24df31bf9..348ab7c4fbd 100644
+--- a/llvm/test/tools/llvm-objcopy/ELF/strict-no-add.test
++++ b/llvm/test/tools/llvm-objcopy/ELF/strict-no-add.test
+@@ -1,7 +1,7 @@
+ # This test makes sure that sections added at the end that don't have symbols
+ # defined in them don't trigger the creation of a large index table.
+
+-RUN: %python %p/Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t.0
++RUN: %python %p/../Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t.0
+ RUN: cat %p/Inputs/alloc-symtab.o > %t
+ RUN: llvm-objcopy -R .text -R s0 -R s1 -R s2 -R s3 -R s4 -R s5 -R s6 %t.0 %t2
+ RUN: llvm-objcopy --add-section=.s0=%t --add-section=.s1=%t --add-section=.s2=%t %t2 %t2
+diff --git a/llvm/test/tools/llvm-objcopy/ELF/Inputs/ungzip.py b/llvm/test/tools/llvm-objcopy/Inputs/ungzip.py
+similarity index 100%
+rename from llvm/test/tools/llvm-objcopy/ELF/Inputs/ungzip.py
+rename to llvm/test/tools/llvm-objcopy/Inputs/ungzip.py
+diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+index 20adbe11e7a..64b4e79a4e0 100644
+--- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+@@ -37,7 +37,7 @@ static uint64_t getNextRVA(const Object &Obj) {
+ return 0;
+ const Section &Last = Obj.getSections().back();
+ return alignTo(Last.Header.VirtualAddress + Last.Header.VirtualSize,
+- Obj.PeHeader.SectionAlignment);
++ Obj.IsPE ? Obj.PeHeader.SectionAlignment : 1);
+ }
+
+ static uint32_t getCRC32(StringRef Data) {
+@@ -74,8 +74,8 @@ static void addGnuDebugLink(Object &Obj, StringRef DebugLinkFile) {
+ Sec.Name = ".gnu_debuglink";
+ Sec.Header.VirtualSize = Sec.getContents().size();
+ Sec.Header.VirtualAddress = StartRVA;
+- Sec.Header.SizeOfRawData =
+- alignTo(Sec.Header.VirtualSize, Obj.PeHeader.FileAlignment);
++ Sec.Header.SizeOfRawData = alignTo(Sec.Header.VirtualSize,
++ Obj.IsPE ? Obj.PeHeader.FileAlignment : 1);
+ // Sec.Header.PointerToRawData is filled in by the writer.
+ Sec.Header.PointerToRelocations = 0;
+ Sec.Header.PointerToLinenumbers = 0;
+diff --git a/llvm/tools/llvm-objcopy/COFF/Object.cpp b/llvm/tools/llvm-objcopy/COFF/Object.cpp
+index 8c382c1faef..0ad5a05a144 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Object.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Object.cpp
+@@ -26,12 +26,8 @@ void Object::addSymbols(ArrayRef<Symbol> NewSymbols) {
+
+ void Object::updateSymbols() {
+ SymbolMap = DenseMap<size_t, Symbol *>(Symbols.size());
+- size_t RawSymIndex = 0;
+- for (Symbol &Sym : Symbols) {
++ for (Symbol &Sym : Symbols)
+ SymbolMap[Sym.UniqueId] = &Sym;
+- Sym.RawIndex = RawSymIndex;
+- RawSymIndex += 1 + Sym.Sym.NumberOfAuxSymbols;
+- }
+ }
+
+ const Symbol *Object::findSymbol(size_t UniqueId) const {
+diff --git a/llvm/tools/llvm-objcopy/COFF/Object.h b/llvm/tools/llvm-objcopy/COFF/Object.h
+index afa272286ef..21475b06862 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Object.h
++++ b/llvm/tools/llvm-objcopy/COFF/Object.h
+@@ -66,10 +66,24 @@ private:
+ std::vector<uint8_t> OwnedContents;
+ };
+
++struct AuxSymbol {
++ AuxSymbol(ArrayRef<uint8_t> In) {
++ assert(In.size() == sizeof(Opaque));
++ std::copy(In.begin(), In.end(), Opaque);
++ }
++
++ ArrayRef<uint8_t> getRef() const {
++ return ArrayRef<uint8_t>(Opaque, sizeof(Opaque));
++ }
++
++ uint8_t Opaque[sizeof(object::coff_symbol16)];
++};
++
+ struct Symbol {
+ object::coff_symbol32 Sym;
+ StringRef Name;
+- std::vector<uint8_t> AuxData;
++ std::vector<AuxSymbol> AuxData;
++ StringRef AuxFile;
+ ssize_t TargetSectionId;
+ ssize_t AssociativeComdatTargetSectionId = 0;
+ Optional<size_t> WeakTargetSymbolId;
+@@ -132,7 +146,7 @@ private:
+
+ ssize_t NextSectionUniqueId = 1; // Allow a UniqueId 0 to mean undefined.
+
+- // Update SymbolMap and RawIndex in each Symbol.
++ // Update SymbolMap.
+ void updateSymbols();
+
+ // Update SectionMap and Index in each Section.
+diff --git a/llvm/tools/llvm-objcopy/COFF/Reader.cpp b/llvm/tools/llvm-objcopy/COFF/Reader.cpp
+index 87dd60a43cf..7270bbf94de 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Reader.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Reader.cpp
+@@ -107,9 +107,24 @@ Error COFFReader::readSymbols(Object &Obj, bool IsBigObj) const {
+ *reinterpret_cast<const coff_symbol16 *>(SymRef.getRawPtr()));
+ if (auto EC = COFFObj.getSymbolName(SymRef, Sym.Name))
+ return errorCodeToError(EC);
+- Sym.AuxData = COFFObj.getSymbolAuxData(SymRef);
+- assert((Sym.AuxData.size() %
+- (IsBigObj ? sizeof(coff_symbol32) : sizeof(coff_symbol16))) == 0);
++
++ ArrayRef<uint8_t> AuxData = COFFObj.getSymbolAuxData(SymRef);
++ size_t SymSize = IsBigObj ? sizeof(coff_symbol32) : sizeof(coff_symbol16);
++ assert(AuxData.size() == SymSize * SymRef.getNumberOfAuxSymbols());
++ // The auxillary symbols are structs of sizeof(coff_symbol16) each.
++ // In the big object format (where symbols are coff_symbol32), each
++ // auxillary symbol is padded with 2 bytes at the end. Copy each
++ // auxillary symbol to the Sym.AuxData vector. For file symbols,
++ // the whole range of aux symbols are interpreted as one null padded
++ // string instead.
++ if (SymRef.isFileRecord())
++ Sym.AuxFile = StringRef(reinterpret_cast<const char *>(AuxData.data()),
++ AuxData.size())
++ .rtrim('\0');
++ else
++ for (size_t I = 0; I < SymRef.getNumberOfAuxSymbols(); I++)
++ Sym.AuxData.push_back(AuxData.slice(I * SymSize, sizeof(AuxSymbol)));
++
+ // Find the unique id of the section
+ if (SymRef.getSectionNumber() <=
+ 0) // Special symbol (undefined/absolute/debug)
+diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.cpp b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
+index db897e2ff33..6e69c597217 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Writer.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
+@@ -55,7 +55,8 @@ Error COFFWriter::finalizeSymbolContents() {
+ if (Sym.Sym.NumberOfAuxSymbols == 1 &&
+ Sym.Sym.StorageClass == IMAGE_SYM_CLASS_STATIC) {
+ coff_aux_section_definition *SD =
+- reinterpret_cast<coff_aux_section_definition *>(Sym.AuxData.data());
++ reinterpret_cast<coff_aux_section_definition *>(
++ Sym.AuxData[0].Opaque);
+ uint32_t SDSectionNumber;
+ if (Sym.AssociativeComdatTargetSectionId == 0) {
+ // Not a comdat associative section; just set the Number field to
+@@ -79,7 +80,7 @@ Error COFFWriter::finalizeSymbolContents() {
+ // we want to set. Only >= 1 would be required, but only == 1 makes sense.
+ if (Sym.WeakTargetSymbolId && Sym.Sym.NumberOfAuxSymbols == 1) {
+ coff_aux_weak_external *WE =
+- reinterpret_cast<coff_aux_weak_external *>(Sym.AuxData.data());
++ reinterpret_cast<coff_aux_weak_external *>(Sym.AuxData[0].Opaque);
+ const Symbol *Target = Obj.findSymbol(*Sym.WeakTargetSymbolId);
+ if (Target == nullptr)
+ return createStringError(object_error::invalid_symbol_index,
+@@ -141,13 +142,26 @@ size_t COFFWriter::finalizeStringTable() {
+
+ template <class SymbolTy>
+ std::pair<size_t, size_t> COFFWriter::finalizeSymbolTable() {
+- size_t SymTabSize = Obj.getSymbols().size() * sizeof(SymbolTy);
+- for (const auto &S : Obj.getSymbols())
+- SymTabSize += S.AuxData.size();
+- return std::make_pair(SymTabSize, sizeof(SymbolTy));
++ size_t RawSymIndex = 0;
++ for (auto &S : Obj.getMutableSymbols()) {
++ // Symbols normally have NumberOfAuxSymbols set correctly all the time.
++ // For file symbols, we need to know the output file's symbol size to be
++ // able to calculate the number of slots it occupies.
++ if (!S.AuxFile.empty())
++ S.Sym.NumberOfAuxSymbols =
++ alignTo(S.AuxFile.size(), sizeof(SymbolTy)) / sizeof(SymbolTy);
++ S.RawIndex = RawSymIndex;
++ RawSymIndex += 1 + S.Sym.NumberOfAuxSymbols;
++ }
++ return std::make_pair(RawSymIndex * sizeof(SymbolTy), sizeof(SymbolTy));
+ }
+
+ Error COFFWriter::finalize(bool IsBigObj) {
++ size_t SymTabSize, SymbolSize;
++ std::tie(SymTabSize, SymbolSize) = IsBigObj
++ ? finalizeSymbolTable<coff_symbol32>()
++ : finalizeSymbolTable<coff_symbol16>();
++
+ if (Error E = finalizeRelocTargets())
+ return E;
+ if (Error E = finalizeSymbolContents())
+@@ -199,10 +213,6 @@ Error COFFWriter::finalize(bool IsBigObj) {
+ }
+
+ size_t StrTabSize = finalizeStringTable();
+- size_t SymTabSize, SymbolSize;
+- std::tie(SymTabSize, SymbolSize) = IsBigObj
+- ? finalizeSymbolTable<coff_symbol32>()
+- : finalizeSymbolTable<coff_symbol16>();
+
+ size_t PointerToSymbolTable = FileSize;
+ // StrTabSize <= 4 is the size of an empty string table, only consisting
+@@ -312,8 +322,23 @@ template <class SymbolTy> void COFFWriter::writeSymbolStringTables() {
+ copySymbol<SymbolTy, coff_symbol32>(*reinterpret_cast<SymbolTy *>(Ptr),
+ S.Sym);
+ Ptr += sizeof(SymbolTy);
+- std::copy(S.AuxData.begin(), S.AuxData.end(), Ptr);
+- Ptr += S.AuxData.size();
++ if (!S.AuxFile.empty()) {
++ // For file symbols, just write the string into the aux symbol slots,
++ // assuming that the unwritten parts are initialized to zero in the memory
++ // mapped file.
++ std::copy(S.AuxFile.begin(), S.AuxFile.end(), Ptr);
++ Ptr += S.Sym.NumberOfAuxSymbols * sizeof(SymbolTy);
++ } else {
++ // For other auxillary symbols, write their opaque payload into one symbol
++ // table slot each. For big object files, the symbols are larger than the
++ // opaque auxillary symbol struct and we leave padding at the end of each
++ // entry.
++ for (const AuxSymbol &AuxSym : S.AuxData) {
++ ArrayRef<uint8_t> Ref = AuxSym.getRef();
++ std::copy(Ref.begin(), Ref.end(), Ptr);
++ Ptr += sizeof(SymbolTy);
++ }
++ }
+ }
+ if (StrTabBuilder.getSize() > 4 || !Obj.IsPE) {
+ // Always write a string table in object files, even an empty one.
+diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.h b/llvm/tools/llvm-objcopy/COFF/Writer.h
+index 9b1cfa91d00..681a8d5e4a6 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Writer.h
++++ b/llvm/tools/llvm-objcopy/COFF/Writer.h
+@@ -30,11 +30,11 @@ class COFFWriter {
+ size_t SizeOfInitializedData;
+ StringTableBuilder StrTabBuilder;
+
++ template <class SymbolTy> std::pair<size_t, size_t> finalizeSymbolTable();
+ Error finalizeRelocTargets();
+ Error finalizeSymbolContents();
+ void layoutSections();
+ size_t finalizeStringTable();
+- template <class SymbolTy> std::pair<size_t, size_t> finalizeSymbolTable();
+
+ Error finalize(bool IsBigObj);
+
+--
+2.17.1
+
diff --git a/projects/clang/win-patches/llvm-objcopy-12.patch b/projects/clang/win-patches/llvm-objcopy-12.patch
new file mode 100644
index 0000000..35dec30
--- /dev/null
+++ b/projects/clang/win-patches/llvm-objcopy-12.patch
@@ -0,0 +1,43 @@
+From abacd83232acf69d7cbacd53fc2f9aae66c1a32e Mon Sep 17 00:00:00 2001
+From: Martin Storsjo <martin(a)martin.st>
+Date: Wed, 23 Jan 2019 11:54:55 +0000
+Subject: [PATCH] [llvm-objcopy] [COFF] Error out on use of unhandled options
+
+Prefer erroring out than silently not doing what was requested.
+
+Differential Revision: https://reviews.llvm.org/D57045
+
+git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351948 91177308-0d34-0410-b5e6-96231b3b80d8
+---
+ tools/llvm-objcopy/COFF/COFFObjcopy.cpp | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+index 64b4e79a4e0..b7b3d3cb629 100644
+--- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+@@ -170,6 +170,21 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
+ if (!Config.AddGnuDebugLink.empty())
+ addGnuDebugLink(Obj, Config.AddGnuDebugLink);
+
++ if (!Config.BuildIdLinkDir.empty() || Config.BuildIdLinkInput ||
++ Config.BuildIdLinkOutput || !Config.SplitDWO.empty() ||
++ !Config.SymbolsPrefix.empty() || !Config.AddSection.empty() ||
++ !Config.DumpSection.empty() || !Config.KeepSection.empty() ||
++ !Config.SymbolsToGlobalize.empty() || !Config.SymbolsToKeep.empty() ||
++ !Config.SymbolsToLocalize.empty() || !Config.SymbolsToWeaken.empty() ||
++ !Config.SymbolsToKeepGlobal.empty() || !Config.SectionsToRename.empty() ||
++ !Config.SymbolsToRename.empty() || Config.ExtractDWO ||
++ Config.KeepFileSymbols || Config.LocalizeHidden || Config.PreserveDates ||
++ Config.StripDWO || Config.StripNonAlloc || Config.StripSections ||
++ Config.Weaken || Config.DecompressDebugSections) {
++ return createStringError(llvm::errc::invalid_argument,
++ "Option not supported by llvm-objcopy for COFF");
++ }
++
+ return Error::success();
+ }
+
+--
+2.17.1
+
diff --git a/projects/clang/win-patches/llvm-objcopy-2.patch b/projects/clang/win-patches/llvm-objcopy-2.patch
new file mode 100644
index 0000000..41e7a94
--- /dev/null
+++ b/projects/clang/win-patches/llvm-objcopy-2.patch
@@ -0,0 +1,665 @@
+From 2ccafacb7ddd740054dbee06655749ebc55a4d86 Mon Sep 17 00:00:00 2001
+From: Martin Storsjo <martin(a)martin.st>
+Date: Sat, 19 Jan 2019 19:42:35 +0000
+Subject: [PATCH] [llvm-objcopy] [COFF] Add support for removing sections
+
+Differential Revision: https://reviews.llvm.org/D56683
+
+git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351660 91177308-0d34-0410-b5e6-96231b3b80d8
+---
+ .../llvm-objcopy/COFF/remove-section.test | 210 ++++++++++++++++++
+ tools/llvm-objcopy/COFF/COFFObjcopy.cpp | 10 +-
+ tools/llvm-objcopy/COFF/Object.cpp | 63 ++++++
+ tools/llvm-objcopy/COFF/Object.h | 27 ++-
+ tools/llvm-objcopy/COFF/Reader.cpp | 31 ++-
+ tools/llvm-objcopy/COFF/Writer.cpp | 68 ++++--
+ tools/llvm-objcopy/COFF/Writer.h | 1 +
+ 7 files changed, 391 insertions(+), 19 deletions(-)
+ create mode 100644 test/tools/llvm-objcopy/COFF/remove-section.test
+
+diff --git a/llvm/test/tools/llvm-objcopy/COFF/remove-section.test b/llvm/test/tools/llvm-objcopy/COFF/remove-section.test
+new file mode 100644
+index 00000000000..b3dfb0b98cb
+--- /dev/null
++++ b/llvm/test/tools/llvm-objcopy/COFF/remove-section.test
+@@ -0,0 +1,210 @@
++# RUN: yaml2obj %s > %t.in.o
++#
++# RUN: llvm-objdump -section-headers %t.in.o | FileCheck %s --check-prefixes=SECTIONS-PRE
++# RUN: llvm-objdump -t %t.in.o | FileCheck %s --check-prefixes=SYMBOLS-PRE
++#
++# RUN: llvm-objcopy -R .bss %t.in.o %t.remove-bss.o
++# RUN: llvm-objdump -section-headers %t.remove-bss.o | FileCheck %s --check-prefix=SECTIONS-REMOVE-BSS
++# RUN: llvm-objdump -t %t.remove-bss.o | FileCheck %s --check-prefix=SYMBOLS-REMOVE-BSS
++#
++# RUN: llvm-objcopy --remove-section .bss %t.in.o %t.cmp.o
++# RUN: cmp %t.remove-bss.o %t.cmp.o
++#
++# RUN: llvm-objcopy -R .text %t.in.o %t.remove-text.o
++# RUN: llvm-objdump -section-headers %t.remove-text.o | FileCheck %s --check-prefix=SECTIONS-REMOVE-TEXT
++# RUN: llvm-objdump -t %t.remove-text.o | FileCheck %s --check-prefix=SYMBOLS-REMOVE-TEXT
++#
++# RUN: not llvm-objcopy -R .comdat %t.in.o %t.remove-comdat.o 2>&1 | FileCheck %s --check-prefix=ERROR-RELOC
++#
++# RUN: llvm-objcopy -R .text -R .comdat %t.in.o %t.remove-text-comdat.o
++# RUN: llvm-objdump -section-headers %t.remove-text-comdat.o | FileCheck %s --check-prefix=SECTIONS-REMOVE-TEXT-COMDAT
++# RUN: llvm-objdump -t %t.remove-text-comdat.o | FileCheck %s --check-prefix=SYMBOLS-REMOVE-TEXT-COMDAT
++#
++#
++# SECTIONS-PRE: Sections:
++# SECTIONS-PRE-NEXT: Idx Name
++# SECTIONS-PRE-NEXT: 0 .text
++# SECTIONS-PRE-NEXT: 1 .bss
++# SECTIONS-PRE-NEXT: 2 .comdat
++# SECTIONS-PRE-NEXT: 3 .associative
++# SECTIONS-PRE-EMPTY:
++#
++# SYMBOLS-PRE: SYMBOL TABLE:
++# SYMBOLS-PRE-NEXT: {{.*}}(sec -1){{.*}} @feat.00
++# SYMBOLS-PRE-NEXT: {{.*}}(sec 1){{.*}} .text
++# SYMBOLS-PRE-NEXT: AUX scnlen {{.*}} assoc 1 comdat 0
++# SYMBOLS-PRE-NEXT: {{.*}}(sec 2){{.*}} .bss
++# SYMBOLS-PRE-NEXT: AUX scnlen {{.*}} assoc 2 comdat 0
++# SYMBOLS-PRE-NEXT: {{.*}}(sec 4){{.*}} .associative
++# SYMBOLS-PRE-NEXT: AUX scnlen {{.*}} assoc 3 comdat 5
++# SYMBOLS-PRE-NEXT: {{.*}}(sec 3){{.*}} .comdat
++# SYMBOLS-PRE-NEXT: AUX scnlen {{.*}} assoc 3 comdat 2
++# SYMBOLS-PRE-NEXT: {{.*}}(sec 3){{.*}} foo
++# SYMBOLS-PRE-NEXT: {{.*}}(sec 1){{.*}} main
++# SYMBOLS-PRE-EMPTY:
++#
++#
++# Removing the .bss section removes one symbol and its aux symbol,
++# and updates the section indices in symbols pointing to later
++# symbols, including the aux section defintitions.
++#
++# Testing that the absolute symbol @feat.00 survives the section number
++# mangling.
++#
++# SECTIONS-REMOVE-BSS: Sections:
++# SECTIONS-REMOVE-BSS-NEXT: Idx Name
++# SECTIONS-REMOVE-BSS-NEXT: 0 .text
++# SECTIONS-REMOVE-BSS-NEXT: 1 .comdat
++# SECTIONS-REMOVE-BSS-NEXT: 2 .associative
++# SECTIONS-REMOVE-BSS-EMPTY:
++#
++# SYMBOLS-REMOVE-BSS: SYMBOL TABLE:
++# SYMBOLS-REMOVE-BSS-NEXT: {{.*}}(sec -1){{.*}} @feat.00
++# SYMBOLS-REMOVE-BSS-NEXT: {{.*}}(sec 1){{.*}} .text
++# SYMBOLS-REMOVE-BSS-NEXT: AUX scnlen {{.*}} assoc 1 comdat 0
++# SYMBOLS-REMOVE-BSS-NEXT: {{.*}}(sec 3){{.*}} .associative
++# SYMBOLS-REMOVE-BSS-NEXT: AUX scnlen {{.*}} assoc 2 comdat 5
++# SYMBOLS-REMOVE-BSS-NEXT: {{.*}}(sec 2){{.*}} .comdat
++# SYMBOLS-REMOVE-BSS-NEXT: AUX scnlen {{.*}} assoc 2 comdat 2
++# SYMBOLS-REMOVE-BSS-NEXT: {{.*}}(sec 2){{.*}} foo
++# SYMBOLS-REMOVE-BSS-NEXT: {{.*}}(sec 1){{.*}} main
++# SYMBOLS-REMOVE-BSS-EMPTY:
++#
++#
++# Removing the .text section is ok and just removes the external symbol
++# referring to it.
++#
++# SECTIONS-REMOVE-TEXT: Sections:
++# SECTIONS-REMOVE-TEXT-NEXT: Idx Name
++# SECTIONS-REMOVE-TEXT-NEXT: 0 .bss
++# SECTIONS-REMOVE-TEXT-NEXT: 1 .comdat
++# SECTIONS-REMOVE-TEXT-NEXT: 2 .associative
++# SECTIONS-REMOVE-TEXT-EMPTY:
++#
++# SYMBOLS-REMOVE-TEXT: SYMBOL TABLE:
++# SYMBOLS-REMOVE-TEXT-NEXT: {{.*}}(sec -1){{.*}} @feat.00
++# SYMBOLS-REMOVE-TEXT-NEXT: {{.*}}(sec 1){{.*}} .bss
++# SYMBOLS-REMOVE-TEXT-NEXT: AUX scnlen {{.*}} assoc 1 comdat 0
++# SYMBOLS-REMOVE-TEXT-NEXT: {{.*}}(sec 3){{.*}} .associative
++# SYMBOLS-REMOVE-TEXT-NEXT: AUX scnlen {{.*}} assoc 2 comdat 5
++# SYMBOLS-REMOVE-TEXT-NEXT: {{.*}}(sec 2){{.*}} .comdat
++# SYMBOLS-REMOVE-TEXT-NEXT: AUX scnlen {{.*}} assoc 2 comdat 2
++# SYMBOLS-REMOVE-TEXT-NEXT: {{.*}}(sec 2){{.*}} foo
++# SYMBOLS-REMOVE-TEXT-EMPTY:
++#
++#
++# Removing the .comdat section fails, since the .text section has relocations
++# against it.
++#
++# ERROR-RELOC: Relocation target foo ({{.*}}) not found
++#
++#
++# Removing the .comdat section and .text (with a relocation against .comdat)
++# works, as it also removes the .associative section transitively.
++#
++# SECTIONS-REMOVE-TEXT-COMDAT: Sections:
++# SECTIONS-REMOVE-TEXT-COMDAT-NEXT: Idx Name
++# SECTIONS-REMOVE-TEXT-COMDAT-NEXT: 0 .bss
++# SECTIONS-REMOVE-TEXT-COMDAT-EMPTY:
++#
++# SYMBOLS-REMOVE-TEXT-COMDAT: SYMBOL TABLE:
++# SYMBOLS-REMOVE-TEXT-COMDAT-NEXT: {{.*}}(sec -1){{.*}} @feat.00
++# SYMBOLS-REMOVE-TEXT-COMDAT-NEXT: {{.*}}(sec 1){{.*}} .bss
++# SYMBOLS-REMOVE-TEXT-COMDAT-NEXT: AUX scnlen {{.*}} assoc 1 comdat 0
++# SYMBOLS-REMOVE-TEXT-COMDAT-EMPTY:
++
++--- !COFF
++header:
++ Machine: IMAGE_FILE_MACHINE_AMD64
++ Characteristics: [ ]
++sections:
++ - Name: .text
++ Characteristics: [ ]
++ Alignment: 4
++ SectionData: 488B0500000000C3
++ Relocations:
++ - VirtualAddress: 3
++ SymbolName: foo
++ Type: IMAGE_REL_AMD64_REL32
++ - Name: .bss
++ Characteristics: [ ]
++ Alignment: 4
++ SectionData: ''
++ - Name: .comdat
++ Characteristics: [ IMAGE_SCN_LNK_COMDAT ]
++ Alignment: 1
++ SectionData: '2A000000'
++ - Name: .associative
++ Characteristics: [ IMAGE_SCN_LNK_COMDAT ]
++ Alignment: 1
++ SectionData: '0000000000000000'
++symbols:
++ - Name: '@feat.00'
++ Value: 0
++ SectionNumber: -1
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_NULL
++ StorageClass: IMAGE_SYM_CLASS_STATIC
++ - Name: .text
++ Value: 0
++ SectionNumber: 1
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_NULL
++ StorageClass: IMAGE_SYM_CLASS_STATIC
++ SectionDefinition:
++ Length: 8
++ NumberOfRelocations: 1
++ NumberOfLinenumbers: 0
++ CheckSum: 583624169
++ Number: 1
++ - Name: .bss
++ Value: 0
++ SectionNumber: 2
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_NULL
++ StorageClass: IMAGE_SYM_CLASS_STATIC
++ SectionDefinition:
++ Length: 0
++ NumberOfRelocations: 0
++ NumberOfLinenumbers: 0
++ CheckSum: 0
++ Number: 2
++ - Name: .associative
++ Value: 0
++ SectionNumber: 4
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_NULL
++ StorageClass: IMAGE_SYM_CLASS_STATIC
++ SectionDefinition:
++ Length: 8
++ NumberOfRelocations: 0
++ NumberOfLinenumbers: 0
++ CheckSum: 0
++ Number: 3
++ Selection: IMAGE_COMDAT_SELECT_ASSOCIATIVE
++ - Name: .comdat
++ Value: 0
++ SectionNumber: 3
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_NULL
++ StorageClass: IMAGE_SYM_CLASS_STATIC
++ SectionDefinition:
++ Length: 4
++ NumberOfRelocations: 0
++ NumberOfLinenumbers: 0
++ CheckSum: 3482275674
++ Number: 3
++ Selection: IMAGE_COMDAT_SELECT_ANY
++ - Name: foo
++ Value: 0
++ SectionNumber: 3
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_NULL
++ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
++ - Name: main
++ Value: 0
++ SectionNumber: 1
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_NULL
++ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
++...
+diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+index 437dccbd3d5..dd2e4829218 100644
+--- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+@@ -27,9 +27,17 @@ using namespace object;
+ using namespace COFF;
+
+ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
++ // Perform the actual section removals.
++ Obj.removeSections([&Config](const Section &Sec) {
++ if (is_contained(Config.ToRemove, Sec.Name))
++ return true;
++
++ return false;
++ });
++
+ // StripAll removes all symbols and thus also removes all relocations.
+ if (Config.StripAll || Config.StripAllGNU)
+- for (Section &Sec : Obj.Sections)
++ for (Section &Sec : Obj.getMutableSections())
+ Sec.Relocs.clear();
+
+ // If we need to do per-symbol removals, initialize the Referenced field.
+diff --git a/llvm/tools/llvm-objcopy/COFF/Object.cpp b/llvm/tools/llvm-objcopy/COFF/Object.cpp
+index e58e161e7d2..e19cea6aa9d 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Object.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Object.cpp
+@@ -7,6 +7,7 @@
+ //===----------------------------------------------------------------------===//
+
+ #include "Object.h"
++#include "llvm/ADT/DenseSet.h"
+ #include <algorithm>
+
+ namespace llvm {
+@@ -64,6 +65,68 @@ Error Object::markSymbols() {
+ return Error::success();
+ }
+
++void Object::addSections(ArrayRef<Section> NewSections) {
++ for (Section S : NewSections) {
++ S.UniqueId = NextSectionUniqueId++;
++ Sections.emplace_back(S);
++ }
++ updateSections();
++}
++
++void Object::updateSections() {
++ SectionMap = DenseMap<ssize_t, Section *>(Sections.size());
++ size_t Index = 1;
++ for (Section &S : Sections) {
++ SectionMap[S.UniqueId] = &S;
++ S.Index = Index++;
++ }
++}
++
++const Section *Object::findSection(ssize_t UniqueId) const {
++ auto It = SectionMap.find(UniqueId);
++ if (It == SectionMap.end())
++ return nullptr;
++ return It->second;
++}
++
++void Object::removeSections(function_ref<bool(const Section &)> ToRemove) {
++ DenseSet<ssize_t> AssociatedSections;
++ auto RemoveAssociated = [&AssociatedSections](const Section &Sec) {
++ return AssociatedSections.count(Sec.UniqueId) == 1;
++ };
++ do {
++ DenseSet<ssize_t> RemovedSections;
++ Sections.erase(
++ std::remove_if(std::begin(Sections), std::end(Sections),
++ [ToRemove, &RemovedSections](const Section &Sec) {
++ bool Remove = ToRemove(Sec);
++ if (Remove)
++ RemovedSections.insert(Sec.UniqueId);
++ return Remove;
++ }),
++ std::end(Sections));
++ // Remove all symbols referring to the removed sections.
++ AssociatedSections.clear();
++ Symbols.erase(
++ std::remove_if(
++ std::begin(Symbols), std::end(Symbols),
++ [&RemovedSections, &AssociatedSections](const Symbol &Sym) {
++ // If there are sections that are associative to a removed
++ // section,
++ // remove those as well as nothing will include them (and we can't
++ // leave them dangling).
++ if (RemovedSections.count(Sym.AssociativeComdatTargetSectionId) ==
++ 1)
++ AssociatedSections.insert(Sym.TargetSectionId);
++ return RemovedSections.count(Sym.TargetSectionId) == 1;
++ }),
++ std::end(Symbols));
++ ToRemove = RemoveAssociated;
++ } while (!AssociatedSections.empty());
++ updateSections();
++ updateSymbols();
++}
++
+ } // end namespace coff
+ } // end namespace objcopy
+ } // end namespace llvm
+diff --git a/llvm/tools/llvm-objcopy/COFF/Object.h b/llvm/tools/llvm-objcopy/COFF/Object.h
+index e6147c40b7c..a73e93620d3 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Object.h
++++ b/llvm/tools/llvm-objcopy/COFF/Object.h
+@@ -37,12 +37,16 @@ struct Section {
+ ArrayRef<uint8_t> Contents;
+ std::vector<Relocation> Relocs;
+ StringRef Name;
++ ssize_t UniqueId;
++ size_t Index;
+ };
+
+ struct Symbol {
+ object::coff_symbol32 Sym;
+ StringRef Name;
+- ArrayRef<uint8_t> AuxData;
++ std::vector<uint8_t> AuxData;
++ ssize_t TargetSectionId;
++ ssize_t AssociativeComdatTargetSectionId = 0;
+ size_t UniqueId;
+ size_t RawIndex;
+ bool Referenced;
+@@ -61,7 +65,6 @@ struct Object {
+ uint32_t BaseOfData = 0; // pe32plus_header lacks this field.
+
+ std::vector<object::data_directory> DataDirectories;
+- std::vector<Section> Sections;
+
+ ArrayRef<Symbol> getSymbols() const { return Symbols; }
+ // This allows mutating individual Symbols, but not mutating the list
+@@ -79,14 +82,34 @@ struct Object {
+ // all sections.
+ Error markSymbols();
+
++ ArrayRef<Section> getSections() const { return Sections; }
++ // This allows mutating individual Sections, but not mutating the list
++ // of symbols itself.
++ iterator_range<std::vector<Section>::iterator> getMutableSections() {
++ return make_range(Sections.begin(), Sections.end());
++ }
++
++ const Section *findSection(ssize_t UniqueId) const;
++
++ void addSections(ArrayRef<Section> NewSections);
++ void removeSections(function_ref<bool(const Section &)> ToRemove);
++
+ private:
+ std::vector<Symbol> Symbols;
+ DenseMap<size_t, Symbol *> SymbolMap;
+
+ size_t NextSymbolUniqueId = 0;
+
++ std::vector<Section> Sections;
++ DenseMap<ssize_t, Section *> SectionMap;
++
++ ssize_t NextSectionUniqueId = 1; // Allow a UniqueId 0 to mean undefined.
++
+ // Update SymbolMap and RawIndex in each Symbol.
+ void updateSymbols();
++
++ // Update SectionMap and Index in each Section.
++ void updateSections();
+ };
+
+ // Copy between coff_symbol16 and coff_symbol32.
+diff --git a/llvm/tools/llvm-objcopy/COFF/Reader.cpp b/llvm/tools/llvm-objcopy/COFF/Reader.cpp
+index d794042ae24..c8abe2913a2 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Reader.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Reader.cpp
+@@ -11,6 +11,7 @@
+ #include "llvm-objcopy.h"
+ #include "llvm/ADT/ArrayRef.h"
+ #include "llvm/ADT/StringRef.h"
++#include "llvm/BinaryFormat/COFF.h"
+ #include "llvm/Object/COFF.h"
+ #include "llvm/Support/ErrorHandling.h"
+ #include <cstddef>
+@@ -21,6 +22,7 @@ namespace objcopy {
+ namespace coff {
+
+ using namespace object;
++using namespace COFF;
+
+ Error COFFReader::readExecutableHeaders(Object &Obj) const {
+ const dos_header *DH = COFFObj.getDOSHeader();
+@@ -58,13 +60,14 @@ Error COFFReader::readExecutableHeaders(Object &Obj) const {
+ }
+
+ Error COFFReader::readSections(Object &Obj) const {
++ std::vector<Section> Sections;
+ // Section indexing starts from 1.
+ for (size_t I = 1, E = COFFObj.getNumberOfSections(); I <= E; I++) {
+ const coff_section *Sec;
+ if (auto EC = COFFObj.getSection(I, Sec))
+ return errorCodeToError(EC);
+- Obj.Sections.push_back(Section());
+- Section &S = Obj.Sections.back();
++ Sections.push_back(Section());
++ Section &S = Sections.back();
+ S.Header = *Sec;
+ if (auto EC = COFFObj.getSectionContents(Sec, S.Contents))
+ return errorCodeToError(EC);
+@@ -77,12 +80,14 @@ Error COFFReader::readSections(Object &Obj) const {
+ return make_error<StringError>("Extended relocations not supported yet",
+ object_error::parse_failed);
+ }
++ Obj.addSections(Sections);
+ return Error::success();
+ }
+
+ Error COFFReader::readSymbols(Object &Obj, bool IsBigObj) const {
+ std::vector<Symbol> Symbols;
+ Symbols.reserve(COFFObj.getRawNumberOfSymbols());
++ ArrayRef<Section> Sections = Obj.getSections();
+ for (uint32_t I = 0, E = COFFObj.getRawNumberOfSymbols(); I < E;) {
+ Expected<COFFSymbolRef> SymOrErr = COFFObj.getSymbol(I);
+ if (!SymOrErr)
+@@ -103,6 +108,26 @@ Error COFFReader::readSymbols(Object &Obj, bool IsBigObj) const {
+ Sym.AuxData = COFFObj.getSymbolAuxData(SymRef);
+ assert((Sym.AuxData.size() %
+ (IsBigObj ? sizeof(coff_symbol32) : sizeof(coff_symbol16))) == 0);
++ // Find the unique id of the section
++ if (SymRef.getSectionNumber() <=
++ 0) // Special symbol (undefined/absolute/debug)
++ Sym.TargetSectionId = SymRef.getSectionNumber();
++ else if (static_cast<uint32_t>(SymRef.getSectionNumber() - 1) <
++ Sections.size())
++ Sym.TargetSectionId = Sections[SymRef.getSectionNumber() - 1].UniqueId;
++ else
++ return make_error<StringError>("Section number out of range",
++ object_error::parse_failed);
++ // For section definitions, check if it is comdat associative, and if
++ // it is, find the target section unique id.
++ const coff_aux_section_definition *SD = SymRef.getSectionDefinition();
++ if (SD && SD->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
++ int32_t Index = SD->getNumber(IsBigObj);
++ if (Index <= 0 || static_cast<uint32_t>(Index - 1) >= Sections.size())
++ return make_error<StringError>("Unexpected associative section index",
++ object_error::parse_failed);
++ Sym.AssociativeComdatTargetSectionId = Sections[Index - 1].UniqueId;
++ }
+ I += 1 + SymRef.getNumberOfAuxSymbols();
+ }
+ Obj.addSymbols(Symbols);
+@@ -116,7 +141,7 @@ Error COFFReader::setRelocTargets(Object &Obj) const {
+ for (size_t I = 0; I < Sym.Sym.NumberOfAuxSymbols; I++)
+ RawSymbolTable.push_back(nullptr);
+ }
+- for (Section &Sec : Obj.Sections) {
++ for (Section &Sec : Obj.getMutableSections()) {
+ for (Relocation &R : Sec.Relocs) {
+ if (R.Reloc.SymbolTableIndex >= RawSymbolTable.size())
+ return make_error<StringError>("SymbolTableIndex out of range",
+diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.cpp b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
+index c347810dd24..9fb7812672b 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Writer.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
+@@ -25,7 +25,7 @@ using namespace object;
+ using namespace COFF;
+
+ Error COFFWriter::finalizeRelocTargets() {
+- for (Section &Sec : Obj.Sections) {
++ for (Section &Sec : Obj.getMutableSections()) {
+ for (Relocation &R : Sec.Relocs) {
+ const Symbol *Sym = Obj.findSymbol(R.Target);
+ if (Sym == nullptr)
+@@ -39,8 +39,48 @@ Error COFFWriter::finalizeRelocTargets() {
+ return Error::success();
+ }
+
++Error COFFWriter::finalizeSectionNumbers() {
++ for (Symbol &Sym : Obj.getMutableSymbols()) {
++ if (Sym.TargetSectionId <= 0) {
++ // Undefined, or a special kind of symbol. These negative values
++ // are stored in the SectionNumber field which is unsigned.
++ Sym.Sym.SectionNumber = static_cast<uint32_t>(Sym.TargetSectionId);
++ } else {
++ const Section *Sec = Obj.findSection(Sym.TargetSectionId);
++ if (Sec == nullptr)
++ return make_error<StringError>("Symbol " + Sym.Name +
++ " points to a removed section",
++ object_error::invalid_symbol_index);
++ Sym.Sym.SectionNumber = Sec->Index;
++
++ if (Sym.Sym.NumberOfAuxSymbols == 1 &&
++ Sym.Sym.StorageClass == IMAGE_SYM_CLASS_STATIC) {
++ coff_aux_section_definition *SD =
++ reinterpret_cast<coff_aux_section_definition *>(Sym.AuxData.data());
++ uint32_t SDSectionNumber;
++ if (Sym.AssociativeComdatTargetSectionId == 0) {
++ // Not a comdat associative section; just set the Number field to
++ // the number of the section itself.
++ SDSectionNumber = Sec->Index;
++ } else {
++ Sec = Obj.findSection(Sym.AssociativeComdatTargetSectionId);
++ if (Sec == nullptr)
++ return make_error<StringError>(
++ "Symbol " + Sym.Name + " is associative to a removed section",
++ object_error::invalid_symbol_index);
++ SDSectionNumber = Sec->Index;
++ }
++ // Update the section definition with the new section number.
++ SD->NumberLowPart = static_cast<uint16_t>(SDSectionNumber);
++ SD->NumberHighPart = static_cast<uint16_t>(SDSectionNumber >> 16);
++ }
++ }
++ }
++ return Error::success();
++}
++
+ void COFFWriter::layoutSections() {
+- for (auto &S : Obj.Sections) {
++ for (auto &S : Obj.getMutableSections()) {
+ if (S.Header.SizeOfRawData > 0)
+ S.Header.PointerToRawData = FileSize;
+ FileSize += S.Header.SizeOfRawData; // For executables, this is already
+@@ -57,7 +97,7 @@ void COFFWriter::layoutSections() {
+ }
+
+ size_t COFFWriter::finalizeStringTable() {
+- for (auto &S : Obj.Sections)
++ for (const auto &S : Obj.getSections())
+ if (S.Name.size() > COFF::NameSize)
+ StrTabBuilder.add(S.Name);
+
+@@ -67,7 +107,7 @@ size_t COFFWriter::finalizeStringTable() {
+
+ StrTabBuilder.finalize();
+
+- for (auto &S : Obj.Sections) {
++ for (auto &S : Obj.getMutableSections()) {
+ if (S.Name.size() > COFF::NameSize) {
+ snprintf(S.Header.Name, sizeof(S.Header.Name), "/%d",
+ (int)StrTabBuilder.getOffset(S.Name));
+@@ -97,6 +137,8 @@ std::pair<size_t, size_t> COFFWriter::finalizeSymbolTable() {
+ Error COFFWriter::finalize(bool IsBigObj) {
+ if (Error E = finalizeRelocTargets())
+ return E;
++ if (Error E = finalizeSectionNumbers())
++ return E;
+
+ size_t SizeOfHeaders = 0;
+ FileAlignment = 1;
+@@ -113,10 +155,10 @@ Error COFFWriter::finalize(bool IsBigObj) {
+ SizeOfHeaders +=
+ PeHeaderSize + sizeof(data_directory) * Obj.DataDirectories.size();
+ }
+- Obj.CoffFileHeader.NumberOfSections = Obj.Sections.size();
++ Obj.CoffFileHeader.NumberOfSections = Obj.getSections().size();
+ SizeOfHeaders +=
+ IsBigObj ? sizeof(coff_bigobj_file_header) : sizeof(coff_file_header);
+- SizeOfHeaders += sizeof(coff_section) * Obj.Sections.size();
++ SizeOfHeaders += sizeof(coff_section) * Obj.getSections().size();
+ SizeOfHeaders = alignTo(SizeOfHeaders, FileAlignment);
+
+ Obj.CoffFileHeader.SizeOfOptionalHeader =
+@@ -131,8 +173,8 @@ Error COFFWriter::finalize(bool IsBigObj) {
+ Obj.PeHeader.SizeOfHeaders = SizeOfHeaders;
+ Obj.PeHeader.SizeOfInitializedData = SizeOfInitializedData;
+
+- if (!Obj.Sections.empty()) {
+- const Section &S = Obj.Sections.back();
++ if (!Obj.getSections().empty()) {
++ const Section &S = Obj.getSections().back();
+ Obj.PeHeader.SizeOfImage =
+ alignTo(S.Header.VirtualAddress + S.Header.VirtualSize,
+ Obj.PeHeader.SectionAlignment);
+@@ -198,7 +240,7 @@ void COFFWriter::writeHeaders(bool IsBigObj) {
+ BigObjHeader.unused4 = 0;
+ // The value in Obj.CoffFileHeader.NumberOfSections is truncated, thus
+ // get the original one instead.
+- BigObjHeader.NumberOfSections = Obj.Sections.size();
++ BigObjHeader.NumberOfSections = Obj.getSections().size();
+ BigObjHeader.PointerToSymbolTable = Obj.CoffFileHeader.PointerToSymbolTable;
+ BigObjHeader.NumberOfSymbols = Obj.CoffFileHeader.NumberOfSymbols;
+
+@@ -223,14 +265,14 @@ void COFFWriter::writeHeaders(bool IsBigObj) {
+ Ptr += sizeof(DD);
+ }
+ }
+- for (const auto &S : Obj.Sections) {
++ for (const auto &S : Obj.getSections()) {
+ memcpy(Ptr, &S.Header, sizeof(S.Header));
+ Ptr += sizeof(S.Header);
+ }
+ }
+
+ void COFFWriter::writeSections() {
+- for (const auto &S : Obj.Sections) {
++ for (const auto &S : Obj.getSections()) {
+ uint8_t *Ptr = Buf.getBufferStart() + S.Header.PointerToRawData;
+ std::copy(S.Contents.begin(), S.Contents.end(), Ptr);
+
+@@ -295,7 +337,7 @@ Error COFFWriter::patchDebugDirectory() {
+ const data_directory *Dir = &Obj.DataDirectories[DEBUG_DIRECTORY];
+ if (Dir->Size <= 0)
+ return Error::success();
+- for (const auto &S : Obj.Sections) {
++ for (const auto &S : Obj.getSections()) {
+ if (Dir->RelativeVirtualAddress >= S.Header.VirtualAddress &&
+ Dir->RelativeVirtualAddress <
+ S.Header.VirtualAddress + S.Header.SizeOfRawData) {
+@@ -324,7 +366,7 @@ Error COFFWriter::patchDebugDirectory() {
+ }
+
+ Error COFFWriter::write() {
+- bool IsBigObj = Obj.Sections.size() > MaxNumberOfSections16;
++ bool IsBigObj = Obj.getSections().size() > MaxNumberOfSections16;
+ if (IsBigObj && Obj.IsPE)
+ return make_error<StringError>("Too many sections for executable",
+ object_error::parse_failed);
+diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.h b/llvm/tools/llvm-objcopy/COFF/Writer.h
+index 52fef385926..a967a103df9 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Writer.h
++++ b/llvm/tools/llvm-objcopy/COFF/Writer.h
+@@ -31,6 +31,7 @@ class COFFWriter {
+ StringTableBuilder StrTabBuilder;
+
+ Error finalizeRelocTargets();
++ Error finalizeSectionNumbers();
+ void layoutSections();
+ size_t finalizeStringTable();
+ template <class SymbolTy> std::pair<size_t, size_t> finalizeSymbolTable();
+--
+2.17.1
+
diff --git a/projects/clang/win-patches/llvm-objcopy-3.patch b/projects/clang/win-patches/llvm-objcopy-3.patch
new file mode 100644
index 0000000..6e303c0
--- /dev/null
+++ b/projects/clang/win-patches/llvm-objcopy-3.patch
@@ -0,0 +1,160 @@
+From 2b6e1b7585d6bd997ea4e4233c904a6d2c11ad33 Mon Sep 17 00:00:00 2001
+From: Martin Storsjo <martin(a)martin.st>
+Date: Sat, 19 Jan 2019 19:42:41 +0000
+Subject: [PATCH] [llvm-objcopy] [COFF] Implement --strip-debug
+
+Also remove sections similarly for --strip-all, --discard-all,
+--strip-unneeded.
+
+Differential Revision: https://reviews.llvm.org/D56839
+
+git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351661 91177308-0d34-0410-b5e6-96231b3b80d8
+---
+ test/tools/llvm-objcopy/COFF/strip-debug.test | 109 ++++++++++++++++++
+ tools/llvm-objcopy/COFF/COFFObjcopy.cpp | 11 ++
+ 2 files changed, 120 insertions(+)
+ create mode 100644 test/tools/llvm-objcopy/COFF/strip-debug.test
+
+diff --git a/llvm/test/tools/llvm-objcopy/COFF/strip-debug.test b/llvm/test/tools/llvm-objcopy/COFF/strip-debug.test
+new file mode 100644
+index 00000000000..97fa96aac70
+--- /dev/null
++++ b/llvm/test/tools/llvm-objcopy/COFF/strip-debug.test
+@@ -0,0 +1,109 @@
++# RUN: yaml2obj %s > %t.in.o
++#
++# RUN: llvm-objdump --section-headers %t.in.o | FileCheck %s --check-prefixes=SECTIONS,SECTIONS-PRE
++# RUN: llvm-objdump -t %t.in.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-PRE
++#
++# RUN: llvm-objcopy --strip-debug %t.in.o %t.out.o
++# RUN: llvm-objdump --section-headers %t.out.o | FileCheck %s --check-prefixes=SECTIONS
++# RUN: llvm-objdump -t %t.out.o | FileCheck %s --check-prefixes=SYMBOLS
++#
++# Test that --strip-all, --strip-all-gnu, --discard-all and --strip-unneeded,
++# plus llvm-strip without arguments all produce a similiar set of sections
++# (while they remove symbols differently).
++#
++# RUN: llvm-objcopy --strip-all %t.in.o %t.strip-all.o
++# RUN: llvm-objdump --section-headers %t.strip-all.o | FileCheck %s --check-prefixes=SECTIONS
++#
++# RUN: llvm-objcopy --strip-all-gnu %t.in.o %t.strip-all-gnu.o
++# RUN: llvm-objdump --section-headers %t.strip-all-gnu.o | FileCheck %s --check-prefixes=SECTIONS
++#
++# RUN: llvm-objcopy --discard-all %t.in.o %t.discard-all.o
++# RUN: llvm-objdump --section-headers %t.discard-all.o | FileCheck %s --check-prefixes=SECTIONS
++#
++# RUN: llvm-objcopy --discard-all %t.in.o %t.strip-unneeded.o
++# RUN: llvm-objdump --section-headers %t.strip-unneeded.o | FileCheck %s --check-prefixes=SECTIONS
++#
++# SECTIONS: Sections:
++# SECTIONS-NEXT: Idx Name
++# SECTIONS-NEXT: 0 .text
++# SECTIONS-NEXT: 1 .data
++# SECTIONS-NEXT: 2 .bss
++# SECTIONS-NEXT: 3 .xdata
++# SECTIONS-NEXT: 4 .reloc
++# SECTIONS-PRE-NEXT: 5 .debug_discardable
++# SECTIONS-NEXT: {{.*}} .debug_undiscardable
++# SECTIONS-NEXT: {{.*}} .llvm_addrsig
++# SECTIONS-EMPTY:
++#
++# Test that --strip-debug doesn't remove e.g. unreferenced local symbols.
++#
++# SYMBOLS: SYMBOL TABLE:
++# SYMBOLS-NEXT: external
++# SYMBOLS-NEXT: local_unreferenced
++# SYMBOLS-PRE-NEXT: debug_discardable_sym
++# SYMBOLS-NEXT: debug_undiscardable_sym
++# SYMBOLS-EMPTY:
++
++--- !COFF
++header:
++ Machine: IMAGE_FILE_MACHINE_AMD64
++ Characteristics: [ ]
++sections:
++ - Name: .text
++ Characteristics: [ ]
++ Alignment: 4
++ SectionData: 00000000
++ - Name: .data
++ Characteristics: [ ]
++ Alignment: 4
++ SectionData: 00000000
++ - Name: .bss
++ Characteristics: [ ]
++ Alignment: 4
++ SectionData: 00000000
++ - Name: .xdata
++ Characteristics: [ ]
++ Alignment: 4
++ SectionData: 00000000
++ - Name: .reloc
++ Characteristics: [ IMAGE_SCN_MEM_DISCARDABLE ]
++ Alignment: 4
++ SectionData: 00000000
++ - Name: .debug_discardable
++ Characteristics: [ IMAGE_SCN_MEM_DISCARDABLE ]
++ Alignment: 4
++ SectionData: 00000000
++ - Name: .debug_undiscardable
++ Characteristics: [ ]
++ Alignment: 4
++ SectionData: 00000000
++ - Name: .llvm_addrsig
++ Characteristics: [ IMAGE_SCN_LNK_REMOVE ]
++ Alignment: 4
++ SectionData: 00000000
++symbols:
++ - Name: external
++ Value: 0
++ SectionNumber: 1
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_NULL
++ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
++ - Name: local_unreferenced
++ Value: 0
++ SectionNumber: 1
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_NULL
++ StorageClass: IMAGE_SYM_CLASS_STATIC
++ - Name: debug_discardable_sym
++ Value: 0
++ SectionNumber: 6
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_NULL
++ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
++ - Name: debug_undiscardable_sym
++ Value: 0
++ SectionNumber: 7
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_NULL
++ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
++...
+diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+index dd2e4829218..13d8efde37c 100644
+--- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+@@ -26,9 +26,20 @@ namespace coff {
+ using namespace object;
+ using namespace COFF;
+
++static bool isDebugSection(const Section &Sec) {
++ return Sec.Name.startswith(".debug");
++}
++
+ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
+ // Perform the actual section removals.
+ Obj.removeSections([&Config](const Section &Sec) {
++ if (Config.StripDebug || Config.StripAll || Config.StripAllGNU ||
++ Config.DiscardAll || Config.StripUnneeded) {
++ if (isDebugSection(Sec) &&
++ (Sec.Header.Characteristics & IMAGE_SCN_MEM_DISCARDABLE) != 0)
++ return true;
++ }
++
+ if (is_contained(Config.ToRemove, Sec.Name))
+ return true;
+
+--
+2.17.1
+
diff --git a/projects/clang/win-patches/llvm-objcopy-4.patch b/projects/clang/win-patches/llvm-objcopy-4.patch
new file mode 100644
index 0000000..e922384
--- /dev/null
+++ b/projects/clang/win-patches/llvm-objcopy-4.patch
@@ -0,0 +1,222 @@
+From 526aa2e94355b7feb3bf7774a6e1899f68e94ad8 Mon Sep 17 00:00:00 2001
+From: Martin Storsjo <martin(a)martin.st>
+Date: Sat, 19 Jan 2019 19:42:48 +0000
+Subject: [PATCH] [llvm-objcopy] [COFF] Implement --only-keep-debug
+
+Differential Revision: https://reviews.llvm.org/D56840
+
+git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351662 91177308-0d34-0410-b5e6-96231b3b80d8
+---
+ .../COFF/Inputs/only-keep-sections.yaml | 77 +++++++++++++++++++
+ .../llvm-objcopy/COFF/only-keep-debug.test | 58 ++++++++++++++
+ tools/llvm-objcopy/COFF/COFFObjcopy.cpp | 10 +++
+ tools/llvm-objcopy/COFF/Object.cpp | 10 +++
+ tools/llvm-objcopy/COFF/Object.h | 1 +
+ 5 files changed, 156 insertions(+)
+ create mode 100644 test/tools/llvm-objcopy/COFF/Inputs/only-keep-sections.yaml
+ create mode 100644 test/tools/llvm-objcopy/COFF/only-keep-debug.test
+
+diff --git a/llvm/test/tools/llvm-objcopy/COFF/Inputs/only-keep-sections.yaml b/llvm/test/tools/llvm-objcopy/COFF/Inputs/only-keep-sections.yaml
+new file mode 100644
+index 00000000000..b5437e10763
+--- /dev/null
++++ b/llvm/test/tools/llvm-objcopy/COFF/Inputs/only-keep-sections.yaml
+@@ -0,0 +1,77 @@
++--- !COFF
++OptionalHeader:
++ AddressOfEntryPoint: 4144
++ ImageBase: 1073741824
++ SectionAlignment: 4096
++ FileAlignment: 512
++ MajorOperatingSystemVersion: 6
++ MinorOperatingSystemVersion: 0
++ MajorImageVersion: 0
++ MinorImageVersion: 0
++ MajorSubsystemVersion: 6
++ MinorSubsystemVersion: 0
++ Subsystem: IMAGE_SUBSYSTEM_WINDOWS_CUI
++ DLLCharacteristics: [ ]
++ SizeOfStackReserve: 1048576
++ SizeOfStackCommit: 4096
++ SizeOfHeapReserve: 1048576
++ SizeOfHeapCommit: 4096
++header:
++ Machine: IMAGE_FILE_MACHINE_AMD64
++ Characteristics: [ ]
++sections:
++ - Name: .text
++ Characteristics: [ IMAGE_SCN_CNT_CODE ]
++ VirtualAddress: 4096
++ VirtualSize: 4
++ SectionData: C3C3C3C3
++ - Name: .rdata
++ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA ]
++ VirtualAddress: 8192
++ VirtualSize: 4
++ SectionData: 2A000000
++ - Name: .buildid
++ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA ]
++ VirtualAddress: 12288
++ VirtualSize: 4
++ SectionData: 2B000000
++ - Name: .reloc
++ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE ]
++ VirtualAddress: 16384
++ VirtualSize: 4
++ SectionData: 2C000000
++ - Name: .debug_discardable
++ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_DISCARDABLE ]
++ VirtualAddress: 20480
++ VirtualSize: 4
++ SectionData: 2D000000
++ - Name: .debug_undiscardable
++ Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA ]
++ VirtualAddress: 24576
++ VirtualSize: 4
++ SectionData: 2E000000
++ - Name: .unflagged
++ Characteristics: [ ]
++ VirtualAddress: 28672
++ VirtualSize: 4
++ SectionData: 2F000000
++symbols:
++ - Name: main
++ Value: 2
++ SectionNumber: 1
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
++ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
++ - Name: debug_discardable_sym
++ Value: 0
++ SectionNumber: 5
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
++ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
++ - Name: debug_undiscardable_sym
++ Value: 0
++ SectionNumber: 6
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
++ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
++...
+diff --git a/llvm/test/tools/llvm-objcopy/COFF/only-keep-debug.test b/llvm/test/tools/llvm-objcopy/COFF/only-keep-debug.test
+new file mode 100644
+index 00000000000..5518d4000fc
+--- /dev/null
++++ b/llvm/test/tools/llvm-objcopy/COFF/only-keep-debug.test
+@@ -0,0 +1,58 @@
++RUN: yaml2obj %p/Inputs/only-keep-sections.yaml > %t.in.exe
++
++RUN: llvm-objcopy --only-keep-debug %t.in.exe %t.out.exe
++RUN: llvm-readobj --sections %t.out.exe | FileCheck %s --check-prefix=SECTIONS
++RUN: llvm-objdump -t %t.out.exe | FileCheck %s --check-prefix=SYMBOLS
++
++Check that all non-debug/buildid sections with IMAGE_SCN_CNT_CODE
++or IMAGE_SCN_CNT_INITIALIZED_DATA are truncated, and no others.
++
++SECTIONS: Sections [
++SECTIONS-NEXT: Section {
++SECTIONS-NEXT: Number: 1
++SECTIONS-NEXT: Name: .text
++SECTIONS-NEXT: VirtualSize: 0x4
++SECTIONS-NEXT: VirtualAddress:
++SECTIONS-NEXT: RawDataSize: 0
++SECTIONS: Section {
++SECTIONS-NEXT: Number: 2
++SECTIONS-NEXT: Name: .rdata
++SECTIONS-NEXT: VirtualSize: 0x4
++SECTIONS-NEXT: VirtualAddress:
++SECTIONS-NEXT: RawDataSize: 0
++SECTIONS: Section {
++SECTIONS-NEXT: Number: 3
++SECTIONS-NEXT: Name: .buildid
++SECTIONS-NEXT: VirtualSize: 0x4
++SECTIONS-NEXT: VirtualAddress:
++SECTIONS-NEXT: RawDataSize: 512
++SECTIONS: Section {
++SECTIONS-NEXT: Number: 4
++SECTIONS-NEXT: Name: .reloc
++SECTIONS-NEXT: VirtualSize: 0x4
++SECTIONS-NEXT: VirtualAddress:
++SECTIONS-NEXT: RawDataSize: 0
++SECTIONS: Section {
++SECTIONS-NEXT: Number: 5
++SECTIONS-NEXT: Name: .debug_discardable
++SECTIONS-NEXT: VirtualSize: 0x4
++SECTIONS-NEXT: VirtualAddress:
++SECTIONS-NEXT: RawDataSize: 512
++SECTIONS: Section {
++SECTIONS-NEXT: Number: 6
++SECTIONS-NEXT: Name: .debug_undiscardable
++SECTIONS-NEXT: VirtualSize: 0x4
++SECTIONS-NEXT: VirtualAddress:
++SECTIONS-NEXT: RawDataSize: 512
++SECTIONS: Section {
++SECTIONS-NEXT: Number: 7
++SECTIONS-NEXT: Name: .unflagged
++SECTIONS-NEXT: VirtualSize: 0x4
++SECTIONS-NEXT: VirtualAddress:
++SECTIONS-NEXT: RawDataSize: 512
++
++SYMBOLS: SYMBOL TABLE:
++SYMBOLS-NEXT: main
++SYMBOLS-NEXT: debug_discardable_sym
++SYMBOLS-NEXT: debug_undiscardable_sym
++SYMBOLS-EMPTY:
+diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+index 13d8efde37c..60afbf7bb54 100644
+--- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+@@ -46,6 +46,16 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
+ return false;
+ });
+
++ if (Config.OnlyKeepDebug) {
++ // For --only-keep-debug, we keep all other sections, but remove their
++ // content. The VirtualSize field in the section header is kept intact.
++ Obj.truncateSections([](const Section &Sec) {
++ return !isDebugSection(Sec) && Sec.Name != ".buildid" &&
++ ((Sec.Header.Characteristics &
++ (IMAGE_SCN_CNT_CODE | IMAGE_SCN_CNT_INITIALIZED_DATA)) != 0);
++ });
++ }
++
+ // StripAll removes all symbols and thus also removes all relocations.
+ if (Config.StripAll || Config.StripAllGNU)
+ for (Section &Sec : Obj.getMutableSections())
+diff --git a/llvm/tools/llvm-objcopy/COFF/Object.cpp b/llvm/tools/llvm-objcopy/COFF/Object.cpp
+index e19cea6aa9d..fc87d9e574d 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Object.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Object.cpp
+@@ -127,6 +127,16 @@ void Object::removeSections(function_ref<bool(const Section &)> ToRemove) {
+ updateSymbols();
+ }
+
++void Object::truncateSections(function_ref<bool(const Section &)> ToTruncate) {
++ for (Section &Sec : Sections) {
++ if (ToTruncate(Sec)) {
++ Sec.Contents = ArrayRef<uint8_t>();
++ Sec.Relocs.clear();
++ Sec.Header.SizeOfRawData = 0;
++ }
++ }
++}
++
+ } // end namespace coff
+ } // end namespace objcopy
+ } // end namespace llvm
+diff --git a/llvm/tools/llvm-objcopy/COFF/Object.h b/llvm/tools/llvm-objcopy/COFF/Object.h
+index a73e93620d3..8e200369f0b 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Object.h
++++ b/llvm/tools/llvm-objcopy/COFF/Object.h
+@@ -93,6 +93,7 @@ struct Object {
+
+ void addSections(ArrayRef<Section> NewSections);
+ void removeSections(function_ref<bool(const Section &)> ToRemove);
++ void truncateSections(function_ref<bool(const Section &)> ToTruncate);
+
+ private:
+ std::vector<Symbol> Symbols;
+--
+2.17.1
+
diff --git a/projects/clang/win-patches/llvm-objcopy-5.patch b/projects/clang/win-patches/llvm-objcopy-5.patch
new file mode 100644
index 0000000..657c72a
--- /dev/null
+++ b/projects/clang/win-patches/llvm-objcopy-5.patch
@@ -0,0 +1,61 @@
+From 17dcf25b3ade15605ca27150e4440bcc75caed65 Mon Sep 17 00:00:00 2001
+From: Martin Storsjo <martin(a)martin.st>
+Date: Sat, 19 Jan 2019 19:42:54 +0000
+Subject: [PATCH] [llvm-objcopy] [COFF] Implement --only-section
+
+Differential Revision: https://reviews.llvm.org/D56873
+
+git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351663 91177308-0d34-0410-b5e6-96231b3b80d8
+---
+ .../tools/llvm-objcopy/COFF/only-section.test | 21 +++++++++++++++++++
+ tools/llvm-objcopy/COFF/COFFObjcopy.cpp | 6 ++++++
+ 2 files changed, 27 insertions(+)
+ create mode 100644 test/tools/llvm-objcopy/COFF/only-section.test
+
+diff --git a/llvm/test/tools/llvm-objcopy/COFF/only-section.test b/llvm/test/tools/llvm-objcopy/COFF/only-section.test
+new file mode 100644
+index 00000000000..42492ed80ff
+--- /dev/null
++++ b/llvm/test/tools/llvm-objcopy/COFF/only-section.test
+@@ -0,0 +1,21 @@
++RUN: yaml2obj %p/Inputs/only-keep-sections.yaml > %t.in.exe
++
++RUN: llvm-objcopy --only-section .debug_discardable %t.in.exe %t.out.exe
++RUN: llvm-objdump --section-headers -t %t.out.exe | FileCheck %s --check-prefixes=SECTIONS,SECTIONS-DEBUG,SYMBOLS,SYMBOLS-DEBUG
++
++Adding another section stripping option makes it return the intersection of
++kept sections - in this case keeping only .text.
++
++RUN: llvm-objcopy --only-section .debug_discardable --only-section .text --strip-debug %t.in.exe %t.combination.exe
++RUN: llvm-objdump --section-headers -t %t.combination.exe | FileCheck %s --check-prefixes=SECTIONS,SECTIONS-TEXT,SYMBOLS,SYMBOLS-TEXT
++
++SECTIONS: Sections:
++SECTIONS-NEXT: Idx Name
++SECTIONS-DEBUG-NEXT: .debug_discardable
++SECTIONS-TEXT-NEXT: .text
++SECTIONS-EMPTY:
++
++SYMBOLS: SYMBOL TABLE:
++SYMBOLS-DEBUG-NEXT: debug_discardable_sym
++SYMBOLS-TEXT-NEXT: main
++SYMBOLS-EMPTY:
+diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+index 60afbf7bb54..99929d10a1f 100644
+--- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+@@ -33,6 +33,12 @@ static bool isDebugSection(const Section &Sec) {
+ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
+ // Perform the actual section removals.
+ Obj.removeSections([&Config](const Section &Sec) {
++ // Contrary to --only-keep-debug, --only-section fully removes sections that
++ // aren't mentioned.
++ if (!Config.OnlySection.empty() &&
++ !is_contained(Config.OnlySection, Sec.Name))
++ return true;
++
+ if (Config.StripDebug || Config.StripAll || Config.StripAllGNU ||
+ Config.DiscardAll || Config.StripUnneeded) {
+ if (isDebugSection(Sec) &&
+--
+2.17.1
+
diff --git a/projects/clang/win-patches/llvm-objcopy-6.patch b/projects/clang/win-patches/llvm-objcopy-6.patch
new file mode 100644
index 0000000..e70f1b9
--- /dev/null
+++ b/projects/clang/win-patches/llvm-objcopy-6.patch
@@ -0,0 +1,242 @@
+From d3b89a1637cddee1c61e59257cfe92227ead29e5 Mon Sep 17 00:00:00 2001
+From: Martin Storsjo <martin(a)martin.st>
+Date: Tue, 22 Jan 2019 10:57:59 +0000
+Subject: [PATCH] [llvm-objcopy] Consistently use createStringError instead of
+ make_error<StringError>
+
+This was requested in the review of D57006.
+
+Also add missing quotes around symbol names in error messages.
+
+Differential Revision: https://reviews.llvm.org/D57014
+
+git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351799 91177308-0d34-0410-b5e6-96231b3b80d8
+---
+ .../llvm-objcopy/COFF/remove-section.test | 2 +-
+ tools/llvm-objcopy/COFF/COFFObjcopy.cpp | 8 ++---
+ tools/llvm-objcopy/COFF/Object.cpp | 5 ++-
+ tools/llvm-objcopy/COFF/Reader.cpp | 24 +++++++-------
+ tools/llvm-objcopy/COFF/Writer.cpp | 33 +++++++++----------
+ tools/llvm-objcopy/ELF/ELFObjcopy.cpp | 10 +++---
+ 6 files changed, 40 insertions(+), 42 deletions(-)
+
+diff --git a/llvm/test/tools/llvm-objcopy/COFF/remove-section.test b/llvm/test/tools/llvm-objcopy/COFF/remove-section.test
+index b3dfb0b98cb..6dc8f6a6c2e 100644
+--- a/llvm/test/tools/llvm-objcopy/COFF/remove-section.test
++++ b/llvm/test/tools/llvm-objcopy/COFF/remove-section.test
+@@ -96,7 +96,7 @@
+ # Removing the .comdat section fails, since the .text section has relocations
+ # against it.
+ #
+-# ERROR-RELOC: Relocation target foo ({{.*}}) not found
++# ERROR-RELOC: Relocation target 'foo' ({{.*}}) not found
+ #
+ #
+ # Removing the .comdat section and .text (with a relocation against .comdat)
+diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+index 99929d10a1f..8d8f53d13d8 100644
+--- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+@@ -84,10 +84,10 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
+ // Explicitly removing a referenced symbol is an error.
+ if (Sym.Referenced)
+ reportError(Config.OutputFilename,
+- make_error<StringError>(
+- "not stripping symbol '" + Sym.Name +
+- "' because it is named in a relocation.",
+- llvm::errc::invalid_argument));
++ createStringError(llvm::errc::invalid_argument,
++ "not stripping symbol '%s' because it is "
++ "named in a relocation.",
++ Sym.Name.str().c_str()));
+ return true;
+ }
+
+diff --git a/llvm/tools/llvm-objcopy/COFF/Object.cpp b/llvm/tools/llvm-objcopy/COFF/Object.cpp
+index fc87d9e574d..83435dffa98 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Object.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Object.cpp
+@@ -56,9 +56,8 @@ Error Object::markSymbols() {
+ for (const Relocation &R : Sec.Relocs) {
+ auto It = SymbolMap.find(R.Target);
+ if (It == SymbolMap.end())
+- return make_error<StringError>("Relocation target " + Twine(R.Target) +
+- " not found",
+- object_error::invalid_symbol_index);
++ return createStringError(object_error::invalid_symbol_index,
++ "Relocation target %zu not found", R.Target);
+ It->second->Referenced = true;
+ }
+ }
+diff --git a/llvm/tools/llvm-objcopy/COFF/Reader.cpp b/llvm/tools/llvm-objcopy/COFF/Reader.cpp
+index c8abe2913a2..20ff32a59dc 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Reader.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Reader.cpp
+@@ -77,8 +77,8 @@ Error COFFReader::readSections(Object &Obj) const {
+ if (auto EC = COFFObj.getSectionName(Sec, S.Name))
+ return errorCodeToError(EC);
+ if (Sec->hasExtendedRelocations())
+- return make_error<StringError>("Extended relocations not supported yet",
+- object_error::parse_failed);
++ return createStringError(object_error::parse_failed,
++ "Extended relocations not supported yet");
+ }
+ Obj.addSections(Sections);
+ return Error::success();
+@@ -116,16 +116,16 @@ Error COFFReader::readSymbols(Object &Obj, bool IsBigObj) const {
+ Sections.size())
+ Sym.TargetSectionId = Sections[SymRef.getSectionNumber() - 1].UniqueId;
+ else
+- return make_error<StringError>("Section number out of range",
+- object_error::parse_failed);
++ return createStringError(object_error::parse_failed,
++ "Section number out of range");
+ // For section definitions, check if it is comdat associative, and if
+ // it is, find the target section unique id.
+ const coff_aux_section_definition *SD = SymRef.getSectionDefinition();
+ if (SD && SD->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
+ int32_t Index = SD->getNumber(IsBigObj);
+ if (Index <= 0 || static_cast<uint32_t>(Index - 1) >= Sections.size())
+- return make_error<StringError>("Unexpected associative section index",
+- object_error::parse_failed);
++ return createStringError(object_error::parse_failed,
++ "Unexpected associative section index");
+ Sym.AssociativeComdatTargetSectionId = Sections[Index - 1].UniqueId;
+ }
+ I += 1 + SymRef.getNumberOfAuxSymbols();
+@@ -144,12 +144,12 @@ Error COFFReader::setRelocTargets(Object &Obj) const {
+ for (Section &Sec : Obj.getMutableSections()) {
+ for (Relocation &R : Sec.Relocs) {
+ if (R.Reloc.SymbolTableIndex >= RawSymbolTable.size())
+- return make_error<StringError>("SymbolTableIndex out of range",
+- object_error::parse_failed);
++ return createStringError(object_error::parse_failed,
++ "SymbolTableIndex out of range");
+ const Symbol *Sym = RawSymbolTable[R.Reloc.SymbolTableIndex];
+ if (Sym == nullptr)
+- return make_error<StringError>("Invalid SymbolTableIndex",
+- object_error::parse_failed);
++ return createStringError(object_error::parse_failed,
++ "Invalid SymbolTableIndex");
+ R.Target = Sym->UniqueId;
+ R.TargetName = Sym->Name;
+ }
+@@ -169,8 +169,8 @@ Expected<std::unique_ptr<Object>> COFFReader::create() const {
+ Obj->CoffFileHeader = *CFH;
+ } else {
+ if (!CBFH)
+- return make_error<StringError>("No COFF file header returned",
+- object_error::parse_failed);
++ return createStringError(object_error::parse_failed,
++ "No COFF file header returned");
+ // Only copying the few fields from the bigobj header that we need
+ // and won't recreate in the end.
+ Obj->CoffFileHeader.Machine = CBFH->Machine;
+diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.cpp b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
+index 9fb7812672b..0321f94a896 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Writer.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
+@@ -29,10 +29,9 @@ Error COFFWriter::finalizeRelocTargets() {
+ for (Relocation &R : Sec.Relocs) {
+ const Symbol *Sym = Obj.findSymbol(R.Target);
+ if (Sym == nullptr)
+- return make_error<StringError>("Relocation target " + R.TargetName +
+- " (" + Twine(R.Target) +
+- ") not found",
+- object_error::invalid_symbol_index);
++ return createStringError(object_error::invalid_symbol_index,
++ "Relocation target '%s' (%zu) not found",
++ R.TargetName.str().c_str(), R.Target);
+ R.Reloc.SymbolTableIndex = Sym->RawIndex;
+ }
+ }
+@@ -48,9 +47,9 @@ Error COFFWriter::finalizeSectionNumbers() {
+ } else {
+ const Section *Sec = Obj.findSection(Sym.TargetSectionId);
+ if (Sec == nullptr)
+- return make_error<StringError>("Symbol " + Sym.Name +
+- " points to a removed section",
+- object_error::invalid_symbol_index);
++ return createStringError(object_error::invalid_symbol_index,
++ "Symbol '%s' points to a removed section",
++ Sym.Name.str().c_str());
+ Sym.Sym.SectionNumber = Sec->Index;
+
+ if (Sym.Sym.NumberOfAuxSymbols == 1 &&
+@@ -65,9 +64,10 @@ Error COFFWriter::finalizeSectionNumbers() {
+ } else {
+ Sec = Obj.findSection(Sym.AssociativeComdatTargetSectionId);
+ if (Sec == nullptr)
+- return make_error<StringError>(
+- "Symbol " + Sym.Name + " is associative to a removed section",
+- object_error::invalid_symbol_index);
++ return createStringError(
++ object_error::invalid_symbol_index,
++ "Symbol '%s' is associative to a removed section",
++ Sym.Name.str().c_str());
+ SDSectionNumber = Sec->Index;
+ }
+ // Update the section definition with the new section number.
+@@ -343,9 +343,8 @@ Error COFFWriter::patchDebugDirectory() {
+ S.Header.VirtualAddress + S.Header.SizeOfRawData) {
+ if (Dir->RelativeVirtualAddress + Dir->Size >
+ S.Header.VirtualAddress + S.Header.SizeOfRawData)
+- return make_error<StringError>(
+- "Debug directory extends past end of section",
+- object_error::parse_failed);
++ return createStringError(object_error::parse_failed,
++ "Debug directory extends past end of section");
+
+ size_t Offset = Dir->RelativeVirtualAddress - S.Header.VirtualAddress;
+ uint8_t *Ptr = Buf.getBufferStart() + S.Header.PointerToRawData + Offset;
+@@ -361,15 +360,15 @@ Error COFFWriter::patchDebugDirectory() {
+ return Error::success();
+ }
+ }
+- return make_error<StringError>("Debug directory not found",
+- object_error::parse_failed);
++ return createStringError(object_error::parse_failed,
++ "Debug directory not found");
+ }
+
+ Error COFFWriter::write() {
+ bool IsBigObj = Obj.getSections().size() > MaxNumberOfSections16;
+ if (IsBigObj && Obj.IsPE)
+- return make_error<StringError>("Too many sections for executable",
+- object_error::parse_failed);
++ return createStringError(object_error::parse_failed,
++ "Too many sections for executable");
+ return write(IsBigObj);
+ }
+
+diff --git a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
+index db0cd76ced4..a2996395c1f 100644
+--- a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
++++ b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
+@@ -185,9 +185,10 @@ static Error dumpSectionToFile(StringRef SecName, StringRef Filename,
+ for (auto &Sec : Obj.sections()) {
+ if (Sec.Name == SecName) {
+ if (Sec.OriginalData.empty())
+- return make_error<StringError>("Can't dump section \"" + SecName +
+- "\": it has no contents",
+- object_error::parse_failed);
++ return createStringError(
++ object_error::parse_failed,
++ "Can't dump section \"%s\": it has no contents",
++ SecName.str().c_str());
+ Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
+ FileOutputBuffer::create(Filename, Sec.OriginalData.size());
+ if (!BufferOrErr)
+@@ -200,8 +201,7 @@ static Error dumpSectionToFile(StringRef SecName, StringRef Filename,
+ return Error::success();
+ }
+ }
+- return make_error<StringError>("Section not found",
+- object_error::parse_failed);
++ return createStringError(object_error::parse_failed, "Section not found");
+ }
+
+ static bool isCompressed(const SectionBase &Section) {
+--
+2.17.1
+
diff --git a/projects/clang/win-patches/llvm-objcopy-7.patch b/projects/clang/win-patches/llvm-objcopy-7.patch
new file mode 100644
index 0000000..80e9785
--- /dev/null
+++ b/projects/clang/win-patches/llvm-objcopy-7.patch
@@ -0,0 +1,224 @@
+From d37f67c7311cd371d9ff1afd398bc92f309e6baf Mon Sep 17 00:00:00 2001
+From: Martin Storsjo <martin(a)martin.st>
+Date: Tue, 22 Jan 2019 10:58:09 +0000
+Subject: [PATCH] [llvm-objcopy] [COFF] Update symbol indices in weak externals
+
+Differential Revision: https://reviews.llvm.org/D57006
+
+git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351800 91177308-0d34-0410-b5e6-96231b3b80d8
+---
+ .../llvm-objcopy/COFF/weak-external.test | 49 +++++++++++++++++++
+ tools/llvm-objcopy/COFF/Object.h | 2 +
+ tools/llvm-objcopy/COFF/Reader.cpp | 24 ++++++++-
+ tools/llvm-objcopy/COFF/Reader.h | 2 +-
+ tools/llvm-objcopy/COFF/Writer.cpp | 16 +++++-
+ tools/llvm-objcopy/COFF/Writer.h | 2 +-
+ 6 files changed, 89 insertions(+), 6 deletions(-)
+ create mode 100644 test/tools/llvm-objcopy/COFF/weak-external.test
+
+diff --git a/llvm/test/tools/llvm-objcopy/COFF/weak-external.test b/llvm/test/tools/llvm-objcopy/COFF/weak-external.test
+new file mode 100644
+index 00000000000..d36a53b4eb1
+--- /dev/null
++++ b/llvm/test/tools/llvm-objcopy/COFF/weak-external.test
+@@ -0,0 +1,49 @@
++# RUN: yaml2obj %s > %t.in.o
++
++# RUN: llvm-objdump -t %t.in.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-PRE
++
++# RUN: llvm-objcopy -N func %t.in.o %t.out.o
++# RUN: llvm-objdump -t %t.out.o | FileCheck %s --check-prefixes=SYMBOLS,SYMBOLS-POST
++
++# RUN: not llvm-objcopy -N .weak.foobar.file1 %t.in.o %t.err.o 2>&1 | FileCheck %s --check-prefix=ERROR
++
++# SYMBOLS: SYMBOL TABLE:
++# SYMBOLS-PRE-NEXT: func
++# SYMBOLS-NEXT: .weak.foobar.file1
++# SYMBOLS-NEXT: foobar
++# SYMBOLS-PRE-NEXT: AUX indx 1
++# SYMBOLS-POST-NEXT: AUX indx 0
++# SYMBOLS-EMPTY:
++
++# ERROR: Symbol 'foobar' is missing its weak target
++
++--- !COFF
++header:
++ Machine: IMAGE_FILE_MACHINE_AMD64
++ Characteristics: [ ]
++sections:
++ - Name: .text
++ Characteristics: [ ]
++symbols:
++ - Name: func
++ Value: 0
++ SectionNumber: 1
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_NULL
++ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
++ - Name: .weak.foobar.file1
++ Value: 1
++ SectionNumber: 1
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_NULL
++ StorageClass: IMAGE_SYM_CLASS_EXTERNAL
++ - Name: foobar
++ Value: 0
++ SectionNumber: 0
++ SimpleType: IMAGE_SYM_TYPE_NULL
++ ComplexType: IMAGE_SYM_DTYPE_FUNCTION
++ StorageClass: IMAGE_SYM_CLASS_WEAK_EXTERNAL
++ WeakExternal:
++ TagIndex: 1
++ Characteristics: IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY
++...
+diff --git a/llvm/tools/llvm-objcopy/COFF/Object.h b/llvm/tools/llvm-objcopy/COFF/Object.h
+index 8e200369f0b..0630f9c5ff8 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Object.h
++++ b/llvm/tools/llvm-objcopy/COFF/Object.h
+@@ -11,6 +11,7 @@
+
+ #include "llvm/ADT/ArrayRef.h"
+ #include "llvm/ADT/DenseMap.h"
++#include "llvm/ADT/Optional.h"
+ #include "llvm/ADT/StringRef.h"
+ #include "llvm/ADT/iterator_range.h"
+ #include "llvm/BinaryFormat/COFF.h"
+@@ -47,6 +48,7 @@ struct Symbol {
+ std::vector<uint8_t> AuxData;
+ ssize_t TargetSectionId;
+ ssize_t AssociativeComdatTargetSectionId = 0;
++ Optional<size_t> WeakTargetSymbolId;
+ size_t UniqueId;
+ size_t RawIndex;
+ bool Referenced;
+diff --git a/llvm/tools/llvm-objcopy/COFF/Reader.cpp b/llvm/tools/llvm-objcopy/COFF/Reader.cpp
+index 20ff32a59dc..2446277cc2b 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Reader.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Reader.cpp
+@@ -121,12 +121,18 @@ Error COFFReader::readSymbols(Object &Obj, bool IsBigObj) const {
+ // For section definitions, check if it is comdat associative, and if
+ // it is, find the target section unique id.
+ const coff_aux_section_definition *SD = SymRef.getSectionDefinition();
++ const coff_aux_weak_external *WE = SymRef.getWeakExternal();
+ if (SD && SD->Selection == IMAGE_COMDAT_SELECT_ASSOCIATIVE) {
+ int32_t Index = SD->getNumber(IsBigObj);
+ if (Index <= 0 || static_cast<uint32_t>(Index - 1) >= Sections.size())
+ return createStringError(object_error::parse_failed,
+ "Unexpected associative section index");
+ Sym.AssociativeComdatTargetSectionId = Sections[Index - 1].UniqueId;
++ } else if (WE) {
++ // This is a raw symbol index for now, but store it in the Symbol
++ // until we've added them to the Object, which assigns the final
++ // unique ids.
++ Sym.WeakTargetSymbolId = WE->TagIndex;
+ }
+ I += 1 + SymRef.getNumberOfAuxSymbols();
+ }
+@@ -134,13 +140,27 @@ Error COFFReader::readSymbols(Object &Obj, bool IsBigObj) const {
+ return Error::success();
+ }
+
+-Error COFFReader::setRelocTargets(Object &Obj) const {
++Error COFFReader::setSymbolTargets(Object &Obj) const {
+ std::vector<const Symbol *> RawSymbolTable;
+ for (const Symbol &Sym : Obj.getSymbols()) {
+ RawSymbolTable.push_back(&Sym);
+ for (size_t I = 0; I < Sym.Sym.NumberOfAuxSymbols; I++)
+ RawSymbolTable.push_back(nullptr);
+ }
++ for (Symbol &Sym : Obj.getMutableSymbols()) {
++ // Convert WeakTargetSymbolId from the original raw symbol index to
++ // a proper unique id.
++ if (Sym.WeakTargetSymbolId) {
++ if (*Sym.WeakTargetSymbolId >= RawSymbolTable.size())
++ return createStringError(object_error::parse_failed,
++ "Weak external reference out of range");
++ const Symbol *Target = RawSymbolTable[*Sym.WeakTargetSymbolId];
++ if (Target == nullptr)
++ return createStringError(object_error::parse_failed,
++ "Invalid SymbolTableIndex");
++ Sym.WeakTargetSymbolId = Target->UniqueId;
++ }
++ }
+ for (Section &Sec : Obj.getMutableSections()) {
+ for (Relocation &R : Sec.Relocs) {
+ if (R.Reloc.SymbolTableIndex >= RawSymbolTable.size())
+@@ -184,7 +204,7 @@ Expected<std::unique_ptr<Object>> COFFReader::create() const {
+ return std::move(E);
+ if (Error E = readSymbols(*Obj, IsBigObj))
+ return std::move(E);
+- if (Error E = setRelocTargets(*Obj))
++ if (Error E = setSymbolTargets(*Obj))
+ return std::move(E);
+
+ return std::move(Obj);
+diff --git a/llvm/tools/llvm-objcopy/COFF/Reader.h b/llvm/tools/llvm-objcopy/COFF/Reader.h
+index 4493705e73c..ec15369db0b 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Reader.h
++++ b/llvm/tools/llvm-objcopy/COFF/Reader.h
+@@ -28,7 +28,7 @@ class COFFReader {
+ Error readExecutableHeaders(Object &Obj) const;
+ Error readSections(Object &Obj) const;
+ Error readSymbols(Object &Obj, bool IsBigObj) const;
+- Error setRelocTargets(Object &Obj) const;
++ Error setSymbolTargets(Object &Obj) const;
+
+ public:
+ explicit COFFReader(const COFFObjectFile &O) : COFFObj(O) {}
+diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.cpp b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
+index 0321f94a896..4f57131d5ab 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Writer.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
+@@ -38,7 +38,7 @@ Error COFFWriter::finalizeRelocTargets() {
+ return Error::success();
+ }
+
+-Error COFFWriter::finalizeSectionNumbers() {
++Error COFFWriter::finalizeSymbolContents() {
+ for (Symbol &Sym : Obj.getMutableSymbols()) {
+ if (Sym.TargetSectionId <= 0) {
+ // Undefined, or a special kind of symbol. These negative values
+@@ -75,6 +75,18 @@ Error COFFWriter::finalizeSectionNumbers() {
+ SD->NumberHighPart = static_cast<uint16_t>(SDSectionNumber >> 16);
+ }
+ }
++ // Check that we actually have got AuxData to match the weak symbol target
++ // we want to set. Only >= 1 would be required, but only == 1 makes sense.
++ if (Sym.WeakTargetSymbolId && Sym.Sym.NumberOfAuxSymbols == 1) {
++ coff_aux_weak_external *WE =
++ reinterpret_cast<coff_aux_weak_external *>(Sym.AuxData.data());
++ const Symbol *Target = Obj.findSymbol(*Sym.WeakTargetSymbolId);
++ if (Target == nullptr)
++ return createStringError(object_error::invalid_symbol_index,
++ "Symbol '%s' is missing its weak target",
++ Sym.Name.str().c_str());
++ WE->TagIndex = Target->RawIndex;
++ }
+ }
+ return Error::success();
+ }
+@@ -137,7 +149,7 @@ std::pair<size_t, size_t> COFFWriter::finalizeSymbolTable() {
+ Error COFFWriter::finalize(bool IsBigObj) {
+ if (Error E = finalizeRelocTargets())
+ return E;
+- if (Error E = finalizeSectionNumbers())
++ if (Error E = finalizeSymbolContents())
+ return E;
+
+ size_t SizeOfHeaders = 0;
+diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.h b/llvm/tools/llvm-objcopy/COFF/Writer.h
+index a967a103df9..9b1cfa91d00 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Writer.h
++++ b/llvm/tools/llvm-objcopy/COFF/Writer.h
+@@ -31,7 +31,7 @@ class COFFWriter {
+ StringTableBuilder StrTabBuilder;
+
+ Error finalizeRelocTargets();
+- Error finalizeSectionNumbers();
++ Error finalizeSymbolContents();
+ void layoutSections();
+ size_t finalizeStringTable();
+ template <class SymbolTy> std::pair<size_t, size_t> finalizeSymbolTable();
+--
+2.17.1
+
diff --git a/projects/clang/win-patches/llvm-objcopy-8.patch b/projects/clang/win-patches/llvm-objcopy-8.patch
new file mode 100644
index 0000000..6fd9776
--- /dev/null
+++ b/projects/clang/win-patches/llvm-objcopy-8.patch
@@ -0,0 +1,330 @@
+From 8cf7aa39d7c9461e2d765f6d4fa7e0925571695f Mon Sep 17 00:00:00 2001
+From: Jordan Rupprecht <rupprecht(a)google.com>
+Date: Tue, 22 Jan 2019 23:49:16 +0000
+Subject: [PATCH] [llvm-objcopy] Return Error from Buffer::allocate(),
+ [ELF]Writer::finalize(), and [ELF]Writer::commit()
+
+Summary:
+This patch changes a few methods to return Error instead of manually calling error/reportError to abort. This will make it easier to extract into a library.
+
+Note that error() takes just a string (this patch also adds an overload that takes an Error), while reportError() takes string + [error/code]. To help unify things, use FileError to associate a given filename with an error. Note that this takes some special care (for now), e.g. calling reportError(FileName, <something that could be FileError>) will duplicate the filename. The goal is to eventually remove reportError() and have every error associated with a file to be a FileError, and just one error handling block at the tool level.
+
+This change was suggested in D56806. I took it a little further than suggested, but completely fixing llvm-objcopy will take a couple more patches. If this approach looks good, I'll commit this and apply similar patche(s) for the rest.
+
+This change is NFC in terms of non-error related code, although the error message changes in one context.
+
+Reviewers: alexshap, jhenderson, jakehehrlich, mstorsjo, espindola
+
+Reviewed By: alexshap, jhenderson
+
+Subscribers: llvm-commits, emaste, arichardson
+
+Differential Revision: https://reviews.llvm.org/D56930
+
+git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351896 91177308-0d34-0410-b5e6-96231b3b80d8
+---
+ .../ELF/fail-no-output-directory.test | 2 +-
+ tools/llvm-objcopy/Buffer.cpp | 20 ++++++++++++-----
+ tools/llvm-objcopy/Buffer.h | 6 ++---
+ tools/llvm-objcopy/COFF/Writer.cpp | 3 ++-
+ tools/llvm-objcopy/ELF/ELFObjcopy.cpp | 18 ++++++++++-----
+ tools/llvm-objcopy/ELF/Object.cpp | 22 ++++++++++---------
+ tools/llvm-objcopy/ELF/Object.h | 12 +++++-----
+ tools/llvm-objcopy/llvm-objcopy.cpp | 15 +++++++++++--
+ tools/llvm-objcopy/llvm-objcopy.h | 1 +
+ 9 files changed, 64 insertions(+), 35 deletions(-)
+
+diff --git a/llvm/test/tools/llvm-objcopy/ELF/fail-no-output-directory.test b/llvm/test/tools/llvm-objcopy/ELF/fail-no-output-directory.test
+index f66b2e09fce..732046fa925 100644
+--- a/llvm/test/tools/llvm-objcopy/ELF/fail-no-output-directory.test
++++ b/llvm/test/tools/llvm-objcopy/ELF/fail-no-output-directory.test
+@@ -1,6 +1,6 @@
+ # RUN: yaml2obj %s > %t
+ # RUN: not llvm-objcopy %t no/such/dir 2>&1 | FileCheck %s
+-# CHECK: failed to open no/such/dir:
++# CHECK: error: 'no/such/dir': No such file or directory
+
+ !ELF
+ FileHeader:
+diff --git a/llvm/tools/llvm-objcopy/Buffer.cpp b/llvm/tools/llvm-objcopy/Buffer.cpp
+index 2da03dee1af..1789097f276 100644
+--- a/llvm/tools/llvm-objcopy/Buffer.cpp
++++ b/llvm/tools/llvm-objcopy/Buffer.cpp
+@@ -17,23 +17,31 @@ namespace objcopy {
+
+ Buffer::~Buffer() {}
+
+-void FileBuffer::allocate(size_t Size) {
++Error FileBuffer::allocate(size_t Size) {
+ Expected<std::unique_ptr<FileOutputBuffer>> BufferOrErr =
+ FileOutputBuffer::create(getName(), Size, FileOutputBuffer::F_executable);
+- handleAllErrors(BufferOrErr.takeError(), [this](const ErrorInfoBase &E) {
+- error("failed to open " + getName() + ": " + E.message());
+- });
++ // FileOutputBuffer::create() returns an Error that is just a wrapper around
++ // std::error_code. Wrap it in FileError to include the actual filename.
++ if (!BufferOrErr)
++ return createFileError(getName(), BufferOrErr.takeError());
+ Buf = std::move(*BufferOrErr);
++ return Error::success();
+ }
+
+-Error FileBuffer::commit() { return Buf->commit(); }
++Error FileBuffer::commit() {
++ Error Err = Buf->commit();
++ // FileOutputBuffer::commit() returns an Error that is just a wrapper around
++ // std::error_code. Wrap it in FileError to include the actual filename.
++ return Err ? createFileError(getName(), std::move(Err)) : std::move(Err);
++}
+
+ uint8_t *FileBuffer::getBufferStart() {
+ return reinterpret_cast<uint8_t *>(Buf->getBufferStart());
+ }
+
+-void MemBuffer::allocate(size_t Size) {
++Error MemBuffer::allocate(size_t Size) {
+ Buf = WritableMemoryBuffer::getNewMemBuffer(Size, getName());
++ return Error::success();
+ }
+
+ Error MemBuffer::commit() { return Error::success(); }
+diff --git a/llvm/tools/llvm-objcopy/Buffer.h b/llvm/tools/llvm-objcopy/Buffer.h
+index 482777fe05c..40670accac2 100644
+--- a/llvm/tools/llvm-objcopy/Buffer.h
++++ b/llvm/tools/llvm-objcopy/Buffer.h
+@@ -27,7 +27,7 @@ class Buffer {
+
+ public:
+ virtual ~Buffer();
+- virtual void allocate(size_t Size) = 0;
++ virtual Error allocate(size_t Size) = 0;
+ virtual uint8_t *getBufferStart() = 0;
+ virtual Error commit() = 0;
+
+@@ -39,7 +39,7 @@ class FileBuffer : public Buffer {
+ std::unique_ptr<FileOutputBuffer> Buf;
+
+ public:
+- void allocate(size_t Size) override;
++ Error allocate(size_t Size) override;
+ uint8_t *getBufferStart() override;
+ Error commit() override;
+
+@@ -50,7 +50,7 @@ class MemBuffer : public Buffer {
+ std::unique_ptr<WritableMemoryBuffer> Buf;
+
+ public:
+- void allocate(size_t Size) override;
++ Error allocate(size_t Size) override;
+ uint8_t *getBufferStart() override;
+ Error commit() override;
+
+diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.cpp b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
+index 4f57131d5ab..db3589bb119 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Writer.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
+@@ -324,7 +324,8 @@ Error COFFWriter::write(bool IsBigObj) {
+ if (Error E = finalize(IsBigObj))
+ return E;
+
+- Buf.allocate(FileSize);
++ if (Error E = Buf.allocate(FileSize))
++ return E;
+
+ writeHeaders(IsBigObj);
+ writeSections();
+diff --git a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
+index a2996395c1f..2a52f1f9951 100644
+--- a/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
++++ b/llvm/tools/llvm-objcopy/ELF/ELFObjcopy.cpp
+@@ -176,8 +176,10 @@ static void splitDWOToFile(const CopyConfig &Config, const Reader &Reader,
+ DWOFile->Machine = Config.OutputArch.getValue().EMachine;
+ FileBuffer FB(File);
+ auto Writer = createWriter(Config, *DWOFile, FB, OutputElfType);
+- Writer->finalize();
+- Writer->write();
++ if (Error E = Writer->finalize())
++ error(std::move(E));
++ if (Error E = Writer->write())
++ error(std::move(E));
+ }
+
+ static Error dumpSectionToFile(StringRef SecName, StringRef Filename,
+@@ -542,8 +544,10 @@ void executeObjcopyOnRawBinary(const CopyConfig &Config, MemoryBuffer &In,
+ handleArgs(Config, *Obj, Reader, OutputElfType);
+ std::unique_ptr<Writer> Writer =
+ createWriter(Config, *Obj, Out, OutputElfType);
+- Writer->finalize();
+- Writer->write();
++ if (Error E = Writer->finalize())
++ error(std::move(E));
++ if (Error E = Writer->write())
++ error(std::move(E));
+ }
+
+ void executeObjcopyOnBinary(const CopyConfig &Config,
+@@ -570,8 +574,10 @@ void executeObjcopyOnBinary(const CopyConfig &Config,
+ handleArgs(Config, *Obj, Reader, OutputElfType);
+ std::unique_ptr<Writer> Writer =
+ createWriter(Config, *Obj, Out, OutputElfType);
+- Writer->finalize();
+- Writer->write();
++ if (Error E = Writer->finalize())
++ error(std::move(E));
++ if (Error E = Writer->write())
++ error(std::move(E));
+ if (!Config.BuildIdLinkDir.empty() && Config.BuildIdLinkOutput) {
+ linkToBuildIdDir(Config, Config.OutputFilename,
+ Config.BuildIdLinkOutput.getValue(), BuildIdBytes);
+diff --git a/llvm/tools/llvm-objcopy/ELF/Object.cpp b/llvm/tools/llvm-objcopy/ELF/Object.cpp
+index fecb752a39f..ef5dc5d7951 100644
+--- a/llvm/tools/llvm-objcopy/ELF/Object.cpp
++++ b/llvm/tools/llvm-objcopy/ELF/Object.cpp
+@@ -1488,17 +1488,16 @@ template <class ELFT> size_t ELFWriter<ELFT>::totalSize() const {
+ NullSectionSize;
+ }
+
+-template <class ELFT> void ELFWriter<ELFT>::write() {
++template <class ELFT> Error ELFWriter<ELFT>::write() {
+ writeEhdr();
+ writePhdrs();
+ writeSectionData();
+ if (WriteSectionHeaders)
+ writeShdrs();
+- if (auto E = Buf.commit())
+- reportError(Buf.getName(), errorToErrorCode(std::move(E)));
++ return Buf.commit();
+ }
+
+-template <class ELFT> void ELFWriter<ELFT>::finalize() {
++template <class ELFT> Error ELFWriter<ELFT>::finalize() {
+ // It could happen that SectionNames has been removed and yet the user wants
+ // a section header table output. We need to throw an error if a user tries
+ // to do that.
+@@ -1582,21 +1581,22 @@ template <class ELFT> void ELFWriter<ELFT>::finalize() {
+ Section.finalize();
+ }
+
+- Buf.allocate(totalSize());
++ if (Error E = Buf.allocate(totalSize()))
++ return E;
+ SecWriter = llvm::make_unique<ELFSectionWriter<ELFT>>(Buf);
++ return Error::success();
+ }
+
+-void BinaryWriter::write() {
++Error BinaryWriter::write() {
+ for (auto &Section : Obj.sections()) {
+ if ((Section.Flags & SHF_ALLOC) == 0)
+ continue;
+ Section.accept(*SecWriter);
+ }
+- if (auto E = Buf.commit())
+- reportError(Buf.getName(), errorToErrorCode(std::move(E)));
++ return Buf.commit();
+ }
+
+-void BinaryWriter::finalize() {
++Error BinaryWriter::finalize() {
+ // TODO: Create a filter range to construct OrderedSegments from so that this
+ // code can be deduped with assignOffsets above. This should also solve the
+ // todo below for LayoutSections.
+@@ -1675,8 +1675,10 @@ void BinaryWriter::finalize() {
+ TotalSize = std::max(TotalSize, Section->Offset + Section->Size);
+ }
+
+- Buf.allocate(TotalSize);
++ if (Error E = Buf.allocate(TotalSize))
++ return E;
+ SecWriter = llvm::make_unique<BinarySectionWriter>(Buf);
++ return Error::success();
+ }
+
+ template class ELFBuilder<ELF64LE>;
+diff --git a/llvm/tools/llvm-objcopy/ELF/Object.h b/llvm/tools/llvm-objcopy/ELF/Object.h
+index 0dcb0d888bc..9e2b64be9dc 100644
+--- a/llvm/tools/llvm-objcopy/ELF/Object.h
++++ b/llvm/tools/llvm-objcopy/ELF/Object.h
+@@ -193,8 +193,8 @@ protected:
+
+ public:
+ virtual ~Writer();
+- virtual void finalize() = 0;
+- virtual void write() = 0;
++ virtual Error finalize() = 0;
++ virtual Error write() = 0;
+
+ Writer(Object &O, Buffer &B) : Obj(O), Buf(B) {}
+ };
+@@ -226,8 +226,8 @@ public:
+ virtual ~ELFWriter() {}
+ bool WriteSectionHeaders = true;
+
+- void finalize() override;
+- void write() override;
++ Error finalize() override;
++ Error write() override;
+ ELFWriter(Object &Obj, Buffer &Buf, bool WSH)
+ : Writer(Obj, Buf), WriteSectionHeaders(WSH) {}
+ };
+@@ -240,8 +240,8 @@ private:
+
+ public:
+ ~BinaryWriter() {}
+- void finalize() override;
+- void write() override;
++ Error finalize() override;
++ Error write() override;
+ BinaryWriter(Object &Obj, Buffer &Buf) : Writer(Obj, Buf) {}
+ };
+
+diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
+index d27395f2ae0..75d513546b7 100644
+--- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
++++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
+@@ -56,6 +56,16 @@ LLVM_ATTRIBUTE_NORETURN void error(Twine Message) {
+ exit(1);
+ }
+
++LLVM_ATTRIBUTE_NORETURN void error(Error E) {
++ assert(E);
++ std::string Buf;
++ raw_string_ostream OS(Buf);
++ logAllUnhandledErrors(std::move(E), OS);
++ OS.flush();
++ WithColor::error(errs(), ToolName) << Buf;
++ exit(1);
++}
++
+ LLVM_ATTRIBUTE_NORETURN void reportError(StringRef File, std::error_code EC) {
+ assert(EC);
+ WithColor::error(errs(), ToolName)
+@@ -100,10 +110,11 @@ static Error deepWriteArchive(StringRef ArcName,
+ // NewArchiveMember still requires them even though writeArchive does not
+ // write them on disk.
+ FileBuffer FB(Member.MemberName);
+- FB.allocate(Member.Buf->getBufferSize());
++ if (Error E = FB.allocate(Member.Buf->getBufferSize()))
++ return E;
+ std::copy(Member.Buf->getBufferStart(), Member.Buf->getBufferEnd(),
+ FB.getBufferStart());
+- if (auto E = FB.commit())
++ if (Error E = FB.commit())
+ return E;
+ }
+ return Error::success();
+diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.h b/llvm/tools/llvm-objcopy/llvm-objcopy.h
+index 46d8339576c..18a789ca1f8 100644
+--- a/llvm/tools/llvm-objcopy/llvm-objcopy.h
++++ b/llvm/tools/llvm-objcopy/llvm-objcopy.h
+@@ -19,6 +19,7 @@ namespace llvm {
+ namespace objcopy {
+
+ LLVM_ATTRIBUTE_NORETURN extern void error(Twine Message);
++LLVM_ATTRIBUTE_NORETURN extern void error(Error E);
+ LLVM_ATTRIBUTE_NORETURN extern void reportError(StringRef File, Error E);
+ LLVM_ATTRIBUTE_NORETURN extern void reportError(StringRef File,
+ std::error_code EC);
+--
+2.17.1
+
diff --git a/projects/clang/win-patches/llvm-objcopy-9.patch b/projects/clang/win-patches/llvm-objcopy-9.patch
new file mode 100644
index 0000000..6cb4656
--- /dev/null
+++ b/projects/clang/win-patches/llvm-objcopy-9.patch
@@ -0,0 +1,260 @@
+From 840d70f854a1d550924ced1d00160efcc7b8549a Mon Sep 17 00:00:00 2001
+From: Martin Storsjo <martin(a)martin.st>
+Date: Wed, 23 Jan 2019 08:25:28 +0000
+Subject: [PATCH] Reapply: [llvm-objcopy] [COFF] Implement --add-gnu-debuglink
+
+This was reverted since it broke a couple buildbots. The reason
+for the breakage is not yet known, but this time, the test has
+got more diagnostics added, to hopefully allow figuring out
+what goes wrong.
+
+Differential Revision: https://reviews.llvm.org/D57007
+
+git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@351931 91177308-0d34-0410-b5e6-96231b3b80d8
+---
+ .../llvm-objcopy/COFF/add-gnu-debuglink.test | 48 +++++++++++++++
+ tools/llvm-objcopy/COFF/COFFObjcopy.cpp | 61 +++++++++++++++++++
+ tools/llvm-objcopy/COFF/Object.cpp | 2 +-
+ tools/llvm-objcopy/COFF/Object.h | 26 +++++++-
+ tools/llvm-objcopy/COFF/Reader.cpp | 4 +-
+ tools/llvm-objcopy/COFF/Writer.cpp | 9 +--
+ 6 files changed, 143 insertions(+), 7 deletions(-)
+ create mode 100644 test/tools/llvm-objcopy/COFF/add-gnu-debuglink.test
+
+diff --git a/llvm/test/tools/llvm-objcopy/COFF/add-gnu-debuglink.test b/llvm/test/tools/llvm-objcopy/COFF/add-gnu-debuglink.test
+new file mode 100644
+index 00000000000..cf3a9bba920
+--- /dev/null
++++ b/llvm/test/tools/llvm-objcopy/COFF/add-gnu-debuglink.test
+@@ -0,0 +1,48 @@
++RUN: yaml2obj %p/Inputs/x86_64-exe.yaml > %t.in123.exe
++
++# Using a debuglink filename with a length that is a multiple of 4, to
++# showcase padding in CONTENTS below.
++
++RUN: llvm-objcopy --add-gnu-debuglink=%t.in123.exe %t.in123.exe %t.out.exe
++
++# Temporary debugging of issues with this test:
++RUN: ls -l %t.out.exe || true
++RUN: od -Ax -t x1 %t.out.exe || true
++RUN: llvm-readobj -sections %t.out.exe || true
++
++RUN: llvm-readobj -sections %t.out.exe | FileCheck %s --check-prefix=SECTIONS
++RUN: llvm-objdump -s %t.out.exe | FileCheck %s --check-prefix=CONTENTS
++
++# Show the last of the preexisting sections, which is used for choosing
++# a virtual address for the generated one.
++
++SECTIONS: Section {
++SECTIONS: Number: 4
++SECTIONS-NEXT: Name: .pdata
++SECTIONS-NEXT: VirtualSize: 0x18
++SECTIONS-NEXT: VirtualAddress: 0x4000
++SECTIONS-NEXT: RawDataSize: 512
++SECTIONS: Section {
++SECTIONS-NEXT: Number: 5
++SECTIONS-NEXT: Name: .gnu_debuglink
++SECTIONS-NEXT: VirtualSize: 0x2C
++SECTIONS-NEXT: VirtualAddress: 0x5000
++SECTIONS-NEXT: RawDataSize: 512
++SECTIONS-NEXT: PointerToRawData:
++SECTIONS-NEXT: PointerToRelocations:
++SECTIONS-NEXT: PointerToLineNumbers:
++SECTIONS-NEXT: RelocationCount:
++SECTIONS-NEXT: LineNumberCount:
++SECTIONS-NEXT: Characteristics [ (0x42000040)
++SECTIONS-NEXT: IMAGE_SCN_CNT_INITIALIZED_DATA (0x40)
++SECTIONS-NEXT: IMAGE_SCN_MEM_DISCARDABLE (0x2000000)
++SECTIONS-NEXT: IMAGE_SCN_MEM_READ (0x40000000)
++SECTIONS-NEXT: ]
++
++# Note: The last 4 bytes here are the crc of the referenced file - if the
++# yaml2obj generated file changes, this crc changes.
++
++CONTENTS: Contents of section .gnu_debuglink:
++CONTENTS: 40005000 6164642d 676e752d 64656275 676c696e add-gnu-debuglin
++CONTENTS: 40005010 6b2e7465 73742e74 6d702e69 6e313233 k.test.tmp.in123
++CONTENTS: 40005020 2e657865 00000000 7929adc3 .exe
+diff --git a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+index 8d8f53d13d8..20adbe11e7a 100644
+--- a/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/COFFObjcopy.cpp
+@@ -17,6 +17,8 @@
+ #include "llvm/Object/Binary.h"
+ #include "llvm/Object/COFF.h"
+ #include "llvm/Support/Errc.h"
++#include "llvm/Support/JamCRC.h"
++#include "llvm/Support/Path.h"
+ #include <cassert>
+
+ namespace llvm {
+@@ -30,6 +32,61 @@ static bool isDebugSection(const Section &Sec) {
+ return Sec.Name.startswith(".debug");
+ }
+
++static uint64_t getNextRVA(const Object &Obj) {
++ if (Obj.getSections().empty())
++ return 0;
++ const Section &Last = Obj.getSections().back();
++ return alignTo(Last.Header.VirtualAddress + Last.Header.VirtualSize,
++ Obj.PeHeader.SectionAlignment);
++}
++
++static uint32_t getCRC32(StringRef Data) {
++ JamCRC CRC;
++ CRC.update(ArrayRef<char>(Data.data(), Data.size()));
++ // The CRC32 value needs to be complemented because the JamCRC dosn't
++ // finalize the CRC32 value. It also dosn't negate the initial CRC32 value
++ // but it starts by default at 0xFFFFFFFF which is the complement of zero.
++ return ~CRC.getCRC();
++}
++
++static std::vector<uint8_t> createGnuDebugLinkSectionContents(StringRef File) {
++ ErrorOr<std::unique_ptr<MemoryBuffer>> LinkTargetOrErr =
++ MemoryBuffer::getFile(File);
++ if (!LinkTargetOrErr)
++ error("'" + File + "': " + LinkTargetOrErr.getError().message());
++ auto LinkTarget = std::move(*LinkTargetOrErr);
++ uint32_t CRC32 = getCRC32(LinkTarget->getBuffer());
++
++ StringRef FileName = sys::path::filename(File);
++ size_t CRCPos = alignTo(FileName.size() + 1, 4);
++ std::vector<uint8_t> Data(CRCPos + 4);
++ memcpy(Data.data(), FileName.data(), FileName.size());
++ support::endian::write32le(Data.data() + CRCPos, CRC32);
++ return Data;
++}
++
++static void addGnuDebugLink(Object &Obj, StringRef DebugLinkFile) {
++ uint32_t StartRVA = getNextRVA(Obj);
++
++ std::vector<Section> Sections;
++ Section Sec;
++ Sec.setOwnedContents(createGnuDebugLinkSectionContents(DebugLinkFile));
++ Sec.Name = ".gnu_debuglink";
++ Sec.Header.VirtualSize = Sec.getContents().size();
++ Sec.Header.VirtualAddress = StartRVA;
++ Sec.Header.SizeOfRawData =
++ alignTo(Sec.Header.VirtualSize, Obj.PeHeader.FileAlignment);
++ // Sec.Header.PointerToRawData is filled in by the writer.
++ Sec.Header.PointerToRelocations = 0;
++ Sec.Header.PointerToLinenumbers = 0;
++ // Sec.Header.NumberOfRelocations is filled in by the writer.
++ Sec.Header.NumberOfLinenumbers = 0;
++ Sec.Header.Characteristics = IMAGE_SCN_CNT_INITIALIZED_DATA |
++ IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE;
++ Sections.push_back(Sec);
++ Obj.addSections(Sections);
++}
++
+ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
+ // Perform the actual section removals.
+ Obj.removeSections([&Config](const Section &Sec) {
+@@ -109,6 +166,10 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
+
+ return false;
+ });
++
++ if (!Config.AddGnuDebugLink.empty())
++ addGnuDebugLink(Obj, Config.AddGnuDebugLink);
++
+ return Error::success();
+ }
+
+diff --git a/llvm/tools/llvm-objcopy/COFF/Object.cpp b/llvm/tools/llvm-objcopy/COFF/Object.cpp
+index 83435dffa98..8c382c1faef 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Object.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Object.cpp
+@@ -129,7 +129,7 @@ void Object::removeSections(function_ref<bool(const Section &)> ToRemove) {
+ void Object::truncateSections(function_ref<bool(const Section &)> ToTruncate) {
+ for (Section &Sec : Sections) {
+ if (ToTruncate(Sec)) {
+- Sec.Contents = ArrayRef<uint8_t>();
++ Sec.clearContents();
+ Sec.Relocs.clear();
+ Sec.Header.SizeOfRawData = 0;
+ }
+diff --git a/llvm/tools/llvm-objcopy/COFF/Object.h b/llvm/tools/llvm-objcopy/COFF/Object.h
+index 0630f9c5ff8..afa272286ef 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Object.h
++++ b/llvm/tools/llvm-objcopy/COFF/Object.h
+@@ -35,11 +35,35 @@ struct Relocation {
+
+ struct Section {
+ object::coff_section Header;
+- ArrayRef<uint8_t> Contents;
+ std::vector<Relocation> Relocs;
+ StringRef Name;
+ ssize_t UniqueId;
+ size_t Index;
++
++ ArrayRef<uint8_t> getContents() const {
++ if (!OwnedContents.empty())
++ return OwnedContents;
++ return ContentsRef;
++ }
++
++ void setContentsRef(ArrayRef<uint8_t> Data) {
++ OwnedContents.clear();
++ ContentsRef = Data;
++ }
++
++ void setOwnedContents(std::vector<uint8_t> &&Data) {
++ ContentsRef = ArrayRef<uint8_t>();
++ OwnedContents = std::move(Data);
++ }
++
++ void clearContents() {
++ ContentsRef = ArrayRef<uint8_t>();
++ OwnedContents.clear();
++ }
++
++private:
++ ArrayRef<uint8_t> ContentsRef;
++ std::vector<uint8_t> OwnedContents;
+ };
+
+ struct Symbol {
+diff --git a/llvm/tools/llvm-objcopy/COFF/Reader.cpp b/llvm/tools/llvm-objcopy/COFF/Reader.cpp
+index 2446277cc2b..87dd60a43cf 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Reader.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Reader.cpp
+@@ -69,8 +69,10 @@ Error COFFReader::readSections(Object &Obj) const {
+ Sections.push_back(Section());
+ Section &S = Sections.back();
+ S.Header = *Sec;
+- if (auto EC = COFFObj.getSectionContents(Sec, S.Contents))
++ ArrayRef<uint8_t> Contents;
++ if (auto EC = COFFObj.getSectionContents(Sec, Contents))
+ return errorCodeToError(EC);
++ S.setContentsRef(Contents);
+ ArrayRef<coff_relocation> Relocs = COFFObj.getRelocations(Sec);
+ for (const coff_relocation &R : Relocs)
+ S.Relocs.push_back(R);
+diff --git a/llvm/tools/llvm-objcopy/COFF/Writer.cpp b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
+index db3589bb119..05e46291c39 100644
+--- a/llvm/tools/llvm-objcopy/COFF/Writer.cpp
++++ b/llvm/tools/llvm-objcopy/COFF/Writer.cpp
+@@ -286,14 +286,15 @@ void COFFWriter::writeHeaders(bool IsBigObj) {
+ void COFFWriter::writeSections() {
+ for (const auto &S : Obj.getSections()) {
+ uint8_t *Ptr = Buf.getBufferStart() + S.Header.PointerToRawData;
+- std::copy(S.Contents.begin(), S.Contents.end(), Ptr);
++ ArrayRef<uint8_t> Contents = S.getContents();
++ std::copy(Contents.begin(), Contents.end(), Ptr);
+
+ // For executable sections, pad the remainder of the raw data size with
+ // 0xcc, which is int3 on x86.
+ if ((S.Header.Characteristics & IMAGE_SCN_CNT_CODE) &&
+- S.Header.SizeOfRawData > S.Contents.size())
+- memset(Ptr + S.Contents.size(), 0xcc,
+- S.Header.SizeOfRawData - S.Contents.size());
++ S.Header.SizeOfRawData > Contents.size())
++ memset(Ptr + Contents.size(), 0xcc,
++ S.Header.SizeOfRawData - Contents.size());
+
+ Ptr += S.Header.SizeOfRawData;
+ for (const auto &R : S.Relocs) {
+--
+2.17.1
+
1
0
commit 525e93a130757ab4df445888ecc211bace1122eb
Author: Georg Koppen <gk(a)torproject.org>
Date: Tue Jul 30 20:38:50 2019 +0000
Release prep for 9.0a5
We want to better test aarch64 support on Google Play before the 64bit
requirement on Aug 1 is getting enforced.
---
projects/firefox/config | 2 +-
projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt | 4 ++++
rbm.conf | 4 ++--
3 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/projects/firefox/config b/projects/firefox/config
index 9565b8e..0b340f5 100644
--- a/projects/firefox/config
+++ b/projects/firefox/config
@@ -1,7 +1,7 @@
# vim: filetype=yaml sw=2
version: '[% c("abbrev") %]'
filename: 'firefox-[% c("version") %]-[% c("var/osname") %]-[% c("var/build_id") %]'
-git_hash: 'tor-browser-[% c("var/firefox_version") %]-[% c("var/torbrowser_branch") %]-1-build1'
+git_hash: 'tor-browser-[% c("var/firefox_version") %]-[% c("var/torbrowser_branch") %]-1-build2'
tag_gpg_id: 1
git_url: https://git.torproject.org/tor-browser.git
git_submodule: 1
diff --git a/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt b/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
index ffab828..594225a 100644
--- a/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
+++ b/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
@@ -1,3 +1,7 @@
+Tor Browser 9.0a5 -- July 31 2019
+ * Android
+ * Bug 31260: Backport bug 1477259 for aarch64 support on Google Play
+
Tor Browser 9.0a4 -- July 9 2019
* All platforms
* Update Firefox to 60.8.0esr
diff --git a/rbm.conf b/rbm.conf
index 4f6e943..76695f3 100644
--- a/rbm.conf
+++ b/rbm.conf
@@ -24,8 +24,8 @@ buildconf:
git_signtag_opt: '-s'
var:
- torbrowser_version: '9.0a4'
- torbrowser_build: 'build2'
+ torbrowser_version: '9.0a5'
+ torbrowser_build: 'build1'
torbrowser_incremental_from:
- 9.0a3
project_name: tor-browser
1
0

[tor-browser/tor-browser-60.8.0esr-8.5-1] Bug 1477259 - Use separate version codes for 64-bit builds; r=nalexander
by gk@torproject.org 30 Jul '19
by gk@torproject.org 30 Jul '19
30 Jul '19
commit 3111f2ee9a389db8d4c4f025b34314f8fe42d865
Author: Jim Chen <nchen(a)mozilla.com>
Date: Thu Aug 30 21:51:18 2018 +0000
Bug 1477259 - Use separate version codes for 64-bit builds; r=nalexander
Use the unused 'p' bit in the version code to denote 64-bit builds, so
we have different version codes for 64-bit builds on aarch64 and x86-64.
Differential Revision: https://phabricator.services.mozilla.com/D4260
--HG--
extra : moz-landing-system : lando
---
python/mozbuild/mozbuild/android_version_code.py | 53 ++++++++++++------------
1 file changed, 27 insertions(+), 26 deletions(-)
diff --git a/python/mozbuild/mozbuild/android_version_code.py b/python/mozbuild/mozbuild/android_version_code.py
index 5e786b2358c0..92392d563c42 100644
--- a/python/mozbuild/mozbuild/android_version_code.py
+++ b/python/mozbuild/mozbuild/android_version_code.py
@@ -49,26 +49,24 @@ def android_version_code_v1(buildid, cpu_arch=None, min_sdk=0, max_sdk=0):
The bits labelled 'x', 'p', and 'g' are feature flags.
- The bit labelled 'x' is 1 if the build is for an x86 or ARM64 architecture,
- and 0 otherwise, which means the build is for a (32-bit) ARM architecture.
+ The bit labelled 'x' is 1 if the build is for an x86 or x86-64 architecture,
+ and 0 otherwise, which means the build is for an ARM or ARM64 architecture.
(Fennec no longer supports ARMv6, so ARM is equivalent to ARMv7.
ARM64 is also known as AArch64; it is logically ARMv8.)
- For the same release, x86 and ARM64 builds have higher version codes and
+ For the same release, x86 and x86_64 builds have higher version codes and
take precedence over ARM builds, so that they are preferred over ARM on
devices that have ARM emulation.
- The bit labelled 'p' is a placeholder that is always 0 (for now).
+ The bit labelled 'p' is 1 if the build is for a 64-bit architecture (x86-64
+ or ARM64), and 0 otherwise, which means the build is for a 32-bit
+ architecture (x86 or ARM). 64-bit builds have higher version codes so
+ they take precedence over 32-bit builds on devices that support 64-bit.
- Firefox no longer supports API 14 or earlier.
-
- This version code computation allows for a split on API levels that allowed
- us to ship builds specifically for Gingerbread (API 9-10); we preserve
- that functionality for sanity's sake, and to allow us to reintroduce a
- split in the future.
-
- At present, the bit labelled 'g' is 1 if the build is an ARM build
- targeting API 16+, which will always be the case.
+ The bit labelled 'g' is 1 if the build targets a recent API level, which
+ is currently always the case, because Firefox no longer ships releases that
+ are split by API levels. However, we may reintroduce a split in the future,
+ in which case the release that targets an older API level will
We throw an explanatory exception when we are within one calendar year of
running out of build events. This gives lots of time to update the version
@@ -113,24 +111,27 @@ def android_version_code_v1(buildid, cpu_arch=None, min_sdk=0, max_sdk=0):
# for architecture and APK splits.
version |= base << 3
- # None is interpreted as arm.
- if not cpu_arch or cpu_arch == 'armeabi-v7a':
- # 0 is interpreted as SDK 9.
- if not min_sdk or min_sdk == 9:
- pass
- # This used to compare to 11. The 16+ APK directly supersedes 11+, so
- # we reuse this check.
- elif min_sdk == 16:
- version |= 1 << 0
- else:
- raise ValueError("Don't know how to compute android:versionCode "
- "for CPU arch %s and min SDK %s" % (cpu_arch, min_sdk))
- elif cpu_arch in ['x86', 'arm64-v8a']:
+ # 'x' bit is 1 for x86/x86-64 architectures (`None` is interpreted as ARM).
+ if cpu_arch in ['x86', 'x86_64']:
version |= 1 << 2
+ elif not cpu_arch or cpu_arch in ['armeabi-v7a', 'arm64-v8a']:
+ pass
else:
raise ValueError("Don't know how to compute android:versionCode "
"for CPU arch %s" % cpu_arch)
+ # 'p' bit is 1 for 64-bit architectures.
+ if cpu_arch in ['arm64-v8a', 'x86_64']:
+ version |= 1 << 1
+ elif cpu_arch in ['armeabi-v7a', 'x86']:
+ pass
+ else:
+ raise ValueError("Don't know how to compute android:versionCode "
+ "for CPU arch %s" % cpu_arch)
+
+ # 'g' bit is currently always 1, but may depend on `min_sdk` in the future.
+ version |= 1 << 0
+
return version
def android_version_code(buildid, *args, **kwargs):
1
0

[tor-browser/tor-browser-60.8.0esr-9.0-1] Bug 1477259 - Use separate version codes for 64-bit builds; r=nalexander
by gk@torproject.org 30 Jul '19
by gk@torproject.org 30 Jul '19
30 Jul '19
commit c847e888cd2a4fb7cbddfe8fc890fe25a024faf7
Author: Jim Chen <nchen(a)mozilla.com>
Date: Thu Aug 30 21:51:18 2018 +0000
Bug 1477259 - Use separate version codes for 64-bit builds; r=nalexander
Use the unused 'p' bit in the version code to denote 64-bit builds, so
we have different version codes for 64-bit builds on aarch64 and x86-64.
Differential Revision: https://phabricator.services.mozilla.com/D4260
--HG--
extra : moz-landing-system : lando
---
python/mozbuild/mozbuild/android_version_code.py | 53 ++++++++++++------------
1 file changed, 27 insertions(+), 26 deletions(-)
diff --git a/python/mozbuild/mozbuild/android_version_code.py b/python/mozbuild/mozbuild/android_version_code.py
index 5e786b2358c0..92392d563c42 100644
--- a/python/mozbuild/mozbuild/android_version_code.py
+++ b/python/mozbuild/mozbuild/android_version_code.py
@@ -49,26 +49,24 @@ def android_version_code_v1(buildid, cpu_arch=None, min_sdk=0, max_sdk=0):
The bits labelled 'x', 'p', and 'g' are feature flags.
- The bit labelled 'x' is 1 if the build is for an x86 or ARM64 architecture,
- and 0 otherwise, which means the build is for a (32-bit) ARM architecture.
+ The bit labelled 'x' is 1 if the build is for an x86 or x86-64 architecture,
+ and 0 otherwise, which means the build is for an ARM or ARM64 architecture.
(Fennec no longer supports ARMv6, so ARM is equivalent to ARMv7.
ARM64 is also known as AArch64; it is logically ARMv8.)
- For the same release, x86 and ARM64 builds have higher version codes and
+ For the same release, x86 and x86_64 builds have higher version codes and
take precedence over ARM builds, so that they are preferred over ARM on
devices that have ARM emulation.
- The bit labelled 'p' is a placeholder that is always 0 (for now).
+ The bit labelled 'p' is 1 if the build is for a 64-bit architecture (x86-64
+ or ARM64), and 0 otherwise, which means the build is for a 32-bit
+ architecture (x86 or ARM). 64-bit builds have higher version codes so
+ they take precedence over 32-bit builds on devices that support 64-bit.
- Firefox no longer supports API 14 or earlier.
-
- This version code computation allows for a split on API levels that allowed
- us to ship builds specifically for Gingerbread (API 9-10); we preserve
- that functionality for sanity's sake, and to allow us to reintroduce a
- split in the future.
-
- At present, the bit labelled 'g' is 1 if the build is an ARM build
- targeting API 16+, which will always be the case.
+ The bit labelled 'g' is 1 if the build targets a recent API level, which
+ is currently always the case, because Firefox no longer ships releases that
+ are split by API levels. However, we may reintroduce a split in the future,
+ in which case the release that targets an older API level will
We throw an explanatory exception when we are within one calendar year of
running out of build events. This gives lots of time to update the version
@@ -113,24 +111,27 @@ def android_version_code_v1(buildid, cpu_arch=None, min_sdk=0, max_sdk=0):
# for architecture and APK splits.
version |= base << 3
- # None is interpreted as arm.
- if not cpu_arch or cpu_arch == 'armeabi-v7a':
- # 0 is interpreted as SDK 9.
- if not min_sdk or min_sdk == 9:
- pass
- # This used to compare to 11. The 16+ APK directly supersedes 11+, so
- # we reuse this check.
- elif min_sdk == 16:
- version |= 1 << 0
- else:
- raise ValueError("Don't know how to compute android:versionCode "
- "for CPU arch %s and min SDK %s" % (cpu_arch, min_sdk))
- elif cpu_arch in ['x86', 'arm64-v8a']:
+ # 'x' bit is 1 for x86/x86-64 architectures (`None` is interpreted as ARM).
+ if cpu_arch in ['x86', 'x86_64']:
version |= 1 << 2
+ elif not cpu_arch or cpu_arch in ['armeabi-v7a', 'arm64-v8a']:
+ pass
else:
raise ValueError("Don't know how to compute android:versionCode "
"for CPU arch %s" % cpu_arch)
+ # 'p' bit is 1 for 64-bit architectures.
+ if cpu_arch in ['arm64-v8a', 'x86_64']:
+ version |= 1 << 1
+ elif cpu_arch in ['armeabi-v7a', 'x86']:
+ pass
+ else:
+ raise ValueError("Don't know how to compute android:versionCode "
+ "for CPU arch %s" % cpu_arch)
+
+ # 'g' bit is currently always 1, but may depend on `min_sdk` in the future.
+ version |= 1 << 0
+
return version
def android_version_code(buildid, *args, **kwargs):
1
0
commit d249b24614605f02d76f7ceff02aba27f2ebdf6f
Author: Georg Koppen <gk(a)torproject.org>
Date: Fri Jul 19 10:00:45 2019 +0000
Fold in stable changelog
---
projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt b/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
index 63c6606..ffab828 100644
--- a/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
+++ b/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
@@ -24,6 +24,24 @@ Tor Browser 9.0a4 -- July 9 2019
* Android
* Bug 28119: Tor Browser for aarch64
+Tor Browser 8.5.4 -- July 9 2019
+ * All platforms
+ * Update Firefox to 60.8.0esr
+ * Update Torbutton to 2.1.12
+ * Bug 30577: Add Fundraising Banner
+ * Bug 31041: Stop syncing network.cookie.lifetimePolicy
+ * Translations update
+ * Update HTTPS Everywhere to 2019.6.27
+ * Bug 31055+31058: Remove four default bridges
+ * Bug 30712: Backport fix for Mozilla's bug 1552993
+ * Bug 30849: Backport fixes for Mozilla's bug 1552627 and 1549833
+ * Windows + OS X + Linux
+ * Update Tor to 0.4.0.5
+ * Update OpenSSL to 1.0.2s
+ * Bug 29045: Ensure that tor does not start up in dormant mode
+ * OS X
+ * Bug 30631: Blurry Tor Browser icon on macOS app switcher
+
Tor Browser 9.0a3 -- June 24 2019
* All platforms
* Pick up fixes for Mozilla's bug 1544386 and 1560192
1
0
commit 958c5fef2072692464417012c1cb551f1858bab4
Author: Georg Koppen <gk(a)torproject.org>
Date: Tue Jul 9 17:56:34 2019 +0000
Correct Changelog
It seems #30573 did not get solved in that alpha. Remove the entry.
---
projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt | 1 -
1 file changed, 1 deletion(-)
diff --git a/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt b/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
index 5a1a67a..63c6606 100644
--- a/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
+++ b/projects/tor-browser/Bundle-Data/Docs/ChangeLog.txt
@@ -23,7 +23,6 @@ Tor Browser 9.0a4 -- July 9 2019
* Bug 30631: Blurry Tor Browser icon on macOS app switcher
* Android
* Bug 28119: Tor Browser for aarch64
- * Bug 30573: Sanitize old tabs and wait for tor before opening new tabs
Tor Browser 9.0a3 -- June 24 2019
* All platforms
1
0

08 Jul '19
commit 248aaaa5e02b5aff0b438e563b6a73692b4533f9
Author: Nicolas Vigier <boklm(a)torproject.org>
Date: Mon Jul 8 23:27:15 2019 +0200
Remove obfs3 tests
With #31055 we don't have default obfs3 bridges anymore.
---
TBBTestSuite/TestSuite/BrowserBundleTests.pm | 15 ---------------
tor-config/tor_obfs3.conf | 15 ---------------
tor-config/tor_obfs3_httpproxy.conf | 2 --
3 files changed, 32 deletions(-)
diff --git a/TBBTestSuite/TestSuite/BrowserBundleTests.pm b/TBBTestSuite/TestSuite/BrowserBundleTests.pm
index a7ad663..cf580f0 100644
--- a/TBBTestSuite/TestSuite/BrowserBundleTests.pm
+++ b/TBBTestSuite/TestSuite/BrowserBundleTests.pm
@@ -219,21 +219,6 @@ our @tests = (
run_once => 1,
},
{
- name => 'tor_obfs3',
- type => 'tor_bootstrap',
- descr => 'Access tor using obfs3',
- enable => sub { $OSNAME eq 'linux' && $options->{PTtests} },
- run_once => 1,
- },
- {
- name => 'tor_obfs3_httpproxy',
- type => 'tor_bootstrap',
- descr => 'Access tor using obfs3 and an http proxy',
- httpproxy => 1,
- enable => sub { $OSNAME eq 'linux' && $options->{PTtests} },
- run_once => 1,
- },
- {
name => 'tor_obfs4',
type => 'tor_bootstrap',
descr => 'Access tor using obfs4',
diff --git a/tor-config/tor_obfs3.conf b/tor-config/tor_obfs3.conf
deleted file mode 100644
index 42b9b14..0000000
--- a/tor-config/tor_obfs3.conf
+++ /dev/null
@@ -1,15 +0,0 @@
-[% INCLUDE main_config %]
-[% IF tbbinfos.os == 'Windows';
- SET bin_ext = 'exe';
- ELSE;
- SET bin_ext = 'bin';
- END;
--%]
-
-UseBridges 1
-Bridge obfs3 83.212.101.3:80 A09D536DD1752D542E1FBB3C9CE4449D51298239
-Bridge obfs3 169.229.59.74:31493 AF9F66B7B04F8FF6F32D455F05135250A16543C9
-Bridge obfs3 169.229.59.75:46328 AF9F66B7B04F8FF6F32D455F05135250A16543C9
-Bridge obfs3 109.105.109.163:38980 1E05F577A0EC0213F971D81BF4D86A9E4E8229ED
-Bridge obfs3 109.105.109.163:47779 4C331FA9B3D1D6D8FB0D8FBBF0C259C360D97E6A
-ClientTransportPlugin obfs3 exec [% tbbinfos.ptdir %]/obfsproxy.[% bin_ext %] managed
diff --git a/tor-config/tor_obfs3_httpproxy.conf b/tor-config/tor_obfs3_httpproxy.conf
deleted file mode 100644
index 1e4753b..0000000
--- a/tor-config/tor_obfs3_httpproxy.conf
+++ /dev/null
@@ -1,2 +0,0 @@
-[% INCLUDE tor_obfs3.conf %]
-[% INCLUDE http_proxy %]
1
0

[tor-browser-build/master] Bug 31054: Add android-aarch64 nightly builds
by boklm@torproject.org 08 Jul '19
by boklm@torproject.org 08 Jul '19
08 Jul '19
commit 7bee08d921c147712a69140c44b506eaf19d57d6
Author: Nicolas Vigier <boklm(a)torproject.org>
Date: Mon Jul 8 19:20:05 2019 +0200
Bug 31054: Add android-aarch64 nightly builds
Update the tor-browser-bundle-testsuite.git commit, to add
android-aarch64 nightly builds.
At the same time, we update the tor-browser-bundle-testsuite.git URL to
use the repository that created with #30516.
---
tools/ansible/roles/tbb-nightly-build/defaults/main.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/ansible/roles/tbb-nightly-build/defaults/main.yml b/tools/ansible/roles/tbb-nightly-build/defaults/main.yml
index 2a4cc6e..acc88f9 100644
--- a/tools/ansible/roles/tbb-nightly-build/defaults/main.yml
+++ b/tools/ansible/roles/tbb-nightly-build/defaults/main.yml
@@ -4,8 +4,8 @@ nightly_build_cron_hour: 2
nightly_build_cron_minute: 20
nightly_build_keep_builds: 2
testsuite_dir: "/home/{{ nightly_build_user }}/tbb-testsuite"
-testsuite_git_url: https://git.torproject.org/user/boklm/tor-browser-bundle-testsuite.git
-testsuite_git_commit: 9283635ace22c3a7f629b5bc60e8fec0af4dc13c
+testsuite_git_url: https://git.torproject.org/tor-browser-bundle-testsuite.git
+testsuite_git_commit: 6a2c39273bfd729446ef787e4f7d1bf3138cfc4a
nightly_build_wwwdir: "/home/{{ nightly_build_user }}/www"
nightly_build_nginx_enable: true
nightly_build_nginx_listen: 127.0.0.1:80
1
0

[tor-browser-bundle-testsuite/master] .gitkeyring: Add new sub-keys
by boklm@torproject.org 08 Jul '19
by boklm@torproject.org 08 Jul '19
08 Jul '19
commit 6a2c39273bfd729446ef787e4f7d1bf3138cfc4a
Author: Nicolas Vigier <boklm(a)torproject.org>
Date: Mon Jul 8 19:13:18 2019 +0200
.gitkeyring: Add new sub-keys
Update .gitkeyring to add a new sub-key, fixing pulling of this git
repository using the tools/pull script.
---
.gitkeyring | Bin 11674 -> 5610 bytes
1 file changed, 0 insertions(+), 0 deletions(-)
diff --git a/.gitkeyring b/.gitkeyring
index b1622f1..cceaf37 100644
Binary files a/.gitkeyring and b/.gitkeyring differ
1
0