GCC 8.2.0

onre

Administrator
Staff member
Feb 8, 2019
58
18
8
So,

In last December I had some extra free time and merged back the support bits for IRIX from 4.7.4 and got together a somewhat working 8.2.0. It's on Github.

https://github.com/sgidevnet/gcc/ - the branch is called gcc-8_2_0-irix

It can produce C and C++ binaries at least.

What does not work?

  • any other version of binutils besides 2.17a
  • limits.h out of box
  • certain C++ constructors at least
  • DWARF2 debugging symbol generation
What would be nice?

  • test suite validation - there are tests that have no chance of succeeding on IRIX and/or our CPUs
  • limits.h fix
Discuss.
 
Last edited:
Reactions: foetz and racc

Deleted member 13

Guest
has it been tested with Ada-core?

p.s.
has anyone already tried to cross-compile source=IRIX/Gcc-ada target=Linux-MIPS-be/Gcc-ada?
it's something we (at DTB) need for a project we are working on
 

onre

Administrator
Staff member
Feb 8, 2019
58
18
8
Haven't tried Ada at all. There is a bunch of stuff that'd need to be put back in place for it to work even in theory.
 

Deleted member 13

Guest
gcc-v8.2 and 8.3 are experimental, especially on PowerPC, HPPA, MIPS, and RISC-V.
and on RISC-V there are a lot of extra patches.

Life is too complex X__X
 

hammy

Member
Jun 1, 2019
35
12
8
UK
Hey hey.

I've been giving this a spin (native on irix builds, using gcc 4.7.1 with bootstrap, wow it takes a while)
  • any other version of binutils besides 2.17a
I've had luck with ld from binutils 2.19 and other tools from binutils 2.32 (although this mix + matches dwarf versions, so debugging == broken).
  • limits.h out of box
If an issue with bad contents + you have a copy of the limits.h you think it should be creating - I can have a pop at adapting the fixincludes now I have a little experience there. If it's a problem with not created the file at all - this might be related to doing things via cross compilation - native builds create this file.
  • certain C++ constructors at least
The failures I see (I guess the same as you) in the C++ constructor tests seem actually to be an underlying problem with exception handling - in that throw / catch aren't working at all and cause abort()s to happen.

What I have been able to find out - If you build a C++98 only binary using gcc8 that tries to use exceptions - this will happily run against the gcc4 libraries - which to me indicates broken libstdc++ or libgcc handling of exceptions. I'm still trying to dig deeper.
  • DWARF2 debugging symbol generation
It would be nice to get latest binutils working - that might help in getting a consistent set of dwarf symbols, and maybe in getting further along with a GDB roughly equal to the GCC version.

Cheers + thanks again to the team for the work on this!

Dan
 

onre

Administrator
Staff member
Feb 8, 2019
58
18
8
Hey hey.

I've been giving this a spin (native on irix builds, using gcc 4.7.1 with bootstrap, wow it takes a while)
  • any other version of binutils besides 2.17a
I've had luck with ld from binutils 2.19 and other tools from binutils 2.32 (although this mix + matches dwarf versions, so debugging == broken).
I need to pick my brain a bit but IIRC the problem with newer binutils was mostly ending up with some sections in ELF files which IRIX rld didn't like at all.

Here we have a helloworld executable produced with 4.7.4 cross-compiler and 2.32 (I think) ld:


If you run this, it'll dump core. You can take a look at the executable with elfdump -h and what I think is causing breakage would be the ELF sections which don't get a proper type printed out, but a hexadecimal value instead. Names of those sections are .gnu.attributes and .MIPS.abiflags. This could be a red herring, though, but what I'm guessing here is that rld does not know what to do with these sections, and by the looks of it, ends up dumping core rather early on because it's simply not prepared to handle anything like this.

Or something else, possibly.

edit; if 2.17a is used, those sections do not appear and the executable works. I have a vague recollection that the gcc build process may actually probe target binutils versions and output something if the binutils are new enough. I have to check this once I get home.

  • limits.h out of box
If an issue with bad contents + you have a copy of the limits.h you think it should be creating - I can have a pop at adapting the fixincludes now I have a little experience there. If it's a problem with not created the file at all - this might be related to doing things via cross compilation - native builds create this file.
It gets fixed but with incorrect content. If you look at the limits.h generated by your 4.7.1 fixincludes and compare it with the one generated by the 8.2.0, you'll notice the difference.

  • certain C++ constructors at least
The failures I see (I guess the same as you) in the C++ constructor tests seem actually to be an underlying problem with exception handling - in that throw / catch aren't working at all and cause abort()s to happen.

