COFF: Fix /base option.

Previously, __ImageBase symbol got a different value than the one
specified by /base:<number> because the symbol was created in the
SymbolTable's constructor. When the constructor is called,
no command line options are processed yet, so the symbol was
created always with the initial value. This caused wrong relocations
and thus caused mysterious crashes of some executables linked by LLD.

llvm-svn: 241313
This commit is contained in:
Rui Ueyama 2015-07-03 00:02:19 +00:00
parent 754eb7c563
commit 49d6cd35ad
5 changed files with 60 additions and 11 deletions

View File

@ -79,7 +79,7 @@ struct Configuration {
// Used for /alternatename.
std::map<StringRef, StringRef> AlternateNames;
uint64_t ImageBase = 0x140000000;
uint64_t ImageBase = 0x140000000U;
uint64_t StackReserve = 1024 * 1024;
uint64_t StackCommit = 4096;
uint64_t HeapReserve = 1024 * 1024;

View File

@ -302,6 +302,7 @@ bool LinkerDriver::link(llvm::ArrayRef<const char *> ArgsArr) {
// Handle /dll
if (Args.hasArg(OPT_dll)) {
Config->DLL = true;
Config->ImageBase = 0x180000000U;
Config->ManifestID = 2;
if (Config->Entry == nullptr && !Config->NoEntry)
Config->Entry = addUndefined("_DllMainCRTStartup");
@ -526,6 +527,8 @@ bool LinkerDriver::link(llvm::ArrayRef<const char *> ArgsArr) {
OwningMBs.push_back(std::move(MB)); // take ownership
}
Symtab.addAbsolute("__ImageBase", Config->ImageBase);
// Read all input files given via the command line. Note that step()
// doesn't read files that are specified by directive sections.
for (MemoryBufferRef MB : Inputs)

View File

@ -23,10 +23,6 @@ using namespace llvm;
namespace lld {
namespace coff {
SymbolTable::SymbolTable() {
addSymbol(new (Alloc) DefinedAbsolute("__ImageBase", Config->ImageBase));
}
void SymbolTable::addFile(std::unique_ptr<InputFile> FileP) {
InputFile *File = FileP.get();
Files.push_back(std::move(FileP));
@ -279,6 +275,10 @@ Undefined *SymbolTable::addUndefined(StringRef Name) {
return New;
}
void SymbolTable::addAbsolute(StringRef Name, uint64_t VA) {
addSymbol(new (Alloc) DefinedAbsolute(Name, VA));
}
void SymbolTable::printMap(llvm::raw_ostream &OS) {
for (ObjectFile *File : ObjectFiles) {
OS << File->getShortName() << ":\n";

View File

@ -41,7 +41,6 @@ struct Symbol;
// to replace the lazy symbol. The logic is implemented in resolve().
class SymbolTable {
public:
SymbolTable();
void addFile(std::unique_ptr<InputFile> File);
std::error_code step();
std::error_code run();
@ -79,6 +78,7 @@ public:
// Creates an Undefined symbol for a given name.
Undefined *addUndefined(StringRef Name);
void addAbsolute(StringRef Name, uint64_t VA);
// A list of chunks which to be added to .rdata.
std::vector<Chunk *> LocalImportChunks;

View File

@ -1,11 +1,57 @@
# RUN: yaml2obj < %p/Inputs/ret42.yaml > %t.obj
# RUN: yaml2obj < %s > %t.obj
# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj
# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=DEFAULT %s
# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=DEFAULT-HEADER %s
# RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=DEFAULT-TEXT %s
DEFAULT: ImageBase: 0x140000000
# DEFAULT-HEADER: ImageBase: 0x140000000
# DEFAULT-TEXT: Contents of section .text:
# DEFAULT-TEXT-NEXT: 1000 00000040 01000000
# RUN: lld -flavor link2 /out:%t.exe /entry:main %t.obj /base:0x280000000
# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=BASE %s
# RUN: llvm-readobj -file-headers %t.exe | FileCheck -check-prefix=BASE-HEADER %s
# RUN: llvm-objdump -s %t.exe | FileCheck -check-prefix=BASE-TEXT %s
BASE: ImageBase: 0x280000000
# BASE-HEADER: ImageBase: 0x280000000
# BASE-TEXT: Contents of section .text:
# BASE-TEXT-NEXT: 1000 00000080 02000000
---
header:
Machine: IMAGE_FILE_MACHINE_AMD64
Characteristics: []
sections:
- Name: .text
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
Alignment: 4096
SectionData: 0000000000000000
Relocations:
- VirtualAddress: 0
SymbolName: __ImageBase
Type: IMAGE_REL_AMD64_ADDR64
symbols:
- 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: 0
Number: 0
- Name: main
Value: 0
SectionNumber: 1
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
- Name: __ImageBase
Value: 0
SectionNumber: 0
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
...