Please look at the fragment of the hex dump of LLVM-created ELF showing the beginning and end of .eh_frame: .eh_frame begin 000297a0 14 00 00 00 00 00 00 00 01 7a 52 00 01 78 10 01 |.........zR..x..| 000297b0 1b 0c 07 08 90 01 00 00 18 00 00 00 1c 00 00 00 |................| <...skipped...> 0002cb00 00 00 00 00 0b 01 00 00 00 41 0e 10 86 02 43 0d |.........A....C.| 0002cb10 06 42 83 03 18 00 00 00 78 33 00 00 00 00 00 00 |.B......x3......| 0002cb20 ae 00 00 00 00 41 0e 10 86 02 43 0d 06 00 00 00 |.....A....C.....| .eh_frame end 0002cb30 00 2e 72 65 6c 61 2e 74 65 78 74 00 2e 72 6f 64 |..rela.text..rod| Corresponding to the end of .eh_frame part of output of command 'readelf -at -wf myelf.bin': 00003374 00000018 00003378 FDE cie=00000000 pc=00021520..000215ce DW_CFA_advance_loc: 1 to 00021521 DW_CFA_def_cfa_offset: 16 DW_CFA_offset: r6 at cfa-16 DW_CFA_advance_loc: 3 to 00021524 DW_CFA_def_cfa_reg: r6 DW_CFA_nop DW_CFA_nop DW_CFA_nop You can see that the last section of .eh_frame begins at 0x2cb14 in file, and has 4 (size value DWORD)+0x18(data)=0x1C bytes. There is the string table immediately after .eh_frame. The problem with this is that __register_frame function (in libgcc_s.so), registering .eh_frame with an exception handler, only takes the pointer to .eh_frame, and not the size of data, and should be able to detect the end of data by scanning it and hitting zero DWORD (size). There is no trailing zero, and it runs into the next section and tries to interpret it as an exception data too. There has to be DWORD zero placed right after the current .eh_frame, otherwise such ELF is invalid as it is. I am particularly looking at an old rev.134967, but I don't think this has been fixed in the current trunk. Somebody familiar with an ELF writer should add the proper trailing zero. Yuri
Rafael Espíndola
2013-Apr-30 18:53 UTC
[LLVMdev] LLVM creates unterminated ELF .eh_frame sections
> The problem with this is that __register_frame function (in libgcc_s.so), > registering .eh_frame with an exception handler, only takes the pointer to > .eh_frame, and not the size of data, and should be able to detect the end of > data by scanning it and hitting zero DWORD (size). There is no trailing > zero, and it runs into the next section and tries to interpret it as an > exception data too. > > There has to be DWORD zero placed right after the current .eh_frame, > otherwise such ELF is invalid as it is. > > I am particularly looking at an old rev.134967, but I don't think this has > been fixed in the current trunk. > > Somebody familiar with an ELF writer should add the proper trailing zero.Are you trying MCJIT? :-) The problem is here is that crtendS.o (which is normally added when the .o files are linked into the final executable) contains the 4 zero bytes that is missing. I first tried to compensate for that in MCJIT by adding those 4 bytes. That works for Linux, but not for OS X where __register_frame takes a single FDE at a time. I have an incomplete wip patch if you are interested.> YuriCheers, Rafael
On 04/30/2013 11:53, Rafael Espíndola wrote:> Are you trying MCJIT?:-)No.> > I first tried to compensate for that in MCJIT by adding those 4 bytes. > That works for Linux, but not for OS X where __register_frame takes a > single FDE at a time. I have an incomplete wip patch if you are > interested.On BSD __register_frame also takes a single argument and therefore needs terminating zero. I also have a simple patch for this: adding Streamer.EmitIntValue(0, 4); at the end of MCDwarfFrameEmitter::Emit in lib/MC/MCDwarf.cpp fixed the issue for me. Somebody needs to check this or similar in. Yuri