OSDN Git Service

Add support for #pragma clang section
authorJaved Absar <javed.absar@arm.com>
Mon, 5 Jun 2017 10:09:13 +0000 (10:09 +0000)
committerJaved Absar <javed.absar@arm.com>
Mon, 5 Jun 2017 10:09:13 +0000 (10:09 +0000)
This patch provides a means to specify section-names for global variables,
functions and static variables, using #pragma directives.
This feature is only defined to work sensibly for ELF targets.
One can specify section names as:
#pragma clang section bss="myBSS" data="myData" rodata="myRodata" text="myText"
One can "unspecify" a section name with empty string e.g.
#pragma clang section bss="" data="" text="" rodata=""

Reviewers: Roger Ferrer, Jonathan Roelofs, Reid Kleckner
Differential Revision: https://reviews.llvm.org/D33413

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@304704 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/IR/GlobalVariable.h
lib/CodeGen/GlobalMerge.cpp
lib/CodeGen/TargetLoweringObjectFileImpl.cpp
lib/Target/TargetLoweringObjectFile.cpp
test/CodeGen/ARM/clang-section.ll [new file with mode: 0644]
test/MC/ELF/clang-section.s [new file with mode: 0644]

index 3f5d00b..2df868d 100644 (file)
@@ -235,6 +235,13 @@ public:
     Attrs = A;
   }
 
+  /// Check if section name is present
+  bool hasImplicitSection() const {
+    return getAttributes().hasAttribute("bss-section") ||
+           getAttributes().hasAttribute("data-section") ||
+           getAttributes().hasAttribute("rodata-section");
+  }
+
   // Methods for support type inquiry through isa, cast, and dyn_cast:
   static inline bool classof(const Value *V) {
     return V->getValueID() == Value::GlobalVariableVal;
index 3603f9b..c6ca49c 100644 (file)
@@ -553,7 +553,8 @@ bool GlobalMerge::doInitialization(Module &M) {
   // Grab all non-const globals.
   for (auto &GV : M.globals()) {
     // Merge is safe for "normal" internal or external globals only
-    if (GV.isDeclaration() || GV.isThreadLocal() || GV.hasSection())
+    if (GV.isDeclaration() || GV.isThreadLocal() ||
+        GV.hasSection() || GV.hasImplicitSection())
       continue;
 
     // It's not safe to merge globals that may be preempted
index 1d232c7..3ba4a3a 100644 (file)
@@ -248,6 +248,25 @@ MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal(
     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
   StringRef SectionName = GO->getSection();
 
+  // Check if '#pragma clang section' name is applicable.
+  // Note that pragma directive overrides -ffunction-section, -fdata-section
+  // and so section name is exactly as user specified and not uniqued.
+  const GlobalVariable *GV = dyn_cast<GlobalVariable>(GO);
+  if (GV && GV->hasImplicitSection()) {
+    auto Attrs = GV->getAttributes();
+    if (Attrs.hasAttribute("bss-section") && Kind.isBSS()) {
+      SectionName = Attrs.getAttribute("bss-section").getValueAsString();
+    } else if (Attrs.hasAttribute("rodata-section") && Kind.isReadOnly()) {
+      SectionName = Attrs.getAttribute("rodata-section").getValueAsString();
+    } else if (Attrs.hasAttribute("data-section") && Kind.isData()) {
+      SectionName = Attrs.getAttribute("data-section").getValueAsString();
+    }
+  }
+  const Function *F = dyn_cast<Function>(GO);
+  if (F && F->hasFnAttribute("implicit-section-name")) {
+    SectionName = F->getFnAttribute("implicit-section-name").getValueAsString();
+  }
+
   // Infer section flags from the section name if we can.
   Kind = getELFKindForNamedSection(SectionName, Kind);
 
index 91cc97e..293a620 100644 (file)
@@ -240,6 +240,20 @@ MCSection *TargetLoweringObjectFile::SectionForGlobal(
   if (GO->hasSection())
     return getExplicitSectionGlobal(GO, Kind, TM);
 
+  if (auto *GVar = dyn_cast<GlobalVariable>(GO)) {
+    auto Attrs = GVar->getAttributes();
+    if ((Attrs.hasAttribute("bss-section") && Kind.isBSS()) ||
+        (Attrs.hasAttribute("data-section") && Kind.isData()) ||
+        (Attrs.hasAttribute("rodata-section") && Kind.isReadOnly()))  {
+       return getExplicitSectionGlobal(GO, Kind, TM);
+    }
+  }
+
+  if (auto *F = dyn_cast<Function>(GO)) {
+    if (F->hasFnAttribute("implicit-section-name"))
+      return getExplicitSectionGlobal(GO, Kind, TM);
+  }
+
   // Use default section depending on the 'type' of global
   return SelectSectionForGlobal(GO, Kind, TM);
 }
diff --git a/test/CodeGen/ARM/clang-section.ll b/test/CodeGen/ARM/clang-section.ll
new file mode 100644 (file)
index 0000000..343f0e7
--- /dev/null
@@ -0,0 +1,140 @@
+;RUN: llc -mtriple=armv7-eabi %s -o - | FileCheck %s
+;Test that global variables and functions are assigned to correct sections.
+
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
+target triple = "armv7-arm-none-eabi"
+
+@a = global i32 0, align 4 #0
+@b = global i32 1, align 4 #0
+@c = global [4 x i32] zeroinitializer, align 4 #0
+@d = global [5 x i16] zeroinitializer, align 2 #0
+@e = global [6 x i16] [i16 0, i16 0, i16 1, i16 0, i16 0, i16 0], align 2 #0
+@f = constant i32 2, align 4 #0
+@h = global i32 0, align 4 #1
+@i = global i32 0, align 4 #2
+@j = constant i32 4, align 4 #2
+@k = global i32 0, align 4 #2
+@_ZZ3gooE7lstat_h = internal global i32 0, align 4 #2
+@_ZL1g = internal global [2 x i32] zeroinitializer, align 4 #0
+@l = global i32 5, align 4 #3
+@m = constant i32 6, align 4 #3
+@n = global i32 0, align 4
+@o = global i32 6, align 4
+@p = constant i32 7, align 4
+
+; Function Attrs: noinline nounwind
+define i32 @foo() #4 {
+entry:
+  %0 = load i32, i32* @b, align 4
+  ret i32 %0
+}
+
+; Function Attrs: noinline
+define i32 @goo() #5 {
+entry:
+  %call = call i32 @zoo(i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZL1g, i32 0, i32 0), i32* @_ZZ3gooE7lstat_h)
+  ret i32 %call
+}
+
+declare i32 @zoo(i32*, i32*) #6
+
+; Function Attrs: noinline nounwind
+define i32 @hoo() #7 {
+entry:
+  %0 = load i32, i32* @b, align 4
+  ret i32 %0
+}
+
+attributes #0 = { "bss-section"="my_bss.1" "data-section"="my_data.1" "rodata-section"="my_rodata.1" }
+attributes #1 = { "data-section"="my_data.1" "rodata-section"="my_rodata.1" }
+attributes #2 = { "bss-section"="my_bss.2" "rodata-section"="my_rodata.1" }
+attributes #3 = { "bss-section"="my_bss.2" "data-section"="my_data.2" "rodata-section"="my_rodata.2" }
+attributes #4 = { noinline nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "denormal-fp-math"="preserve-sign" "disable-tail-calls"="false" "implicit-section-name"="my_text.1" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="true" "no-jump-tables"="false" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="cortex-a9" "target-features"="+dsp,+fp16,+neon,+vfp3" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #5 = { noinline "correctly-rounded-divide-sqrt-fp-math"="false" "denormal-fp-math"="preserve-sign" "disable-tail-calls"="false" "implicit-section-name"="my_text.2" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="true" "no-jump-tables"="false" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="cortex-a9" "target-features"="+dsp,+fp16,+neon,+vfp3" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #6 = { "correctly-rounded-divide-sqrt-fp-math"="false" "denormal-fp-math"="preserve-sign" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="true" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="cortex-a9" "target-features"="+dsp,+fp16,+neon,+vfp3" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #7 = { noinline nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "denormal-fp-math"="preserve-sign" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="true" "no-jump-tables"="false" "no-nans-fp-math"="true" "no-signed-zeros-fp-math"="true" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="cortex-a9" "target-features"="+dsp,+fp16,+neon,+vfp3" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.module.flags = !{!0, !1, !2, !3}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{i32 1, !"static_rwdata", i32 1}
+!2 = !{i32 1, !"enumsize_buildattr", i32 2}
+!3 = !{i32 1, !"armlib_unavailable", i32 0}
+
+;CHECK:        .section        my_text.1,"ax",%progbits
+;CHECK:        .type   foo,%function
+;CHECK: foo:
+
+;CHECK:        .section        my_text.2,"ax",%progbits
+;CHECK:        .type   goo,%function
+;CHECK: goo:
+
+;CHECK:        .text
+;CHECK:        .type   hoo,%function
+;CHECK: hoo:
+
+;CHECK:        .type   a,%object
+;CHECK:        .section        my_bss.1,"aw",%nobits
+;CHECK: a:
+
+;CHECK:        .type   b,%object
+;CHECK:        .section        my_data.1,"aw",%progbits
+;CHECK: b:
+
+;CHECK:        .type   c,%object
+;CHECK:        .section        my_bss.1,"aw",%nobits
+;CHECK: c:
+
+;CHECK:        .type   d,%object
+;CHECK: d:
+
+;CHECK:        .type   e,%object
+;CHECK:        .section        my_data.1,"aw",%progbits
+;CHECK: e:
+
+;CHECK:        .type   f,%object
+;CHECK:        .section        my_rodata.1,"a",%progbits
+;CHECK: f:
+
+;CHECK:        .type   h,%object
+;CHECK:        .bss
+;CHECK: h:
+
+;CHECK:        .type   i,%object
+;CHECK:        .section        my_bss.2,"aw",%nobits
+;CHECK: i:
+
+;CHECK:        .type   j,%object
+;CHECK:        .section        my_rodata.1,"a",%progbits
+;CHECK: j:
+
+;CHECK:        .type   k,%object
+;CHECK:        .section        my_bss.2,"aw",%nobits
+;CHECK: k:
+
+;CHECK:        .type   _ZZ3gooE7lstat_h,%object @ @_ZZ3gooE7lstat_h
+;CHECK: _ZZ3gooE7lstat_h:
+
+;CHECK:        .type   _ZL1g,%object
+;CHECK:        .section        my_bss.1,"aw",%nobits
+;CHECK: _ZL1g:
+
+;CHECK:        .type   l,%object
+;CHECK:        .section        my_data.2,"aw",%progbits
+;CHECK: l:
+
+;CHECK:        .type   m,%object
+;CHECK:        .section        my_rodata.2,"a",%progbits
+;CHECK: m:
+
+;CHECK:        .type   n,%object
+;CHECK:        .bss
+;CHECK: n:
+
+;CHECK:        .type   o,%object
+;CHECK:        .data
+;CHECK: o:
+
+;CHECK:        .type   p,%object
+;CHECK:        .section        .rodata,"a",%progbits
+;CHECK: p:
diff --git a/test/MC/ELF/clang-section.s b/test/MC/ELF/clang-section.s
new file mode 100644 (file)
index 0000000..0b0d27c
--- /dev/null
@@ -0,0 +1,399 @@
+// RUN: llvm-mc -filetype=obj -triple arm-eabi %s -o - | llvm-readobj -s -t | FileCheck %s
+// Test that global variables and functions are assigned correct section.
+       .text
+       .syntax unified
+       .eabi_attribute 67, "2.09"      @ Tag_conformance
+       .eabi_attribute 6, 1    @ Tag_CPU_arch
+       .eabi_attribute 8, 1    @ Tag_ARM_ISA_use
+       .eabi_attribute 17, 1   @ Tag_ABI_PCS_GOT_use
+       .eabi_attribute 20, 1   @ Tag_ABI_FP_denormal
+       .eabi_attribute 21, 1   @ Tag_ABI_FP_exceptions
+       .eabi_attribute 23, 3   @ Tag_ABI_FP_number_model
+       .eabi_attribute 34, 1   @ Tag_CPU_unaligned_access
+       .eabi_attribute 24, 1   @ Tag_ABI_align_needed
+       .eabi_attribute 25, 1   @ Tag_ABI_align_preserved
+       .eabi_attribute 38, 1   @ Tag_ABI_FP_16bit_format
+       .eabi_attribute 18, 4   @ Tag_ABI_PCS_wchar_t
+       .eabi_attribute 26, 2   @ Tag_ABI_enum_size
+       .eabi_attribute 14, 0   @ Tag_ABI_PCS_R9_use
+       .section        my_text.1,"ax",%progbits
+       .globl  foo
+       .p2align        2
+       .type   foo,%function
+       .code   32                      @ @foo
+foo:
+       .fnstart
+@ BB#0:                                 @ %entry
+       ldr     r0, .LCPI0_0
+       ldr     r0, [r0]
+       mov     pc, lr
+       .p2align        2
+@ BB#1:
+.LCPI0_0:
+       .long   b
+.Lfunc_end0:
+       .size   foo, .Lfunc_end0-foo
+       .cantunwind
+       .fnend
+
+       .section        my_text.2,"ax",%progbits
+       .globl  goo
+       .p2align        2
+       .type   goo,%function
+       .code   32                      @ @goo
+goo:
+       .fnstart
+@ BB#0:                                 @ %entry
+       .save   {r11, lr}
+       push    {r11, lr}
+       ldr     r0, .LCPI1_0
+       ldr     r1, .LCPI1_1
+       bl      zoo
+       pop     {r11, lr}
+       mov     pc, lr
+       .p2align        2
+@ BB#1:
+.LCPI1_0:
+       .long   _ZL1g
+.LCPI1_1:
+       .long   _ZZ3gooE7lstat_h
+.Lfunc_end1:
+       .size   goo, .Lfunc_end1-goo
+       .cantunwind
+       .fnend
+
+       .text
+       .globl  hoo
+       .p2align        2
+       .type   hoo,%function
+       .code   32                      @ @hoo
+hoo:
+       .fnstart
+@ BB#0:                                 @ %entry
+       ldr     r0, .LCPI2_0
+       ldr     r0, [r0]
+       mov     pc, lr
+       .p2align        2
+@ BB#1:
+.LCPI2_0:
+       .long   b
+.Lfunc_end2:
+       .size   hoo, .Lfunc_end2-hoo
+       .cantunwind
+       .fnend
+
+       .type   a,%object               @ @a
+       .section        my_bss.1,"aw",%nobits
+       .globl  a
+       .p2align        2
+a:
+       .long   0                       @ 0x0
+       .size   a, 4
+
+       .type   b,%object               @ @b
+       .section        my_data.1,"aw",%progbits
+       .globl  b
+       .p2align        2
+b:
+       .long   1                       @ 0x1
+       .size   b, 4
+
+       .type   c,%object               @ @c
+       .section        my_bss.1,"aw",%nobits
+       .globl  c
+       .p2align        2
+c:
+       .zero   16
+       .size   c, 16
+
+       .type   d,%object               @ @d
+       .globl  d
+       .p2align        1
+d:
+       .zero   10
+       .size   d, 10
+
+       .type   e,%object               @ @e
+       .section        my_data.1,"aw",%progbits
+       .globl  e
+       .p2align        1
+e:
+       .short  0                       @ 0x0
+       .short  0                       @ 0x0
+       .short  1                       @ 0x1
+       .short  0                       @ 0x0
+       .short  0                       @ 0x0
+       .short  0                       @ 0x0
+       .size   e, 12
+
+       .type   f,%object               @ @f
+       .section        my_rodata.1,"a",%progbits
+       .globl  f
+       .p2align        2
+f:
+       .long   2                       @ 0x2
+       .size   f, 4
+
+       .type   h,%object               @ @h
+       .bss
+       .globl  h
+       .p2align        2
+h:
+       .long   0                       @ 0x0
+       .size   h, 4
+
+       .type   i,%object               @ @i
+       .section        my_bss.2,"aw",%nobits
+       .globl  i
+       .p2align        2
+i:
+       .long   0                       @ 0x0
+       .size   i, 4
+
+       .type   j,%object               @ @j
+       .section        my_rodata.1,"a",%progbits
+       .globl  j
+       .p2align        2
+j:
+       .long   4                       @ 0x4
+       .size   j, 4
+
+       .type   k,%object               @ @k
+       .section        my_bss.2,"aw",%nobits
+       .globl  k
+       .p2align        2
+k:
+       .long   0                       @ 0x0
+       .size   k, 4
+
+       .type   _ZZ3gooE7lstat_h,%object @ @_ZZ3gooE7lstat_h
+       .p2align        2
+_ZZ3gooE7lstat_h:
+       .long   0                       @ 0x0
+       .size   _ZZ3gooE7lstat_h, 4
+
+       .type   _ZL1g,%object           @ @_ZL1g
+       .section        my_bss.1,"aw",%nobits
+       .p2align        2
+_ZL1g:
+       .zero   8
+       .size   _ZL1g, 8
+
+       .type   l,%object               @ @l
+       .section        my_data.2,"aw",%progbits
+       .globl  l
+       .p2align        2
+l:
+       .long   5                       @ 0x5
+       .size   l, 4
+
+       .type   m,%object               @ @m
+       .section        my_rodata.2,"a",%progbits
+       .globl  m
+       .p2align        2
+m:
+       .long   6                       @ 0x6
+       .size   m, 4
+
+       .type   n,%object               @ @n
+       .bss
+       .globl  n
+       .p2align        2
+n:
+       .long   0                       @ 0x0
+       .size   n, 4
+
+       .type   o,%object               @ @o
+       .data
+       .globl  o
+       .p2align        2
+o:
+       .long   6                       @ 0x6
+       .size   o, 4
+
+       .type   p,%object               @ @p
+       .section        .rodata,"a",%progbits
+       .globl  p
+       .p2align        2
+p:
+       .long   7                       @ 0x7
+       .size   p, 4
+
+
+       .ident  "clang version 5.0.0 (http://llvm.org/git/clang.git 254242a3ad440307fb451093a429c71ea9a8c888) (http://llvm.org/git/llvm.git 3c8daefbe3d1672ac1dae775b211f881f0063038)"
+       .section        ".note.GNU-stack","",%progbits
+       .eabi_attribute 30, 1   @ Tag_ABI_optimization_goals
+
+//CHECK:   Section {
+//CHECK:     Name: .text
+//CHECK:     Type: SHT_PROGBITS (0x1)
+//CHECK:     Flags [ (0x6)
+//CHECK:       SHF_ALLOC (0x2)
+//CHECK:       SHF_EXECINSTR (0x4)
+//CHECK:     ]
+//CHECK:   }
+//CHECK:   Section {
+//CHECK:     Name: my_text.1
+//CHECK:     Type: SHT_PROGBITS (0x1)
+//CHECK:     Flags [ (0x6)
+//CHECK:       SHF_ALLOC (0x2)
+//CHECK:       SHF_EXECINSTR (0x4)
+//CHECK:     ]
+//CHECK:   }
+//CHECK:   Section {
+//CHECK:     Name: my_text.2
+//CHECK:     Type: SHT_PROGBITS (0x1)
+//CHECK:     Flags [ (0x6)
+//CHECK:       SHF_ALLOC (0x2)
+//CHECK:       SHF_EXECINSTR (0x4)
+//CHECK:     ]
+//CHECK:   }
+//CHECK:   Section {
+//CHECK:     Name: my_bss.1
+//CHECK:     Type: SHT_NOBITS (0x8)
+//CHECK:     Flags [ (0x3)
+//CHECK:       SHF_ALLOC (0x2)
+//CHECK:       SHF_WRITE (0x1)
+//CHECK:     ]
+//CHECK:   }
+//CHECK:   Section {
+//CHECK:     Name: my_data.1
+//CHECK:     Type: SHT_PROGBITS (0x1)
+//CHECK:     Flags [ (0x3)
+//CHECK:       SHF_ALLOC (0x2)
+//CHECK:       SHF_WRITE (0x1)
+//CHECK:     ]
+//CHECK:   }
+//CHECK:   Section {
+//CHECK:     Name: my_rodata.1
+//CHECK:     Type: SHT_PROGBITS (0x1)
+//CHECK:     Flags [ (0x2)
+//CHECK:       SHF_ALLOC (0x2)
+//CHECK:     ]
+//CHECK:   }
+//CHECK:   Section {
+//CHECK:     Name: .bss
+//CHECK:     Type: SHT_NOBITS (0x8)
+//CHECK:     Flags [ (0x3)
+//CHECK:       SHF_ALLOC (0x2)
+//CHECK:       SHF_WRITE (0x1)
+//CHECK:     ]
+//CHECK:   }
+//CHECK:   Section {
+//CHECK:     Name: my_bss.2
+//CHECK:     Type: SHT_NOBITS (0x8)
+//CHECK:     Flags [ (0x3)
+//CHECK:       SHF_ALLOC (0x2)
+//CHECK:       SHF_WRITE (0x1)
+//CHECK:     ]
+//CHECK:   }
+//CHECK:   Section {
+//CHECK:     Name: my_data.2
+//CHECK:     Type: SHT_PROGBITS (0x1)
+//CHECK:     Flags [ (0x3)
+//CHECK:       SHF_ALLOC (0x2)
+//CHECK:       SHF_WRITE (0x1)
+//CHECK:     ]
+//CHECK:   }
+//CHECK:   Section {
+//CHECK:     Name: my_rodata.2
+//CHECK:     Type: SHT_PROGBITS (0x1)
+//CHECK:     Flags [ (0x2)
+//CHECK:       SHF_ALLOC (0x2)
+//CHECK:     ]
+//CHECK:   }
+//CHECK:   Section {
+//CHECK:     Name: .data
+//CHECK:     Type: SHT_PROGBITS (0x1)
+//CHECK:     Flags [ (0x3)
+//CHECK:       SHF_ALLOC (0x2)
+//CHECK:       SHF_WRITE (0x1)
+//CHECK:     ]
+//CHECK:   }
+//CHECK:   Section {
+//CHECK:     Name: .rodata
+//CHECK:     Type: SHT_PROGBITS (0x1)
+//CHECK:     Flags [ (0x2)
+//CHECK:       SHF_ALLOC (0x2)
+//CHECK:     ]
+//CHECK:   }
+//CHECK:   Symbol {
+//CHECK:     Name: _ZL1g
+//CHECK:     Section: my_bss.1 (0xE)
+//CHECK:   }
+//CHECK:   Symbol {
+//CHECK:     Name: _ZZ3gooE7lstat_h
+//CHECK:     Section: my_bss.2 (0x12)
+//CHECK:   }
+//CHECK:   Symbol {
+//CHECK:     Name: a
+//CHECK:     Section: my_bss.1 (0xE)
+//CHECK:   }
+//CHECK:   Symbol {
+//CHECK:     Name: b
+//CHECK:     Section: my_data.1 (0xF)
+//CHECK:   }
+//CHECK:   Symbol {
+//CHECK:     Name: c
+//CHECK:     Section: my_bss.1 (0xE)
+//CHECK:   }
+//CHECK:   Symbol {
+//CHECK:     Name: d
+//CHECK:     Section: my_bss.1 (0xE)
+//CHECK:   }
+//CHECK:   Symbol {
+//CHECK:     Name: e
+//CHECK:     Section: my_data.1 (0xF)
+//CHECK:   }
+//CHECK:   Symbol {
+//CHECK:     Name: f
+//CHECK:     Section: my_rodata.1 (0x10)
+//CHECK:   }
+//CHECK:   Symbol {
+//CHECK:     Name: foo
+//CHECK:     Section: my_text.1 (0x4)
+//CHECK:   }
+//CHECK:   Symbol {
+//CHECK:     Name: goo
+//CHECK:     Section: my_text.2 (0x8)
+//CHECK:   }
+//CHECK:   Symbol {
+//CHECK:     Name: h
+//CHECK:     Section: .bss (0x11)
+//CHECK:   }
+//CHECK:   Symbol {
+//CHECK:     Name: hoo
+//CHECK:     Section: .text (0x2)
+//CHECK:   }
+//CHECK:   Symbol {
+//CHECK:     Name: i
+//CHECK:     Section: my_bss.2 (0x12)
+//CHECK:   }
+//CHECK:   Symbol {
+//CHECK:     Name: j
+//CHECK:     Section: my_rodata.1 (0x10)
+//CHECK:   }
+//CHECK:   Symbol {
+//CHECK:     Name: k
+//CHECK:     Section: my_bss.2 (0x12)
+//CHECK:   }
+//CHECK:   Symbol {
+//CHECK:     Name: l
+//CHECK:     Section: my_data.2 (0x13)
+//CHECK:   }
+//CHECK:   Symbol {
+//CHECK:     Name: m
+//CHECK:     Section: my_rodata.2 (0x14)
+//CHECK:   }
+//CHECK:   Symbol {
+//CHECK:     Name: n
+//CHECK:     Section: .bss (0x11)
+//CHECK:   }
+//CHECK:   Symbol {
+//CHECK:     Name: o
+//CHECK:     Section: .data (0x15)
+//CHECK:   }
+//CHECK:   Symbol {
+//CHECK:     Name: p
+//CHECK:     Section: .rodata (0x16)
+//CHECK:   }