tinycc-devel
[Top][All Lists]
Advanced

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

Re: [Tinycc-devel] Failed compilation on armel: bug?


From: Thomas Preud'homme
Subject: Re: [Tinycc-devel] Failed compilation on armel: bug?
Date: Sun, 8 May 2011 23:21:49 +0200
User-agent: KMail/1.13.5 (Linux/2.6.38-2-amd64; KDE/4.4.5; x86_64; ; )

Le mardi 11 mai 2010 02:20:15, Daniel Glöckner a écrit :
> On Mon, May 10, 2010 at 01:13:33AM +0200, Thomas Preud'homme wrote:
> > tcc tests fails to run on armel debian build daemon and it doesn't seems
> > like a debian specific issue as I got a "can't relocate at value x"
> > message. See
> > https://buildd.debian.org/fetch.cgi?pkg=tcc&arch=armel&ver=0.9.25-3&stam
> > p=1273440303&file=log for more details.
> 
> There appear to be several issues with linking the debian libraries.
> One of them is the lack of support for R_ARM_V4BX relocations in tinycc.
> I'll probably have some more time to look deeper into this at the end of
> the week.
> 
>   Daniel

Hi Daniel,

I looked into this problem again recently and realize the problem seems quite 
obvious (or maybe not, in which case please correct me). The error happen 
because there is a relative call whose offset cannot be encoded in 24 bits (as 
are relative call on arm). The symbol which fails to be relocated in dlopen 
(or maybe dlsym, I already forgot). At first I thought: "How can dlopen be 
relocated by tinycc and not by ld.so?" and then realized it's normal since 
it's the ./tcc -run tcc.c -run tcc.c -run tcc.c test case. I guess in one of 
the stage the glibc is mapped to far from the code and hence a relative call 
can't be done.

But now here's what puzzle me. The code which generate relative call with 
relocation in arm-gen.c contains this:

    x=encbranch(ind,ind+vtop->c.ul,0);
    if(x) {
      if (vtop->r & VT_SYM) {
        /* relocation case */
        greloc(cur_text_section, vtop->sym, ind, R_ARM_PC24);
      } else
        put_elf_reloc(symtab_section, cur_text_section, ind, R_ARM_PC24, 0);
      o(x|(is_jmp?0xE0000000:0xE1000000));
    } else {
      if(!is_jmp)
        o(0xE28FE004); // add lr,pc,#4
      o(0xE51FF004);   // ldr pc,[pc,#-4]
      if (vtop->r & VT_SYM)
        greloc(cur_text_section, vtop->sym, ind, R_ARM_ABS32);
      o(vtop->c.ul);
    }

If I read it correctly, it first look if the distance from the current pc to 
the symbol is not to big and if not, it uses a R_ARM_PC24 relocation. If the 
offset is too big, it uses a R_ARM_ABS32.

The thing here is that we are talking about relocation so we don't know the 
address of the symbol at this stage. Maybe after relocation it will turn out 
the symbol is too far and right now there is no fallback. As ARM is a RISC 
architecture, I guess an absolute call instruction takes the same place as a 
relative call. Hence, if the relocation fail the relative call could be 
replaced by an absolute call.

Another and more immediate solution would be to just always use R_ARM_ABS32 
relocation. The execution would be a bit slower but the compilation and the 
code simpler (no need for a if here).

So, what do you thing about that?

Best regards,

Thomas Preud'homme



reply via email to

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