2018-07-19 06:49:31 +08:00
|
|
|
# REQUIRES: x86
|
|
|
|
|
|
|
|
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t1.o
|
|
|
|
# RUN: llvm-objcopy %t1.o %t1copy.o
|
|
|
|
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/icf-safe.s -o %t2.o
|
|
|
|
# RUN: ld.lld %t1.o %t2.o -o %t2 --icf=safe --print-icf-sections | FileCheck %s
|
|
|
|
# RUN: ld.lld %t1.o %t2.o -o %t3 --icf=safe --print-icf-sections -shared | FileCheck --check-prefix=EXPORT %s
|
|
|
|
# RUN: ld.lld %t1.o %t2.o -o %t3 --icf=safe --print-icf-sections --export-dynamic | FileCheck --check-prefix=EXPORT %s
|
2018-07-21 10:14:59 +08:00
|
|
|
# RUN: ld.lld %t1.o %t2.o -o %t2 --icf=all --print-icf-sections | FileCheck --check-prefix=ALL %s
|
|
|
|
# RUN: ld.lld %t1.o %t2.o -o %t2 --icf=all --print-icf-sections --export-dynamic | FileCheck --check-prefix=ALL-EXPORT %s
|
2018-07-19 06:49:31 +08:00
|
|
|
# RUN: ld.lld %t1copy.o -o %t4 --icf=safe 2>&1 | FileCheck --check-prefix=OBJCOPY %s
|
|
|
|
|
|
|
|
# CHECK-NOT: selected section {{.*}}:(.text.f1)
|
|
|
|
# CHECK: selected section {{.*}}:(.text.f3)
|
|
|
|
# CHECK: removing identical section {{.*}}:(.text.f4)
|
|
|
|
|
|
|
|
# CHECK-NOT: selected section {{.*}}:(.rodata.h1)
|
|
|
|
# CHECK: selected section {{.*}}:(.rodata.h3)
|
|
|
|
# CHECK: removing identical section {{.*}}:(.rodata.h4)
|
|
|
|
|
2018-07-27 07:34:35 +08:00
|
|
|
# CHECK-NOT: selected section {{.*}}:(.rodata.l1)
|
|
|
|
# CHECK: selected section {{.*}}:(.rodata.l3)
|
|
|
|
# CHECK: removing identical section {{.*}}:(.rodata.l4)
|
|
|
|
|
2018-07-19 06:49:31 +08:00
|
|
|
# CHECK-NOT: selected section {{.*}}:(.rodata.g1)
|
|
|
|
# CHECK: selected section {{.*}}:(.rodata.g3)
|
|
|
|
# CHECK: removing identical section {{.*}}:(.rodata.g4)
|
|
|
|
|
|
|
|
# CHECK-NOT: selected section {{.*}}:(.text.non_addrsig{{.}})
|
|
|
|
|
2018-07-21 10:14:59 +08:00
|
|
|
# With --icf=all address-significance implies keep-unique only for rodata, not
|
|
|
|
# text.
|
|
|
|
# ALL: selected section {{.*}}:(.text.f3)
|
|
|
|
# ALL: removing identical section {{.*}}:(.text.f4)
|
|
|
|
|
2018-07-27 07:34:35 +08:00
|
|
|
# ALL-NOT: selected section {{.*}}:(.rodata.h1)
|
|
|
|
# ALL: selected section {{.*}}:(.rodata.h3)
|
|
|
|
# ALL: removing identical section {{.*}}:(.rodata.h4)
|
|
|
|
|
2018-07-21 10:14:59 +08:00
|
|
|
# ALL: selected section {{.*}}:(.text.f1)
|
|
|
|
# ALL: removing identical section {{.*}}:(.text.f2)
|
|
|
|
# ALL: removing identical section {{.*}}:(.text.non_addrsig1)
|
|
|
|
# ALL: removing identical section {{.*}}:(.text.non_addrsig2)
|
|
|
|
|
2018-07-27 07:34:35 +08:00
|
|
|
# ALL-NOT: selected section {{.*}}:(.rodata.l1)
|
|
|
|
# ALL: selected section {{.*}}:(.rodata.l3)
|
|
|
|
# ALL: removing identical section {{.*}}:(.rodata.l4)
|
2018-07-21 10:14:59 +08:00
|
|
|
|
|
|
|
# ALL-NOT: selected section {{.*}}:(.rodata.g1)
|
|
|
|
# ALL: selected section {{.*}}:(.rodata.g3)
|
|
|
|
# ALL: removing identical section {{.*}}:(.rodata.g4)
|
|
|
|
|
2018-07-19 06:49:31 +08:00
|
|
|
# llvm-mc normally emits an empty .text section into every object file. Since
|
|
|
|
# nothing actually refers to it via a relocation, it doesn't have any associated
|
|
|
|
# symbols (thus nor can anything refer to it via a relocation, making it safe to
|
|
|
|
# merge with the empty section in the other input file). Here we check that the
|
|
|
|
# only two sections merged are the two empty sections and the sections with only
|
|
|
|
# STB_LOCAL or STV_HIDDEN symbols. The dynsym entries should have prevented
|
|
|
|
# anything else from being merged.
|
|
|
|
# EXPORT-NOT: selected section
|
|
|
|
# EXPORT: selected section {{.*}}:(.rodata.h3)
|
|
|
|
# EXPORT: removing identical section {{.*}}:(.rodata.h4)
|
|
|
|
# EXPORT-NOT: selected section
|
|
|
|
# EXPORT: selected section {{.*}}:(.text)
|
|
|
|
# EXPORT: removing identical section {{.*}}:(.text)
|
|
|
|
# EXPORT-NOT: selected section
|
2018-07-27 07:34:35 +08:00
|
|
|
# EXPORT: selected section {{.*}}:(.rodata.l3)
|
|
|
|
# EXPORT: removing identical section {{.*}}:(.rodata.l4)
|
|
|
|
# EXPORT-NOT: selected section
|
2018-07-19 06:49:31 +08:00
|
|
|
|
2018-07-21 10:14:59 +08:00
|
|
|
# If --icf=all is specified when exporting we can also merge the exported text
|
|
|
|
# sections, but not the exported rodata.
|
|
|
|
# ALL-EXPORT-NOT: selected section
|
|
|
|
# ALL-EXPORT: selected section {{.*}}:(.text.f3)
|
|
|
|
# ALL-EXPORT: removing identical section {{.*}}:(.text.f4)
|
|
|
|
# ALL-EXPORT-NOT: selected section
|
2018-07-27 07:34:35 +08:00
|
|
|
# ALL-EXPORT: selected section {{.*}}:(.rodata.h3)
|
|
|
|
# ALL-EXPORT: removing identical section {{.*}}:(.rodata.h4)
|
|
|
|
# ALL-EXPORT-NOT: selected section
|
2018-07-21 10:14:59 +08:00
|
|
|
# ALL-EXPORT: selected section {{.*}}:(.text.f1)
|
|
|
|
# ALL-EXPORT: removing identical section {{.*}}:(.text.f2)
|
|
|
|
# ALL-EXPORT: removing identical section {{.*}}:(.text.non_addrsig1)
|
|
|
|
# ALL-EXPORT: removing identical section {{.*}}:(.text.non_addrsig2)
|
|
|
|
# ALL-EXPORT-NOT: selected section
|
|
|
|
# ALL-EXPORT: selected section {{.*}}:(.text)
|
|
|
|
# ALL-EXPORT: removing identical section {{.*}}:(.text)
|
|
|
|
# ALL-EXPORT-NOT: selected section
|
2018-07-27 07:34:35 +08:00
|
|
|
# ALL-EXPORT: selected section {{.*}}:(.rodata.l3)
|
|
|
|
# ALL-EXPORT: removing identical section {{.*}}:(.rodata.l4)
|
|
|
|
# ALL-EXPORT-NOT: selected section
|
2018-07-21 10:14:59 +08:00
|
|
|
|
2018-07-19 06:49:31 +08:00
|
|
|
# OBJCOPY: --icf=safe is incompatible with object files created using objcopy or ld -r
|
|
|
|
|
|
|
|
.section .text.f1,"ax",@progbits
|
|
|
|
.globl f1
|
|
|
|
f1:
|
|
|
|
ret
|
|
|
|
|
|
|
|
.section .text.f2,"ax",@progbits
|
|
|
|
.globl f2
|
|
|
|
f2:
|
|
|
|
ret
|
|
|
|
|
|
|
|
.section .text.f3,"ax",@progbits
|
|
|
|
.globl f3
|
|
|
|
f3:
|
|
|
|
ud2
|
|
|
|
|
|
|
|
.section .text.f4,"ax",@progbits
|
|
|
|
.globl f4
|
|
|
|
f4:
|
|
|
|
ud2
|
|
|
|
|
|
|
|
.section .rodata.g1,"a",@progbits
|
|
|
|
.globl g1
|
|
|
|
g1:
|
|
|
|
.byte 1
|
|
|
|
|
|
|
|
.section .rodata.g2,"a",@progbits
|
|
|
|
.globl g2
|
|
|
|
g2:
|
|
|
|
.byte 1
|
|
|
|
|
|
|
|
.section .rodata.g3,"a",@progbits
|
|
|
|
.globl g3
|
|
|
|
g3:
|
|
|
|
.byte 2
|
|
|
|
|
|
|
|
.section .rodata.g4,"a",@progbits
|
|
|
|
.globl g4
|
|
|
|
g4:
|
|
|
|
.byte 2
|
|
|
|
|
|
|
|
.section .rodata.l1,"a",@progbits
|
|
|
|
l1:
|
|
|
|
.byte 3
|
|
|
|
|
|
|
|
.section .rodata.l2,"a",@progbits
|
|
|
|
l2:
|
|
|
|
.byte 3
|
|
|
|
|
|
|
|
.section .rodata.l3,"a",@progbits
|
|
|
|
l3:
|
|
|
|
.byte 4
|
|
|
|
|
|
|
|
.section .rodata.l4,"a",@progbits
|
|
|
|
l4:
|
|
|
|
.byte 4
|
|
|
|
|
|
|
|
.section .rodata.h1,"a",@progbits
|
|
|
|
.globl h1
|
|
|
|
.hidden h1
|
|
|
|
h1:
|
|
|
|
.byte 5
|
|
|
|
|
|
|
|
.section .rodata.h2,"a",@progbits
|
|
|
|
.globl h2
|
|
|
|
.hidden h2
|
|
|
|
h2:
|
|
|
|
.byte 5
|
|
|
|
|
|
|
|
.section .rodata.h3,"a",@progbits
|
|
|
|
.globl h3
|
|
|
|
.hidden h3
|
|
|
|
h3:
|
|
|
|
.byte 6
|
|
|
|
|
|
|
|
.section .rodata.h4,"a",@progbits
|
|
|
|
.globl h4
|
|
|
|
.hidden h4
|
|
|
|
h4:
|
|
|
|
.byte 6
|
|
|
|
|
|
|
|
.addrsig
|
|
|
|
.addrsig_sym f1
|
|
|
|
.addrsig_sym f2
|
|
|
|
.addrsig_sym g1
|
|
|
|
.addrsig_sym g2
|
|
|
|
.addrsig_sym l1
|
|
|
|
.addrsig_sym l2
|
|
|
|
.addrsig_sym h1
|
|
|
|
.addrsig_sym h2
|