-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Description
I expect LLVM to assemble this x86-64 test case. It fails in today's git f719771,
$ clang --target=amd64-openbsd -c exam.s
exam.s:38:9: error: invalid number of bytes
.space (p_nop - p_1st) - (. - q_1st), 0xcc
^
It also fails with the OpenBSD package of llvm-19.1.7p0, but succeeds with the OpenBSD package of llvm-18.1.8p3.
.section .p
p_1st:
0: pause
lfence
jmp 0b
.section .q
q_1st:
addl 11,%eax
addl 22,%eax
q_cli:
cli
0: pause
lfence
jmp 0b
.section .p
.space (q_cli - q_1st) - (. - p_1st), 0xcc
cli
.section .q
q_sti:
sti
.section .p
.space (q_sti - q_1st) - (. - p_1st), 0xcc
sti
addl 33,%eax
addl 44,%eax
p_nop:
nop
.section .q
0: pause
lfence
jmp 0b
.space (p_nop - p_1st) - (. - q_1st), 0xcc
nopThis test case has 2 sections (.p and .q). Each .space should evaluate to .space 7, 0xcc. (Then cli in .p and cli in .q will have the same offset, and same for sti and nop.) LLVM 18 emits the correct .o file, for which llvm-objdump -d -j.p -j.q exam.o shows 3 groups of 7 bytes of 0xcc = int3.
I need a jmp 0b to reproduce the error in LLVM 19 or git. If I change the 1st jmp 0b (on line 5) to incl %eax (both instructions are 2 bytes), then the error goes away, and each .space inserts the correct 7 bytes.
The wrong "error: invalid number of bytes" comes from a check if (Size < 0) in llvm/lib/MC/MCAssembler.cpp. I modified LLVM 19 to print the Size in each check. For this test case, I got
- exam.s:19 if 7 < 0
- exam.s:38 if -15 < 0, error
- exam.s:27 if 7 < 0
- exam.s:19 if 7 < 0
- exam.s:27 if 7 < 0
- exam.s:38 if 7 < 0
It visited the check if (Size < 0) twice for each .space line. The 1st visit to line 38 got the wrong size -15 and gave the error, though the 2nd visit got the correct size 7. The 1st visits with line 38 before 27 are in the wrong order; you can't calculate the size at line 38 unless you know the size at line 27. After I changed the 1st jmp 0b to incl %eax, it visited 27 before 38.