From 6a44013b0e319979ce6ea9ead2a740564e434f76 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Tue, 14 Dec 2021 10:31:06 -0800 Subject: [PATCH] [ELF] -Map: Print symbols which needs canonical PLT entry/copy relocation just once If a copy related symbol (say `copy`) is referenced in two .o files, this change removes a duplicated line from the -Map output: ``` 202470 202470 1 1 .bss.rel.ro 202470 202470 1 1 :(.bss.rel.ro) 202470 202470 1 1 copy removed 202470 202470 1 1 copy ``` Differential Revision: https://reviews.llvm.org/D115697 --- lld/ELF/MapFile.cpp | 9 ++++++- lld/test/ELF/map-file-copy.s | 52 ++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 lld/test/ELF/map-file-copy.s diff --git a/lld/ELF/MapFile.cpp b/lld/ELF/MapFile.cpp index cefe8a235b48..275983527538 100644 --- a/lld/ELF/MapFile.cpp +++ b/lld/ELF/MapFile.cpp @@ -72,10 +72,17 @@ static SymbolMapTy getSectionSyms(ArrayRef syms) { // Sort symbols by address. We want to print out symbols in the // order in the output file rather than the order they appeared // in the input files. - for (auto &it : ret) + SmallPtrSet set; + for (auto &it : ret) { + // Deduplicate symbols which need a canonical PLT entry/copy relocation. + set.clear(); + llvm::erase_if(it.second, + [&](Defined *sym) { return !set.insert(sym).second; }); + llvm::stable_sort(it.second, [](Defined *a, Defined *b) { return a->getVA() < b->getVA(); }); + } return ret; } diff --git a/lld/test/ELF/map-file-copy.s b/lld/test/ELF/map-file-copy.s new file mode 100644 index 000000000000..58c0ce981048 --- /dev/null +++ b/lld/test/ELF/map-file-copy.s @@ -0,0 +1,52 @@ +# REQUIRES: x86 + +# RUN: split-file %s %t +# RUN: llvm-mc -filetype=obj -triple=x86_64 %t/1.s -o %t/1.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 %t/2.s -o %t/2.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 %t/3.s -o %t/3.o +# RUN: ld.lld -shared -soname=3 --version-script=%t/3.ver %t/3.o -o %t/3.so +# RUN: ld.lld -Map=%t/1.map %t/1.o %t/2.o %t/3.so -o %t/1 +# RUN: FileCheck %s --input-file=%t/1.map + +## Both TUs reference func/copy which need a canonical PLT entry/copy relocation. +## Test we print func/copy just once. +# CHECK: {{ }}.plt +# CHECK-NEXT: :(.plt) +# CHECK-NEXT: func@v1{{$}} +# CHECK-NEXT: .dynamic + +# CHECK: .bss.rel.ro +# CHECK-NEXT: :(.bss.rel.ro) +## Ideally this is displayed as copy@v2. +# CHECK-NEXT: copy{{$}} +# CHECK-NEXT: .got.plt + +#--- 1.s +.global _start +_start: +.symver func, func@@@v1 + mov $copy, %eax + mov $func - ., %eax + +#--- 2.s +.symver func, func@@@v1 + mov $copy, %eax + mov $func - ., %eax + +#--- 3.s +.globl func +.symver func, func@v1, remove +.type func, @function +func: + ret + +.section .rodata,"a" +.globl copy +.type copy, @object +copy: +.byte 1 +.size copy, 1 + +#--- 3.ver +v1 { func; }; +v2 { copy; };