summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@bigpond.net.au>2004-07-02 06:40:19 +0000
committerAlan Modra <amodra@bigpond.net.au>2004-07-02 06:40:19 +0000
commitc0e9878d97ec741976d963609b5497b266b2f1b9 (patch)
tree612a763af873e016ba5c0c0c97ebef85f939d243
parent76bddbd62cdafbd06f163206a262f455e88dc167 (diff)
downloadbinutils-redhat-c0e9878d97ec741976d963609b5497b266b2f1b9.tar.gz
* 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.
-rw-r--r--gas/ChangeLog7
-rw-r--r--gas/config/tc-ppc.c6
-rw-r--r--gas/config/tc-ppc.h9
-rw-r--r--gas/frags.h9
-rw-r--r--gas/write.c5
5 files changed, 31 insertions, 5 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 1c0e301721..ab0551eb7d 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,10 @@
+2004-07-02 Alan Modra <amodra@bigpond.net.au>
+
+ * 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.
+
2004-06-28 Maciej W. Rozycki <macro@linux-mips.org>
* doc/Makefile.am (info): Rename goal to...
diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c
index fe66d2ba2d..d4893e7610 100644
--- a/gas/config/tc-ppc.c
+++ b/gas/config/tc-ppc.c
@@ -2091,6 +2091,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 +2619,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
diff --git a/gas/config/tc-ppc.h b/gas/config/tc-ppc.h
index 0844f84cef..e08b12dfdb 100644
--- a/gas/config/tc-ppc.h
+++ b/gas/config/tc-ppc.h
@@ -1,6 +1,6 @@
/* tc-ppc.h -- Header file for tc-ppc.c.
- Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
- Free Software Foundation, Inc.
+ Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+ 2004 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Cygnus Support.
This file is part of GAS, the GNU Assembler.
@@ -110,6 +110,11 @@ extern char *ppc_target_format PARAMS ((void));
} \
}
+#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
diff --git a/gas/frags.h b/gas/frags.h
index 52a6cfeb4b..a3bd522216 100644
--- a/gas/frags.h
+++ b/gas/frags.h
@@ -1,6 +1,6 @@
/* frags.h - Header file for the frag concept.
- Copyright 1987, 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001
- Free Software Foundation, Inc.
+ Copyright 1987, 1992, 1993, 1994, 1995, 1997, 1998, 1999, 2000, 2001,
+ 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -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;
diff --git a/gas/write.c b/gas/write.c
index 5acd607784..509596fbdd 100644
--- a/gas/write.c
+++ b/gas/write.c
@@ -1,6 +1,6 @@
/* write.c - emit .o file
Copyright 1986, 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000, 2001, 2002, 2003
+ 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -616,6 +616,9 @@ cvt_frag_to_fill (object_headers *headersP, segT sec, fragS *fragP)
BAD_CASE (fragP->fr_type);
break;
}
+#ifdef md_frag_check
+ md_frag_check (fragP);
+#endif
}
#endif /* defined (BFD_ASSEMBLER) || !defined (BFD) */