Re: Stop Gas from generating line info or address ranges

* 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.
This commit is contained in:
Alan Modra
2020-11-17 12:41:36 +10:30
parent 99fabbc973
commit 058430b4a1
9 changed files with 121 additions and 31 deletions

View File

@@ -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> 2020-11-18 Jozef Lawrynowicz <jozef.l@mittosystems.com>
H.J. Lu <hongjiu.lu@intel.com> H.J. Lu <hongjiu.lu@intel.com>

View File

@@ -6169,14 +6169,18 @@ counter, and @code{.nolist} decrements it. Assembly listings are
generated whenever the counter is greater than zero. generated whenever the counter is greater than zero.
@node Nop @node Nop
@section @code{.nop} @section @code{.nop [@var{size}]}
@cindex @code{nop} directive @cindex @code{nop} directive
@cindex filling memory with no-op instructions @cindex filling memory with no-op instructions
This directive emits a single no-op instruction. It is provided on all This directive emits no-op instructions. It is provided on all architectures,
architectures, allowing the creation of architecture neutral tests involving allowing the creation of architecture neutral tests involving actual code. The
actual code. The size of the generated instruction is target specific. The size of the generated instruction is target specific, but if the optional
instruction does affect the generation of DWARF debug line information. @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 @node Nops
@section @code{.nops @var{size}[, @var{control}]} @section @code{.nops @var{size}[, @var{control}]}

View File

@@ -504,16 +504,18 @@ dwarf2_gen_line_info_1 (symbolS *label, struct dwarf2_line_info *loc)
{ {
struct line_subseg *lss; struct line_subseg *lss;
struct line_entry *e; 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, /* PR 26850: Do not record LOCs in non-executable or non-loaded
or non-loaded sections. */ 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 ((now_seg->flags & need_flags) != need_flags)
{ {
if (! SEG_NORMAL (now_seg)) /* FIXME: Add code to suppress multiple warnings ? */
/* FIXME: Add code to suppress multiple warnings ? */ as_warn ("dwarf line number information for %s ignored",
as_warn ("dwarf line number information for %s ignored", segment_name (now_seg));
segment_name (now_seg));
return; return;
} }

View File

@@ -468,6 +468,48 @@ frag_offset_fixed_p (const fragS *frag1, const fragS *frag2, offsetT *offset)
return FALSE; 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 /* Return TRUE if we can determine whether FRAG2 OFF2 appears after
(strict >, not >=) FRAG1 OFF1, assuming it is not before. Set (strict >, not >=) FRAG1 OFF1, assuming it is not before. Set
*OFFSET so that resolve_expression will resolve an O_gt operation *OFFSET so that resolve_expression will resolve an O_gt operation

View File

@@ -154,6 +154,8 @@ char *frag_var (relax_stateT type,
char *opcode); char *opcode);
bfd_boolean frag_offset_fixed_p (const fragS *, const fragS *, offsetT *); 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 *, bfd_boolean frag_gtoffset_p (valueT, const fragS *, valueT, const fragS *,
offsetT *); offsetT *);

View File

@@ -3506,6 +3506,11 @@ s_space (int mult)
void void
s_nop (int ignore ATTRIBUTE_UNUSED) s_nop (int ignore ATTRIBUTE_UNUSED)
{ {
expressionS exp;
fragS *start;
addressT start_off;
offsetT frag_off;
#ifdef md_flush_pending_output #ifdef md_flush_pending_output
md_flush_pending_output (); md_flush_pending_output ();
#endif #endif
@@ -3515,29 +3520,42 @@ s_nop (int ignore ATTRIBUTE_UNUSED)
#endif #endif
SKIP_WHITESPACE (); SKIP_WHITESPACE ();
expression (&exp);
demand_empty_rest_of_line (); demand_empty_rest_of_line ();
start = frag_now;
start_off = frag_now_fix ();
do
{
#ifdef md_emit_single_noop #ifdef md_emit_single_noop
md_emit_single_noop; md_emit_single_noop;
#else #else
char * nop; char *nop;
#ifndef md_single_noop_insn #ifndef md_single_noop_insn
#define md_single_noop_insn "nop" #define md_single_noop_insn "nop"
#endif #endif
/* md_assemble might modify its argument, so /* md_assemble might modify its argument, so
we must pass it a string that is writeable. */ we must pass it a string that is writable. */
if (asprintf (&nop, "%s", md_single_noop_insn) < 0) if (asprintf (&nop, "%s", md_single_noop_insn) < 0)
as_fatal ("%s", xstrerror (errno)); as_fatal ("%s", xstrerror (errno));
/* Some targets assume that they can update input_line_pointer inside /* Some targets assume that they can update input_line_pointer
md_assemble, and, worse, that they can leave it assigned to the string inside md_assemble, and, worse, that they can leave it
pointer that was provided as an argument. So preserve ilp here. */ assigned to the string pointer that was provided as an
char * saved_ilp = input_line_pointer; argument. So preserve ilp here. */
md_assemble (nop); char *saved_ilp = input_line_pointer;
input_line_pointer = saved_ilp; md_assemble (nop);
free (nop); input_line_pointer = saved_ilp;
free (nop);
#endif #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 void

View File

@@ -3,6 +3,12 @@
#name: DWARF2_20: debug ranges ignore non-code sections #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. # 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*-* #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: Contents of the .debug_aranges section:
@@ -13,6 +19,6 @@ Contents of the .debug_aranges section:
[ ]+Segment Size:[ ]+0 [ ]+Segment Size:[ ]+0
[ ]+Address[ ]+Length [ ]+Address[ ]+Length
[ ]+0+000 0+00. [ ]+0+000 0+010
[ ]+0+000 0+000 [ ]+0+000 0+000
#pass #pass

View File

@@ -1,10 +1,10 @@
.section .alloc0,"a" .section .alloc0,"a"
.nop .nop 16
.section .alloc1,"a" .section .alloc1,"a"
.nop .nop 16
.section .nonalloc,"" .section .nonalloc,""
.nop .nop 16
.section .allocexec,"ax" .section .allocexec,"ax"
.nop .nop 16
.section .nonallocexec,"x" .section .nonallocexec,"x"
.nop .nop 16

View File

@@ -2,6 +2,10 @@
#as: -m68hc12 -gdwarf2 #as: -m68hc12 -gdwarf2
#name: 68HC12 indexed addressing mode with 5, 9 and 16-bit offsets (indexed12) #name: 68HC12 indexed addressing mode with 5, 9 and 16-bit offsets (indexed12)
#source: indexed12.s #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 .*: +file format elf32\-m68hc12