warning on wrongly aligned insns

Alan Modra amodra@bigpond.net.au
Fri Jul 2 06:31:00 GMT 2004


I think this is all we need to check that instruction addresses are
sane.  One problem is that the error emitted by md_frag_check can
have an unusual line number, typically the line where the next frag
starts.

It shouldn't be too hard to extend this patch for ia64 and other
architectures.

	* frags.h (struct frag): Add has_code and insn_addr fields.
	* write.c (cvt_frag_to_fill): Invoke md_frag_check.
	* config/tc-ppc.c (md_assemble): Check and set insn_addr.
	* config/tc-ppc.h (md_frag_check): Define.

Index: gas/frags.h
===================================================================
RCS file: /cvs/src/src/gas/frags.h,v
retrieving revision 1.15
diff -u -p -r1.15 frags.h
--- gas/frags.h	23 Jan 2004 12:52:19 -0000	1.15
+++ gas/frags.h	2 Jul 2004 06:00:57 -0000
@@ -74,6 +74,11 @@ struct frag {
      fr_address has been adjusted.  */
   unsigned int relax_marker:1;
 
+  /* Used to ensure that all insns are emitted on proper address
+     boundaries.  */
+  unsigned int has_code:1;
+  unsigned int insn_addr:6;
+
   /* What state is my tail in? */
   relax_stateT fr_type;
   relax_substateT fr_subtype;
Index: gas/write.c
===================================================================
RCS file: /cvs/src/src/gas/write.c,v
retrieving revision 1.76
diff -u -p -r1.76 write.c
--- gas/write.c	6 Dec 2003 16:16:51 -0000	1.76
+++ gas/write.c	2 Jul 2004 06:00:59 -0000
@@ -616,6 +616,9 @@ cvt_frag_to_fill (object_headers *header
       BAD_CASE (fragP->fr_type);
       break;
     }
+#ifdef md_frag_check
+  md_frag_check (fragP);
+#endif
 }
 
 #endif /* defined (BFD_ASSEMBLER) || !defined (BFD)  */
Index: gas/config/tc-ppc.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-ppc.c,v
retrieving revision 1.88
diff -u -p -r1.88 tc-ppc.c
--- gas/config/tc-ppc.c	6 May 2004 11:01:48 -0000	1.88
+++ gas/config/tc-ppc.c	2 Jul 2004 06:01:05 -0000
@@ -2091,6 +2092,7 @@ md_assemble (str)
   struct ppc_fixup fixups[MAX_INSN_FIXUPS];
   int fc;
   char *f;
+  int addr_mod;
   int i;
 #ifdef OBJ_ELF
   bfd_reloc_code_real_type reloc;
@@ -2618,6 +2620,11 @@ md_assemble (str)
 
   /* Write out the instruction.  */
   f = frag_more (4);
+  addr_mod = frag_now_fix () & 3;
+  if (frag_now->has_code && frag_now->insn_addr != addr_mod)
+    as_bad (_("instruction address is not a multiple of 4"));
+  frag_now->insn_addr = addr_mod;
+  frag_now->has_code = 1;
   md_number_to_chars (f, insn, 4);
 
 #ifdef OBJ_ELF
Index: gas/config/tc-ppc.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-ppc.h,v
retrieving revision 1.24
diff -u -p -r1.24 tc-ppc.h
--- gas/config/tc-ppc.h	4 Nov 2003 23:35:54 -0000	1.24
+++ gas/config/tc-ppc.h	2 Jul 2004 06:01:05 -0000
@@ -110,6 +110,11 @@ extern char *ppc_target_format PARAMS ((
 	}								\
     }
 
+#define md_frag_check(FRAGP) \
+  if ((FRAGP)->has_code							\
+      && (((FRAGP)->fr_address + (FRAGP)->insn_addr) & 3) != 0)		\
+    as_bad_where ((FRAGP)->fr_file, (FRAGP)->fr_line,			\
+		  _("instruction address is not a multiple of 4"));
 
 #ifdef TE_PE
 

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre



More information about the Binutils mailing list