diff --git a/bfd/elfnn-riscv.c b/bfd/elfnn-riscv.c
index a23b91ac15c..26f965945d3 100644
--- a/bfd/elfnn-riscv.c
+++ b/bfd/elfnn-riscv.c
@@ -4512,6 +4512,9 @@ _bfd_riscv_relax_lui (bfd *abfd,
   bfd_vma gp = htab->params->relax_gp
 	       ? riscv_global_pointer_value (link_info)
 	       : 0;
+  bfd_vma data_segment_alignment = link_info->relro
+				   ? ELF_MAXPAGESIZE + ELF_COMMONPAGESIZE
+				   : ELF_MAXPAGESIZE;
   int use_rvc = elf_elfheader (abfd)->e_flags & EF_RISCV_RVC;
 
   BFD_ASSERT (rel->r_offset + 4 <= sec->size);
@@ -4536,6 +4539,16 @@ _bfd_riscv_relax_lui (bfd *abfd,
 	      htab->max_alignment_for_gp = max_alignment;
 	    }
 	}
+
+      /* PR27566, for default linker script, if a symbol's value outsides the
+	 bounds of the defined section, then it may cross the data segment
+	 alignment, so we should reserve more size about MAXPAGESIZE and
+	 COMMONPAGESIZE, since the data segment alignment might move the
+	 section forward.  */
+      if (symval < sec_addr (sym_sec)
+	  || symval > (sec_addr (sym_sec) + sym_sec->size))
+	max_alignment = data_segment_alignment > max_alignment
+			? data_segment_alignment : max_alignment;
     }
 
   /* Is the reference in range of x0 or gp?
@@ -4580,8 +4593,7 @@ _bfd_riscv_relax_lui (bfd *abfd,
       && ELFNN_R_TYPE (rel->r_info) == R_RISCV_HI20
       && VALID_CITYPE_LUI_IMM (RISCV_CONST_HIGH_PART (symval))
       && VALID_CITYPE_LUI_IMM (RISCV_CONST_HIGH_PART (symval)
-			    + (link_info->relro ? 2 * ELF_MAXPAGESIZE
-			       : ELF_MAXPAGESIZE)))
+			       + data_segment_alignment))
     {
       /* Replace LUI with C.LUI if legal (i.e., rd != x0 and rd != x2/sp).  */
       bfd_vma lui = bfd_getl32 (contents + rel->r_offset);
@@ -4726,6 +4738,9 @@ _bfd_riscv_relax_pc (bfd *abfd ATTRIBUTE_UNUSED,
   bfd_vma gp = htab->params->relax_gp
 	       ? riscv_global_pointer_value (link_info)
 	       : 0;
+  bfd_vma data_segment_alignment = link_info->relro
+				   ? ELF_MAXPAGESIZE + ELF_COMMONPAGESIZE
+				   : ELF_MAXPAGESIZE;
 
   BFD_ASSERT (rel->r_offset + 4 <= sec->size);
 
@@ -4800,6 +4815,16 @@ _bfd_riscv_relax_pc (bfd *abfd ATTRIBUTE_UNUSED,
 	      htab->max_alignment_for_gp = max_alignment;
 	    }
 	}
+
+      /* PR27566, for default linker script, if a symbol's value outsides the
+	 bounds of the defined section, then it may cross the data segment
+	 alignment, so we should reserve more size about MAXPAGESIZE and
+	 COMMONPAGESIZE, since the data segment alignment might move the
+	 section forward.  */
+      if (symval < sec_addr (sym_sec)
+	  || symval > (sec_addr (sym_sec) + sym_sec->size))
+	max_alignment = data_segment_alignment > max_alignment
+			? data_segment_alignment : max_alignment;
     }
 
   /* Is the reference in range of x0 or gp?
diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
index 9e103b283f7..713e741c8af 100644
--- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
+++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
@@ -172,6 +172,7 @@ if [istarget "riscv*-*-*"] {
     run_dump_test "attr-merge-priv-spec-failed-06"
     run_dump_test "attr-phdr"
     run_dump_test "relax-max-align-gp"
+    run_dump_test "relax-data-segment-align"
     run_ld_link_tests [list \
 	[list "Weak reference 32" "-T weakref.ld -m[riscv_choose_ilp32_emul]" "" \
 	    "-march=rv32i -mabi=ilp32" {weakref32.s} \
diff --git a/ld/testsuite/ld-riscv-elf/relax-data-segment-align.d b/ld/testsuite/ld-riscv-elf/relax-data-segment-align.d
new file mode 100644
index 00000000000..22aeb4c3f90
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/relax-data-segment-align.d
@@ -0,0 +1,8 @@
+#source: relax-data-segment-align.s
+#ld:
+#objdump: -d
+
+#failif
+#...
+.*gp.*
+#...
diff --git a/ld/testsuite/ld-riscv-elf/relax-data-segment-align.s b/ld/testsuite/ld-riscv-elf/relax-data-segment-align.s
new file mode 100644
index 00000000000..98718922fb5
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/relax-data-segment-align.s
@@ -0,0 +1,16 @@
+	.text
+	.globl _start
+_start:
+	.rept 6000
+	lla a0, symbol
+	.endr
+
+	.section .rodata
+	.set symbol, . + 4598
+	.fill 100, 4, 1
+
+	.data
+	.align 3
+	.rept 860
+	.long 0x1000
+	.endr
