COFF: add support for CONSTANT exports

The CONSTANT export type is marked as obsolete, but link still supports
this.  Furthermore, WinObjC uses this for certain exports.  Add support
for this export type.

llvm-svn: 301013
This commit is contained in:
Saleem Abdulrasool 2017-04-21 18:05:46 +00:00
parent 81acbf3daa
commit 72fbd346c6
7 changed files with 127 additions and 7 deletions

View File

@ -43,6 +43,7 @@ struct Export {
bool Noname = false; bool Noname = false;
bool Data = false; bool Data = false;
bool Private = false; bool Private = false;
bool Constant = false;
// If an export is a form of /export:foo=dllname.bar, that means // If an export is a form of /export:foo=dllname.bar, that means
// that foo should be exported as an alias to bar in the DLL. // that foo should be exported as an alias to bar in the DLL.

View File

@ -479,6 +479,10 @@ Export parseExport(StringRef Arg) {
E.Data = true; E.Data = true;
continue; continue;
} }
if (Tok.equals_lower("constant")) {
E.Constant = true;
continue;
}
if (Tok.equals_lower("private")) { if (Tok.equals_lower("private")) {
E.Private = true; E.Private = true;
continue; continue;

View File

@ -162,7 +162,7 @@ public:
// Create a short import file which is described in PE/COFF spec 7. Import // Create a short import file which is described in PE/COFF spec 7. Import
// Library Format. // Library Format.
NewArchiveMember createShortImport(StringRef Sym, uint16_t Ordinal, NewArchiveMember createShortImport(StringRef Sym, uint16_t Ordinal,
ImportNameType NameType, bool isData); ImportType Type, ImportNameType NameType);
}; };
} }
@ -440,8 +440,8 @@ NewArchiveMember ObjectFactory::createNullThunk(std::vector<uint8_t> &Buffer) {
NewArchiveMember ObjectFactory::createShortImport(StringRef Sym, NewArchiveMember ObjectFactory::createShortImport(StringRef Sym,
uint16_t Ordinal, uint16_t Ordinal,
ImportNameType NameType, ImportType ImportType,
bool isData) { ImportNameType NameType) {
size_t ImpSize = DLLName.size() + Sym.size() + 2; // +2 for NULs size_t ImpSize = DLLName.size() + Sym.size() + 2; // +2 for NULs
size_t Size = sizeof(coff_import_header) + ImpSize; size_t Size = sizeof(coff_import_header) + ImpSize;
char *Buf = Alloc.Allocate<char>(Size); char *Buf = Alloc.Allocate<char>(Size);
@ -456,8 +456,7 @@ NewArchiveMember ObjectFactory::createShortImport(StringRef Sym,
Imp->SizeOfData = ImpSize; Imp->SizeOfData = ImpSize;
if (Ordinal > 0) if (Ordinal > 0)
Imp->OrdinalHint = Ordinal; Imp->OrdinalHint = Ordinal;
Imp->TypeInfo = (isData ? IMPORT_DATA : IMPORT_CODE); Imp->TypeInfo = (NameType << 2) | ImportType;
Imp->TypeInfo |= NameType << 2;
// Write symbol name and DLL name. // Write symbol name and DLL name.
memcpy(P, Sym.data(), Sym.size()); memcpy(P, Sym.data(), Sym.size());
@ -490,11 +489,18 @@ void lld::coff::writeImportLibrary() {
if (E.Private) if (E.Private)
continue; continue;
ImportNameType Type = getNameType(E.SymbolName, E.Name); ImportType ImportType = IMPORT_CODE;
if (E.Data)
ImportType = IMPORT_DATA;
if (E.Constant)
ImportType = IMPORT_CONST;
ImportNameType NameType = getNameType(E.SymbolName, E.Name);
std::string Name = E.ExtName.empty() std::string Name = E.ExtName.empty()
? std::string(E.SymbolName) ? std::string(E.SymbolName)
: replace(E.SymbolName, E.Name, E.ExtName); : replace(E.SymbolName, E.Name, E.ExtName);
Members.push_back(OF.createShortImport(Name, E.Ordinal, Type, E.Data)); Members.push_back(OF.createShortImport(Name, E.Ordinal, ImportType,
NameType));
} }
std::pair<StringRef, std::error_code> Result = std::pair<StringRef, std::error_code> Result =

View File

@ -38,6 +38,7 @@ enum Kind {
Comma, Comma,
Equal, Equal,
KwBase, KwBase,
KwConstant,
KwData, KwData,
KwExports, KwExports,
KwHeapsize, KwHeapsize,
@ -92,6 +93,7 @@ public:
StringRef Word = Buf.substr(0, End); StringRef Word = Buf.substr(0, End);
Kind K = llvm::StringSwitch<Kind>(Word) Kind K = llvm::StringSwitch<Kind>(Word)
.Case("BASE", KwBase) .Case("BASE", KwBase)
.Case("CONSTANT", KwConstant)
.Case("DATA", KwData) .Case("DATA", KwData)
.Case("EXPORTS", KwExports) .Case("EXPORTS", KwExports)
.Case("HEAPSIZE", KwHeapsize) .Case("HEAPSIZE", KwHeapsize)
@ -227,6 +229,11 @@ private:
E.Data = true; E.Data = true;
continue; continue;
} }
if (Tok.K == KwConstant) {
warn("CONSTANT keyword is obsolete; use DATA");
E.Constant = true;
continue;
}
if (Tok.K == KwPrivate) { if (Tok.K == KwPrivate) {
E.Private = true; E.Private = true;
continue; continue;

View File

@ -0,0 +1,10 @@
target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
target triple = "i686-unknown-windows-msvc18.0.0"
@__CFConstantStringClassReference = common global [32 x i32] zeroinitializer, align 4
!llvm.module.flags = !{!0}
!0 = !{i32 6, !"Linker Options", !1}
!1 = !{!2}
!2 = !{!" -export:___CFConstantStringClassReference,CONSTANT"}

View File

@ -0,0 +1,9 @@
# RUN: mkdir -p %t
# RUN: yaml2obj -o %t/constant-export.obj %S/constant-export.yaml
# RUN: lld-link /machine:x86 /dll /entry:__CFConstantStringClassReference -out:%t/constant-export.dll %t/constant-export.obj
# RUN: llvm-readobj -coff-exports %t/constant-export.lib | FileCheck %s
# CHECK: Type: const
# CHECK: Name type: noprefix
# CHECK: Symbol: __imp____CFConstantStringClassReference

View File

@ -0,0 +1,83 @@
--- !COFF
header:
Machine: IMAGE_FILE_MACHINE_I386
Characteristics: [ ]
sections:
- Name: .text
Characteristics: [ IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_READ ]
Alignment: 4
SectionData: ''
- Name: .data
Characteristics: [ IMAGE_SCN_CNT_INITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
Alignment: 4
SectionData: ''
- Name: .bss
Characteristics: [ IMAGE_SCN_CNT_UNINITIALIZED_DATA, IMAGE_SCN_MEM_READ, IMAGE_SCN_MEM_WRITE ]
Alignment: 4
SectionData: ''
- Name: .drectve
Characteristics: [ IMAGE_SCN_LNK_INFO, IMAGE_SCN_LNK_REMOVE ]
Alignment: 1
SectionData: 20202D6578706F72743A5F5F5F4346436F6E7374616E74537472696E67436C6173735265666572656E63652C434F4E5354414E54
symbols:
- Name: .text
Value: 0
SectionNumber: 1
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: 1
- Name: .data
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: .bss
Value: 0
SectionNumber: 3
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: 3
- Name: .drectve
Value: 0
SectionNumber: 4
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
SectionDefinition:
Length: 52
NumberOfRelocations: 0
NumberOfLinenumbers: 0
CheckSum: 1983959296
Number: 4
- Name: '@feat.00'
Value: 1
SectionNumber: -1
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_STATIC
- Name: ___CFConstantStringClassReference
Value: 128
SectionNumber: 0
SimpleType: IMAGE_SYM_TYPE_NULL
ComplexType: IMAGE_SYM_DTYPE_NULL
StorageClass: IMAGE_SYM_CLASS_EXTERNAL
...