This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Support aligning text section from odd addresses


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=e5b737de4a22c3099345f2613c106623d7f8d7e7

commit e5b737de4a22c3099345f2613c106623d7f8d7e7
Author: Andrew Waterman <andrew@sifive.com>
Date:   Tue Dec 20 14:25:39 2016 -0800

    Support aligning text section from odd addresses
    
    Previously, the alignment directives were not correctly supported
    in the text section when current alignment was only 1 byte (i.e.,
    when the address was odd).  Since there are no 1-byte instructions
    in RISC-V, this patch resolves the bug by writing a zero byte to
    obtain 2-byte alignment, at which point a 2-byte NOP can be used
    to obtain 4-byte alignment.
    
    Resolves https://github.com/riscv/riscv-gnu-toolchain/issues/205
    
    	* config/tc-riscv.c (riscv_make_nops): Emit 2-byte NOPs.
    	(riscv_frag_align_code): Correct frag_align_code arg.

Diff:
---
 gas/ChangeLog         |  5 +++++
 gas/config/tc-riscv.c | 22 ++++++++++++++++------
 2 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/gas/ChangeLog b/gas/ChangeLog
index 616fd09..de6e5d5 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,8 @@
+2016-12-21 Andrew Waterman <andrew@sifive.com>
+
+	* config/tc-riscv.c (riscv_make_nops): Emit 2-byte NOPs.
+	(riscv_frag_align_code): Correct frag_align_code arg.
+
 2016-12-21 Tim Newsome <tim@sifive.com>
 
 	* config/tc-riscv.c (riscv_pre_output_hook): Remove const from
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 8c78f61..8c732f0 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -2190,14 +2190,20 @@ riscv_make_nops (char *buf, bfd_vma bytes)
 {
   bfd_vma i = 0;
 
-  if (bytes % 4 == 2)
+  /* RISC-V instructions cannot begin or end on odd addresses, so this case
+     means we are not within a valid instruction sequence.  It is thus safe
+     to use a zero byte, even though that is not a valid instruction.  */
+  if (bytes % 2 == 1)
+    buf[i++] = 0;
+
+  /* Use at most one 2-byte NOP.  */
+  if ((bytes - i) % 4 == 2)
     {
-      md_number_to_chars (buf, RVC_NOP, 2);
+      md_number_to_chars (buf + i, RVC_NOP, 2);
       i += 2;
     }
 
-  gas_assert ((bytes - i) % 4 == 0);
-
+  /* Fill the remainder with 4-byte NOPs.  */
   for ( ; i < bytes; i += 4)
     md_number_to_chars (buf + i, RISCV_NOP, 4);
 }
@@ -2210,8 +2216,12 @@ riscv_make_nops (char *buf, bfd_vma bytes)
 bfd_boolean
 riscv_frag_align_code (int n)
 {
-  bfd_vma bytes = (bfd_vma)1 << n;
-  bfd_vma min_text_alignment = riscv_opts.rvc ? 2 : 4;
+  bfd_vma bytes = (bfd_vma) 1 << n;
+  bfd_vma min_text_alignment_order = riscv_opts.rvc ? 1 : 2;
+  bfd_vma min_text_alignment = (bfd_vma) 1 << min_text_alignment_order;
+
+  /* First, get back to minimal alignment.  */
+  frag_align_code (min_text_alignment_order, 0);
 
   /* When not relaxing, riscv_handle_align handles code alignment.  */
   if (!riscv_opts.relax)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]