Why .rodata.cfstring? Which linker treats that specially?
On 30 May 2016 at 12:23, Saleem Abdulrasool via cfe-commits <cfe-commits@lists.llvm.org> wrote: > Author: compnerd > Date: Mon May 30 11:23:07 2016 > New Revision: 271211 > > URL: http://llvm.org/viewvc/llvm-project?rev=271211&view=rev > Log: > CodeGen: tweak CFConstantStrings for COFF and ELF > > Adjust the constant CFString emission to emit into more appropriate sections > on > ELF and COFF targets. It would previously try to use MachO section names > irrespective of the file format. > > Added: > cfe/trunk/test/CodeGen/CFStrings.c > Modified: > cfe/trunk/lib/CodeGen/CodeGenModule.cpp > > Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=271211&r1=271210&r2=271211&view=diff > ============================================================================== > --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original) > +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Mon May 30 11:23:07 2016 > @@ -3092,19 +3092,19 @@ CodeGenModule::GetAddrOfConstantCFString > llvm::Constant *Zero = llvm::Constant::getNullValue(Int32Ty); > llvm::Constant *Zeros[] = { Zero, Zero }; > llvm::Value *V; > - > + > // 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::Constant *GV = CreateRuntimeVariable(Ty, > - > "__CFConstantStringClassReference"); > + llvm::Constant *GV = > + CreateRuntimeVariable(Ty, "__CFConstantStringClassReference"); > // Decay array -> ptr > V = llvm::ConstantExpr::getGetElementPtr(Ty, GV, Zeros); > CFConstantStringClassRef = V; > - } > - else > + } else { > V = CFConstantStringClassRef; > + } > > QualType CFTy = getContext().getCFConstantStringType(); > > @@ -3117,8 +3117,8 @@ CodeGenModule::GetAddrOfConstantCFString > > // Flags. > llvm::Type *Ty = getTypes().ConvertType(getContext().UnsignedIntTy); > - Fields[1] = isUTF16 ? llvm::ConstantInt::get(Ty, 0x07d0) : > - llvm::ConstantInt::get(Ty, 0x07C8); > + Fields[1] = isUTF16 ? llvm::ConstantInt::get(Ty, 0x07d0) > + : llvm::ConstantInt::get(Ty, 0x07C8); > > // String pointer. > llvm::Constant *C = nullptr; > @@ -3139,18 +3139,17 @@ CodeGenModule::GetAddrOfConstantCFString > GV->setUnnamedAddr(true); > // Don't enforce the target's minimum global alignment, since the only use > // of the string is via this class initializer. > - // FIXME: We set the section explicitly to avoid a bug in ld64 224.1. > Without > - // it LLVM can merge the string with a non unnamed_addr one during LTO. > Doing > - // that changes the section it ends in, which surprises ld64. > - if (isUTF16) { > - CharUnits Align = getContext().getTypeAlignInChars(getContext().ShortTy); > - GV->setAlignment(Align.getQuantity()); > - GV->setSection("__TEXT,__ustring"); > - } else { > - CharUnits Align = getContext().getTypeAlignInChars(getContext().CharTy); > - GV->setAlignment(Align.getQuantity()); > - GV->setSection("__TEXT,__cstring,cstring_literals"); > - } > + CharUnits Align = isUTF16 > + ? > getContext().getTypeAlignInChars(getContext().ShortTy) > + : > getContext().getTypeAlignInChars(getContext().CharTy); > + GV->setAlignment(Align.getQuantity()); > + > + // FIXME: We set the section explicitly to avoid a bug in ld64 224.1. > + // Without it LLVM can merge the string with a non unnamed_addr one during > + // LTO. Doing that changes the section it ends in, which surprises ld64. > + if (getTarget().getTriple().getObjectFormat() == llvm::Triple::MachO) > + GV->setSection(isUTF16 ? "__TEXT,__ustring" > + : "__TEXT,__cstring,cstring_literals"); > > // String. > Fields[2] = > @@ -3171,8 +3170,20 @@ CodeGenModule::GetAddrOfConstantCFString > GV = new llvm::GlobalVariable(getModule(), C->getType(), true, > llvm::GlobalVariable::PrivateLinkage, C, > "_unnamed_cfstring_"); > - GV->setSection("__DATA,__cfstring"); > GV->setAlignment(Alignment.getQuantity()); > + switch (getTarget().getTriple().getObjectFormat()) { > + case llvm::Triple::UnknownObjectFormat: > + llvm_unreachable("unknown file format"); > + case llvm::Triple::COFF: > + GV->setSection(".rdata.cfstring"); > + break; > + case llvm::Triple::ELF: > + GV->setSection(".rodata.cfstring"); > + break; > + case llvm::Triple::MachO: > + GV->setSection("__DATA,__cfstring"); > + break; > + } > Entry.second = GV; > > return ConstantAddress(GV, Alignment); > > Added: cfe/trunk/test/CodeGen/CFStrings.c > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/CFStrings.c?rev=271211&view=auto > ============================================================================== > --- cfe/trunk/test/CodeGen/CFStrings.c (added) > +++ cfe/trunk/test/CodeGen/CFStrings.c Mon May 30 11:23:07 2016 > @@ -0,0 +1,49 @@ > +// RUN: %clang_cc1 -triple thumbv7-windows -S -emit-llvm %s -o - | FileCheck > %s -check-prefix CHECK-COFF > +// RUN: %clang_cc1 -triple i686-windows -S -emit-llvm %s -o - | FileCheck %s > -check-prefix CHECK-COFF > +// RUN: %clang_cc1 -triple x86_64-windows -S -emit-llvm %s -o - | FileCheck > %s -check-prefix CHECK-COFF > + > +// RUN: %clang_cc1 -triple armv7-elf -S -emit-llvm %s -o - | FileCheck %s > -check-prefix CHECK-ELF -check-prefix CHECK-ELF32 > +// RUN: %clang_cc1 -triple i686-elf -S -emit-llvm %s -o - | FileCheck %s > -check-prefix CHECK-ELF -check-prefix CHECK-ELF32 > +// RUN: %clang_cc1 -triple x86_64-elf -S -emit-llvm %s -o - | FileCheck %s > -check-prefix CHECK-ELF -check-prefix CHECK-ELF64 > +// RUN: %clang_cc1 -triple armv7-elf -S %s -o - | FileCheck %s -check-prefix > CHECK-ELF-DATA-SECTION > + > +// RUN: %clang_cc1 -triple armv7-macho -S -emit-llvm %s -o - | FileCheck %s > -check-prefix CHECK-MACHO -check-prefix CHECK-MACHO32 > +// RUN: %clang_cc1 -triple i386-apple-macosx -S -emit-llvm %s -o - | > FileCheck %s -check-prefix CHECK-MACHO -check-prefix CHECK-MACHO32 > +// RUN: %clang_cc1 -triple x86_64-macho -S -emit-llvm %s -o - | FileCheck %s > -check-prefix CHECK-MACHO -check-prefix CHECK-MACHO64 > + > +typedef struct __CFString *CFStringRef; > +const CFStringRef one = > (CFStringRef)__builtin___CFStringMakeConstantString("one"); > +const CFStringRef two = > (CFStringRef)__builtin___CFStringMakeConstantString("\xef\xbf\xbd\x74\xef\xbf\xbd\x77\xef\xbf\xbd\x6f"); > + > +// CHECK-COFF: @.str = private unnamed_addr constant [4 x i8] c"one\00", > align 1 > +// CHECK-ELF: @.str = private unnamed_addr constant [4 x i8] c"one\00", > align 1 > +// CHECK-MACHO: @.str = private unnamed_addr constant [4 x i8] c"one\00", > section "__TEXT,__cstring,cstring_literals", align 1 > + > +// CHECK-COFF: @_unnamed_cfstring_ = private constant > %struct.__NSConstantString_tag { i32* getelementptr inbounds ([0 x i32], [0 x > i32]* @__CFConstantStringClassReference, i32 0, i32 0), i32 1992, i8* > getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i32 3 }, > section ".rdata.cfstring", align {{[48]}} > +// CHECK-ELF32: @_unnamed_cfstring_ = private constant > %struct.__NSConstantString_tag { i32* getelementptr inbounds ([0 x i32], [0 x > i32]* @__CFConstantStringClassReference, i32 0, i32 0), i32 1992, i8* > getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i32 3 }, > section ".rodata.cfstring", align 4 > +// CHECK-ELF64: @_unnamed_cfstring_ = private constant > %struct.__NSConstantString_tag { i32* getelementptr inbounds ([0 x i32], [0 x > i32]* @__CFConstantStringClassReference, i32 0, i32 0), i32 1992, i8* > getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i64 3 }, > section ".rodata.cfstring", align 8 > +// CHECK-MACHO32: @_unnamed_cfstring_ = private constant > %struct.__NSConstantString_tag { i32* getelementptr inbounds ([0 x i32], [0 x > i32]* @__CFConstantStringClassReference, i32 0, i32 0), i32 1992, i8* > getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i32 3 }, > section "__DATA,__cfstring", align 4 > +// CHECK-MACHO64: @_unnamed_cfstring_ = private constant > %struct.__NSConstantString_tag { i32* getelementptr inbounds ([0 x i32], [0 x > i32]* @__CFConstantStringClassReference, i32 0, i32 0), i32 1992, i8* > getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i64 3 }, > section "__DATA,__cfstring", align 8 > + > +// CHECK-COFF: @.str.1 = private unnamed_addr constant [7 x i16] [i16 -3, > i16 116, i16 -3, i16 119, i16 -3, i16 111, i16 0], align 2 > +// CHECK-ELF: @.str.1 = private unnamed_addr constant [7 x i16] [i16 -3, i16 > 116, i16 -3, i16 119, i16 -3, i16 111, i16 0], align 2 > +// CHECK-MACHO: @.str.1 = private unnamed_addr constant [7 x i16] [i16 -3, > i16 116, i16 -3, i16 119, i16 -3, i16 111, i16 0], section > "__TEXT,__ustring", align 2 > + > +// CHECK-COFF: @_unnamed_cfstring_.2 = private constant > %struct.__NSConstantString_tag { i32* getelementptr inbounds ([0 x i32], [0 x > i32]* @__CFConstantStringClassReference, i32 0, i32 0), i32 2000, i8* bitcast > ([7 x i16]* @.str.1 to i8*), i32 6 }, section ".rdata.cfstring", align > {{[48]}} > +// CHECK-ELF32: @_unnamed_cfstring_.2 = private constant > %struct.__NSConstantString_tag { i32* getelementptr inbounds ([0 x i32], [0 x > i32]* @__CFConstantStringClassReference, i32 0, i32 0), i32 2000, i8* bitcast > ([7 x i16]* @.str.1 to i8*), i32 6 }, section ".rodata.cfstring", align 4 > +// CHECK-ELF64: @_unnamed_cfstring_.2 = private constant > %struct.__NSConstantString_tag { i32* getelementptr inbounds ([0 x i32], [0 x > i32]* @__CFConstantStringClassReference, i32 0, i32 0), i32 2000, i8* bitcast > ([7 x i16]* @.str.1 to i8*), i64 6 }, section ".rodata.cfstring", align 8 > +// CHECK-MACHO32: @_unnamed_cfstring_.2 = private constant > %struct.__NSConstantString_tag { i32* getelementptr inbounds ([0 x i32], [0 x > i32]* @__CFConstantStringClassReference, i32 0, i32 0), i32 2000, i8* bitcast > ([7 x i16]* @.str.1 to i8*), i32 6 }, section "__DATA,__cfstring", align 4 > +// CHECK-MACHO64: @_unnamed_cfstring_.2 = private constant > %struct.__NSConstantString_tag { i32* getelementptr inbounds ([0 x i32], [0 x > i32]* @__CFConstantStringClassReference, i32 0, i32 0), i32 2000, i8* bitcast > ([7 x i16]* @.str.1 to i8*), i64 6 }, section "__DATA,__cfstring", align 8 > + > +// CHECK-ELF-DATA-SECTION: .section .rodata.str1.1 > +// CHECK-ELF-DATA-SECTION: .asciz "one" > + > +// CHECK-ELF-DATA-SECTION: .section .rodata.str2.2 > +// CHECK-ELF-DATA-SECTION: .short 65533 > +// CHECK-ELF-DATA-SECTION: .short 116 > +// CHECK-ELF-DATA-SECTION: .short 65533 > +// CHECK-ELF-DATA-SECTION: .short 119 > +// CHECK-ELF-DATA-SECTION: .short 65533 > +// CHECK-ELF-DATA-SECTION: .short 111 > +// CHECK-ELF-DATA-SECTION: .short 0 > + > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits