bug-binutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug ld/27566] [RISC-V] relocation truncated to fit: R_RISCV_GPREL_I aga


From: nelsonc1225 at sourceware dot org
Subject: [Bug ld/27566] [RISC-V] relocation truncated to fit: R_RISCV_GPREL_I against aymbol
Date: Fri, 26 Mar 2021 09:53:44 +0000

https://sourceware.org/bugzilla/show_bug.cgi?id=27566

--- Comment #6 from Nelson Chu <nelsonc1225 at sourceware dot org> ---
Jim's assumption is right, the gp won't overlap the rodata.  But it could
overlap the symbol defined in the rodata, and it's value plus a constant.

    .align  3
    .globl hello_rodata
    .set hello_rodata, . + 0x1800
.Lpadding:
    .zero   128

Lifang's assumption is also correct.  I had traced the source code and did some
experiments, we should get the symbol values that have considered the
DATA_SEGMENT_ALIGN when relaxing.  But sometimes, they don't consider the
DATA_SEGMENT_RELRO_END.  It causes that we may get the unexpected symbol values
when relaxing.  After the following change, Lifang's example is fixed,


 ld/ldlang.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/ld/ldlang.c b/ld/ldlang.c
index 629be32..53513de 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -6378,7 +6378,8 @@ lang_size_relro_segment_1 (seg_align_type *seg)
 }

 static bfd_boolean
-lang_size_relro_segment (bfd_boolean *relax, bfd_boolean check_regions)
+lang_size_relro_segment (bfd_boolean *relax ATTRIBUTE_UNUSED,
+                        bfd_boolean check_regions)
 {
   bfd_boolean do_reset = FALSE;
   bfd_boolean do_data_relro;
@@ -6399,7 +6400,7 @@ lang_size_relro_segment (bfd_boolean *relax, bfd_boolean
check_regions)
   if (do_data_relro)
     {
       lang_reset_memory_regions ();
-      one_lang_size_sections_pass (relax, check_regions);
+      one_lang_size_sections_pass (FALSE, check_regions);

       /* Assignments to dot, or to output section address in a user
         script have increased padding over the original.  Revert.  */
       if (do_data_relro && expld.dataseg.relro_end > data_relro_end)
        {
          expld.dataseg.base = data_initial_base;;
          do_reset = TRUE;
        }
    }

  if (!do_data_relro && lang_size_segment (&expld.dataseg))
    do_reset = TRUE;


An interesting thing is that - although we have update the expld.dataseg in the
lang_size_relro_segment_1, but the symbol values are updated until the
lang_size_segment, and we will do the relaxations again in the
one_lang_size_sections_pass before that point.  But is looks strange to me, why
we will do the same relax pass again by the while loop in the
lang_relax_sections, but we still do it again here, with the symbols that don't
consider the relro_end?

However, I think we still need to consider the maxpagesize+commonpagesize when
the gp (or pc of c.lui) and target symbols cross the DATA_SEGMENT_ALIGN.  Since
relaxation might cause the data segment gap larger, but we should create
another new testcase to describe the problem.  Not sure how to check if the
symbols cross the DATA_SEGMENT_ALIGN, we probably need to get the value of
expdl.dataseg.base, and store it to the link_info.

-- 
You are receiving this mail because:
You are on the CC list for the bug.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]