aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog12
-rw-r--r--gas/doc/as.texi14
-rw-r--r--gas/dwarf2dbg.c16
-rw-r--r--gas/frags.c42
-rw-r--r--gas/frags.h2
-rw-r--r--gas/read.c46
-rw-r--r--gas/testsuite/gas/elf/dwarf2-20.d8
-rw-r--r--gas/testsuite/gas/elf/dwarf2-20.s10
-rw-r--r--gas/testsuite/gas/m68hc11/indexed12.d4
9 files changed, 122 insertions, 32 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index fcfce70..9266585 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,15 @@
+2020-11-18 Alan Modra <amodra@gmail.com>
+
+ * doc/as.texi (.nop): Document optional size arg.
+ * dwarf2dbg.c (dwarf2_gen_line_info_1): Only check SEC_ALLOC
+ when ELF. Warn whenever dwarf line number information is ignored.
+ * frags.c (frag_offset_ignore_align_p): New function.
+ * frags.h (frag_offset_ignore_align_p): Declare.
+ * read.c (s_nop): Extend to support optional size arg.
+ * testsuite/gas/elf/dwarf2-20.d: Expect warnings, and exact range.
+ * testsuite/gas/elf/dwarf2-20.s: Emit 16 bytes worth of nops.
+ * testsuite/gas/m68hc11/indexed12.d: Expect warnings.
+
2020-11-18 Jozef Lawrynowicz <jozef.l@mittosystems.com>
H.J. Lu <hongjiu.lu@intel.com>
diff --git a/gas/doc/as.texi b/gas/doc/as.texi
index 84a7e61..983cec3 100644
--- a/gas/doc/as.texi
+++ b/gas/doc/as.texi
@@ -6169,14 +6169,18 @@ counter, and @code{.nolist} decrements it. Assembly listings are
generated whenever the counter is greater than zero.
@node Nop
-@section @code{.nop}
+@section @code{.nop [@var{size}]}
@cindex @code{nop} directive
@cindex filling memory with no-op instructions
-This directive emits a single no-op instruction. It is provided on all
-architectures, allowing the creation of architecture neutral tests involving
-actual code. The size of the generated instruction is target specific. The
-instruction does affect the generation of DWARF debug line information.
+This directive emits no-op instructions. It is provided on all architectures,
+allowing the creation of architecture neutral tests involving actual code. The
+size of the generated instruction is target specific, but if the optional
+@var{size} argument is given and resolves to an absolute positive value at that
+point in assembly (no forward expressions allowed) then the fewest no-op
+instructions are emitted that equal or exceed a total @var{size} in bytes.
+@code{.nop} does affect the generation of DWARF debug line information.
+Some targets do not support using @code{.nop} with @var{size}.
@node Nops
@section @code{.nops @var{size}[, @var{control}]}
diff --git a/gas/dwarf2dbg.c b/gas/dwarf2dbg.c
index 25ebc94..e927c50 100644
--- a/gas/dwarf2dbg.c
+++ b/gas/dwarf2dbg.c
@@ -504,16 +504,18 @@ dwarf2_gen_line_info_1 (symbolS *label, struct dwarf2_line_info *loc)
{
struct line_subseg *lss;
struct line_entry *e;
- flagword need_flags = SEC_ALLOC | SEC_LOAD | SEC_CODE;
+ flagword need_flags = SEC_LOAD | SEC_CODE;
- /* PR 26850: Do not record LOCs in non-executable, non-allocated,
- or non-loaded sections. */
+ /* PR 26850: Do not record LOCs in non-executable or non-loaded
+ sections. SEC_ALLOC isn't tested for non-ELF because obj-coff.c
+ obj_coff_section is careless in setting SEC_ALLOC. */
+ if (IS_ELF)
+ need_flags |= SEC_ALLOC;
if ((now_seg->flags & need_flags) != need_flags)
{
- if (! SEG_NORMAL (now_seg))
- /* FIXME: Add code to suppress multiple warnings ? */
- as_warn ("dwarf line number information for %s ignored",
- segment_name (now_seg));
+ /* FIXME: Add code to suppress multiple warnings ? */
+ as_warn ("dwarf line number information for %s ignored",
+ segment_name (now_seg));
return;
}
diff --git a/gas/frags.c b/gas/frags.c
index c926ec3..9ed4d7b 100644
--- a/gas/frags.c
+++ b/gas/frags.c
@@ -468,6 +468,48 @@ frag_offset_fixed_p (const fragS *frag1, const fragS *frag2, offsetT *offset)
return FALSE;
}
+/* Return TRUE if FRAG2 follows FRAG1 with a fixed relationship
+ between the two assuming alignment frags do nothing. Set OFFSET to
+ the difference in address not already accounted for in the frag
+ FR_ADDRESS. */
+
+bfd_boolean
+frag_offset_ignore_align_p (const fragS *frag1, const fragS *frag2,
+ offsetT *offset)
+{
+ const fragS *frag;
+ offsetT off;
+
+ /* Start with offset initialised to difference between the two frags.
+ Prior to assigning frag addresses this will be zero. */
+ off = frag1->fr_address - frag2->fr_address;
+ if (frag1 == frag2)
+ {
+ *offset = off;
+ return TRUE;
+ }
+
+ frag = frag1;
+ while (frag->fr_type == rs_fill
+ || frag->fr_type == rs_align
+ || frag->fr_type == rs_align_code
+ || frag->fr_type == rs_align_test)
+ {
+ if (frag->fr_type == rs_fill)
+ off += frag->fr_fix + frag->fr_offset * frag->fr_var;
+ frag = frag->fr_next;
+ if (frag == NULL)
+ break;
+ if (frag == frag2)
+ {
+ *offset = off;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
/* Return TRUE if we can determine whether FRAG2 OFF2 appears after
(strict >, not >=) FRAG1 OFF1, assuming it is not before. Set
*OFFSET so that resolve_expression will resolve an O_gt operation
diff --git a/gas/frags.h b/gas/frags.h
index 39005ae..6e519ab 100644
--- a/gas/frags.h
+++ b/gas/frags.h
@@ -154,6 +154,8 @@ char *frag_var (relax_stateT type,
char *opcode);
bfd_boolean frag_offset_fixed_p (const fragS *, const fragS *, offsetT *);
+bfd_boolean frag_offset_ignore_align_p (const fragS *, const fragS *,
+ offsetT *);
bfd_boolean frag_gtoffset_p (valueT, const fragS *, valueT, const fragS *,
offsetT *);
diff --git a/gas/read.c b/gas/read.c
index 9ba61cd..a4c6e4e 100644
--- a/gas/read.c
+++ b/gas/read.c
@@ -3506,6 +3506,11 @@ s_space (int mult)
void
s_nop (int ignore ATTRIBUTE_UNUSED)
{
+ expressionS exp;
+ fragS *start;
+ addressT start_off;
+ offsetT frag_off;
+
#ifdef md_flush_pending_output
md_flush_pending_output ();
#endif
@@ -3515,29 +3520,42 @@ s_nop (int ignore ATTRIBUTE_UNUSED)
#endif
SKIP_WHITESPACE ();
+ expression (&exp);
demand_empty_rest_of_line ();
+ start = frag_now;
+ start_off = frag_now_fix ();
+ do
+ {
#ifdef md_emit_single_noop
- md_emit_single_noop;
+ md_emit_single_noop;
#else
- char * nop;
+ char *nop;
#ifndef md_single_noop_insn
#define md_single_noop_insn "nop"
#endif
- /* md_assemble might modify its argument, so
- we must pass it a string that is writeable. */
- if (asprintf (&nop, "%s", md_single_noop_insn) < 0)
- as_fatal ("%s", xstrerror (errno));
-
- /* Some targets assume that they can update input_line_pointer inside
- md_assemble, and, worse, that they can leave it assigned to the string
- pointer that was provided as an argument. So preserve ilp here. */
- char * saved_ilp = input_line_pointer;
- md_assemble (nop);
- input_line_pointer = saved_ilp;
- free (nop);
+ /* md_assemble might modify its argument, so
+ we must pass it a string that is writable. */
+ if (asprintf (&nop, "%s", md_single_noop_insn) < 0)
+ as_fatal ("%s", xstrerror (errno));
+
+ /* Some targets assume that they can update input_line_pointer
+ inside md_assemble, and, worse, that they can leave it
+ assigned to the string pointer that was provided as an
+ argument. So preserve ilp here. */
+ char *saved_ilp = input_line_pointer;
+ md_assemble (nop);
+ input_line_pointer = saved_ilp;
+ free (nop);
+#endif
+#ifdef md_flush_pending_output
+ md_flush_pending_output ();
#endif
+ } while (exp.X_op == O_constant
+ && exp.X_add_number > 0
+ && frag_offset_ignore_align_p (start, frag_now, &frag_off)
+ && frag_off + frag_now_fix () < start_off + exp.X_add_number);
}
void
diff --git a/gas/testsuite/gas/elf/dwarf2-20.d b/gas/testsuite/gas/elf/dwarf2-20.d
index 363510a..7f3d21c 100644
--- a/gas/testsuite/gas/elf/dwarf2-20.d
+++ b/gas/testsuite/gas/elf/dwarf2-20.d
@@ -3,6 +3,12 @@
#name: DWARF2_20: debug ranges ignore non-code sections
# The mn10200 target has a pointer size of 3, but it does not use segment selectors. This confuses DWARF and readelf will complain.
#xfail: mn102*-*
+# score-elf, tic6x-elf and xtensa-elf need special handling to support .nop 16
+#xfail: score-* tic6x-* xtensa-*
+#warning: .* \.alloc0 ignored
+#warning: .* \.alloc1 ignored
+#warning: .* \.nonalloc ignored
+#warning: .* \.nonallocexec ignored
Contents of the .debug_aranges section:
@@ -13,6 +19,6 @@ Contents of the .debug_aranges section:
[ ]+Segment Size:[ ]+0
[ ]+Address[ ]+Length
-[ ]+0+000 0+00.
+[ ]+0+000 0+010
[ ]+0+000 0+000
#pass
diff --git a/gas/testsuite/gas/elf/dwarf2-20.s b/gas/testsuite/gas/elf/dwarf2-20.s
index 0ad0cc3..00b6314 100644
--- a/gas/testsuite/gas/elf/dwarf2-20.s
+++ b/gas/testsuite/gas/elf/dwarf2-20.s
@@ -1,10 +1,10 @@
.section .alloc0,"a"
- .nop
+ .nop 16
.section .alloc1,"a"
- .nop
+ .nop 16
.section .nonalloc,""
- .nop
+ .nop 16
.section .allocexec,"ax"
- .nop
+ .nop 16
.section .nonallocexec,"x"
- .nop
+ .nop 16
diff --git a/gas/testsuite/gas/m68hc11/indexed12.d b/gas/testsuite/gas/m68hc11/indexed12.d
index 1862b6a..08279d7 100644
--- a/gas/testsuite/gas/m68hc11/indexed12.d
+++ b/gas/testsuite/gas/m68hc11/indexed12.d
@@ -2,6 +2,10 @@
#as: -m68hc12 -gdwarf2
#name: 68HC12 indexed addressing mode with 5, 9 and 16-bit offsets (indexed12)
#source: indexed12.s
+#warning: .* line number information for \.data ignored
+#warning: .* line number information for \.data ignored
+#warning: .* line number information for \.data ignored
+#warning: .* line number information for \.data ignored
.*: +file format elf32\-m68hc12