[llvm] r211500 - Stop producing func.eh symbols on Darwin.

Nick Kledzik kledzik at apple.com
Fri Jul 18 16:29:11 PDT 2014


I’ve been looking at __eh_frame processing today for lld so this is fresh in my mind.

Some background
------------------------
For MacOSX 10.6, we (Apple) rolled out “compact unwind  info” as a way to reduce the size and runtime cost of C++ exceptions.  But because the transition of gcc->llvmgcc->clang was in progress, we did not get compiler support for this.  Instead the linker interpreted any dwarf unwind info it saw and if it seemed safe, converted that to compact unwind.  

Now that Apple uses just clang which can generate compact unwind, we want to get the linker out of the business of interpreting dwarf unwind info.  But if the linker just stopped doing the conversion, existing .o files (i.e. in archives) would regress.  So, instead the linker checks if the compact unwind section exists (__LD,__compact_unwind).  If not, it is an old .o file and the linker should convert any dwarf unwind info.  If the linker sees both compact unwind and dwarf unwind for a function, it picks the compact unwind and discards the dwarf. 

The linker can parse the __eh_frame section because it is a well known format.  The linker does not need any labels in the section because the size of each CFI chunk is encoded in the chunk header.  The linker does not need relocations because it can interpret the bytes in each CFI that “point” to the CFI or function. How the linker does this is if the __eh_frame section has no relocations, it just parses the section as-is.  If there are relocations, it makes a copy of the section and has a special case piece of code to “apply” the relocations to the copy, then parses that.

Current problem
----------------------
The issue Steven is looking at is that various optimizations have been added to LLVM to remove the .eh labels and remove the relocations.  But the current state is busted for x86_64 when -mmacosx-version-min=10.5 (or earlier).  The .eh labels are gone (good), but the relocations are still used.  But because the labels are gone, the usual SUBSTRACTOR/UNSIGNED external relocation pair cannot be used.  The relocations that are used is a combination that the mini dwarf interpreter in ld64 cannot handle.

I suspect that the code in LLVM which suppressed the relocations on the __eh_frame section is disabled for older OS (when there might be an older linker).  That same check should be done for the removal of the .eh labels.  In other words:

for 10.5 and earlier:  Have .eh labels and relocations on __eh_frame
for 10.6 and later:  Have no .eh labels and no relocations on __eh_frame

-Nick

On Jul 17, 2014, at 2:23 PM, Steven Wu <stevenwu at apple.com> wrote:
> Hi Rafael
> 
> I don’t know if you are expecting this, but this commit breaks the old x86_64 OS X systems (10.5 and below) which need __eh_frame. It will failed to compile any programs for old OS X (with “-mmacosx-version-min” flag). I attached two simple test cases which give slightly different error messages:
> 
> $ clang -arch x86_64 -Os -mmacosx-version-min=10.4 test_case.c -o test.o
> ld: sectionForAddress(0xFFFFFFFFFF91969F) address not in any section file '/var/folders/cg/pyj86ks15y74w3hkwhm_zltm0000gp/T/test_case-cd1eb6.o' for architecture x86_64
> clang-3.5: error: linker command failed with exit code 1 (use -v to see invocation)
> $ clang -arch x86_64 -Os -mmacosx-version-min=10.4 test_case2.c -o test
> ld: symbol index out of range file '/var/folders/cg/pyj86ks15y74w3hkwhm_zltm0000gp/T/test_case2-9a07c6.o' for architecture x86_64
> clang-3.5: error: linker command failed with exit code 1 (use -v to see invocation)
> 
> The reason of the failure is that the OS X linker cannot recognize the generated relocations in __eh_frame. The current clang will create relocation section looks like:
> Relocation information (__TEXT,__eh_frame) 4 entries
> address  pcrel length extern type    scattered symbolnum/value
> 00000048 False quad   False  SUB     False     2 (__TEXT,__eh_frame)
> 00000048 False quad   True   UNSIGND False     _main
> 00000020 False quad   False  SUB     False     2 (__TEXT,__eh_frame)
> 00000020 False quad   True   UNSIGND False     _foo
> But the linker is expecting either a pair of SUB/UNSIGNED relocations in eh_frame (for old systems) or no relocations (for new systems). A fix might just be remove all the relocations in eh_frame. I CCed Nick in this thread, so Nick correct me if I am wrong.
> 
> Thanks
> 
> Steven
> 
> <test_case.c>
> <test_case2.c>
> 
>> Author: rafael
>> Date: Mon Jun 23 10:13:23 2014
>> New Revision: 211500
>> 
>> URL: http://llvm.org/viewvc/llvm-project?rev=211500&view=rev
>> Log:
>> Stop producing func.eh symbols on Darwin.
>> 
>> According Nick Kledzik (http://llvm.org/bugs/show_bug.cgi?id=19430#c2):
>> "... mach-o no longer needs names in the __eh_frame section (and has not for
>> years)."
>> 
>> Iain Sandoe confirms it is also unnecessary for their old darwin support.
>> 
>> Removed:
>>     llvm/trunk/test/MC/MachO/eh-symbols.s
>> Modified:
>>     llvm/trunk/include/llvm/MC/MCObjectFileInfo.h
>>     llvm/trunk/lib/MC/MCDwarf.cpp
>>     llvm/trunk/lib/MC/MCObjectFileInfo.cpp
>>     llvm/trunk/test/MC/MachO/eh-frame-reloc.s
>> 
>> Modified: llvm/trunk/include/llvm/MC/MCObjectFileInfo.h
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140718/3abee361/attachment.html>


More information about the llvm-commits mailing list