March 01, 2014
On Saturday, 1 March 2014 at 10:49:57 UTC, Johannes Pfau wrote:
> On Saturday, 1 March 2014 at 09:24:40 UTC, Mike wrote:
>> On Saturday, 1 March 2014 at 08:56:26 UTC, Timo Sintonen wrote:
>>> There is nothing interesting in the assembly, only this wrong
>>> call.
>>> This form of instruction is just missing in M4 and it gives an
>>> invalid instruction fault. So what are we arguing about?
>>>
>>> If this is so hard for us to find, no wonder the compiler writers
>>> have not noticed this.
>>
>> Well, I yield then to the compiler folks.  Hopefully Iain or
>> Johannes can provide some insight.
>
> AFAIK the call to _Unwind_RaiseException [1] is just a normal function call [2] to a extern(C) function in a different compilation unit. It's not even a builtin so it doesn't look like a gdc bug. GCC bug is more likely but I wonder what exactly makes this case special? Why does this not happen for every function call to a extern(C) function?
>
> Please try the following:
> * Verify your --with-cpu, --with-arch, --with-tune flags for gcc configure. Also make sure that binutils is configured with the correct flags.
> * Have a look at the build log how gcc/deh.d is compiled. Use the same compile command, but generate assembly via -S. Then look at the asm code to check whether the compiler or the assembler/linker is to blame.
> * Try to reduce the example / understand why exactly this happens only in this case.
> * When you have a reduced example, try to port it to C and see if GCC handles it correctly.
>
>
> [1] https://github.com/D-Programming-GDC/GDC/blob/master/libphobos/libdruntime/gcc/deh.d#L151
> [2] https://github.com/D-Programming-GDC/GDC/blob/master/libphobos/libdruntime/gcc/unwind/arm.d#L191

I checked my code and the library code and there is no other call like this. I think there is one thing that makes this function special: if I understand correct, this function will not return. If there is some noreturn attribute somewhere this function might be handled in a different way.

Is it so that gdc does not generate any assembly directly? So this would be a bug in gcc side and I may report it there.

March 01, 2014
On Saturday, 1 March 2014 at 11:46:03 UTC, Timo Sintonen wrote:
>
> I checked my code and the library code and there is no other call like this. I think there is one thing that makes this function special: if I understand correct, this function will not return. If there is some noreturn attribute somewhere this function might be handled in a different way.
>
> Is it so that gdc does not generate any assembly directly? So this would be a bug in gcc side and I may report it there.

