From 5197c88e2a8a17f7a67ce683df068b5bdf619427 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Sat, 5 Feb 2022 20:01:40 +1030 Subject: [PATCH] Revert "ld: Rewrite lang_size_relro_segment_1" This reverts commit c804c6f98d342c3d46f73d7a7ec6229d5ab1c9f3. PR ld/28743 PR ld/28819 * ldlang.c (lang_size_relro_segment_1): Revert 2022-01-14 change. * testsuite/ld-x86-64/pr28743-1.d: Likewise. * testsuite/ld-x86-64/pr28743-1.s: Likewise. * testsuite/ld-x86-64/x86-64.exp: Likewise. --- ld/ldlang.c | 95 ++++++++++++++---------------- ld/testsuite/ld-x86-64/pr28743-1.d | 50 ---------------- ld/testsuite/ld-x86-64/pr28743-1.s | 16 ----- ld/testsuite/ld-x86-64/x86-64.exp | 1 - 4 files changed, 44 insertions(+), 118 deletions(-) delete mode 100644 ld/testsuite/ld-x86-64/pr28743-1.d delete mode 100644 ld/testsuite/ld-x86-64/pr28743-1.s diff --git a/ld/ldlang.c b/ld/ldlang.c index 5dd3df12a0f..cf13932a9b1 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -6370,101 +6370,94 @@ lang_size_segment (seg_align_type *seg) static bfd_vma lang_size_relro_segment_1 (seg_align_type *seg) { - bfd_vma relro_end, desired_relro_base; - asection *sec, *relro_sec = NULL; + bfd_vma relro_end, desired_end; + asection *sec, *prev_sec = NULL; + bool remove_page_gap = false; unsigned int max_alignment_power = 0; - bool seen_reloc_section = false; - bool desired_relro_base_reduced = false; /* Compute the expected PT_GNU_RELRO/PT_LOAD segment end. */ relro_end = ((seg->relro_end + seg->pagesize - 1) & ~(seg->pagesize - 1)); /* Adjust by the offset arg of XXX_SEGMENT_RELRO_END. */ - desired_relro_base = relro_end - seg->relro_offset; + desired_end = relro_end - seg->relro_offset; - /* For sections in the relro segment. */ + /* For sections in the relro segment.. */ for (sec = link_info.output_bfd->section_last; sec; sec = sec->prev) if ((sec->flags & SEC_ALLOC) != 0) { - /* Record the maximum alignment for all sections starting from - the relro segment. */ if (sec->alignment_power > max_alignment_power) max_alignment_power = sec->alignment_power; if (sec->vma >= seg->base && sec->vma < seg->relro_end - seg->relro_offset) { - /* Where do we want to put the relro section so that the - relro segment ends on the page bounary? */ + /* Where do we want to put this section so that it ends as + desired? */ bfd_vma start, end, bump; end = start = sec->vma; if (!IS_TBSS (sec)) end += TO_ADDR (sec->size); - bump = desired_relro_base - end; + bump = desired_end - end; /* We'd like to increase START by BUMP, but we must heed alignment so the increase might be less than optimum. */ start += bump; start &= ~(((bfd_vma) 1 << sec->alignment_power) - 1); /* This is now the desired end for the previous section. */ - desired_relro_base = start; - relro_sec = sec; - seen_reloc_section = true; + desired_end = start; + prev_sec = sec->prev; } - else if (seen_reloc_section) + } + + seg->phase = exp_seg_relro_adjust; + ASSERT (desired_end >= seg->base); + + for (; prev_sec; prev_sec = prev_sec->prev) + if ((prev_sec->flags & SEC_ALLOC) != 0) + { + if (prev_sec->alignment_power > max_alignment_power) + max_alignment_power = prev_sec->alignment_power; + + if (prev_sec->size != 0) { - /* Stop searching if we see a non-relro section after seeing - relro sections. */ + /* The 1-page gap before the RELRO segment may be removed. */ + remove_page_gap = ((prev_sec->vma + prev_sec->size + + seg->maxpagesize) < desired_end); + break; } } - if (relro_sec != NULL - && seg->maxpagesize >= (1U << max_alignment_power)) + if (remove_page_gap) { - asection *prev_sec; - bfd_vma prev_sec_end_plus_1_page; - - /* Find the first preceding load section. */ - for (prev_sec = relro_sec->prev; - prev_sec != NULL; - prev_sec = prev_sec->prev) - if ((prev_sec->flags & SEC_ALLOC) != 0) - break; + /* Find the maximum section alignment. */ + for (sec = prev_sec; sec; sec = sec->prev) + if ((sec->flags & SEC_ALLOC) != 0 + && sec->alignment_power > max_alignment_power) + max_alignment_power = sec->alignment_power; - prev_sec_end_plus_1_page = (prev_sec->vma + prev_sec->size - + seg->maxpagesize); - if (prev_sec_end_plus_1_page < desired_relro_base) + /* Remove the 1-page gap before the RELRO segment only if the + maximum page size >= the maximum section alignment. */ + if (seg->maxpagesize >= (1U << max_alignment_power)) { - bfd_vma aligned_relro_base; - - desired_relro_base_reduced = true; - - /* Don't add the 1-page gap before the relro segment. Align - the relro segment first. */ - aligned_relro_base = (desired_relro_base - & ~(seg->maxpagesize - 1)); - if (prev_sec_end_plus_1_page < aligned_relro_base) + /* If the preceding section size is greater than the maximum + page size, subtract the maximum page size. Otherwise, + align the RELRO segment to the maximum page size. */ + if (prev_sec->size > seg->maxpagesize) { - /* Subtract the maximum page size if therer is still a - 1-page gap. */ - desired_relro_base -= seg->maxpagesize; + desired_end -= seg->maxpagesize; relro_end -= seg->maxpagesize; } else { - /* Align the relro segment. */ - desired_relro_base = aligned_relro_base; + desired_end &= ~(seg->maxpagesize - 1); relro_end &= ~(seg->maxpagesize - 1); } - } - } + } + } - seg->phase = exp_seg_relro_adjust; - ASSERT (desired_relro_base_reduced - || desired_relro_base >= seg->base); - seg->base = desired_relro_base; + seg->base = desired_end; return relro_end; } diff --git a/ld/testsuite/ld-x86-64/pr28743-1.d b/ld/testsuite/ld-x86-64/pr28743-1.d deleted file mode 100644 index 4a20f8e3900..00000000000 --- a/ld/testsuite/ld-x86-64/pr28743-1.d +++ /dev/null @@ -1,50 +0,0 @@ -#as: --64 -#ld: -melf_x86_64 -shared -z relro -z now --hash-style=sysv -z max-page-size=0x1000 -z noseparate-code $NO_DT_RELR_LDFLAGS -#readelf: -S -l --wide -#target: x86_64-*-linux* - -There are 17 section headers, starting at offset 0x101228: - -Section Headers: - \[Nr\] Name Type Address Off Size ES Flg Lk Inf Al - \[ 0\] NULL 0000000000000000 000000 000000 00 0 0 0 - \[ 1\] .hash HASH 0000000000000120 000120 000018 04 A 2 0 8 - \[ 2\] .dynsym DYNSYM 0000000000000138 000138 000048 18 A 3 1 8 - \[ 3\] .dynstr STRTAB 0000000000000180 000180 00000a 00 A 0 0 1 - \[ 4\] .rela.dyn RELA 0000000000000190 000190 000018 18 A 2 0 8 - \[ 5\] .plt PROGBITS 00000000000001b0 0001b0 000010 10 AX 0 0 16 - \[ 6\] .plt.got PROGBITS 00000000000001c0 0001c0 000008 08 AX 0 0 8 - \[ 7\] .text PROGBITS 00000000000001c8 0001c8 00000c 00 AX 0 0 1 - \[ 8\] .eh_frame PROGBITS 00000000000001d8 0001d8 00006c 00 A 0 0 8 - \[ 9\] .init_array INIT_ARRAY 00000000000ffff8 0ffff8 000004 08 WA 0 0 8 - \[10\] .fini_array FINI_ARRAY 0000000000100000 100000 000100 08 WA 0 0 1048576 - \[11\] .dynamic DYNAMIC 0000000000100100 100100 000150 10 WA 3 0 8 - \[12\] .got PROGBITS 0000000000100250 100250 000020 08 WA 0 0 8 - \[13\] .data PROGBITS 0000000000101000 101000 000100 00 WA 0 0 1 - \[14\] .symtab SYMTAB 0000000000000000 101100 000078 18 15 3 8 - \[15\] .strtab STRTAB 0000000000000000 101178 000029 00 0 0 1 - \[16\] .shstrtab STRTAB 0000000000000000 1011a1 000080 00 0 0 1 -Key to Flags: - W \(write\), A \(alloc\), X \(execute\), M \(merge\), S \(strings\), I \(info\), - L \(link order\), O \(extra OS processing required\), G \(group\), T \(TLS\), - C \(compressed\), x \(unknown\), o \(OS specific\), E \(exclude\), - D \(mbind\), l \(large\), p \(processor specific\) - -Elf file type is DYN \(Shared object file\) -Entry point 0x0 -There are 4 program headers, starting at offset 64 - -Program Headers: - Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align - LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x000244 0x000244 R E 0x1000 - LOAD 0x0ffff8 0x00000000000ffff8 0x00000000000ffff8 0x001108 0x001108 RW 0x100000 - DYNAMIC 0x100100 0x0000000000100100 0x0000000000100100 0x000150 0x000150 RW 0x8 - GNU_RELRO 0x0ffff8 0x00000000000ffff8 0x00000000000ffff8 0x001008 0x001008 R 0x1 - - Section to Segment mapping: - Segment Sections... - 00 .hash .dynsym .dynstr .rela.dyn .plt .plt.got .text .eh_frame - 01 .init_array .fini_array .dynamic .got .data - 02 .dynamic - 03 .init_array .fini_array .dynamic .got -#pass diff --git a/ld/testsuite/ld-x86-64/pr28743-1.s b/ld/testsuite/ld-x86-64/pr28743-1.s deleted file mode 100644 index 2e9a1503741..00000000000 --- a/ld/testsuite/ld-x86-64/pr28743-1.s +++ /dev/null @@ -1,16 +0,0 @@ - .text - .globl foo - .type foo, @function -foo: - .cfi_startproc - call func@plt - movq func@GOTPCREL(%rip), %rax - .cfi_endproc - .section .init_array,"aw",@init_array - .p2align 3 - .zero 0x4 - .section .fini_array,"aw",@fini_array - .p2align 20 - .zero 0x100 - .data - .zero 0x100 diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp index 5ef66a237ef..3bfc5e6e467 100644 --- a/ld/testsuite/ld-x86-64/x86-64.exp +++ b/ld/testsuite/ld-x86-64/x86-64.exp @@ -511,7 +511,6 @@ run_dump_test "dt-relr-1a" run_dump_test "dt-relr-1a-x32" run_dump_test "dt-relr-1b" run_dump_test "dt-relr-1b-x32" -run_dump_test "pr28743-1" if ![istarget "x86_64-*-linux*"] { return -- 2.30.2