http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48096
--- Comment #6 from Jack Howarth <howarth at nitro dot med.uc.edu> 2011-03-17 23:41:29 UTC --- The darwin linker developer says... ---------------------------------------------------------------------------- The issue is in the __eh_frame, the reloc for second FDE's pointer to its function (__cold_sect_of_foo) is bad: otool -rv bb-reorg.o Relocation information (__TEXT,__eh_frame) 6 entries address pcrel length extern type scattered symbolnum/value 00000060 False quad True SUB False EH_frame1 00000060 False quad True UNSIGND False _main 00000040 False quad True SUB False EH_frame1 00000040 False quad False UNSIGND False 2 (__TEXT,__text_cold) 00000020 False quad True SUB False EH_frame1 00000020 False quad True UNSIGND False _foo The local relocation at 0x40 should be an external relocation just like it is for _foo and _main. The pair of relocs SUB/UNSIGNED need to point to non-local labels. What does the assembly look like in the FDE? Is it different that in the FDE for main and foo? ------------------------------------------------------------------------------ I see you added the .s file too. It currently starts with: .section __TEXT,__text_cold LCOLDB0: .text ... .section __TEXT,__text_cold __cold_sect_of_foo: If I move the LCOLDB0 label down to be right after the __cold_sect_of_foo label, then it compiles and links fine. I think this is an assembler bug, but the compiler work around should be easy enough: Either use the real label name (e.g. __cold_sect_of_foo) in the FDE, or but L label that is supposed to be equivalent to it after the real label.