Skip to content
This repository was archived by the owner on Mar 22, 2019. It is now read-only.

Commit 3747ba5

Browse files
authored
Merge pull request #25 from scchan/merge_20170822
Merge 20170822
2 parents 3d2ee64 + ca83bf1 commit 3747ba5

19 files changed

+223
-90
lines changed

COFF/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ add_lld_library(lldCOFF
3939
Target
4040
Option
4141
Support
42+
WindowsManifest
4243

4344
LINK_LIBS
4445
lldCore

COFF/DriverUtils.cpp

Lines changed: 68 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "Symbols.h"
2121
#include "llvm/ADT/Optional.h"
2222
#include "llvm/ADT/StringSwitch.h"
23+
#include "llvm/ADT/Triple.h"
2324
#include "llvm/BinaryFormat/COFF.h"
2425
#include "llvm/Object/COFF.h"
2526
#include "llvm/Object/WindowsResource.h"
@@ -32,6 +33,7 @@
3233
#include "llvm/Support/Process.h"
3334
#include "llvm/Support/Program.h"
3435
#include "llvm/Support/raw_ostream.h"
36+
#include "llvm/WindowsManifest/WindowsManifestMerger.h"
3537
#include <memory>
3638

3739
using namespace llvm::COFF;
@@ -328,16 +330,9 @@ class TemporaryFile {
328330
};
329331
}
330332

