Bug 22874 - GAS does not emit multibyte nops before a function symbol
Summary: GAS does not emit multibyte nops before a function symbol
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: gas (show other bugs)
Version: 2.31
: P2 enhancement
Target Milestone: 2.31
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-02-22 10:21 UTC by Martin Liska
Modified: 2018-03-31 12:32 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Liska 2018-02-22 10:21:58 UTC
$ cat nops.c
void
__attribute__((aligned(128)))
foo (int invariant)
{
  for (;;)
    ;
}

void
__attribute__((aligned(64)))
foo2 (int invariant)
{
}


int main() {}

$ gcc nops.c -O2
$ objdump -S a.out
[snip]
00000000004004b0 <__do_global_dtors_aux>:
  4004b0:	80 3d 71 0b 20 00 00 	cmpb   $0x0,0x200b71(%rip)        # 601028 <__TMC_END__>
  4004b7:	75 17                	jne    4004d0 <__do_global_dtors_aux+0x20>
  4004b9:	55                   	push   %rbp
  4004ba:	48 89 e5             	mov    %rsp,%rbp
  4004bd:	e8 7e ff ff ff       	callq  400440 <deregister_tm_clones>
  4004c2:	c6 05 5f 0b 20 00 01 	movb   $0x1,0x200b5f(%rip)        # 601028 <__TMC_END__>
  4004c9:	5d                   	pop    %rbp
  4004ca:	c3                   	retq   
  4004cb:	0f 1f 44 00 00       	nopl   0x0(%rax,%rax,1)
  4004d0:	f3 c3                	repz retq 
  4004d2:	0f 1f 40 00          	nopl   0x0(%rax)
  4004d6:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
  4004dd:	00 00 00 

00000000004004e0 <frame_dummy>:
  4004e0:	55                   	push   %rbp
  4004e1:	48 89 e5             	mov    %rsp,%rbp
  4004e4:	5d                   	pop    %rbp
  4004e5:	eb 89                	jmp    400470 <register_tm_clones>
  4004e7:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
  4004ee:	00 00 00 
  4004f1:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
  4004f8:	00 00 00 
  4004fb:	0f 1f 44 00 00       	nopl   0x0(%rax,%rax,1)

0000000000400500 <foo>:
  400500:	eb fe                	jmp    400500 <foo>
  400502:	90                   	nop
  400503:	90                   	nop
  400504:	90                   	nop
  400505:	90                   	nop
  400506:	90                   	nop
  400507:	90                   	nop
  400508:	90                   	nop
  400509:	90                   	nop
  40050a:	90                   	nop
  40050b:	90                   	nop
  40050c:	90                   	nop
  40050d:	90                   	nop
  40050e:	90                   	nop
  40050f:	90                   	nop
  400510:	90                   	nop
  400511:	90                   	nop
  400512:	90                   	nop
  400513:	90                   	nop
  400514:	90                   	nop
  400515:	90                   	nop
  400516:	90                   	nop
  400517:	90                   	nop
  400518:	90                   	nop
  400519:	90                   	nop
  40051a:	90                   	nop
  40051b:	90                   	nop
  40051c:	90                   	nop
  40051d:	90                   	nop
  40051e:	90                   	nop
  40051f:	90                   	nop
  400520:	90                   	nop
  400521:	90                   	nop
  400522:	90                   	nop
  400523:	90                   	nop
  400524:	90                   	nop
  400525:	90                   	nop
  400526:	90                   	nop
  400527:	90                   	nop
  400528:	90                   	nop
  400529:	90                   	nop
  40052a:	90                   	nop
  40052b:	90                   	nop
  40052c:	90                   	nop
  40052d:	90                   	nop
  40052e:	90                   	nop
  40052f:	90                   	nop
  400530:	90                   	nop
  400531:	90                   	nop
  400532:	90                   	nop
  400533:	90                   	nop
  400534:	90                   	nop
  400535:	90                   	nop
  400536:	90                   	nop
  400537:	90                   	nop
  400538:	90                   	nop
  400539:	90                   	nop
  40053a:	90                   	nop
  40053b:	90                   	nop
  40053c:	90                   	nop
  40053d:	90                   	nop
  40053e:	90                   	nop
  40053f:	90                   	nop

0000000000400540 <foo2>:
  400540:	f3 c3                	repz retq 
  400542:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
  400549:	00 00 00 
  40054c:	0f 1f 40 00          	nopl   0x0(%rax)
[snip]
Comment 1 H.J. Lu 2018-02-22 12:16:37 UTC
The limit of multibyte nop for code alignment is

