https://bugs.kde.org/show_bug.cgi?id=473944
Bug ID: 473944
Summary: Handle mold linker split RW PT_LOAD segments correctly
Classification: Developer tools
Product: valgrind
Version: 3.21.0
Platform: Other
OS: Linux
Status: REPORTED
Severity: normal
Priority: NOR
Component: general
Assignee: [email protected]
Reporter: [email protected]
Target Milestone: ---
Created attachment 161282
--> https://bugs.kde.org/attachment.cgi?id=161282&action=edit
change the condition to detect 2 PT_LOADs will be merged
This is a follow-up/similar problem as reported and fixed in bug 452802.
valgrind could not load the debug info of the main executable.
The problem is the same as 452802. The fix of 452802 does not work as the logic
to detect that
the 2 PT_LOAD segments are different currently wrongly concludes that the 2
segments can be combined.
Here are the details (with some remarks/comments prefixed with #).
The attached patch solves the problem on my setup (RHEL 8.6, ld-2.28, mold
1.5.1), but as this completely changes
the condition to consider the segments to be mergeable, would be nice to
(re-)validate this e.g. with lld
or other setups where split PT_LOAD are produced.
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: Advanced Micro Devices X86-64
Version: 0x1
Entry point address: 0x25e000
Start of program headers: 64 (bytes into file)
Start of section headers: 214499808 (bytes into file)
Flags: 0x0
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 13
Size of section headers: 64 (bytes)
Number of section headers: 64
Section header string table index: 49
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
[ 0] NULL 0000000000000000 00000000
0000000000000000 0000000000000000 0 0 0
[ 1] .interp PROGBITS 0000000000200318 00000318
000000000000001c 0000000000000000 A 0 0 1
[ 2] .note.gnu.build-i NOTE 0000000000200334 00000334
0000000000000024 0000000000000000 A 0 0 4
[ 3] .note.ABI-tag NOTE 0000000000200358 00000358
0000000000000020 0000000000000000 A 0 0 4
[ 4] .hash HASH 0000000000200378 00000378
0000000000007f60 0000000000000004 A 6 0 4
[ 5] .gnu.hash GNU_HASH 00000000002082d8 000082d8
00000000000002b8 0000000000000000 A 6 0 8
[ 6] .dynsym DYNSYM 0000000000208590 00008590
0000000000017e08 0000000000000018 A 7 1 8
[ 7] .dynstr STRTAB 0000000000220398 00020398
000000000001999a 0000000000000000 A 0 0 1
[ 8] .gnu.version VERSYM 0000000000239d32 00039d32
0000000000001fd6 0000000000000002 A 6 0 2
[ 9] .gnu.version_r VERNEED 000000000023bd08 0003bd08
00000000000002c0 0000000000000000 A 7 9 8
[10] .rela.dyn RELA 000000000023bfc8 0003bfc8
0000000000001188 0000000000000018 A 6 0 8
[11] .rela.plt RELA 000000000023d150 0003d150
0000000000013110 0000000000000018 A 6 35 8
[12] .plt PROGBITS 0000000000251000 00051000
000000000000cb80 0000000000000000 AX 0 0 16
[13] .plt.got PROGBITS 000000000025db80 0005db80
0000000000000230 0000000000000000 AX 0 0 16
[14] .fini PROGBITS 000000000025ddb0 0005ddb0
000000000000000d 0000000000000000 AX 0 0 4
[15] .init PROGBITS 000000000025ddc0 0005ddc0
0000000000000020 0000000000000000 AX 0 0 4
[16] .text PROGBITS 000000000025e000 0005e000
0000000007bce0d4 0000000000000000 AX 0 0 4096
[17] google_malloc PROGBITS 0000000007e2c100 07c2c100
0000000000001f1a 0000000000000000 AX 0 0 64
[18] malloc_hook PROGBITS 0000000007e2e020 07c2e020
0000000000000685 0000000000000000 AX 0 0 16
[19] text.hot PROGBITS 0000000007e2e6b0 07c2e6b0
00000000001b9370 0000000000000000 AX 0 0 16
[20] text.unlikely PROGBITS 0000000007fe7a20 07de7a20
0000000001f7f600 0000000000000000 AX 0 0 16
[21] .eh_frame PROGBITS 0000000009f68000 09d68000
00000000011bdc98 0000000000000000 A 0 0 8
[22] .eh_frame_hdr PROGBITS 000000000b125c98 0af25c98
000000000028a734 0000000000000000 A 0 0 4
[23] .gcc_except_table PROGBITS 000000000b3b03cc 0b1b03cc
0000000000a73118 0000000000000000 A 0 0 4
[24] .rodata PROGBITS 000000000be23500 0bc23500
000000000045590f 0000000000000000 A 0 0 64
[25] .rodata.cst PROGBITS 000000000c278e10 0c078e10
0000000000070f50 0000000000000000 A 0 0 16
[26] .rodata.str PROGBITS 000000000c2e9d60 0c0e9d60
00000000005a4940 0000000000000000 A 0 0 32
[27] .tdata PROGBITS 000000000c88f000 0c68f000
0000000000000028 0000000000000000 WAT 0 0 8
[28] .tbss NOBITS 000000000c88f040 00000000
000000000000b2f8 0000000000000000 WAT 0 0 64
[29] .dynamic DYNAMIC 000000000c88f028 0c68f028
0000000000000430 0000000000000010 WA 7 0 8
[30] .data.rel.ro PROGBITS 000000000c88f460 0c68f460
000000000051e4a8 0000000000000000 WA 0 0 32
[31] .fini_array FINI_ARRAY 000000000cdad908 0cbad908
0000000000000010 0000000000000000 WA 0 0 8
[32] .init_array INIT_ARRAY 000000000cdad918 0cbad918
0000000000000088 0000000000000000 WA 0 0 8
[33] .got PROGBITS 000000000cdad9a0 0cbad9a0
0000000000005360 0000000000000000 WA 0 0 8
[34] .copyrel.rel.ro NOBITS 000000000cdb2d00 00000000
0000000000005dc9 0000000000000000 WA 0 0 64
[35] .got.plt PROGBITS 000000000cdb9000 0cbb3000
00000000000065c8 0000000000000000 WA 0 0 8
[36] .ctors PROGBITS 000000000cdbf5c8 0cbb95c8
0000000000000008 0000000000000000 WA 0 0 8
[37] .data PROGBITS 000000000cdbf600 0cbb9600
00000000000d1d60 0000000000000000 WA 0 0 64
[38] .data1 PROGBITS 000000000ce91360 0cc8b360
00000000000001e0 0000000000000000 WA 0 0 32
[39] .tm_clone_table PROGBITS 000000000ce91540 0cc8b540
0000000000000000 0000000000000000 WA 0 0 8
[40] .copyrel NOBITS 000000000ce91540 00000000
00000000000008a8 0000000000000000 WA 0 0 64
[41] .bss NOBITS 000000000ce91e00 00000000
0000000000828f40 0000000000000000 WA 0 0 32
[42] .common NOBITS 000000000d6bad40 00000000
0000000000005f28 0000000000000000 WA 0 0 32
[43] .gnu.build.attrib NOTE 0000000000000000 0cc8b540
00000000000012a0 0000000000000000 0 0 4
[44] .gnu.build.attrib NOTE 0000000000000000 0cc8c7e0
0000000000000e80 0000000000000000 0 0 4
[45] .gnu.build.attrib NOTE 0000000000000000 0cc8d660
0000000000000e80 0000000000000000 0 0 4
[46] .gnu.build.attrib NOTE 0000000000000000 0cc8e4e0
0000000000000e80 0000000000000000 0 0 4
[47] .gnu.build.attrib NOTE 0000000000000000 0cc8f360
0000000000000e80 0000000000000000 0 0 4
[48] .strtab STRTAB 0000000000000000 0cc911e0
0000000001c76dc1 0000000000000000 0 0 1
[49] .shstrtab STRTAB 0000000000000000 0e907fa1
00000000000002e9 0000000000000000 0 0 1
[50] .symtab SYMTAB 0000000000000000 0e908290
000000000119c220 0000000000000018 48 765314 8
[51] .comment PROGBITS 0000000000000000 0faa44b0
00000000000000b8 0000000000000000 0 0 1
[52] .comment PROGBITS 0000000000000000 0faa4568
0000000000de43d0 0000000000000000 0 0 1
[53] .debug_abbrev PROGBITS 0000000000000000 10888938
0000000000731fdd 0000000000000000 0 0 1
[54] .debug_aranges PROGBITS 0000000000000000 10fba920
0000000000469c50 0000000000000000 0 0 16
[55] .debug_info PROGBITS 0000000000000000 11424570
000000000ea9d323 0000000000000000 0 0 1
[56] .debug_line PROGBITS 0000000000000000 1fec1893
00000000039f9b30 0000000000000000 0 0 1
[57] .debug_line_str PROGBITS 0000000000000000 238bb3c3
00000000000a91b0 0000000000000000 0 0 1
[58] .debug_loc PROGBITS 0000000000000000 23964573
00000000000c3a71 0000000000000000 0 0 1
[59] .debug_loclists PROGBITS 0000000000000000 23a27fe4
000000000660eb51 0000000000000000 0 0 1
[60] .debug_macro PROGBITS 0000000000000000 2a036b35
00000000004720ac 0000000000000000 0 0 1
[61] .debug_ranges PROGBITS 0000000000000000 2a4a8be1
0000000000031750 0000000000000000 0 0 1
[62] .debug_rnglists PROGBITS 0000000000000000 2a4da331
00000000015d85c5 0000000000000000 0 0 1
[63] .debug_str PROGBITS 0000000000000000 2bab28f6
0000000002c270cd 0000000000000000 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),
l (large), p (processor specific)
Program Headers:
Type Offset VirtAddr PhysAddr
FileSiz MemSiz Flags Align
PHDR 0x0000000000000040 0x0000000000200040 0x0000000000200040
0x00000000000002d8 0x00000000000002d8 R 0x8
INTERP 0x0000000000000318 0x0000000000200318 0x0000000000200318
0x000000000000001c 0x000000000000001c R 0x1
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
NOTE 0x0000000000000334 0x0000000000200334 0x0000000000200334
0x0000000000000044 0x0000000000000044 R 0x4
LOAD 0x0000000000000000 0x0000000000200000 0x0000000000200000
0x0000000000050260 0x0000000000050260 R 0x1000
LOAD 0x0000000000051000 0x0000000000251000 0x0000000000251000
0x0000000009d16020 0x0000000009d16020 R E 0x1000
LOAD 0x0000000009d68000 0x0000000009f68000 0x0000000009f68000
0x00000000029266a0 0x00000000029266a0 R 0x1000
LOAD 0x000000000c68f000 0x000000000c88f000 0x000000000c88f000
0x0000000000523d00 0x0000000000529ac9 RW 0x1000
# => 0x000000000cdb8ac9 = 0x000000000c88f000 +
0x0000000000529ac9
# + 0x537 = 0x000000000cdb9000
# ??? the MemSiz is bigger than the FileSiz
# ??? this seems to result in a 'hole' after the mapping of
the file content.
LOAD 0x000000000cbb3000 0x000000000cdb9000 0x000000000cdb9000
0x00000000000d8540 0x0000000000907c68 RW 0x1000
# => 0x000000000d6c0c68 = 0x000000000cdb9000 +
0x0000000000907c68
TLS 0x000000000c68f000 0x000000000c88f000 0x000000000c88f000
0x0000000000000028 0x000000000000b338 R 0x40
DYNAMIC 0x000000000c68f028 0x000000000c88f028 0x000000000c88f028
0x0000000000000430 0x0000000000000430 RW 0x8
GNU_EH_FRAME 0x000000000af25c98 0x000000000b125c98 0x000000000b125c98
0x000000000028a734 0x000000000028a734 R 0x4
GNU_STACK 0x0000000000000000 0x0000000000000000 0x0000000000000000
0x0000000000000000 0x0000000000000000 RWE 0x0
GNU_RELRO 0x000000000c68f000 0x000000000c88f000 0x000000000c88f000
0x0000000000523d00 0x000000000052a000 R 0x40
The above shows that the resulting load in memory can/could give in the virtual
addresses
a contiguous segment if pages are rounded to 0x1000.
Valgrind trace of the succesful (with hack) load:
------ name =
/cm/build13/cm/ot/TACT/UIF!28.0.0.62/build_G!30.OP.L8/ada/exe/tact_uif_shared_exe
Un-de-overlapped _DebugInfoMappings:
[0] avma 0x200000 size 331776 foff 0 -- --
ro
[1] avma 0x251000 size 164720640 foff 331776 rx --
--
[2] avma 0x9f68000 size 43151360 foff 165052416 -- --
ro
[3] avma 0xc88f000 size 5390336 foff 208203776 -- rw
--
# 5390336 = 0x524000 = FileSiz 0x0000000000523d00
rounded up 0x1000.
[4] avma 0xcdb9000 size 888832 foff 213594112 -- rw
--
# 888832 = 0xd9000 = FileSiz 0x00000000000d8540
rounded up 0x1000.
De-overlapped DebugInfoMappings:
[0] avma 0x200000 size 331776 foff 0 -- --
ro
[1] avma 0x251000 size 164720640 foff 331776 rx --
--
[2] avma 0x9f68000 size 43151360 foff 165052416 -- --
ro
[3] avma 0xc88f000 size 5390336 foff 208203776 -- rw
--
[4] avma 0xcdb9000 size 888832 foff 213594112 -- rw
--
When the notify accept is done for the executable, the linux mappings are:
(gdb) info proc mappings 46044
process 46044
Mapped address spaces:
Start Addr End Addr Size Offset Perms objfile
0x200000 0x251000 0x51000 0x0 r--p
/cm/build13/cm/ot/TACT/UIF!28.0.0.62/build_G!30.OP.L8/ada/exe/tact_uif_shared_exe
0x251000 0x9f68000 0x9d17000 0x51000 r-xp
/cm/build13/cm/ot/TACT/UIF!28.0.0.62/build_G!30.OP.L8/ada/exe/tact_uif_shared_exe
0x9f68000 0xc88f000 0x2927000 0x9d68000 r--p
/cm/build13/cm/ot/TACT/UIF!28.0.0.62/build_G!30.OP.L8/ada/exe/tact_uif_shared_exe
0xc88f000 0xcdb3000 0x524000 0xc68f000 rw-p
/cm/build13/cm/ot/TACT/UIF!28.0.0.62/build_G!30.OP.L8/ada/exe/tact_uif_shared_exe
0xcdb3000 0xcdb9000 0x6000 0x0 rw-p
0xcdb9000 0xce92000 0xd9000 0xcbb3000 rw-p
/cm/build13/cm/ot/TACT/UIF!28.0.0.62/build_G!30.OP.L8/ada/exe/tact_uif_shared_exe
0xce92000 0xd6c1000 0x82f000 0x0 rw-p
0xd6c1000 0xd6ee000 0x2d000 0x0 r-xp
/usr/lib64/ld-2.28.so
0xd8ee000 0xd8f1000 0x3000 0x2d000 rw-p
/usr/lib64/ld-2.28.so
0xd8f1000 0xd8f2000 0x1000 0x0 rwxp
0x58000000 0x58001000 0x1000 0x0 r--p
/cm/build12/cm/ot/TOOL/GNU!28.0.0.15/build_G!30.OP.L8/generated/libexec/valgrind/memcheck-amd64-linux
0x58001000 0x58202000 0x201000 0x1000 r-xp
/cm/build12/cm/ot/TOOL/GNU!28.0.0.15/build_G!30.OP.L8/generated/libexec/valgrind/memcheck-amd64-linux
0x58202000 0x582a0000 0x9e000 0x202000 r--p
/cm/build12/cm/ot/TOOL/GNU!28.0.0.15/build_G!30.OP.L8/generated/libexec/valgrind/memcheck-amd64-linux
0x582a0000 0x582a5000 0x5000 0x2a0000 rw-p
/cm/build12/cm/ot/TOOL/GNU!28.0.0.15/build_G!30.OP.L8/generated/libexec/valgrind/memcheck-amd64-linux
0x582a5000 0x59cb1000 0x1a0c000 0x0 rw-p [heap]
0x1002001000 0x100297c000 0x97b000 0x0 rwxp
0x1ffefe9000 0x1fff001000 0x18000 0x0 rwxp
0x7ffff7ff9000 0x7ffff7ffd000 0x4000 0x0 r--p [vvar]
0x7ffffffc9000 0x7ffffffff000 0x36000 0x0 rw-p [stack]
0xffffffffff600000 0xffffffffff601000 0x1000 0x0 r-xp
[vsyscall]
(gdb)
So, clearly we have 2 different segments.
The condition
'a_phdr.p_offset == VG_PGROUNDDN(a_phdr.p_offset)'
in readelf.c to consider that the 2nd segment is glued with the first one is
very bizarre.
The above condition only ensures that p_offset (offset in the file) is on a
0x1000 page boundary ????
The condition to determine that the first rw segment will be merged by
aspacemgr with the second
should be something like:
virtaddr seg1 + (some size) == virtaddr seg2
????
The '(some size)' to use is not very clear to me.
In the readelf output, we have the FileSiz and the MemSiz
It looks like the mapping is done with FileSiz rounded up to the page size.
--
You are receiving this mail because:
You are watching all bug changes.