Bug 22724 - gold: --gc-sections needs to preserve DWARF personality functions
Summary: gold: --gc-sections needs to preserve DWARF personality functions
Status: UNCONFIRMED
Alias: None
Product: binutils
Classification: Unclassified
Component: gold (show other bugs)
Version: 2.29
: P2 normal
Target Milestone: ---
Assignee: Cary Coutant
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-01-17 18:08 UTC by Benjamin Peterson
Modified: 2018-01-17 18:08 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Benjamin Peterson 2018-01-17 18:08:06 UTC
This is a bit odious to reproduce because C compilers don't easily let you pick a custom personality. I need two files, tramp.s and main.cc:

===== tramp.s
	.text
	.global call_it
call_it:
    .cfi_startproc
    .cfi_personality 0x1b,nop_pers
    pushq	%rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq	%rsp, %rbp
    call	do_unwind
    nop
    popq	%rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc

===== main.cc
#include <iostream>
#include <unwind.h>

extern "C" void do_unwind(void) {
  throw new std::exception();
}

extern "C" __attribute__((visibility("hidden"))) _Unwind_Reason_Code nop_pers(
    int version,
    _Unwind_Action actions,
    _Unwind_Exception_Class exception_class,
    struct _Unwind_Exception *ue_header,
    struct _Unwind_Context *context) {
  std::cout << "running personality\n";
  return _URC_CONTINUE_UNWIND;
}

extern "C" void call_it(void);

int main() {
  try {
    call_it();
  } catch (...) {
    std::cout << "caught exception!\n";
    return 0;
  }
  std::cerr << "failed\n";
  return 1;
}

Now, notice the difference between GNU ld and gold:

$ g++ -ffunction-sections -O2  tramp.s main.cc -o repro  -Wl,--gc-sections
$ ./repro
running personality
running personality
caught exception!
$ g++ -ffunction-sections -O2  tramp.s main.cc -o repro  -Wl,--gc-sections -fuse-ld=gold
$ ./repro
Segmentation fault (core dumped)

--print-gc-sections reveals this is because the nop_pers function is being deleted by gold.

gold will preserve any section containing "personality" in the name. But I don't believe including "personality" in the name of a personality function is any more than a convention. For example, luajit defines a personality routine named lj_err_unwind_dwarf.