tinycc-devel
[Top][All Lists]
Advanced

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

Re: [Tinycc-devel] Feature request: _Thread_local (and a possible bug)


From: Robert Clausecker
Subject: Re: [Tinycc-devel] Feature request: _Thread_local (and a possible bug)
Date: Mon, 23 Sep 2013 16:22:09 +0200

Hello Thomas,

Thank you for your answer.

Am Montag, den 23.09.2013, 13:02 +0200 schrieb Thomas Preud'homme:
> Le mercredi 21 août 2013 19:41:40 Robert Clausecker a écrit :
> > Dear tcc hackers,
> > 
> > It would be very nice if tcc could implement the _Thread_local (aka
> > __thread) storage class specified. This would make it much easier for me
> > to compile my C code with tcc as it is one of the few parts of C11 I am
> > actually relying on, the others being easily replaceable by supported
> > constructs.
> 
> I have the beginning of a patch. It's not yet ok for merging but it support 
> thread-local storage for uninitialized variable (those that end up in tbss) 
> while compiling. What's missing is to be able to support both initialized and 
> uninitialized thread-local data and to support linking (put tbss and tdata in 
> a separate section). I'll keep you updated if I progress on the patch but if 
> you want to give it a try yourself I can hand you over what I did so far 
> (it's 
> rather small in term of code and I suspect that you could do it in 5-10 
> minutes if you are familiar with tcc's codebase)

Sadly, I am not quite familiar with the codebase of tcc. Maybe this is a
good opportunity to do so.
 
> > Have a nice day,
> > 
> > Yours Robert Clausecker
> > PS: It seems like there is a bug in the x86-64 edition of tcc. If I
> > assemble the following assembly file:
> > 
> >     foo: mov 0,%eax
> > 
> > I get the following machine code:
> > 
> >     a1 00 00 00 00
> > 
> > Which objdump(1) and Agner Fog's objcopy(1) detect as invalid.
> 
> Try compiling the same instruction with gcc -c -m32 and you'll see that 
> objdump is not confused in this case. Since that encoding is valid in 64 bit 
> mode, objdump should accept it as well when compiling for 64 bit mode.
> 
> > For the
> > same code, gas(1) generates the following assembly:
> > 
> >     8b 04 25 00 00 00 00
> 
> This is what gcc generates for mov 0, %eax in 32 bit mode which is a mov from 
> memory to al, ax or eax. In 64 bit mode, gcc choose to use a more generic 32 
> bit mode mov from memory to register.
> 
> > 
> > Assembling the following assembly file
> > 
> >     foo: .byte 0xa1
> >          .zero 8
> > 
> > Generates the following output under objdump(1):
> > 
> >     a1 00 00 00 00 00 00 00 00  movabs 0x0,%eax
> > 
> > TL;DR I suspect tcc's assembler for amd64 is broken here. I am
> > compiling / assembling with tcc version 0.9.26.
> 
> As written above, that code is valid and tcc is thus not broken. However, I 
> tried a mov 0, %rax because in x86_64-asm.h that mov instruction is described 
> as supporting byte, word, long and quadword mov. I'm also surprised that the 
> token for that instruction is movb but since it's just a name, it doesn't 
> matter much how it is called I guess.


The bug / misinterpretation of tcc in this case, which I did not fully
understood when I wrote this message, is that the A1 opcode [1] loads
from an absolute address, which has a size of eight bytes in long mode.
Therefore, the correct assembly of mov 0x0,%eax is either

    a1 00 00 00 00 00 00 00 00

which is decoded as "movabs" in gcc objdump or alternatively the
encoding

    8b 04 25 00 00 00 00

with an explicitly encoded register RAX and a SIB byte with no base
register and (explicit) offset zero.

I am pretty sure tcc is wrong here. For extra fun, try to run the
following assembly (as assembled by tcc) on an amd64 processor and
observe the memory address the processor tries to read from:

    a1 00 00 00 00 a1 00 00 00 90

If you are right, the code will attempt to read from address 0 and then
from address 0x90000000; the disassembly would be

    a1 00 00 00 00                mov 0x00000000,%eax
    a1 00 00 00 90                mov 0x90000000,%eax

If I am correct, the could would be dissassembled as

    a1 00 00 00 00 a1 00 00 00    mov 0xa100000000,%eax
    90                            nop

I am looking forwards to a fix for this. I could imagine that there are
more bugs like this.

Have a nice day, yours Robert Clausecker

[1]: http://ref.x86asm.net/coder64.html#xA1





reply via email to

[Prev in Thread] Current Thread [Next in Thread]