<div dir="ltr">I'm inclined to directly implement what Samuel and other people want to lld if it is useful for not only Chrome but also for other large projects that want to keep track of their binary size and analyze their binary contents.<div><br></div><div>Such "analyze pass" is an independent pass, so it can be designed separately than other passes in the linker.<br><div><br></div><div>We could emit enough information in a map file or something so that a post-processor can analyze binary size, but it might be much easier to do that in the linker, because the linker naturally knows almost everything.</div><div><br></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Nov 17, 2017 at 4:07 PM, Rafael Avila de Espindola <span dir="ltr"><<a href="mailto:rafael.espindola@gmail.com" target="_blank">rafael.espindola@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Samuel, would the information included in this patch solve your problem?<br>
<br>
I agree that printing an address for each input section is bogus.<br>
Keeping the synthetic in the output is probably a good thing, since that<br>
is what has an address and it shows the final size of each merge.<br>
<br>
So what we have to figure out is a format that<br>
* Doesn't print a bogus address for input SHF_MERGE.<br>
* Still includes synthetic sections.<br>
<br>
This map is a direct textual dump of lld's internal state and it is a<br>
fact that some input sections are added directly to output sections<br>
and some are not. How about replacing "Out In" with "Section tree" and<br>
allowing it to have 2 or 3 levels?<br>
<br>
BTW, .eh_frame could also show up as 3 levels.<br>
<br>
Cheers,<br>
Rafael<br>
<div class="HOEnZb"><div class="h5"><br>
<br>
George Rimar via Phabricator <<a href="mailto:reviews@reviews.llvm.org">reviews@reviews.llvm.org</a>> writes:<br>
<br>
> grimar created this revision.<br>
> Herald added subscribers: arichardson, emaste.<br>
><br>
> It is inspired by comments for PR35248 though not directly relative to it.<br>
> It turns out we do not show the internal layout for mergeable sections when<br>
> producing Map file. Though it can be useful to show where is content coming from and<br>
> what is initial size (before mrging) and final size.<br>
> Patch adds support for dumping such sections.<br>
><br>
><br>
> <a href="https://reviews.llvm.org/D40128" rel="noreferrer" target="_blank">https://reviews.llvm.org/<wbr>D40128</a><br>
><br>
> Files:<br>
>   ELF/MapFile.cpp<br>
>   ELF/SyntheticSections.h<br>
>   test/ELF/Inputs/map-file2.s<br>
>   test/ELF/map-file.s<br>
><br>
><br>
> Index: test/ELF/map-file.s<br>
> ==============================<wbr>==============================<wbr>=======<br>
> --- test/ELF/map-file.s<br>
> +++ test/ELF/map-file.s<br>
> @@ -29,6 +29,9 @@<br>
>  abs = 0xAB5<br>
>  labs = 0x1AB5<br>
><br>
> +.section .strings,"MS",@progbits,1<br>
> +.asciz "AAA"<br>
> +<br>
>  // CHECK:      Address          Size             Align Out     In      Symbol<br>
>  // CHECK-NEXT: 0000000000200158 0000000000000030     8 .eh_frame<br>
>  // CHECK-NEXT: 0000000000200158 0000000000000030     8         <internal>:(.eh_frame)<br>
> @@ -49,12 +52,18 @@<br>
>  // CHECK-NEXT: 0000000000202000 0000000000000004    16 .bss<br>
>  // CHECK-NEXT: 0000000000202000 0000000000000004    16         {{.*}}{{/|\\}}map-file.s.tmp1.<wbr>o:(COMMON)<br>
>  // CHECK-NEXT: 0000000000202000 0000000000000004     0                 common<br>
> +// CHECK-NEXT: 0000000000000000 0000000000000008     2 .strings<br>
> +// CHECK-NEXT: 0000000000000000 0000000000000004     1         <internal>:(.strings)<br>
> +// CHECK-NEXT: 0000000000000000 0000000000000004     1                 {{.*}}{{/|\\}}map-file.s.tmp1.<wbr>o:(.strings)<br>
> +// CHECK-NEXT: 0000000000000004 0000000000000004     2         <internal>:(.strings)<br>
> +// CHECK-NEXT: 0000000000000000 0000000000000008     2                 {{.*}}{{/|\\}}map-file.s.tmp2.<wbr>o:(.strings)<br>
>  // CHECK-NEXT: 0000000000000000 0000000000000008     1 .comment<br>
<br>
<br>
<br>
<br>
<br>
<br>
>  // CHECK-NEXT: 0000000000000000 0000000000000008     1         <internal>:(.comment)<br>
> +// CHECK-NEXT: 0000000000000000 0000000000000008     1                 <internal>:(.comment)<br>
>  // CHECK-NEXT: 0000000000000000 0000000000000120     8 .symtab<br>
>  // CHECK-NEXT: 0000000000000000 0000000000000120     8         <internal>:(.symtab)<br>
> -// CHECK-NEXT: 0000000000000000 0000000000000039     1 .shstrtab<br>
> -// CHECK-NEXT: 0000000000000000 0000000000000039     1         <internal>:(.shstrtab)<br>
> +// CHECK-NEXT: 0000000000000000 0000000000000042     1 .shstrtab<br>
> +// CHECK-NEXT: 0000000000000000 0000000000000042     1         <internal>:(.shstrtab)<br>
>  // CHECK-NEXT: 0000000000000000 0000000000000038     1 .strtab<br>
>  // CHECK-NEXT: 0000000000000000 0000000000000038     1         <internal>:(.strtab)<br>
><br>
> Index: test/ELF/Inputs/map-file2.s<br>
> ==============================<wbr>==============================<wbr>=======<br>
> --- test/ELF/Inputs/map-file2.s<br>
> +++ test/ELF/Inputs/map-file2.s<br>
> @@ -6,3 +6,7 @@<br>
>  .section .text.zed,"ax",@progbits<br>
>  .global zed<br>
>  zed:<br>
> +.section .strings,"MS",@progbits,1<br>
> +.align 2<br>
> +.asciz "AAA"<br>
> +.asciz "AAA"<br>
> Index: ELF/SyntheticSections.h<br>
> ==============================<wbr>==============================<wbr>=======<br>
> --- ELF/SyntheticSections.h<br>
> +++ ELF/SyntheticSections.h<br>
> @@ -682,6 +682,8 @@<br>
>  public:<br>
>    void addSection(MergeInputSection *MS);<br>
><br>
> +  ArrayRef<MergeInputSection *> getSections() { return Sections; }<br>
> +<br>
>  protected:<br>
>    MergeSyntheticSection(<wbr>StringRef Name, uint32_t Type, uint64_t Flags,<br>
>                          uint32_t Alignment)<br>
> Index: ELF/MapFile.cpp<br>
> ==============================<wbr>==============================<wbr>=======<br>
> --- ELF/MapFile.cpp<br>
> +++ ELF/MapFile.cpp<br>
> @@ -27,9 +27,11 @@<br>
>  #include "SymbolTable.h"<br>
>  #include "SyntheticSections.h"<br>
>  #include "lld/Common/Threads.h"<br>
> +#include "llvm/BinaryFormat/ELF.h"<br>
>  #include "llvm/Support/raw_ostream.h"<br>
><br>
>  using namespace llvm;<br>
> +using namespace llvm::ELF;<br>
>  using namespace llvm::object;<br>
><br>
>  using namespace lld;<br>
> @@ -132,6 +134,15 @@<br>
>          OS << indent(1) << toString(IS) << '\n';<br>
>          for (Defined *Sym : SectionSyms[IS])<br>
>            OS << SymStr[Sym] << '\n';<br>
> +<br>
> +        // Dump synthetic mergeable sections layout.<br>
> +        if (!isa<SyntheticSection>(IS) || !(IS->Flags & SHF_MERGE))<br>
> +          continue;<br>
> +        MergeSyntheticSection *MS = static_cast<<wbr>MergeSyntheticSection *>(IS);<br>
> +        for (MergeInputSection *Sec : MS->getSections()) {<br>
> +          writeHeader(OS, 0, Sec->getSize(), Sec->Alignment);<br>
> +          OS << indent(2) << toString(Sec) << '\n';<br>
> +        }<br>
>        }<br>
>      }<br>
>    }<br>
><br>
><br>
> Index: test/ELF/map-file.s<br>
> ==============================<wbr>==============================<wbr>=======<br>
> --- test/ELF/map-file.s<br>
> +++ test/ELF/map-file.s<br>
> @@ -29,6 +29,9 @@<br>
>  abs = 0xAB5<br>
>  labs = 0x1AB5<br>
><br>
> +.section .strings,"MS",@progbits,1<br>
> +.asciz "AAA"<br>
> +<br>
>  // CHECK:      Address          Size             Align Out     In      Symbol<br>
>  // CHECK-NEXT: 0000000000200158 0000000000000030     8 .eh_frame<br>
>  // CHECK-NEXT: 0000000000200158 0000000000000030     8         <internal>:(.eh_frame)<br>
> @@ -49,12 +52,18 @@<br>
>  // CHECK-NEXT: 0000000000202000 0000000000000004    16 .bss<br>
>  // CHECK-NEXT: 0000000000202000 0000000000000004    16         {{.*}}{{/|\\}}map-file.s.tmp1.<wbr>o:(COMMON)<br>
>  // CHECK-NEXT: 0000000000202000 0000000000000004     0                 common<br>
> +// CHECK-NEXT: 0000000000000000 0000000000000008     2 .strings<br>
> +// CHECK-NEXT: 0000000000000000 0000000000000004     1         <internal>:(.strings)<br>
> +// CHECK-NEXT: 0000000000000000 0000000000000004     1                 {{.*}}{{/|\\}}map-file.s.tmp1.<wbr>o:(.strings)<br>
> +// CHECK-NEXT: 0000000000000004 0000000000000004     2         <internal>:(.strings)<br>
> +// CHECK-NEXT: 0000000000000000 0000000000000008     2                 {{.*}}{{/|\\}}map-file.s.tmp2.<wbr>o:(.strings)<br>
>  // CHECK-NEXT: 0000000000000000 0000000000000008     1 .comment<br>
>  // CHECK-NEXT: 0000000000000000 0000000000000008     1         <internal>:(.comment)<br>
> +// CHECK-NEXT: 0000000000000000 0000000000000008     1                 <internal>:(.comment)<br>
>  // CHECK-NEXT: 0000000000000000 0000000000000120     8 .symtab<br>
>  // CHECK-NEXT: 0000000000000000 0000000000000120     8         <internal>:(.symtab)<br>
> -// CHECK-NEXT: 0000000000000000 0000000000000039     1 .shstrtab<br>
> -// CHECK-NEXT: 0000000000000000 0000000000000039     1         <internal>:(.shstrtab)<br>
> +// CHECK-NEXT: 0000000000000000 0000000000000042     1 .shstrtab<br>
> +// CHECK-NEXT: 0000000000000000 0000000000000042     1         <internal>:(.shstrtab)<br>
>  // CHECK-NEXT: 0000000000000000 0000000000000038     1 .strtab<br>
>  // CHECK-NEXT: 0000000000000000 0000000000000038     1         <internal>:(.strtab)<br>
><br>
> Index: test/ELF/Inputs/map-file2.s<br>
> ==============================<wbr>==============================<wbr>=======<br>
> --- test/ELF/Inputs/map-file2.s<br>
> +++ test/ELF/Inputs/map-file2.s<br>
> @@ -6,3 +6,7 @@<br>
>  .section .text.zed,"ax",@progbits<br>
>  .global zed<br>
>  zed:<br>
> +.section .strings,"MS",@progbits,1<br>
> +.align 2<br>
> +.asciz "AAA"<br>
> +.asciz "AAA"<br>
> Index: ELF/SyntheticSections.h<br>
> ==============================<wbr>==============================<wbr>=======<br>
> --- ELF/SyntheticSections.h<br>
> +++ ELF/SyntheticSections.h<br>
> @@ -682,6 +682,8 @@<br>
>  public:<br>
>    void addSection(MergeInputSection *MS);<br>
><br>
> +  ArrayRef<MergeInputSection *> getSections() { return Sections; }<br>
> +<br>
>  protected:<br>
>    MergeSyntheticSection(<wbr>StringRef Name, uint32_t Type, uint64_t Flags,<br>
>                          uint32_t Alignment)<br>
> Index: ELF/MapFile.cpp<br>
> ==============================<wbr>==============================<wbr>=======<br>
> --- ELF/MapFile.cpp<br>
> +++ ELF/MapFile.cpp<br>
> @@ -27,9 +27,11 @@<br>
>  #include "SymbolTable.h"<br>
>  #include "SyntheticSections.h"<br>
>  #include "lld/Common/Threads.h"<br>
> +#include "llvm/BinaryFormat/ELF.h"<br>
>  #include "llvm/Support/raw_ostream.h"<br>
><br>
>  using namespace llvm;<br>
> +using namespace llvm::ELF;<br>
>  using namespace llvm::object;<br>
><br>
>  using namespace lld;<br>
> @@ -132,6 +134,15 @@<br>
>          OS << indent(1) << toString(IS) << '\n';<br>
>          for (Defined *Sym : SectionSyms[IS])<br>
>            OS << SymStr[Sym] << '\n';<br>
> +<br>
> +        // Dump synthetic mergeable sections layout.<br>
> +        if (!isa<SyntheticSection>(IS) || !(IS->Flags & SHF_MERGE))<br>
> +          continue;<br>
> +        MergeSyntheticSection *MS = static_cast<<wbr>MergeSyntheticSection *>(IS);<br>
> +        for (MergeInputSection *Sec : MS->getSections()) {<br>
> +          writeHeader(OS, 0, Sec->getSize(), Sec->Alignment);<br>
> +          OS << indent(2) << toString(Sec) << '\n';<br>
> +        }<br>
>        }<br>
>      }<br>
>    }<br>
</div></div></blockquote></div><br></div>