[PATCH] D64854: [ELF] Delete redundant pageAlign at PT_GNU_RELRO boundaries after D58892
Peter Smith via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 17 03:20:01 PDT 2019
peter.smith added a comment.
In D64854#1588970 <https://reviews.llvm.org/D64854#1588970>, @MaskRay wrote:
> Currently we align p_vaddr to the next multiple of max-page-size, instead of `ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1))` as ld.bfd does in its `-z noseparate-code` mode and some cases in its `-z separate-code` mode. See the comment below for a ld.lld -z max-page-size=0x200000 case:
>
> [11] .rodata PROGBITS 0000000000000558 000558 000004 04 AM 0 0 4
> [12] .eh_frame_hdr PROGBITS 000000000000055c 00055c 00002c 00 A 0 0 4
> [13] .eh_frame PROGBITS 0000000000000588 000588 0000cc 00 A 0 0 8
> ////// gap due to separated R-- and R-X
> ///// This gap can be saved in --no-rosegment mode.
> [14] .text PROGBITS 0000000000200000 200000 000161 00 AX 0 0 16
> [15] .init PROGBITS 0000000000200164 200164 000017 00 AX 0 0 4
> [16] .fini PROGBITS 000000000020017c 20017c 000009 00 AX 0 0 4
> [17] .plt PROGBITS 0000000000200190 200190 000020 00 AX 0 0 16
>
> [18] .fini_array FINI_ARRAY 0000000000400000 400000 000008 08 WA 0 0 8
> [19] .init_array INIT_ARRAY 0000000000400008 400008 000008 08 WA 0 0 8
> [20] .dynamic DYNAMIC 0000000000400010 400010 0001a0 10 WA 8 0 8
> [21] .got PROGBITS 00000000004001b0 4001b0 000028 00 WA 0 0 8
> [22] .bss.rel.ro NOBITS 00000000004001d8 4001d8 000000 00 WA 0 0 1
> /// Gap due to PT_GNU_RELRO. It wasts almost 0x200000 bytes.
> /// If we change p_vaddr of the RW PT_LOAD from 0x600000 to 0x6001d8, its p_offset doesn't need to be aligned, and we can save nearly 0x200000 bytes in the file.
> [23] .data PROGBITS 0000000000600000 600000 000010 00 WA 0 0 8
> [24] .tm_clone_table PROGBITS 0000000000600010 600010 000000 00 WA 0 0 8
> [25] .got.plt PROGBITS 0000000000600010 600010 000020 00 WA 0 0 8
> [26] .bss NOBITS 0000000000600030 600030 000001 00 WA 0 0 1
>
>
> We perform several max-page-size alignments for this file and each costs nearly 0x200000 bytes. If we do the optimization as described in the comment, we can save a lot of disk space. This is particularly relevant to targets with a large `defaultMaxPageSize` (AArch64, MIPS (@atanasyan), and PPC (@sfertile): 65536).
>
> What do you think of this trick?
I think BFD uses this at least once for all programs. As I understand it BFD with its builtin linkerscript uses something like:
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) }
/* These sections are generated by the Sun/Oracle C++ compiler. */
.exception_ranges : ONLY_IF_RO { *(.exception_ranges*) }
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
/* Exception handling */
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }
.gnu_extab : ONLY_IF_RW { *(.gnu_extab) }
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
.exception_ranges : ONLY_IF_RW { *(.exception_ranges*) }
/* Thread Local Storage sections */
.tdata :
{
PROVIDE_HIDDEN (__tdata_start = .);
*(.tdata .tdata.* .gnu.linkonce.td.*)
}
The DATA_SEGMENT_ALIGN function is defined in https://sourceware.org/binutils/docs/ld/Builtin-Functions.html#Builtin-Functions as doing either: (ALIGN(maxpagesize) + (. & (maxpagesize - 1))) or (ALIGN(maxpagesize)
+ ((. + commonpagesize - 1) & (maxpagesize - commonpagesize))) depending on whichever uses fewer commonpage sizes for the data segment.
Our implementation of DATA_SEGMENT_ALIGN is just
. = ALIGN(maxpagesize);
In the past the reason given for not using these tricks has been keeping it simple, which is understandable when getting linker scripts to work at all. Now that we have a more stable base and more tests I'm in favour of introducing more of the optimisations.
Repository:
rL LLVM
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D64854/new/
https://reviews.llvm.org/D64854
More information about the llvm-commits
mailing list