It's not marked as noreturn though, neither in C nor in the D code.
The function can return if there is some kind of error (http://refspecs.linuxfoundation.org/LSB_3.1.0/LSB-Core-S390/LSB-Core-S390/baselib--unwind-raiseexception.html)

Some google-fu shows that someone reported this bug here:

http://gcc.gnu.org/ml/gcc-help/2013-06/msg00091.html
https://sourceware.org/bugzilla/show_bug.cgi?id=15628


However, someone also had this problem on this german site:
http://www.mikrocontroller.net/topic/312956

and the solution was that -mcpu alone was not good enough, he had to specify -march flags as well so please double-check your flags.
It's possible that binutils doesn't work properly with -mcpu so I'd do this:

-march=armv7e-m -mcpu=cortex-m4 -mthumb -mtune=cortex-m4

Or better at configure time:

--with-arch=armv7e-m --with-cpu=cortex-m4 --with-mode=thumb --with-tune=cortex-m4


Oh, and if that works: Please add a comment tu the bintuils issue that specifying -march helps.
March 02, 2014
On Saturday, 1 March 2014 at 12:53:14 UTC, Johannes Pfau wrote:

>
> However, someone also had this problem on this german site:
> http://www.mikrocontroller.net/topic/312956
>
> and the solution was that -mcpu alone was not good enough, he had to specify -march flags as well so please double-check your flags.
> It's possible that binutils doesn't work properly with -mcpu so I'd do this:
>
> -march=armv7e-m -mcpu=cortex-m4 -mthumb -mtune=cortex-m4
>
> Or better at configure time:
>
> --with-arch=armv7e-m --with-cpu=cortex-m4 --with-mode=thumb --with-tune=cortex-m4
>
I read somewhere that -march is ignored when the more specific -mcpu is present. On the other hand, ld has no cpu option, only --architecture. That did not have any effect.

A little background: I have the main makefile and all definitions in toplevel directory. Libraries and projects are in subdirs. Any subdir makefile includes settings from topdir. In topdir I just give export projectdir=xxx and then run make. Any project in any language is run from the same makefile with the same settings. I use separate compiling and pass myself options to gcc, as and ld. A reduced version of this toolset is in the minlibd repo in tools directory.

I decided to rebuild all my apps and libs. Now I have lots of blx instructions in my code. So this is not related to exceptions. I just triggered this when playing with deh.d.

I have not been able to confirm this, but this may be something like when linking libraries that have unresolved symbols. If the symbol is already available, the call is bl, but if the symbol will be resolved from a later library, the call will be blx. Libgcc is always the last so any call to its functions will be blx.

When I compile my c only project, I will not get these calls. I have compared the object list files but I can not find any meaningful difference. Could it be possible that gdc generated asm files have some attribute/directive/segment name/whatever that changes the behavior in ld. Obviously there are more segments in d executable, like unwind and debug info. What is the thing that makes it different for ld?

March 02, 2014
Am Sun, 02 Mar 2014 11:20:53 +0000
schrieb "Timo Sintonen" <t.sintonen@luukku.com>:

> On Saturday, 1 March 2014 at 12:53:14 UTC, Johannes Pfau wrote:
> 
> >
> > However, someone also had this problem on this german site: http://www.mikrocontroller.net/topic/312956
> >
> > and the solution was that -mcpu alone was not good enough, he
> > had to specify -march flags as well so please double-check your
> > flags.
> > It's possible that binutils doesn't work properly with -mcpu so
> > I'd do this:
> >
> > -march=armv7e-m -mcpu=cortex-m4 -mthumb -mtune=cortex-m4
> >
> > Or better at configure time:
> >
> > --with-arch=armv7e-m --with-cpu=cortex-m4 --with-mode=thumb --with-tune=cortex-m4
> >
> I read somewhere that -march is ignored when the more specific -mcpu is present. On the other hand, ld has no cpu option, only --architecture. That did not have any effect.
> 
> A little background: I have the main makefile and all definitions in toplevel directory. Libraries and projects are in subdirs. Any subdir makefile includes settings from topdir. In topdir I just give export projectdir=xxx and then run make. Any project in any language is run from the same makefile with the same settings. I use separate compiling and pass myself options to gcc, as and ld. A reduced version of this toolset is in the minlibd repo in tools directory.

OK, but at least for the initial problem the question is how did you
build _libgcc_. I guess it was build as part of the normal
gcc ./configure & make & make install process. To make sure that libgcc
is built correctly for Cortex-M4 you have to specify
"--with-arch=armv7e-m --with-cpu=cortex-m4 --with-mode=thumb
--with-tune=" when configuring gcc/gdc.

(And I don't see these flags mentioned in https://bitbucket.org/timosi/minlibd/src/691c76aa2b543998bb573e6ce6d96951a80817bd/README.gdc?at=default)

> 
> I decided to rebuild all my apps and libs. Now I have lots of blx instructions in my code. So this is not related to exceptions. I just triggered this when playing with deh.d.
> 
> I have not been able to confirm this, but this may be something like when linking libraries that have unresolved symbols. If the symbol is already available, the call is bl, but if the symbol will be resolved from a later library, the call will be blx. Libgcc is always the last so any call to its functions will be blx.

Sounds strange, I don't think we could cause this in the gdc frontend.

I guess binutils generates blx if thumb code calls arm code or the
other way round. So I'd verify which libraries are really picked up by
ld (ld --verbose) then check if the entry points are in thumb or arm
mode:
http://stackoverflow.com/a/15931232

This sounds a lot as if calls to the same library/object file generate bl instructions as the code is in the same mode, but functions in external libraries are in a different mode and therefore generate blx.

> 
> When I compile my c only project, I will not get these calls. I have compared the object list files but I can not find any meaningful difference. Could it be possible that gdc generated asm files have some attribute/directive/segment name/whatever that changes the behavior in ld. Obviously there are more segments in d executable, like unwind and debug info. What is the thing that makes it different for ld?
> 

I'm not sure but I still don't think we could cause this. This low-level stuff is usually part of the backend, the frontend doesn't know much about thumb/arm.

Did you use the same gcc which was compiled with your gdc or did you
use a gcc from a different toolchain?
In either case I probably need a reduced test case, otherwise I'm just
guessing here ;-)
March 02, 2014
On Sunday, 2 March 2014 at 15:36:01 UTC, Johannes Pfau wrote:
> To make sure  that libgcc
> is built correctly for Cortex-M4 you have to specify
> "--with-arch=armv7e-m --with-cpu=cortex-m4 --with-mode=thumb
> --with-tune=" when configuring gcc/gdc.
>
> (And I don't see these flags mentioned in
> https://bitbucket.org/timosi/minlibd/src/691c76aa2b543998bb573e6ce6d96951a80817bd/README.gdc?at=default)
>
Gcc build fails with these. It will take time to check them one by one. Also enable/disable-multilib may affect to this.

Then I updated my host binutils and gcc to latest head and with these I compiled cross binutils and gcc/gdc from head. I used my current settings. Now my own code and minlibd do not have any blx instructions but libgcc has some.

> Sounds strange, I don't think we could cause this in the gdc frontend.
I am not saying it is a gdc bug. It may very well be a side effect of a flag that is related to maybe umwinding or relocation. I do have two kind of object files now in my executable and I just like to know what is the difference between them.

> I guess binutils generates blx if thumb code calls arm code or the
> other way round. So I'd verify which libraries are really picked up by
> ld (ld --verbose) then check if the entry points are in thumb or arm
> mode:
> http://stackoverflow.com/a/15931232
>
> This sounds a lot as if calls to the same library/object file generate
> bl instructions as the code is in the same mode, but functions in
> external libraries are in a different mode and therefore generate blx.
>
Yes, I think blx is for this. M4 does not have arm mode and there is no this instruction, so it should be a linker error if the user try to mix objects with different modes.
As I mentioned, I pass manually everything, including libgcc. Nothing is picked by default. The multilib thing should be just because of this. There are 4 variants of libgcc. If I pick the m4-fpu library it should be already compiled with the right flags. If it is not, I think that is a gcc bug.
How can I check from the library which modes/flags is has?

>
> I'm not sure but I still don't think we could cause this. This
> low-level stuff is usually part of the backend, the frontend doesn't
> know much about thumb/arm.
>
Yes, this is going a little off-topic now
March 07, 2014
Am Sun, 02 Mar 2014 18:33:00 +0000
schrieb "Timo Sintonen" <t.sintonen@luukku.com>:

> On Sunday, 2 March 2014 at 15:36:01 UTC, Johannes Pfau wrote:
> > To make sure  that libgcc
> > is built correctly for Cortex-M4 you have to specify
> > "--with-arch=armv7e-m --with-cpu=cortex-m4 --with-mode=thumb
> > --with-tune=" when configuring gcc/gdc.
> >
> > (And I don't see these flags mentioned in https://bitbucket.org/timosi/minlibd/src/691c76aa2b543998bb573e6ce6d96951a80817bd/README.gdc?at=default)
> >
> Gcc build fails with these. It will take time to check them one by one. Also enable/disable-multilib may affect to this.

Multilib is indeed special. AFAIK it's not possible to change multilib flags without changing some file in gcc (gcc/config/t-arm or something like that).

> I am not saying it is a gdc bug. It may very well be a side effect of a flag that is related to maybe umwinding or relocation. I do have two kind of object files now in my executable and I just like to know what is the difference between them.

I'd like to know the reason as well, but I think I really need a small
test case to continue looking into this. Could you upload your
toolchain binaries somewhere?

> >
> Yes, I think blx is for this. M4 does not have arm mode and there
> is no this instruction, so it should be a linker error if the
> user try to mix objects with different modes.
> As I mentioned, I pass manually everything, including libgcc.
> Nothing is picked by default. The multilib thing should be just
> because of this. There are 4 variants of libgcc. If I pick the
> m4-fpu library it should be already compiled with the right
> flags. If it is not, I think that is a gcc bug.
> How can I check from the library which modes/flags is has?
> 

You seem to be right that binutils doesn't have an architecture flag and therefore the linker can't even know you're targeting Cortex-M4.

http://infocenter.arm.com/help/topic/com.arm.doc.ihi0044e/IHI0044E_aaelf.pdf 4.5.3
----------
In addition to the normal rules for symbol values the following rules
shall also apply to symbols of type STT_FUNC :
If the symbol addresses a Thumb instruction, its value is the address of
the instruction with bit zero set (in a relocatable object, the section
offset with bit zero set)
----------

However, objdump is 'clever' and removes this bit m(

But with readelf:
readelf liba.o -s
8: 00000000    28 FUNC    GLOBAL DEFAULT    1 test

readelf libt.o -s 8: 00000001    18 FUNC    GLOBAL DEFAULT    1 test

In my simple tests ld does really only use blx for arm->thumb / thumb->arm calls. In all other cases it uses bl. And it's indeed the linker making this decision, the compiler always emits 'bl'. Would be great if you could confirm if it's a linker issue in your case as well.
March 08, 2014
On Friday, 7 March 2014 at 18:41:35 UTC, Johannes Pfau wrote:
>> > To make sure  that libgcc
>> > is built correctly for Cortex-M4 you have to specify
>> > "--with-arch=armv7e-m --with-cpu=cortex-m4 --with-mode=thumb
>> > --with-tune=" when configuring gcc/gdc.
>> >
>> Gcc build fails with these. It will take time to check them one by one. Also enable/disable-multilib may affect to this.

It seems that the gcc compilation fails with any of these. These flags do set the features of the compiler which in turn have effect to the libraries it builds. These do not set the libgcc build process and I get similar errors than Mike reported a while ago. The reason is that the build process still try to make arm mode libraries even when the compiler is thumb only.
>
> Multilib is indeed special. AFAIK it's not possible to change multilib
> flags without changing some file in gcc (gcc/config/t-arm or something
> like that).

It has been my plan to investigate the library build process this weekend

> I'd like to know the reason as well, but I think I really need a small
> test case to continue looking into this. Could you upload your
> toolchain binaries somewhere?

>
> You seem to be right that binutils doesn't have an architecture flag and
> therefore the linker can't even know you're targeting Cortex-M4.
>>
> In my simple tests ld does really only use blx for arm->thumb /
> thumb->arm calls. In all other cases it uses bl. And it's indeed the
> linker making this decision, the compiler always emits 'bl'. Would be
> great if you could confirm if it's a linker issue in your case as well.

I was getting different object files from the same sources with different versions of the compiler. I tried to find what was the difference between those files. An oo language naturally makes a little bit different object file than pure c. There was something that made ld think the files are different and needed the interworking call. I just could not find what was the flag or attribute or section that made ld to think so.
As I told, then I updated everything to latest head versions and I think I am now where I was before. I do not have the original binaries any more. Binutils 2-23 and gcc/gdc heads between mid of january to mid of february at least caused the problem. There still is some blx instructions but I think they have always been there. I just have not needed those functions before I started with exceptions.

The linking process seems to be controlled by those arm attributes. I did not know readelf can also read .o files. It lists attributes and all kind of info much better than objdump. Next I will investigate my files with this and try to find out how to affect to libgcc generation.
March 09, 2014
Now I got the exceptions to work.

I have not been able to find how to control the libgcc build process. The configure script seems not to know that I give different defaults for the compiler in --with switches. Configure still assumes the compiler defaults arm mode although it is in thumb mode. I should also be able to give different default values to all four libraries that are built.

I solved this by building with defaults and then hacked the makefile of that libgcc directory I use. (fpu) Then I remade the library. Changing LIBGCC_FLAGS at line 229 did the trick.

So exceptions seems to work now. There is one thing: because I do not have gc, the OurUnwindException struct that is allocated in _d_throw is never freed. This is an issue for anybody not using gc, so there should be a general solution.

The three problems in this project were:
- struct alignment issue that Iain has fixed
- a change/bug in gcc in january-february causing different object generation. Seems to be fixed in head now.
- building libgcc with the same settings than the rest of the application. I am  still looking a way to control the library build process.

March 09, 2014
On Sunday, 9 March 2014 at 07:57:46 UTC, Timo Sintonen wrote:
> Now I got the exceptions to work.
>

Nice Work!  Congratulations!

I read your wiki, but didn't see your source code yet (I assume its coming, yes?).  Anyway, thanks for sharing this information.

Mike

March 09, 2014
Am Sun, 09 Mar 2014 07:57:45 +0000
schrieb "Timo Sintonen" <t.sintonen@luukku.com>:

> Now I got the exceptions to work.
> 
> I have not been able to find how to control the libgcc build process. The configure script seems not to know that I give different defaults for the compiler in --with switches. Configure still assumes the compiler defaults arm mode although it is in thumb mode. I should also be able to give different default values to all four libraries that are built.
> 
> I solved this by building with defaults and then hacked the
> makefile of that libgcc directory I use. (fpu) Then I remade the
> library. Changing LIBGCC_FLAGS at line 229 did the trick.
> [...]
> 

Great!
The configure script doesn't really have to know about the "-with-*"
flags - these are used by default if you don't pass any arguments to
gcc/gdc.

However this can't work for your multilib setup. libgcc should really
build with the correct multilib flags, so that's strange. You can check
the used multilib flags with
gcc -print-multi-lib

You might have to edit
gcc/config/arm/t-arm-elf

You could check how the gcc-arm-embedded project modifies that file, IIRC they build special multilibs for cortex m3/m4 (the default gcc configuration only builds thumb/not-thumb*) https://launchpad.net/gcc-arm-embedded

http://airs.com/ian/configure/configure_8.html http://gcc.gnu.org/onlinedocs/gccint/Target-Fragment.html

* BTW: This can explain invalid instructions in libgcc: it's only build
 with -mthumb but not with -march in the default multilib
 configuration.
1 2 3
Next ›   Last »