summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
authorKristina Brooks <kristina@nym.hush.com>2018-09-25 22:27:40 +0000
committerKristina Brooks <kristina@nym.hush.com>2018-09-25 22:27:40 +0000
commit34e24d5b6a147c72424e043aa9609ed094a4fabf (patch)
tree705babd66ca5a917726abdad747a513232313417 /clang/lib/CodeGen/CodeGenModule.cpp
parent0b7fdca640f020f9b9de53401cc2c29b36748cf7 (diff)
downloadbcm5719-llvm-34e24d5b6a147c72424e043aa9609ed094a4fabf.tar.gz
bcm5719-llvm-34e24d5b6a147c72424e043aa9609ed094a4fabf.zip
Reland "[Clang][CodeGen][ObjC]: Fix CoreFoundation on ELF with `-fconstant-cfstrings`"
Relanding rL342883 with more fragmented tests to test ELF-specific section emission separately from broad-scope CFString tests. Now this tests the following separately 1). CoreFoundation builds and linkage for ELF while building it. 2). CFString ELF section emission outside CF in assembly output. 3). Broad scope `cfstring3.c` tests which cover all object formats at bitcode level and assembly level (including ELF). This fixes 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: 343038
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp63
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);
OpenPOWER on IntegriCloud