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:
parent
99fabbc973
commit
058430b4a1
9 changed files with 121 additions and 31 deletions
|
@ -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>
|
||||
|
||||
|
|
|
@ -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}]}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
42
gas/frags.c
42
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
|
||||
|
|
|
@ -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 *);
|
||||
|
||||
|
|
44
gas/read.c
44
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));
|
||||
/* 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);
|
||||
/* 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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue