From 316d4f96f22afa6630ee1069e48f970362f50f0a Mon Sep 17 00:00:00 2001 From: Jez Ng Date: Tue, 18 Oct 2022 17:21:43 -0400 Subject: [PATCH] [lld-macho] Folded symbols should have size zero in linker map This matches ld64's behavior. I also extended the icf-stabs.s test to demonstrate that even though folded symbols have size zero, we cannot use the size-zero property in lieu of `wasIdenticalCodeFolded`, because size zero symbols should still get STABS entries. Reviewed By: #lld-macho, thakis Differential Revision: https://reviews.llvm.org/D136001 --- lld/MachO/InputSection.cpp | 4 +++- lld/test/MachO/map-file.s | 29 +++++++++++++++++++++++++---- lld/test/MachO/stabs-icf.s | 29 +++++++++++++++++++---------- 3 files changed, 47 insertions(+), 15 deletions(-) diff --git a/lld/MachO/InputSection.cpp b/lld/MachO/InputSection.cpp index 398a5c2..f9a3a6f 100644 --- a/lld/MachO/InputSection.cpp +++ b/lld/MachO/InputSection.cpp @@ -138,8 +138,10 @@ void ConcatInputSection::foldIdentical(ConcatInputSection *copy) { copy->live = false; copy->wasCoalesced = true; copy->replacement = this; - for (auto ©Sym : copy->symbols) + for (auto ©Sym : copy->symbols) { copySym->wasIdenticalCodeFolded = true; + copySym->size = 0; + } symbols.insert(symbols.end(), copy->symbols.begin(), copy->symbols.end()); copy->symbols.clear(); diff --git a/lld/test/MachO/map-file.s b/lld/test/MachO/map-file.s index 3103e47..ac5ae9d 100644 --- a/lld/test/MachO/map-file.s +++ b/lld/test/MachO/map-file.s @@ -13,14 +13,14 @@ # CHECK: Sections: # CHECK-NEXT: Idx Name Size VMA Type # CHECK-NEXT: 0 __text {{[0-9a-f]+}} [[#%x,TEXT:]] TEXT -# CHECK-NEXT: 1 obj {{[0-9a-f]+}} [[#%x,DATA:]] DATA +# CHECK-NEXT: 1 obj {{[0-9a-f]+}} [[#%x,DATA:]] TEXT # CHECK-NEXT: 2 __cstring {{[0-9a-f]+}} [[#%x,CSTR:]] DATA # CHECK-NEXT: 3 __common {{[0-9a-f]+}} [[#%x,BSS:]] BSS # CHECK: SYMBOL TABLE: # CHECK-DAG: [[#%x,MAIN:]] g F __TEXT,__text _main # CHECK-DAG: [[#%x,NUMBER:]] g O __DATA,__common _number -# CHECK-DAG: [[#%x,FOO:]] g O __TEXT,obj _foo +# CHECK-DAG: [[#%x,FOO:]] g F __TEXT,obj _foo # CHECK-DAG: [[#%x,HIWORLD:]] g O __TEXT,__cstring _hello_world # CHECK-DAG: [[#%x,HIITSME:]] g O __TEXT,__cstring _hello_its_me @@ -59,18 +59,37 @@ # STRIPPED-DAG: <> 0x0000000F [ 3] literal string: Hello, it's me # STRIPPED-DAG: <> 0x00000001 [ 1] _number +# RUN: %lld --icf=all -map %t/icf-map %t/test.o %t/foo.o %t/c-string-literal.o -o %t/icf +# RUN: FileCheck --check-prefix=ICF %s < %t/icf-map + +# ICF: Symbols: +# ICF-DAG: 0x[[#%X,FOO:]] 0x00000000 [ 2] _foo +# ICF-DAG: 0x[[#FOO]] 0x00000001 [ 1] _bar + #--- foo.s -.section __TEXT,obj +## ICF will only fold sections marked as pure_instructions +.section __TEXT,obj,regular,pure_instructions .globl _foo +.alt_entry _alt_foo _foo: nop +.subsections_via_symbols + #--- test.s .comm _number, 1 -.globl _main +.globl _main, _bar +.alt_entry _alt_bar + _main: ret +.section __TEXT,obj,regular,pure_instructions +_bar: + nop + +.subsections_via_symbols + #--- c-string-literal.s .globl _hello_world, _hello_its_me @@ -81,3 +100,5 @@ _hello_world: _hello_its_me: .asciz "Hello, it's me" + +.subsections_via_symbols diff --git a/lld/test/MachO/stabs-icf.s b/lld/test/MachO/stabs-icf.s index 61588eb..129fc86 100644 --- a/lld/test/MachO/stabs-icf.s +++ b/lld/test/MachO/stabs-icf.s @@ -4,37 +4,46 @@ # RUN: %lld -lSystem --icf=all %t.o -o %t # RUN: dsymutil -s %t | FileCheck %s -DDIR=%t -DSRC_PATH=%t.o -# This should include no N_FUN entry for _bar2 (which is ICF'd into _bar), -# but it does include a SECT EXT entry. -# CHECK: (N_SO ) 00 0000 0000000000000000 '/tmp{{[/\\]}}test.cpp' +## This should include no N_FUN entry for _baz (which is ICF'd into _bar), +## but it does include a SECT EXT entry. +## NOTE: We do not omit the N_FUN entry for _bar even though it is of size zero. +## Only folded symbols get omitted. +## NOTE: Unlike ld64, we also omit the N_FUN entry for _baz2. +# CHECK: (N_SO ) 00 0000 0000000000000000 '/tmp{{[/\\]}}test.cpp' # CHECK-NEXT: (N_OSO ) 03 0001 {{.*}} '[[SRC_PATH]]' -# CHECK-NEXT: (N_FUN ) 01 0000 [[#%.16x,MAIN:]] '_main' +# CHECK-NEXT: (N_FUN ) 01 0000 [[#%.16x,MAIN:]] '_main' # CHECK-NEXT: (N_FUN ) 00 0000 000000000000000b{{$}} -# CHECK-NEXT: (N_FUN ) 01 0000 [[#%.16x,BAR:]] '_bar' +# CHECK-NEXT: (N_FUN ) 01 0000 [[#%.16x,BAR:]] '_bar' +# CHECK-NEXT: (N_FUN ) 00 0000 0000000000000000{{$}} +# CHECK-NEXT: (N_FUN ) 01 0000 [[#BAR]] '_bar2' # CHECK-NEXT: (N_FUN ) 00 0000 0000000000000001{{$}} # CHECK-NEXT: (N_SO ) 01 0000 0000000000000000{{$}} -# CHECK-DAG: ( SECT EXT) 01 0000 [[#MAIN]] '_main' -# CHECK-DAG: ( SECT EXT) 01 0000 [[#BAR]] '_bar' +# CHECK-DAG: ( SECT EXT) 01 0000 [[#MAIN]] '_main' +# CHECK-DAG: ( SECT EXT) 01 0000 [[#BAR]] '_bar' # CHECK-DAG: ( SECT EXT) 01 0000 [[#BAR]] '_bar2' +# CHECK-DAG: ( SECT EXT) 01 0000 [[#BAR]] '_baz' +# CHECK-DAG: ( SECT EXT) 01 0000 [[#BAR]] '_baz2' # CHECK-DAG: ( {{.*}}) {{[0-9]+}} 0010 {{[0-9a-f]+}} '__mh_execute_header' # CHECK-DAG: ( {{.*}}) {{[0-9]+}} 0100 0000000000000000 'dyld_stub_binder' # CHECK-EMPTY: .text -.globl _bar, _bar2, _main +.globl _bar, _bar2, _baz, _baz2, _main .subsections_via_symbols _bar: +_bar2: ret -_bar2: +_baz: +_baz2: ret _main: Lfunc_begin0: call _bar - call _bar2 + call _baz ret Lfunc_end0: -- 2.7.4