What I have been able to find out - If you build a C++98 only binary using gcc8 that tries to use exceptions - this will happily run against the gcc4 libraries - which to me indicates broken libstdc++ or libgcc handling of exceptions. I'm still trying to dig deeper.
Help is more than appreciated especially in this particular area - my C++ is pretty much helloworld level.
  • DWARF2 debugging symbol generation
It would be nice to get latest binutils working - that might help in getting a consistent set of dwarf symbols, and maybe in getting further along with a GDB roughly equal to the GCC version.
Wouldn't hurt. I compiled myself a 6.8 because I thought that should work at least - and it did.
Cheers + thanks again to the team for the work on this!

Dan
Thanks for the compliments! It's really cool to have someone else poking at this stuff too.
 

onre

Administrator
Staff member
Feb 8, 2019
58
18
8
Disregard what I wrote about limits.h and fixincludes above.

The real problem is that the 8.2.0 limits.h is lacking an #include_next to include the system limits.h.
 

hammy

Member
Jun 1, 2019
35
12
8
UK
Disregard what I wrote about limits.h and fixincludes above.

The real problem is that the 8.2.0 limits.h is lacking an #include_next to include the system limits.h.
No probs, but I only see one additional section generated with 8.2.0.

For ref, here's what my 4.7.1 generated:


Here's what my 8.2.0 generated:


So I only see a section added with

"#ifdef __STDC_WANT_IEC_XXXXX and an appropriate #endif"

Maybe it is a cross compilation thing?

D
 

onre

Administrator
Staff member
Feb 8, 2019
58
18
8
Disregard what I told you to disregard. :D The file is generated by fixincludes.

And yeah, apparently it is a cross compilation thing. Here's what I ended up with:

 

hammy

Member
Jun 1, 2019
35
12
8
UK
Hehe :)

It's not from running a non-bootstrap build either - I just double checked the non-bootstrap 8.2.0 build I have and it's got the include_next too. (I have a "full" 8.2.0 bootstrap from 4.7.1 I use as the compiler for a quicker "non-bootstrap" 8.2.0 I can make changes/tests with).

ergo -> definitely cross compilation issue
 

onre

Administrator
Staff member
Feb 8, 2019
58
18
8
I need to pick my brain a bit but IIRC the problem with newer binutils was mostly ending up with some sections in ELF files which IRIX rld didn't like at all.

Here we have a helloworld executable produced with 4.7.4 cross-compiler and 2.32 (I think) ld:


If you run this, it'll dump core. You can take a look at the executable with elfdump -h and what I think is causing breakage would be the ELF sections which don't get a proper type printed out, but a hexadecimal value instead. Names of those sections are .gnu.attributes and .MIPS.abiflags. This could be a red herring, though, but what I'm guessing here is that rld does not know what to do with these sections, and by the looks of it, ends up dumping core rather early on because it's simply not prepared to handle anything like this.

Or something else, possibly.

edit; if 2.17a is used, those sections do not appear and the executable works. I have a vague recollection that the gcc build process may actually probe target binutils versions and output something if the binutils are new enough. I have to check this once I get home.
There's more to it. Using objcopy to remove the sections does not fix the executable.
 

hammy

Member
Jun 1, 2019
35
12
8
UK
There's more to it. Using objcopy to remove the sections does not fix the executable.
I see the same behaviour. For reference - it seems it's not the object files themselves - I can happily compile programs that work using binutils 2.32 - as long as the LD is from 2.19.

I did some git bisecting back in time and found the breaking commit in binutils that stops binaries working:

  • There was a commit 19 Sep 2010 that did some re-work of the BFD mips handling - First breaking commit
  • The previous commit where I still see success in building gcc using gas/gld - is here
  • The first bad change looks like modifications in the way that the global offset table is filled, lots of mentions of VxWorks, but presumably no-one tested or gave feedback to the maintainers about this breaking things on SGIs
Soo, long story short, I think the issue is the rewrites/relocations of objects within the GOT that seems to be the source of the incompatibilities. Presumably this all works fine on Linux mips.

I briefly tried using RLD_DEBUG with appropriate flags etc but didn't get anywhere useful at the time. For now I've put the binutils stuff on the back burner - would be nice to have a more recent gcc and gdb. One other possible avenue of investigation might be to try and track down source code for the BSD rld flavour that irix uses (probably fruitless).
 

hammy

Member
Jun 1, 2019
35
12
8
UK
Some notes on the C++ exception issues I see.

Scenario:

I build a simple C++98 only application with a try/catch:

Code:
#include <iostream>
#include <ostream>

#include <memory>

#include <math.h>

