[PATCH] D129107: [BOLT][HUGIFY] adds huge pages support of PIE/no-PIE binaries

Alexey Moksyakov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 17 06:06:19 PDT 2022


yavtuk added a comment.

Hi Rafael let me try to explain it from a loader point of view on the different kernels
I have 2 kernels: 5.10 and 4.18

"From the left side, this is already aligned via BinaryContext::PageAlign. This is not just setting p_align, but actually setting the start address to be aligned at 2MB boundary. So this line here is inserting an extra empty 2MB page, but I'm not sure I get the reason why."

Here the debug log from runnnig application with --hugify
kernel 5.10                                  
./redis-server.gold.pie.bolt.test2
[hugify] hot start: 563c2fe00000
[hugify] hot end: 563c2fe0df97
[hugify] aligned huge page from: 563c2fe00000
[hugify] aligned huge page to: 563c30000000

kernel 4.18
./redis-server.gold.pie.bolt.test2
[hugify] hot start: 5616f85c3000
[hugify] hot end: 5616f85d0f97
[hugify] aligned huge page from: 5616f8400000
[hugify] aligned huge page to: 5616f8600000
[hugify] workaround with memory alignment for kernel < 5.10
[hugify] allocated temporary address: 7f127eefb000
[hugify] allocated aligned size: 200000
[hugify] allocated size: df97

As fas as you can see the hot start addresses are different.
for 5.10 the one is aligned to 2MB and we can just call madvise directly.
But for 4.18 we see that address is 4 KB aligned, OS does not give us the huge page due to incorrect address.
In order to fix it I put one extra page from left side (between 2 load segments)
it allows me to remap text section to 2MB page.

"For the right side, this alignment is accomplished by lines RewriteInstance.cpp:3635 ..."

Yes, you are right, but it is padding after all execution sections. 
I am not sure exactly but probably it's not possibly to have 2 RE regions with different page sizes (2MB & 4KB)
inside of one huge page, but without padding from right side I have SEGV_MAPPER error (it can be OS specific)

  [25] .bss              NOBITS          0000000000004038 003038 000008 00  WA  0   0  1
  [26] .text             PROGBITS        0000000000600000 600000 000085 00  AX  0   0 2097152
  [27] .text.injected    PROGBITS        00000000006000c0 6000c0 000005 00  AX  0   0 64
  [28] .text.cold        PROGBITS        0000000000600100 600100 0001a9 00  AX  0   0 64
  [29] .eh_frame         PROGBITS        0000000000800000 800000 000260 00   A  0   0  8
  
    --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x600000} ---
    +++ killed by SIGSEGV +++
    Segmentation fault

"bolt/runtime/common.h
Ok, I debugged user-func-reoder and noticed that this patch is doing something else. Instead of copying the entire contents of the huge page, ..."

I think it redundant functionality to copy cold text and get the huge page for it.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D129107/new/

https://reviews.llvm.org/D129107



More information about the llvm-commits mailing list