#define MAX_MEM_FOR_RS_ALIGN_CODE  31
Comment 2 Alan Modra 2018-02-22 22:23:33 UTC
Those nops are emitted by the linker, not the assembler.  We currently have no generic infrastructure for emitting fancy nop sequences in linker generated padding, but see emultempl/ppc32elf.em:no_zero_padding.

However, I question whether emitting multi-byte nops in padding on x86 is a good idea.  If you somehow execute those nops, what happens when you jump into the middle of a multi-byte nop?
Comment 3 Alan Modra 2018-02-22 22:28:03 UTC
Argh, I wish I could delete comments..  Same source file, these are indeed gas inserted nops.
Comment 4 Martin Liska 2018-02-26 09:55:59 UTC
(In reply to H.J. Lu from comment #1)
> The limit of multibyte nop for code alignment is
> 
> #define MAX_MEM_FOR_RS_ALIGN_CODE  31

Thanks, I can confirm that:

00000000004004c0 <foo>:
  4004c0:	eb fe                	jmp    4004c0 <foo>
  4004c2:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
  4004c9:	00 00 00 
  4004cc:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
  4004d3:	00 00 00 
  4004d6:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
  4004dd:	00 00 00 

00000000004004e0 <foo2>:
  4004e0:	f3 c3                	repz retq 
  4004e2:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
  4004e9:	00 00 00 
  4004ec:	0f 1f 40 00          	nopl   0x0(%rax)

So the logical question is why is it limited? Does it have any disadvantages to emit also big paddings in between symbols?
Comment 5 cvs-commit@gcc.gnu.org 2018-03-07 12:26:07 UTC
The master branch has been updated by H.J. Lu <hjl@sourceware.org>:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=3ae729d5a4f63740ed9a778960b17c2912b0bbdd

commit 3ae729d5a4f63740ed9a778960b17c2912b0bbdd
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Wed Mar 7 04:18:45 2018 -0800

    x86: Rewrite NOP generation for fill and alignment
    
    Rewrite NOP generation for fill and code alignment by:
    
    1. Add a 11-byte NOP with another 0x66 prefix.
    2. Remove the multi-byte NOP entries which consist of 2 instructions.
    3. Select proper NOPs based on ISA and processor tuning.
    4. Generate multiple NOPs with the longer NOPs first followed by the
    shorter NOP.
    5. Use jump for larger NOP padding:
       a. > 8 bytes (2 NOPs) in 16-bit mode.
       b. > 14 bytes (2 NOPs) for older processors.
       c. > 77 bytes (7 NOPs) for newer processors.
    6. Update MAX_MEM_FOR_RS_ALIGN_CODE to 4095.
    
    	PR gas/22874
    	* config/tc-i386.c (f32_5): Removed.
    	(f32_8): Likewise.
    	(f32_9): Likewise.
    	(f32_10): Likewise.
    	(f32_11): Likewise.
    	(f32_12): Likewise.
    	(f32_13): Likewise.
    	(f32_14): Likewise.
    	(f16_5): Likewise.
    	(f16_6): Likewise.
    	(f16_7): Likewise.
    	(f16_8): Likewise.
    	(jump_31): Likewise.
    	(alt64_11): Likewise.
    	(alt64_patt): Likewise.
    	(jump_disp8): New.
    	(jump32_disp32): Likewise.
    	(jump16_disp32): Likewise.
    	(alt_11): Likewise.
    	(f32_patt): Updated.
    	(f16_patt): Likewise.
    	(alt_patt): Add alt_11.
    	(i386_align_code): Merged with ...
    	(i386_generate_nops): This.  Rewritten.
    	(fits_in_imm7): Moved before i386_generate_nops.
    	(fits_in_imm31): Likewise.
    	* config/tc-i386.h (MAX_MEM_FOR_RS_ALIGN_CODE): Updated to
    	4095.
    	(i386_align_code): Removed.
    	(HANDLE_ALIGN): Rewritten with i386_generate_nops.
    	* doc/as.texinfo: Update limits of control byte for x86 .nops
    	directive.
    	* testsuite/gas/i386/i386.exp: Run nops-7 and x86-64-nops-7.
    	* gas/testsuite/gas/i386/noavx-3.l: Updated.
    	* gas/testsuite/gas/i386/nop-1.d: Likewise.
    	* gas/testsuite/gas/i386/nop-1.s: Likewise.
    	* gas/testsuite/gas/i386/nop-2.d: Likewise.
    	* gas/testsuite/gas/i386/nop-2.s: Likewise.
    	* gas/testsuite/gas/i386/nop-3.d: Likewise.
    	* gas/testsuite/gas/i386/nop-4.d: Likewise.
    	* gas/testsuite/gas/i386/nop-5.d: Likewise.
    	* gas/testsuite/gas/i386/nop-5.s: Likewise.
    	* gas/testsuite/gas/i386/nop-6.d: Likewise.
    	* gas/testsuite/gas/i386/nop-bad-1.l: Likewise.
    	* gas/testsuite/gas/i386/nops-1-core2.d: Likewise.
    	* gas/testsuite/gas/i386/nops-1-i386-i686.d: Likewise.
    	* gas/testsuite/gas/i386/nops-1-i386.d: Likewise.
    	* gas/testsuite/gas/i386/nops-1-i686.d: Likewise.
    	* gas/testsuite/gas/i386/nops-1-k8.d: Likewise.
    	* gas/testsuite/gas/i386/nops-1.d: Likewise.
    	* gas/testsuite/gas/i386/nops-2-core2.d: Likewise.
    	* gas/testsuite/gas/i386/nops-2-i386.d: Likewise.
    	* gas/testsuite/gas/i386/nops-2.d: Likewise.
    	* gas/testsuite/gas/i386/nops-3-i386.d: Likewise.
    	* gas/testsuite/gas/i386/nops-3-i686.d: Likewise.
    	* gas/testsuite/gas/i386/nops-3.d: Likewise.
    	* gas/testsuite/gas/i386/nops-4-i386.d: Likewise.
    	* gas/testsuite/gas/i386/nops-4-i686.d: Likewise.
    	* gas/testsuite/gas/i386/nops-4.d: Likewise.
    	* gas/testsuite/gas/i386/nops-4a-i686.d: Likewise.
    	* gas/testsuite/gas/i386/nops-5-i686.d: Likewise.
    	* gas/testsuite/gas/i386/nops-5.d: Likewise.
    	* gas/testsuite/gas/i386/nops-6.d: Likewise.
    	* gas/testsuite/gas/i386/nops16-1.d: Likewise.
    	* gas/testsuite/gas/i386/x86-64-nop-1.d: Likewise.
    	* gas/testsuite/gas/i386/x86-64-nop-2.d: Likewise.
    	* gas/testsuite/gas/i386/x86-64-nop-5.d: Likewise.
    	* gas/testsuite/gas/i386/x86-64-nops-1-core2.d: Likewise.
    	* gas/testsuite/gas/i386/x86-64-nops-1-g64.d: Likewise.
    	* gas/testsuite/gas/i386/x86-64-nops-1-k8.d: Likewise.
    	* gas/testsuite/gas/i386/x86-64-nops-1-pentium.d: Likewise.
    	* gas/testsuite/gas/i386/x86-64-nops-1.d: Likewise.
    	* gas/testsuite/gas/i386/x86-64-nops-2.d: Likewise.
    	* gas/testsuite/gas/i386/x86-64-nops-3.d: Likewise.
    	* gas/testsuite/gas/i386/x86-64-nops-4-core2.d: Likewise.
    	* gas/testsuite/gas/i386/x86-64-nops-4-k8.d: Likewise.
    	* gas/testsuite/gas/i386/x86-64-nops-4.d: Likewise.
    	* gas/testsuite/gas/i386/x86-64-nops-5-k8.d: Likewise.
    	* gas/testsuite/gas/i386/x86-64-nops-5.d: Likewise.
    	* gas/testsuite/gas/i386/ilp32/x86-64-nops-1-core2.d: Likewise.
    	* gas/testsuite/gas/i386/ilp32/x86-64-nops-1-k8.d: Likewise.
    	* gas/testsuite/gas/i386/ilp32/x86-64-nops-1-pentium.d: Likewise.
    	* gas/testsuite/gas/i386/ilp32/x86-64-nops-1.d: Likewise.
    	* gas/testsuite/gas/i386/ilp32/x86-64-nops-2.d: Likewise.
    	* gas/testsuite/gas/i386/ilp32/x86-64-nops-3.d: Likewise.
    	* gas/testsuite/gas/i386/ilp32/x86-64-nops-4-core2.d: Likewise.
    	* gas/testsuite/gas/i386/ilp32/x86-64-nops-4-k8.d: Likewise.
    	* gas/testsuite/gas/i386/ilp32/x86-64-nops-4.d: Likewise.
    	* gas/testsuite/gas/i386/ilp32/x86-64-nops-5-k8.d: Likewise.
    	* gas/testsuite/gas/i386/ilp32/x86-64-nops-5.d: Likewise.
    	* gas/testsuite/gas/i386/nops-7.d: New file.
    	* gas/testsuite/gas/i386/nops-7.s: Likewise.
    	* gas/testsuite/gas/i386/x86-64-nops-7.d: Likewise.
Comment 6 H.J. Lu 2018-03-07 12:27:57 UTC
Fixed for 2.31.