#include <limits.h>
#include <internal/limits_core.h>

class excobj
{
public:
  const char * msg;
  excobj( const char * msg_)
    : msg(msg_)
  {
    std::cout << "excobj cons" << std::endl;
  }
};

int main(int argc, char** argv)
{
  std::cout << "main begin" << std::endl;
  {
    try
      {
    int a = 10;
    throw excobj("test2");
      }
    catch( const excobj & e )
      {
    std::cout << "Caught it! - " << e.msg << std::endl;
      }
  }
  std::cout << "main end" << std::endl;
}
Build with gcc4 using "g++ --std=c++98 -g3 -O0 exceptiontest.cc -o exceptiontest" kind of thing.

By setting LD_LIBRARYN32_PATH to pick up libstdc++.so.6 and libgcc_s.so.1 from the directory where I've built gcc4 or gcc8 I can see

(a) The binary works fine on gcc4
(b) With gcc8 libs this is a segmentation fault

The basic process for exception processing is - "throw exception" causes a call to __cxa_throw, which in turn calls "unwind" - which is using the unwind_* code from libgcc. This stuff looks in the dwarf info of the binary to match up stack frames and look for handlers it needs to call as the stack unwinds. Once all the unwinding / frame handling is done, there is a call to __cxa_begin_catch - which jumps back into "user" code at the start of the catch block (in this case).

The current difference I see between gcc4 and gcc8 is that at the end of the lookup phases of the stack unwinding - the "invoke" of the calls to actually unwind and call handlers is where it's failing. With gcc8 libs it's not getting as far as the __cxa_begin call - but failing in the "invoke" of a stack unwind handler.

I'm feeling a little in over my head with this at the moment, but I'll keep at it.
 
Last edited:

onre

Administrator
Staff member
Feb 8, 2019
58
18
8
Interesting. I think I get from your description how it's supposed to work. Any suggestions on what I should work on? Getting proper dwarf symbols everywhere would be nice at least, making debugging easier.
 

hammy

Member
Jun 1, 2019
35
12
8
UK
Only a suggestion - for dwarf symbols - if you've got the patience for it - having another set of eyes looking into getting recent binutils "ld" working that'd be super useful as it's possible the older binutils version won't ever support newer dwarf sections + layouts.

I was trying 2.32 (compiled with gcc). Patch I applied is here: https://raw.githubusercontent.com/danielhams/didbs/master/packages/gbstest-binutils/binutils2_32.didbsfixes.patch

Ignore the tweaks to "gold" - I was just curious to see how far I could that linker (not very is the answer).

The approach I am intending to use for looking into it:

(1) Create the smallest valid linkable with mipspro (might be useful to just use assembly to get it really small)

(2) Link this "smallest linkable" using irix ld, binutils-217-ld, binutils-232-ld, work out whats different and whats wrong with 2.32

From what I remember its the stuff doing the GOT relocations in bfd/elfxx-mips.* where the major changes since 2.17 happened. There might be issues with unknown/unexpected sections like you mention too. The "readelf" tool in 2.32 should be useful here.

For info like I mentioned, the other utilities in 2.32 seem to work ok (and pass the self-tests too) - like gas, libiberty.
 

onre

Administrator
Staff member
Feb 8, 2019
58
18
8
I'll try to take a look later today. I'm supposed to have multiple boring meetings in a row.
 

hammy

Member
Jun 1, 2019
35
12
8
UK
For reference, I created a little test project with examples built with various pieces here:


And there is a BUG created @ the binutils side here:


There isn't much hope for the bug unfortunately, but maybe we get lucky and someone helps pointing us in the right direction.
 

onre

Administrator
Staff member
Feb 8, 2019
58
18
8
Turns out C++ exception issue is caused by the gcc build process not honoring --with-dwarf2 flag and the stack unwinder relying on DWARF2 symbols. The way gcc 8.2.0 ends up being built is such that -g produces DWARF4 and -gdwarf-2 produces DWARF2. Everything outside gcc subdir is built with -g -O2 by default.

This can be fixed manually by editing the Makefiles in libstdc++ build dir after configuration so that -g is replaced with -gdwarf-2. One can examine the resulting libraries with readelf --debug-dump=info to check that all debugging sections are DWARF2.
 

onre

Administrator
Staff member
Feb 8, 2019
58
18
8
So, I had a bit of a mishap with my build scripts and am no longer exactly sure about what causes what. Apparently using the setjmp/longjmp unwinder works after my DWARF2 fix, but the DWARF2 unwinder still doesn't. Oh well, at least it's debuggable with gdb and dbx now.
 
Reactions: Elf