Re: [kvm-unit-tests PATCH v2 10/10] travis.yml: Add x86 build with clang 10

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Sep 14, 2020 at 06:37:33PM +0200, Thomas Huth wrote:
> On 14/09/2020 16.45, Roman Bolshakov wrote:
> > The difference is only realmode test which doesn't work if built by
> > clang.
> 
> Hmm, if you got some spare minutes, could you check if it works when
> replacing the asm() statements there with asm volatile() ?
> (Otherwise I'll check it if I got some spare time again ... so likely
> not this week ;-))
> 

Hi Thomas,

Sure. There are only two places where volatile is missed (inside functions) and
would make sense to add it. Unfortunately it doesn't help much:

diff --git a/x86/realmode.c b/x86/realmode.c
index 7c2d776..30691bc 100644
--- a/x86/realmode.c
+++ b/x86/realmode.c
@@ -271,7 +271,7 @@ static void report(const char *name, u16 regs_ignore, _Bool ok)
 }

 #define MK_INSN(name, str)                             \
-    asm (                                              \
+    asm volatile (                                             \
         ".pushsection .data.insn  \n\t"                \
         "insn_" #name ": \n\t"                         \
         ".word 1001f, 1002f - 1001f \n\t"              \
@@ -1448,7 +1448,7 @@ static void test_cpuid(void)

     eax = inregs.eax;
     ecx = inregs.ecx;
-    asm("cpuid" : "+a"(eax), "=b"(ebx), "+c"(ecx), "=d"(edx));
+    asm volatile("cpuid" : "+a"(eax), "=b"(ebx), "+c"(ecx), "=d"(edx));
     exec_in_big_real_mode(&insn_cpuid);
     report("cpuid", R_AX|R_BX|R_CX|R_DX,
           outregs.eax == eax && outregs.ebx == ebx




So, I looked further and noticed that multiboot header is missed in the flat
binary:
        ".section .init \n\t"

        ".code32 \n\t"

        "mb_magic = 0x1BADB002 \n\t"
        "mb_flags = 0x0 \n\t"

        "# multiboot header \n\t"
        ".long mb_magic, mb_flags, 0 - (mb_magic + mb_flags) \n\t"


But I can see it in the object file. So, I believe linker didn't place .init
section at 0x1000 despite realmode.lds instruction:

SECTIONS
{
    . = 16K;
    stext = .;
    .text : { *(.init) *(.text) }
    . = ALIGN(4K);
    .data : { *(.data) *(.rodata*) }
    . = ALIGN(16);
    .bss : { *(.bss) }
    edata = .;
}
ENTRY(start)


If I read it correctly, given the segment in realmode.elf:
Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x001000 0x00004000 0x00004000 0x03c90 0x03c90 R E 0x1000

Here's multiboot header in GCC-compiled binary:
00001000: 02b0ad1b 00000000 fe4f52e4 66b83412  .........OR.f.4.

Here's the same location in clang-compiled binary:
00001000: 04000000 14000000 03000000 474e5500  ............GNU.

Here's verbose invocation of linker by clang:

$ clang-10 -v -m32 -nostdlib -o x86/realmode.elf -Wl,-m,elf_i386 -Wl,-T,/home/roolebo
/dev/kvm-unit-tests/x86/realmode.lds x86/realmode.o
clang version 10.0.0-4ubuntu1
Target: i386-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/9
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/9
 "/usr/bin/ld" -z relro --hash-style=gnu --build-id --eh-frame-hdr -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o x86/realmode.elf -L/lib/../lib32 -L/usr/lib/../lib32 -L/usr/lib/llvm-10/bin/../lib -L/lib -L/usr/lib -m elf_i386 -T /home/roolebo/dev/kvm-unit-tests/x86/realmode.lds x86/realmode.o

(BTW, I'm surprised to see -dynamic-linker being set, it has little sense for
the tests but that's likely because -static is not passed explicitly)

And if I pass --print-map option to the linker I can see that GNU build id is
placed at 0x4000:

$ clang-10 -m32 -nostdlib -o x86/realmode.elf -Wl,-M -Wl,-m,elf_i386 -Wl,-T,/home/roo
lebo/dev/kvm-unit-tests/x86/realmode.lds x86/realmode.o

Discarded input sections

 .llvm_addrsig  0x0000000000000000      0x122 x86/realmode.o

Memory Configuration

Name             Origin             Length             Attributes
*default*        0x0000000000000000 0xffffffffffffffff

Linker script and memory map

                0x0000000000004000                . = 0x4000
                0x0000000000004000                stext = .

.note.gnu.build-id
                0x0000000000004000       0x24
 .note.gnu.build-id
                0x0000000000004000       0x24 x86/realmode.o

.text           0x0000000000004030     0x290c
 *(.init)
 .init          0x0000000000004030        0xc x86/realmode.o
 *(.text)
 *fill*         0x000000000000403c        0x4
 .text          0x0000000000004040     0x28fc x86/realmode.o
                0x000000000000404c                start
                0x00000000000040a0                realmode_start

.text.insn      0x000000000000693c      0x40e
 .text.insn     0x000000000000693c      0x40e x86/realmode.o

.iplt           0x0000000000006d4a        0x0
 .iplt          0x0000000000006d4a        0x0 x86/realmode.o

.rel.dyn        0x0000000000006d4c        0x0
 .rel.got       0x0000000000006d4c        0x0 x86/realmode.o
 .rel.iplt      0x0000000000006d4c        0x0 x86/realmode.o
                0x0000000000007000                . = ALIGN (0x1000)

.data           0x0000000000007000     0x2538
 *(.data)
 .data          0x0000000000007000     0x1064 x86/realmode.o
                0x0000000000008000                r_gdt
                0x0000000000008018                r_gdt_descr
                0x000000000000801e                r_idt_descr
 *(.rodata*)
 .rodata.str1.1
                0x0000000000008064      0x4d3 x86/realmode.o
                                        0x4f9 (size before relaxing)
 *fill*         0x0000000000008537        0x1
 .rodata        0x0000000000008538     0x1000 x86/realmode.o

.data.insn      0x0000000000009538      0x21c
 .data.insn     0x0000000000009538      0x21c x86/realmode.o

.got            0x0000000000009754        0x0
 .got           0x0000000000009754        0x0 x86/realmode.o

.got.plt        0x0000000000009754        0x0
 .got.plt       0x0000000000009754        0x0 x86/realmode.o

.igot.plt       0x0000000000009754        0x0
 .igot.plt      0x0000000000009754        0x0 x86/realmode.o
                0x0000000000009760                . = ALIGN (0x10)

.bss            0x0000000000009760      0x284
 *(.bss)
 .bss           0x0000000000009760      0x284 x86/realmode.o
                0x0000000000009764                tmp_stack
                0x00000000000099e4                edata = .
LOAD x86/realmode.o
OUTPUT(x86/realmode.elf elf32-i386)

.debug_str      0x0000000000000000      0x509
 .debug_str     0x0000000000000000      0x509 x86/realmode.o
                                        0x59f (size before relaxing)

.debug_loc      0x0000000000000000      0x484
 .debug_loc     0x0000000000000000      0x484 x86/realmode.o

.debug_abbrev   0x0000000000000000      0x212
 .debug_abbrev  0x0000000000000000      0x212 x86/realmode.o

.debug_info     0x0000000000000000     0x1935
 .debug_info    0x0000000000000000     0x1935 x86/realmode.o

.comment        0x0000000000000000       0x1f
 .comment       0x0000000000000000       0x1f x86/realmode.o
                                         0x20 (size before relaxing)

.note.GNU-stack
                0x0000000000000000        0x0
 .note.GNU-stack
                0x0000000000000000        0x0 x86/realmode.o

.debug_frame    0x0000000000000000      0x824
 .debug_frame   0x0000000000000000      0x824 x86/realmode.o

.debug_line     0x0000000000000000      0xc06
 .debug_line    0x0000000000000000      0xc06 x86/realmode.o


So, a workaround for that could be adding '-Wl,--build-id=none' to the
makefile rule for realmode.elf. Then multiboot magic is placed properly
at 0x4000 instead of 0x4030. Unfortunately it doesn't help with the
test :-)

-Roman



[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux