Revert "ld: Rewrite lang_size_relro_segment_1"
This reverts commit c804c6f98d
.
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.
This commit is contained in:
parent
2b1026f391
commit
5197c88e2a
4 changed files with 44 additions and 118 deletions
95
ld/ldlang.c
95
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 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;
|
||||
|
||||
/* 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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue