r271211 - CodeGen: tweak CFConstantStrings for COFF and ELF
Rafael EspĂndola via cfe-commits
cfe-commits at lists.llvm.org
Mon May 30 12:54:41 PDT 2016
Why .rodata.cfstring? Which linker treats that specially?
On 30 May 2016 at 12:23, Saleem Abdulrasool via cfe-commits
<cfe-commits at 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 at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list