While installing it fails with a QA notice referencing textrels. Reproducible: Always Steps to Reproduce: 1. Compile sys-devel/gdb-9.1 Actual Results: Install fails. Expected Results: Installs correctly.
Created attachment 621090 [details] emerge info emerge --info
Created attachment 621146 [details] emerge -pqv
Created attachment 621148 [details] build.log
>>> Completed installing sys-devel/gdb-9.1 into /var/tmp/portage/sys-devel/gdb-9.1/image * Final size of build directory: 297548 KiB (290.5 MiB) * Final size of installed tree: 11992 KiB ( 11.7 MiB) * QA Notice: The following files contain runtime text relocations * Text relocations force the dynamic linker to perform extra * work at startup, waste system resources, and may pose a security * risk. On some architectures, the code may not even function * properly, if at all. * For more information, see: * * https://wiki.gentoo.org/wiki/Hardened/HOWTO_locate_and_fix_textrels * * Please include the following list of files in your report: * TEXTREL usr/bin/gdb * ERROR: sys-devel/gdb-9.1::gentoo failed: * Aborting due to QA concerns: textrels, * * Call stack: * misc-functions.sh, line 586: Called install_qa_check * misc-functions.sh, line 132: Called source 'install_symlink_html_docs' * 10executable-issues, line 145: Called elf_check * 10executable-issues, line 141: Called die * The specific snippet of code: * die "Aborting due to QA concerns: ${die_msg}"
Created attachment 621160 [details] scanelf
(In reply to Skylar from comment #5) > Created attachment 621160 [details] > scanelf Your output looks bad: ``` scanelf -qT /usr/bin/gdb gdb: (memory/data?) [0x0] in (optimized out) [0x0] gdb: (memory/data?) [0x0] in (optimized out) [0x0] gdb: (memory/data?) [0x0] in (optimized out) [0x0] gdb: (memory/data?) [0x0] in (optimized out) [0x0] gdb: (memory/data?) [0x0] in (optimized out) [0x0] gdb: (memory/data?) [0x0] in (optimized out) [0x0] /usr/bin/gdb ``` Can you attach gdb binary itself? Maybe we can fix scanelf to report better information.
gdb https://filetransfer.io/data-package/eLMgIIvj
(In reply to Skylar from comment #7) > gdb > > https://filetransfer.io/data-package/eLMgIIvj Uploaded as https://dev.gentoo.org/~slyfox/bugs/713082-gdb-TEXTREL/gdb I'm not sure which relocations binutils is concerned about. scanelf is also clearly unhappy about some of them. Of then read-only sections are only: $ readelf gdb (exclude 'W' sections). Section Headers: [ 1] .interp PROGBITS 0000000000000270 00000270 [ 2] .note.ABI-tag NOTE 0000000000000294 00000294 [ 3] .gnu.hash GNU_HASH 00000000000002b8 000002b8 [ 4] .dynsym DYNSYM 0000000000001cd8 00001cd8 [ 5] .dynstr STRTAB 0000000000009868 00009868 [ 6] .gnu.version VERSYM 00000000000104aa 000104aa [ 7] .gnu.version_r VERNEED 0000000000010ef8 00010ef8 [ 8] .rela.dyn RELA 0000000000011138 00011138 [ 9] .rela.plt RELA 00000000000837f8 000837f8 [10] .plt PROGBITS 00000000000871d0 000871d0 [11] .text PROGBITS 0000000000089880 00089880 [12] .rodata PROGBITS 000000000037d3e0 0037d3e0 [13] .eh_frame_hdr PROGBITS 0000000000482c00 00482c00 [14] .eh_frame PROGBITS 00000000004993c0 004993c0 [15] .gcc_except_table PROGBITS 000000000051934c 0051934c $ LANG=C objdump -D -R gdb | egrep 'R_RISC|section ' | egrep -A2 'section ' # removed sections without dynamic relocations manually Disassembly of section .tbss: 543308: R_RISCV_RELATIVE *ABS*+0x92be6 Disassembly of section .preinit_array: 543308: R_RISCV_RELATIVE *ABS*+0x92be6 Disassembly of section .init_array: 543310: R_RISCV_RELATIVE *ABS*+0x92c80 Disassembly of section .fini_array: 543608: R_RISCV_RELATIVE *ABS*+0x92c46 Disassembly of section .data.rel.ro: 543610: R_RISCV_RELATIVE *ABS*+0x37dc30 Disassembly of section .data: 56c010: R_RISCV_RELATIVE *ABS*+0x93234 Disassembly of section .got: 57b128: R_RISCV_JUMP_SLOT PyMemoryView_FromObject These all are writable sections. I think 'scanelf' is confused, it should see no bad relocs. Worth fixing it. It's probably a binutils' bug in 'ld'. It should not have flagged this binary as having TEXTRELs.
Slightly patched binutils to provide exact relocation types and places: --- a/bfd/elfnn-riscv.c +++ b/bfd/elfnn-riscv.c @@ -736,6 +736,10 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, p->pc_count = 0; } + if (strcmp(p->sec->name, ".text") == 0) { + fprintf(stderr, "riscv_elf_check_relocs(): ++ suspicious reloc in '%s'/'%s'\n", p->sec->name, p->sec->owner->filename); + fprintf(stderr, "riscv_elf_check_relocs(): r_type=%u\n", r_type); + } p->count += 1; p->pc_count += r == NULL ? 0 : r->pc_relative; } @@ -1151,6 +1155,7 @@ maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p) struct bfd_link_info *info = (struct bfd_link_info *) info_p; info->flags |= DF_TEXTREL; + fprintf(stderr, "maybe_set_textrel(): TEEEEEEEEXTEEEEEEEEEL\n"); info->callbacks->minfo (_("%pB: dynamic relocation against `%pT' in read-only section `%pA'\n"), sec->owner, h->root.root.string, sec); @@ -1219,7 +1224,11 @@ riscv_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) srel = elf_section_data (p->sec)->sreloc; srel->size += p->count * sizeof (ElfNN_External_Rela); if ((p->sec->output_section->flags & SEC_READONLY) != 0) + { + fprintf(stderr, "riscv_elf_size_dynamic_sections(): TEEEEEEEEXTEEEEEEEEEL:" + " '%s'/'%s'/count=%lu\n", p->sec->owner->filename, p->sec->name, p->count); info->flags |= DF_TEXTREL; + } } } } @@ -1371,6 +1380,7 @@ riscv_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info) if (info->flags & DF_TEXTREL) { + fprintf(stderr, "riscv_elf_size_dynamic_sections(): TTTEEEEXT / 2\n"); if (!add_dynamic_entry (DT_TEXTREL, 0)) return FALSE; } The output is the following: $ gcc++ ... -B/home/slyfox/dev/git/binutils-gdb-riscv64/ld -Wl,-z,text riscv_elf_check_relocs(): ++ suspicious reloc in '.text'/'cp-support.o' riscv_elf_check_relocs(): r_type=29 riscv_elf_check_relocs(): ++ suspicious reloc in '.text'/'cp-support.o' riscv_elf_check_relocs(): r_type=29 riscv_elf_check_relocs(): ++ suspicious reloc in '.text'/'cp-support.o' riscv_elf_check_relocs(): r_type=29 riscv_elf_check_relocs(): ++ suspicious reloc in '.text'/'cp-support.o' riscv_elf_check_relocs(): r_type=29 riscv_elf_check_relocs(): ++ suspicious reloc in '.text'/'event-top.o' riscv_elf_check_relocs(): r_type=29 riscv_elf_check_relocs(): ++ suspicious reloc in '.text'/'gdbsupport/safe-strerror.o' riscv_elf_check_relocs(): r_type=29 riscv_elf_size_dynamic_sections(): TEEEEEEEEXTEEEEEEEEEL: 'cp-support.o'/'.text'/count=4 riscv_elf_size_dynamic_sections(): TEEEEEEEEXTEEEEEEEEEL: 'event-top.o'/'.text'/count=1 riscv_elf_size_dynamic_sections(): TEEEEEEEEXTEEEEEEEEEL: 'gdbsupport/safe-strerror.o'/'.text'/count=1 riscv_elf_size_dynamic_sections(): TTTEEEEXT / 2 /home/slyfox/dev/git/binutils-gdb-riscv64/ld/ld: read-only segment has dynamic relocations collect2: error: ld returned 1 exit status r_type=29 is a 'R_RISCV_TPREL_HI20' relocation: $ egrep R_RISCV.*29 /usr/include/elf.h #define R_RISCV_TPREL_HI20 29 Example source of the relocation is event-top.o where it is encountered once: $ objdump -d -S -r event-top.o 00000000000003ea <handle_sigsegv(int)>: 3ea: 1141 addi sp,sp,-16 3ec: e022 sd s0,0(sp) 3ee: e406 sd ra,8(sp) 3f0: 842a mv s0,a0 3f2: 00000097 auipc ra,0x0 3f2: R_RISCV_CALL install_handle_sigsegv() 3f2: R_RISCV_RELAX *ABS* 3f6: 000080e7 jalr ra # 3f2 <handle_sigsegv(int)+0x8> 3fa: 000007b7 lui a5,0x0 3fa: R_RISCV_TPREL_HI20 .LANCHOR1 3fa: R_RISCV_RELAX *ABS* 3fe: 004787b3 add a5,a5,tp 3fe: R_RISCV_TPREL_ADD .LANCHOR1 3fe: R_RISCV_RELAX *ABS* 402: 00078793 mv a5,a5 402: R_RISCV_TPREL_LO12_I .LANCHOR1 402: R_RISCV_RELAX *ABS* 406: 0007b303 ld t1,0(a5) # 0 <async_do_nothing(void*)> 40a: 00030763 beqz t1,418 <.L89> 40a: R_RISCV_BRANCH .L89 40e: 8522 mv a0,s0 410: 6402 ld s0,0(sp) 412: 60a2 ld ra,8(sp) 414: 0141 addi sp,sp,16 416: 8302 jr t1 That is reference to thread_local variable: https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=gdb/event-top.c;h=1bfc28ea09965872f438a2e18951f6ba836d62c7;hb=HEAD#l853 Let's see if I can craft minimal example.
This seems to be enough: $ cat a.cc static int a () { return 1; } static thread_local int (*tlf) () = &a; int main(void) { return tlf(); } $ x86_64-pc-linux-gnu-g++ a.cc -o a -Wl,-z,text; riscv64-unknown-linux-gnu-g++ a.cc -o b -Wl,-z,text /usr/libexec/gcc/riscv64-unknown-linux-gnu/ld: read-only segment has dynamic relocations collect2: error: ld returned 1 exit status
Filed upstream bug as https://sourceware.org/PR25694. Meanwhile the workaround for you to get gdb is to temporarily drop one of FEATURES='strict stricter'. I don't remember which one.
The bug has been referenced in the following commit(s): https://gitweb.gentoo.org/proj/pax-utils.git/commit/?id=33f047637d8bc3c5d3d3faa37a8ad5b3f8825213 commit 33f047637d8bc3c5d3d3faa37a8ad5b3f8825213 Author: Sergei Trofimovich <slyfox@gentoo.org> AuthorDate: 2020-03-18 23:37:19 +0000 Commit: Sergei Trofimovich <slyfox@gentoo.org> CommitDate: 2020-03-18 23:37:19 +0000 scanelf.c: don't srash in -v mode on non-functions Fix crash when running in verbose mode on bad files: $ ./scanelf -T -v gdb The file is taken from bug #713082. Bug: https://bugs.gentoo.org/713082 Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org> scanelf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
The bug has been referenced in the following commit(s): https://gitweb.gentoo.org/proj/pax-utils.git/commit/?id=79489b3450faac9ffcc0ffc55d57dacdfed897be commit 79489b3450faac9ffcc0ffc55d57dacdfed897be Author: Sergei Trofimovich <slyfox@gentoo.org> AuthorDate: 2020-03-18 23:57:30 +0000 Commit: Sergei Trofimovich <slyfox@gentoo.org> CommitDate: 2020-03-18 23:57:30 +0000 scanelf.c: be more verbose at saying what all the addresses mean Print out relocation type and explain addresses: ``` $ ./scanelf -T -v gdb TYPE TEXTRELS FILE gdb: (memory/data?) [r_offset=0x0] r_type=0 in (optimized out?) [closest_prev_sym=0x0] gdb: (memory/data?) [r_offset=0x0] r_type=0 in (optimized out?) [closest_prev_sym=0x0] gdb: (memory/data?) [r_offset=0x0] r_type=0 in (optimized out?) [closest_prev_sym=0x0] gdb: (memory/data?) [r_offset=0x0] r_type=0 in (optimized out?) [closest_prev_sym=0x0] gdb: (memory/data?) [r_offset=0x0] r_type=0 in (optimized out?) [closest_prev_sym=0x0] gdb: (memory/data?) [r_offset=0x0] r_type=0 in (optimized out?) [closest_prev_sym=0x0] ``` Note: it's now more obvious that suspicious relocations are not real and just zero-initialized leftovers of R_*_NONE type. Bug: https://bugs.gentoo.org/713082 Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org> scanelf.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
(In reply to Sergei Trofimovich from comment #6) > (In reply to Skylar from comment #5) > > Created attachment 621160 [details] > > scanelf > > Your output looks bad: > > ``` > scanelf -qT /usr/bin/gdb > gdb: (memory/data?) [0x0] in (optimized out) [0x0] > gdb: (memory/data?) [0x0] in (optimized out) [0x0] > gdb: (memory/data?) [0x0] in (optimized out) [0x0] > gdb: (memory/data?) [0x0] in (optimized out) [0x0] > gdb: (memory/data?) [0x0] in (optimized out) [0x0] > gdb: (memory/data?) [0x0] in (optimized out) [0x0] > /usr/bin/gdb > ``` These ended up being R_RISCV_NONE relocs. They are no-op relocs that should never appear in final bianries. They are not affecting TEXTRELs directy but likely a sign of mis-accounting for R_RISCV_TPREL_HI20 that was statically relocated by ld.
AFAIK this is fixed in Binutils 2.41.