[prev in list] [next in list] [prev in thread] [next in thread] 

List:       freebsd-arm
Subject:    Re: clang14 issue triggering PR264094?
From:       John F Carr <jfc () mit ! edu>
Date:       2022-05-22 23:03:39
Message-ID: AF3EE778-EC1A-4695-AE8F-C00C306212BC () exchange ! mit ! edu
[Download RAW message or body]



> On May 22, 2022, at 17:20 , John F Carr <jfc@mit.edu> wrote:
> 
> On May 22, 2022, at 16:41 , tuexen@freebsd.org wrote:
> > 
> > Dear all,
> > 
> > I'm trying to analyze https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=264094
> > 
> > The relevant file is:
> > https://cgit.freebsd.org/src/tree/sys/netinet/cc/cc_htcp.c
> > 
> > It is interesting that the panic happens on arm64, but not amd64. It does
> > happen when using clang14 (most recent version in the main tree), it does
> > not happen when using clang13.
> > I also does not happen using clang14 when forcing htcp_recalc_beta() not
> > to be inlined.
> > 
> > The panic happens when accessing V_htcp_adaptive_backoff in
> > https://cgit.freebsd.org/src/tree/sys/netinet/cc/cc_htcp.c#n471
> > 
> > Since this looks strange to me, I disassembled htcp_recalc_beta() when
> > using clang14 and the function not being inlined. This is the relevant
> > code:
> > 
> > (kgdb) disassemble htcp_recalc_beta
> > Dump of assembler code for function htcp_recalc_beta:
> > 0x00000000000113cc <+0>:	stp	x29, x30, [sp, #-16]!
> > 0x00000000000113d0 <+4>:	mov	x29, sp
> > 0x00000000000113d4 <+8>:	ldr	x8, [x0]          ; x8 = ccv
> > 0x00000000000113d8 <+12>:	ldr	x9, [x18]         ; x9 = curthread
> > 0x00000000000113dc <+16>:	adrp	x10, 0x21000      ; x10 = ???
> > 0x00000000000113e0 <+20>:	ldr	x9, [x9, #1368]   ; x9 = curthread->td_vnet
> > 0x00000000000113e4 <+24>:	ldr	x10, [x10, #2168] ; x10 = ???
> > 0x00000000000113e8 <+28>:	ldr	x9, [x9, #40]     ; x9 = \
> > curthread->td_vnet->vnet_data_base 0x00000000000113ec <+32>:	ldr	w9, [x9, x10]    \
> > ; w9 = V_htcp_adaptive_backoff ??? 0x00000000000113f0 <+36>:	cbz	w9, 0x11428 \
> > <htcp_recalc_beta+92> 
> > I don't understand the computations in relation to x10, which is the offset used \
> > to get the relevant variable. 
> > However, this code works.
> > 
> > Looking at the code generated by clang13 when htcp_recalc_beta() is inlined, one \
> > gets: 
> > 0xffff000150610f28 <+212>:	ldr	x10, [x0]                ; x10 = ccv
> > 0xffff000150610f2c <+216>:	ldr	x11, [x18]               ; x11 = curthread
> > 0xffff000150610f30 <+220>:	ldr	x11, [x11, #1368]        ; x11 = \
> > curthread->td_vnet 0xffff000150610f34 <+224>:	ldr	x12, [x11, #40]          ; x12 \
> > = curthread->td_vnet->vnet_data_base 0xffff000150610f38 <+228>:	adrp	x11, \
> > 0xffff000150621000  ; ??? 0xffff000150610f3c <+232>:	ldr	x11, [x11, #2256]        \
> > ; ??? 0xffff000150610f40 <+236>:	ldr	w12, [x12, x11]
> > 0xffff000150610f44 <+240>:	cbz	w12, 0xffff000150610f7c <htcp_ack_received+296>
> > 
> > It looks similar and it does work.
> > 
> > Now comes the inlined code from clang14:
> > 
> > 0xffff0001016acf28 <+212>:	ldr	x10, [x0]         ; x10 = ccv
> > 0xffff0001016acf2c <+216>:	ldr	x11, [x18]        ; x11 = curthread
> > 0xffff0001016acf30 <+220>:	ldr	x12, [x11, #1368] ; x12 = curthread->td_vnet
> > 0xffff0001016acf34 <+224>:	nop
> > 0xffff0001016acf38 <+228>:	adr	x11, 0xffff0001016bd520 \
> > <vnet_entry_htcp_adaptive_backoff> 0xffff0001016acf3c <+232>:	ldr	x12, [x12, #40] \
> > ; x12 = curthread->td_vnet->vnet_data_base ==>0xffff0001016acf40 <+236>:	ldr	w12, \
> > [x12, x11] 0xffff0001016acf44 <+240>:	cbz	w12, 0xffff0001016acf7c \
> > <htcp_ack_received+296> 
> > The line marked with ==> is the line where the panic happens. It looks that the \
> > offset computation is different. 
> > Is this an issue with clang14? Any idea what is going wrong?
> > 
> > Thanks for any help!
> > 
> > Best regards
> > Michael
> > 
> > 
> 
> That nop next to the adr instruction makes me think a 32 bit relocation went wrong. \
> These relocations normally consume two instructions but the linker can patch one \
> into a nop if it is not needed.  Usually you have a pair of instructions adrp+adr \
> or, as in the clang13 example, adrp+ld or adrp+st.   The adrp computes a \
> page-aligned address within a 32 bit offset of the PC and the next instruction has \
> low 12 bits of the address.  The problem could be in the compiler or the linker.  \
> What does the assembly or disassembled .o look like before it gets linked? 
> 

I have an arm64 running CURRENT so I was able to reproduce the problem.

The assembly code is (cc -S)

        ldr     x10, [x0]
        ldr     x11, [x18]
        ldr     x12, [x11, #1368]
        adrp    x11, :got:vnet_entry_htcp_adaptive_backoff
        ldr     x11, [x11, :got_lo12:vnet_entry_htcp_adaptive_backoff]
        ldr     x12, [x12, #40]
        ldr     w12, [x12, x11]


cc_htcp.o disassembles to (objdump --disassemble --reloc)

 1f4:	f940000a 	ldr	x10, [x0]
 1f8:	f940024b 	ldr	x11, [x18]
 1fc:	f942ad6c 	ldr	x12, [x11, #1368]
 200:	9000000b 	adrp	x11, 0 <htcp_mod_init>
			200: R_AARCH64_ADR_GOT_PAGE vnet_entry_htcp_adaptive_backoff
 204:	f940016b 	ldr	x11, [x11]
			204: R_AARCH64_LD64_GOT_LO12_NC	vnet_entry_htcp_adaptive_backoff
 208:	f940158c 	ldr	x12, [x12, #40]
 20c:	b86b698c 	ldr	w12, [x12, x11]



cc_htcp.ko disassembles to

   10f44:	f940000a 	ldr	x10, [x0]
   10f48:	f940024b 	ldr	x11, [x18]
   10f4c:	f942ad6c 	ldr	x12, [x11, #1368]
   10f50:	d503201f 	nop
   10f54:	10082f6b 	adr	x11, 21540 <vnet_entry_htcp_adaptive_backoff>
   10f58:	f940158c 	ldr	x12, [x12, #40]
   10f5c:	b86b698c 	ldr	w12, [x12, x11]

An adrp+ld pair, with paired relocations, is being transformed into a nop+adr pair.  \
So it computes the address of the variable instead of loading its value.   I am not \
familiar with ARM relocation codes and can not say if the R_AARCH64_ADR_GOT_PAGE+ \
R_AARCH64_LD64_GOT_LO12_NC combination is correct here, or whether the :got: and \
:got_lo12: prefixes in the assembly are correct.  I can say that I have seen this \
sort of behavior due to a linker bug before on other systems, when the linker assumes \
a relocation type is only used with a certain opcode.


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic