[PATCH] opcodes/i386: remove trailing whitespace from insns with zero operands
Jan Beulich
jbeulich@suse.com
Thu May 26 15:15:52 GMT 2022
On 26.05.2022 14:45, Andrew Burgess via Binutils wrote:
> While working on another patch[1] I had need to touch this code in
> i386-dis.c:
>
> ins->obufp = ins->mnemonicendp;
> for (i = strlen (ins->obuf) + prefix_length; i < 6; i++)
> oappend (ins, " ");
> oappend (ins, " ");
> (*ins->info->fprintf_styled_func)
> (ins->info->stream, dis_style_mnemonic, "%s", ins->obuf);
>
> What this code does is add whitespace after the instruction mnemonic
> and before the instruction operands.
>
> The problem I ran into when working on this code can be seen by
> assembling this input file:
>
> .text
> nop
> retq
>
> Now, when I disassemble, here's the output. I've replaced trailing
> whitespace with '_' so that the issue is clearer:
>
> Disassembly of section .text:
>
> 0000000000000000 <.text>:
> 0: 90 nop
> 1: c3 retq___
>
> Notice that there's no trailing whitespace after 'nop', but there are
> three spaces after 'retq'!
>
> What happens is that instruction mnemonics are emitted into a buffer
> instr_info::obuf, then instr_info::mnemonicendp is setup to point to
> the '\0' character at the end of the mnemonic.
>
> When we emit the whitespace, this is then added starting at the
> mnemonicendp position. Lets consider 'retq', first the buffer is
> setup like this:
>
> 'r' 'e' 't' 'q' '\0'
>
> Then we add whitespace characters at the '\0', converting the buffer
> to this:
>
> 'r' 'e' 't' 'q' ' ' ' ' ' ' '\0'
>
> However, 'nop' is actually an alias for 'xchg %rax,%rax', so,
> initially, the buffer is setup like this:
>
> 'x' 'c' 'h' 'g' '\0'
>
> Then in NOP_Fixup we spot that we have an instruction that is an alias
> for 'nop', and adjust the buffer to this:
>
> 'n' 'o' 'p' '\0' '\0'
>
> The second '\0' is left over from the original buffer contents.
> However, when we rewrite the buffer, we don't afjust mnemonicendp,
> which still points at the second '\0' character.
>
> Now, when we insert whitespace we get:
>
> 'n' 'o' 'p' '\0' ' ' ' ' ' ' ' ' '\0'
>
> Notice the whitespace is inserted after the first '\0', so, when we
> print the buffer, the whitespace is not printed.
>
> The fix for this is pretty easy, I can change NOP_Fixup to adjust
> mnemonicendp, but now a bunch of tests start failing, we now produce
> whitespace after the 'nop', which the tests don't expect.
>
> So, I could update the tests to expect the whitespace....
>
> ...except I'm not a fan of trailing whitespace, so I'd really rather
> not.
>
> Turns out, I can pretty easily update the whitespace emitting code to
> spot instructions that have zero operands and just not emit any
> whitespace in this case. So this is what I've done.
I appreciate this; I never understood what the trailing blanks were
good for (and I hadn't noticed the NOP anomaly so far). I'll leave
approving of the change to H.J., though, just indicating here that
all looks good to me.
> I've left in the fix for NOP_Fixup, I think updating mnemonicendp is
> probably a good thing, though this is not really required any more.
I agree with keeping it.
> I've then updated all the tests that I saw failing to adjust the
> expected patterns to account for the change in whitespace.
You could have left alone the ones using " *", reducing overall
patch size, but since you went farther then that - even better.
> For reviewing, start with opcodes/i386-dis.c, that's the actual change
> to how whitespace is emitted. If you're happy with that then
> everything else is testsuite updates.
I think this doesn't belong in the commit message, but would better
go ...
> [1] https://sourceware.org/pipermail/binutils/2022-April/120610.html
> ---
... below such a marker.
Jan
More information about the Binutils
mailing list