diff options
author | Kristina Brooks <kristina@nym.hush.com> | 2018-09-24 14:06:47 +0000 |
---|---|---|
committer | Kristina Brooks <kristina@nym.hush.com> | 2018-09-24 14:06:47 +0000 |
commit | 7c142a52e2db5df508fc665c2cc28cbd0ae00ac5 (patch) | |
tree | a4064294c969d49ee1b0f25d009315fd81550c09 /clang/lib/CodeGen/CodeGenModule.cpp | |
parent | edefda48d2f543f6f97b72098ba1c24720c1af6e (diff) | |
download | bcm5719-llvm-7c142a52e2db5df508fc665c2cc28cbd0ae00ac5.tar.gz bcm5719-llvm-7c142a52e2db5df508fc665c2cc28cbd0ae00ac5.zip |
[Clang][CodeGen][ObjC]: Fix CoreFoundation on ELF with `-fconstant-cfstrings`.
[Clang][CodeGen][ObjC]: Fix non-bridged CoreFoundation builds on ELF targets
that use `-fconstant-cfstrings`. The original changes from differential
for a similar patch to PE/COFF (https://reviews.llvm.org/D44491) did not
check for an edge case where the global could be a constant which surfaced
as an issue when building for ELF because of different linkage semantics.
This patch addresses several issues with crashes related to CF builds on ELF
as well as improves data layout by ensuring string literals that back
the actual CFConstStrings end up in .rodata in line with Mach-O.
Change itself tested with CoreFoundation on Linux x86_64 but should be valid
for BSD-like systems as well that use ELF as the native object format.
Differential Revision: https://reviews.llvm.org/D52344
llvm-svn: 342883
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 63 |
1 files changed, 39 insertions, 24 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 85fed525795..baafa98d5c8 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -4109,37 +4109,48 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) { llvm::Constant *Zero = llvm::Constant::getNullValue(Int32Ty); llvm::Constant *Zeros[] = { Zero, Zero }; - + // If we don't already have it, get __CFConstantStringClassReference. if (!CFConstantStringClassRef) { llvm::Type *Ty = getTypes().ConvertType(getContext().IntTy); Ty = llvm::ArrayType::get(Ty, 0); - llvm::GlobalValue *GV = cast<llvm::GlobalValue>( - CreateRuntimeVariable(Ty, "__CFConstantStringClassReference")); - - if (getTriple().isOSBinFormatCOFF()) { - IdentifierInfo &II = getContext().Idents.get(GV->getName()); - TranslationUnitDecl *TUDecl = getContext().getTranslationUnitDecl(); - DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl); - - const VarDecl *VD = nullptr; - for (const auto &Result : DC->lookup(&II)) - if ((VD = dyn_cast<VarDecl>(Result))) - break; - - if (!VD || !VD->hasAttr<DLLExportAttr>()) { - GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); - GV->setLinkage(llvm::GlobalValue::ExternalLinkage); - } else { - GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); - GV->setLinkage(llvm::GlobalValue::ExternalLinkage); + llvm::Constant *C = + CreateRuntimeVariable(Ty, "__CFConstantStringClassReference"); + + if (getTriple().isOSBinFormatELF() || getTriple().isOSBinFormatCOFF()) { + llvm::GlobalValue *GV = nullptr; + + if ((GV = dyn_cast<llvm::GlobalValue>(C))) { + IdentifierInfo &II = getContext().Idents.get(GV->getName()); + TranslationUnitDecl *TUDecl = getContext().getTranslationUnitDecl(); + DeclContext *DC = TranslationUnitDecl::castToDeclContext(TUDecl); + + const VarDecl *VD = nullptr; + for (const auto &Result : DC->lookup(&II)) + if ((VD = dyn_cast<VarDecl>(Result))) + break; + + if (getTriple().isOSBinFormatELF()) { + if (!VD) + GV->setLinkage(llvm::GlobalValue::ExternalLinkage); + } + else { + if (!VD || !VD->hasAttr<DLLExportAttr>()) { + GV->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); + GV->setLinkage(llvm::GlobalValue::ExternalLinkage); + } else { + GV->setDLLStorageClass(llvm::GlobalValue::DLLExportStorageClass); + GV->setLinkage(llvm::GlobalValue::ExternalLinkage); + } + } + + setDSOLocal(GV); } } - setDSOLocal(GV); - + // Decay array -> ptr CFConstantStringClassRef = - llvm::ConstantExpr::getGetElementPtr(Ty, GV, Zeros); + llvm::ConstantExpr::getGetElementPtr(Ty, C, Zeros); } QualType CFTy = getContext().getCFConstantStringType(); @@ -4185,7 +4196,11 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) { if (getTriple().isOSBinFormatMachO()) GV->setSection(isUTF16 ? "__TEXT,__ustring" : "__TEXT,__cstring,cstring_literals"); - + // Make sure the literal ends up in .rodata to allow for safe ICF and for + // the static linker to adjust permissions to read-only later on. + else if (getTriple().isOSBinFormatELF()) + GV->setSection(".rodata"); + // String. llvm::Constant *Str = llvm::ConstantExpr::getGetElementPtr(GV->getValueType(), GV, Zeros); |