331-
// Create the default manifest file as a temporary file.
332-
TemporaryFile createDefaultXml() {
333-
// Create a temporary file.
334-
TemporaryFile File("defaultxml", "manifest");
335-
336-
// Open the temporary file for writing.
337-
std::error_code EC;
338-
raw_fd_ostream OS(File.Path, EC, sys::fs::F_Text);
339-
if (EC)
340-
fatal(EC, "failed to open " + File.Path);
333+
static std::string createDefaultXml() {
334+
std::string Ret;
335+
raw_string_ostream OS(Ret);
341336

342337
// Emit the XML. Note that we do *not* verify that the XML attributes are
343338
// syntactically correct. This is intentional for link.exe compatibility.
@@ -362,37 +357,83 @@ TemporaryFile createDefaultXml() {
362357
<< " </dependency>\n";
363358
}
364359
OS << "</assembly>\n";
365-
OS.close();
366-
return File;
360+
return Ret;
367361
}
368362

369-
static std::string readFile(StringRef Path) {
370-
std::unique_ptr<MemoryBuffer> MB =
371-
check(MemoryBuffer::getFile(Path), "could not open " + Path);
372-
return MB->getBuffer();
363+
static Expected<std::unique_ptr<MemoryBuffer>>
364+
createManifestXmlWithInternalMt(std::string &DefaultXml) {
365+
std::unique_ptr<MemoryBuffer> DefaultXmlCopy =
366+
MemoryBuffer::getMemBufferCopy(DefaultXml);
367+
368+
windows_manifest::WindowsManifestMerger Merger;
369+
if (auto E = Merger.merge(*DefaultXmlCopy.get()))
370+
return std::move(E);
371+
372+
for (StringRef Filename : Config->ManifestInput) {
373+
std::unique_ptr<MemoryBuffer> Manifest =
374+
check(MemoryBuffer::getFile(Filename));
375+
if (auto E = Merger.merge(*Manifest.get())) {
376+
warn("internal manifest tool failed on file " + Filename);
377+
return std::move(E);
378+
}
379+
}
380+
381+
return Merger.getMergedManifest();
373382
}
374383

375-
static std::string createManifestXml() {
376-
// Create the default manifest file.
377-
TemporaryFile File1 = createDefaultXml();
378-
if (Config->ManifestInput.empty())
379-
return readFile(File1.Path);
384+
static std::unique_ptr<MemoryBuffer>
385+
createManifestXmlWithExternalMt(std::string &DefaultXml) {
386+
const Triple HostTriple(Triple::normalize(LLVM_HOST_TRIPLE));
387+
if (!HostTriple.isOSWindows())
388+
fatal("manifest ignored because no external manifest tool available");
389+
// Create the default manifest file as a temporary file.
390+
TemporaryFile Default("defaultxml", "manifest");
391+
std::error_code EC;
392+
raw_fd_ostream OS(Default.Path, EC, sys::fs::F_Text);
393+
if (EC)
394+
fatal(EC, "failed to open " + Default.Path);
395+
OS << DefaultXml;
396+
OS.close();
380397

381-
// If manifest files are supplied by the user using /MANIFESTINPUT
382-
// option, we need to merge them with the default manifest.
383-
TemporaryFile File2("user", "manifest");
398+
// Merge user-supplied manifests if they are given. Since libxml2 is not
399+
// enabled, we must shell out to Microsoft's mt.exe tool.
400+
TemporaryFile User("user", "manifest");
384401

385402
Executor E("mt.exe");
386403
E.add("/manifest");
387-
E.add(File1.Path);
404+
E.add(Default.Path);
388405
for (StringRef Filename : Config->ManifestInput) {
389406
E.add("/manifest");
390407
E.add(Filename);
391408
}
392409
E.add("/nologo");
393-
E.add("/out:" + StringRef(File2.Path));
410+
E.add("/out:" + StringRef(User.Path));
394411
E.run();
395-
return readFile(File2.Path);
412+
413+
return check(MemoryBuffer::getFile(User.Path), "could not open " + User.Path);
414+
}
415+
416+
static std::string createManifestXml() {
417+
std::string DefaultXml = createDefaultXml();
418+
if (Config->ManifestInput.empty())
419+
return DefaultXml;
420+
421+
// If manifest files are supplied by the user using /MANIFESTINPUT
422+
// option, we need to merge them with the default manifest. If libxml2
423+
// is enabled, we may merge them with LLVM's own library.
424+
Expected<std::unique_ptr<MemoryBuffer>> OutputBufferOrError =
425+
createManifestXmlWithInternalMt(DefaultXml);
426+
if (OutputBufferOrError)
427+
return OutputBufferOrError.get()->getBuffer();
428+
// Using built-in library failed, possibly because libxml2 is not installed.
429+
// Shell out to mt.exe instead.
430+
handleAllErrors(OutputBufferOrError.takeError(),
431+
[&](ErrorInfoBase &EIB) {
432+
warn("error with internal manifest tool: " + EIB.message());
433+
});
434+
std::unique_ptr<MemoryBuffer> OutputBuffer;
435+
OutputBuffer = createManifestXmlWithExternalMt(DefaultXml);
436+
return OutputBuffer->getBuffer();
396437
}
397438

398439
static std::unique_ptr<MemoryBuffer>

ELF/LTO.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,13 @@ void BitcodeCompiler::add(BitcodeFile &F) {
144144
// be removed.
145145
R.Prevailing = !ObjSym.isUndefined() && B->getFile() == &F;
146146

147-
R.VisibleToRegularObj = Sym->IsUsedInRegularObj ||
147+
// We ask LTO to preserve following global symbols:
148+
// 1) All symbols when doing relocatable link, so that them can be used
149+
// for doing final link.
150+
// 2) Symbols that are used in regular objects.
151+
// 3) C named sections if we have corresponding __start_/__stop_ symbol.
152+
// 4) Symbols that are defined in bitcode files and used for dynamic linking.
153+
R.VisibleToRegularObj = Config->Relocatable || Sym->IsUsedInRegularObj ||
148154
(R.Prevailing && Sym->includeInDynsym()) ||
149155
UsedStartStop.count(ObjSym.getSectionName());
150156
if (R.Prevailing)

ELF/LinkerScript.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,19 +49,24 @@ using namespace lld::elf;
4949

5050
LinkerScript *elf::Script;
5151

52+
static uint64_t getOutputSectionVA(SectionBase *InputSec, StringRef Loc) {
53+
if (OutputSection *OS = InputSec->getOutputSection())
54+
return OS->Addr;
55+
error(Loc + ": unable to evaluate expression: input section " +
56+
InputSec->Name + " has no output section assigned");
57+
return 0;
58+
}
59+
5260
uint64_t ExprValue::getValue() const {
53-
if (Sec) {
54-
if (OutputSection *OS = Sec->getOutputSection())
55-
return alignTo(Sec->getOffset(Val) + OS->Addr, Alignment);
56-
error(Loc + ": unable to evaluate expression: input section " + Sec->Name +
57-
" has no output section assigned");
58-
}
61+
if (Sec)
62+
return alignTo(Sec->getOffset(Val) + getOutputSectionVA(Sec, Loc),
63+
Alignment);
5964
return alignTo(Val, Alignment);
6065
}
6166

6267
uint64_t ExprValue::getSecAddr() const {
6368
if (Sec)
64-
return Sec->getOffset(0) + Sec->getOutputSection()->Addr;
69+
return Sec->getOffset(0) + getOutputSectionVA(Sec, Loc);
6570
return 0;
6671
}
6772

ELF/Writer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1856,7 +1856,7 @@ template <class ELFT> void Writer<ELFT>::writeSectionsBinary() {
18561856
}
18571857

18581858
static void fillTrap(uint8_t *I, uint8_t *End) {
1859-
for (; I + 4 < End; I += 4)
1859+
for (; I + 4 <= End; I += 4)
18601860
memcpy(I, &Target->TrapInstr, 4);
18611861
}
18621862

test/COFF/manifestinput.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# REQUIRES: win_mt
1+
# REQUIRES: manifest_tool
22

33
# RUN: yaml2obj %p/Inputs/ret42.yaml > %t.obj
44
# RUN: lld-link /out:%t.exe /entry:main \

test/COFF/pdb-diff.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ CHECK-NEXT: | Public Symbol Hash | {{[EI]}} |
6060
CHECK-NEXT: |------------------------------+---|
6161
CHECK-NEXT: | Global Symbol Hash | {{[EI]}} |
6262
CHECK-NEXT: |------------------------------+---|
63-
CHECK-NEXT: | Public Symbol Records | {{[EI]}} |
63+
CHECK-NEXT: | Symbol Records | {{[EI]}} |
6464
CHECK-NEXT: |------------------------------+---|
6565
CHECK-NEXT: ------------------------------------
6666
CHECK-NEXT: | String Table |

test/COFF/pdb-lib.s

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@
1111

1212
# CHECK: Modules
1313
# CHECK-NEXT: ============================================================
14-
# CHECK-NEXT: Mod 0000 | Name: `{{.*pdb-lib.s.tmp[/\\]foo.obj}}`:
14+
# CHECK-NEXT: Mod 0000 | `{{.*pdb-lib.s.tmp[/\\]foo.obj}}`:
1515
# CHECK-NEXT: Obj: `{{.*pdb-lib.s.tmp[/\\]foo.obj}}`:
1616
# CHECK-NEXT: debug stream: 9, # files: 0, has ec info: false
1717
# CHECK-NEXT: pdb file ni: 0 ``, src file ni: 0 ``
18-
# CHECK-NEXT: Mod 0001 | Name: `bar.obj`:
18+
# CHECK-NEXT: Mod 0001 | `bar.obj`:
1919
# CHECK-NEXT: Obj: `{{.*pdb-lib.s.tmp[/\\]bar.lib}}`:
2020
# CHECK-NEXT: debug stream: 10, # files: 0, has ec info: false
2121
# CHECK-NEXT: pdb file ni: 0 ``, src file ni: 0 ``
22-
# CHECK-NEXT: Mod 0002 | Name: `* Linker *`:
22+
# CHECK-NEXT: Mod 0002 | `* Linker *`:
2323
# CHECK-NEXT: Obj: ``:
2424
# CHECK-NEXT: debug stream: 11, # files: 0, has ec info: false
2525
# CHECK-NEXT: pdb file ni: 1 `{{.*foo.pdb}}`, src file ni: 0 ``

test/COFF/pdb-linker-module.test

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
11
RUN: lld-link /debug /pdb:%t.pdb /nodefaultlib /entry:main %S/Inputs/pdb-diff.obj
2-
RUN: llvm-pdbutil dump -modules -symbols %t.pdb | FileCheck %s
2+
RUN: llvm-pdbutil dump -modules %t.pdb | FileCheck --check-prefix=MODS %s
3+
RUN: llvm-pdbutil dump -symbols %t.pdb | FileCheck --check-prefix=SYMS %s
34

4-
CHECK: Mod 0001 | `* Linker *`:
5-
CHECK-NEXT: 4 | S_OBJNAME [size = 20] sig=0, `* Linker *`
6-
CHECK-NEXT: 24 | S_COMPILE3 [size = 40]
7-
CHECK-NEXT: machine = intel 80386, Ver = LLVM Linker, language = link
8-
CHECK-NEXT: frontend = 0.0.0.0, backend = 14.10.25019.0
9-
CHECK-NEXT: flags = none
10-
CHECK-NEXT: 64 | S_ENVBLOCK
11-
CHECK-NEXT: - cwd
12-
CHECK-NEXT: -
13-
CHECK-NEXT: - exe
14-
CHECK-NEXT: - {{.*}}lld-link
15-
CHECK-NEXT: - pdb
16-
CHECK-NEXT: - {{.*}}pdb-linker-module{{.*}}pdb
17-
CHECK-NEXT: - cmd
18-
CHECK-NEXT: - /debug /pdb:{{.*}}pdb-linker-module{{.*}}pdb /nodefaultlib /entry:main {{.*}}pdb-diff.obj
5+
MODS: Mod 0001 | `* Linker *`
6+
MODS-NEXT: Obj: ``:
7+
MODS-NEXT: debug stream: 10, # files: 0, has ec info: false
8+
MODS-NEXT: pdb file ni: 1 `{{.*}}pdb-linker-module.test.tmp.pdb`, src file ni: 0 ``
9+
10+
SYMS: Mod 0001 | `* Linker *`
11+
SYMS-NEXT: 4 | S_OBJNAME [size = 20] sig=0, `* Linker *`
12+
SYMS-NEXT: 24 | S_COMPILE3 [size = 40]
13+
SYMS-NEXT: machine = intel 80386, Ver = LLVM Linker, language = link
14+
SYMS-NEXT: frontend = 0.0.0.0, backend = 14.10.25019.0
15+
SYMS-NEXT: flags = none
16+
SYMS-NEXT: 64 | S_ENVBLOCK
17+
SYMS-NEXT: - cwd
18+
SYMS-NEXT: -
19+
SYMS-NEXT: - exe
20+
SYMS-NEXT: - {{.*}}lld-link
21+
SYMS-NEXT: - pdb
22+
SYMS-NEXT: - {{.*}}pdb-linker-module{{.*}}pdb
23+
SYMS-NEXT: - cmd
24+
SYMS-NEXT: - /debug /pdb:{{.*}}pdb-linker-module{{.*}}pdb /nodefaultlib /entry:main {{.*}}pdb-diff.obj

test/COFF/pdb.test

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,15 +119,15 @@
119119

120120
RAW: Modules
121121
RAW-NEXT: ============================================================
122-
RAW-NEXT: Mod 0000 | Name: `{{.*}}pdb.test.tmp1.obj`:
122+
RAW-NEXT: Mod 0000 | `{{.*}}pdb.test.tmp1.obj`:
123123
RAW-NEXT: Obj: `{{.*}}pdb.test.tmp1.obj`:
124124
RAW-NEXT: debug stream: 9, # files: 1, has ec info: false
125125
RAW-NEXT: pdb file ni: 0 ``, src file ni: 0 ``
126-
RAW-NEXT: Mod 0001 | Name: `{{.*}}pdb.test.tmp2.obj`:
126+
RAW-NEXT: Mod 0001 | `{{.*}}pdb.test.tmp2.obj`:
127127
RAW-NEXT: Obj: `{{.*}}pdb.test.tmp2.obj`:
128128
RAW-NEXT: debug stream: 10, # files: 1, has ec info: false
129129
RAW-NEXT: pdb file ni: 0 ``, src file ni: 0 ``
130-
RAW-NEXT: Mod 0002 | Name: `* Linker *`:
130+
RAW-NEXT: Mod 0002 | `* Linker *`:
131131
RAW-NEXT: Obj: ``:
132132
RAW-NEXT: debug stream: 11, # files: 0, has ec info: false
133133
RAW-NEXT: pdb file ni: 1 `{{.*pdb.test.tmp.pdb}}`, src file ni: 0 ``

test/ELF/build-id.s

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,15 @@ _start:
4848
# DEFAULT: Contents of section .note.test:
4949
# DEFAULT: Contents of section .note.gnu.build-id:
5050
# DEFAULT-NEXT: 04000000 08000000 03000000 474e5500 ............GNU.
51-
# DEFAULT-NEXT: d618a375 bc6301ec
51+
# DEFAULT-NEXT: b0148597 ba5eb7e9
5252

5353
# MD5: Contents of section .note.gnu.build-id:
5454
# MD5-NEXT: 04000000 10000000 03000000 474e5500 ............GNU.
55-
# MD5-NEXT: 051084fe ce1f30ed e035b79e 11262808
55+
# MD5-NEXT: dce3bcaf 5219454c e89a1fc7 86ab17bd
5656

5757
# SHA1: Contents of section .note.gnu.build-id:
5858
# SHA1-NEXT: 04000000 14000000 03000000 474e5500 ............GNU.
59-
# SHA1-NEXT: c70b9aec 903fd291 8b677cd8 1e04f8b6
59+
# SHA1-NEXT: 2f716666 fe3668fe 370a02a1 579c3eb2
6060

6161
# UUID: Contents of section .note.gnu.build-id:
6262
# UUID-NEXT: 04000000 10000000 03000000 474e5500 ............GNU.

test/ELF/dynamic-list.s

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
## There is some bad quoting interaction between lit's internal shell, which is
2-
## implemented in Python, and the Cygwin implementations of the Unix utilities.
3-
## Avoid running these tests on Windows for now by requiring a real shell.
4-
51
# REQUIRES: x86
62

73
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/shared.s -o %t2.o

test/ELF/fill-trap.s

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# REQUIRES: x86
2+
3+
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
4+
# RUN: ld.lld %t -o %t2
5+
# RUN: llvm-readobj -program-headers %t2 | FileCheck %s
6+
# RUN: od -Ax -x -N16 -j0x1ff0 %t2 | FileCheck %s -check-prefix=FILL
7+
8+
# CHECK: ProgramHeader {
9+
# CHECK: Type: PT_LOAD
10+
# CHECK: Offset: 0x1000
11+
# CHECK-NEXT: VirtualAddress:
12+
# CHECK-NEXT: PhysicalAddress:
13+
# CHECK-NEXT: FileSize: 4096
14+
# CHECK-NEXT: MemSize:
15+
# CHECK-NEXT: Flags [
16+
# CHECK-NEXT: PF_R
17+
# CHECK-NEXT: PF_X
18+
# CHECK-NEXT: ]
19+
20+
## Check that executable page is filled with traps at its end.
21+
# FILL: 001ff0 cccc cccc cccc cccc cccc cccc cccc cccc
22+
23+
.globl _start
24+
_start:
25+
nop

test/ELF/linkerscript/early-assign-symbol.s

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
# RUN: echo "SECTIONS { aaa = ABSOLUTE(foo - 1) + 1; .text : { *(.text*) } }" > %t2.script
88
# RUN: not ld.lld -o %t --script %t2.script %t.o 2>&1 | FileCheck %s
99

10+
# RUN: echo "SECTIONS { aaa = foo | 1; .text : { *(.text*) } }" > %t3.script
11+
# RUN: not ld.lld -o %t --script %t3.script %t.o 2>&1 | FileCheck %s
12+
1013
# CHECK: error: {{.*}}.script:1: unable to evaluate expression: input section .text has no output section assigned
1114

1215
.section .text

0 commit comments

Comments
 (0)