processInterproceduralReferences: record references to cold fragments as entry points

Summary:
For interprocedural references to fragments, record them as
fragment entry points. Not registering these entry points leads to
UCE removing the blocks and "Undefined temporary symbol"
assertion.

(cherry picked from FBD24511281)
This commit is contained in:
Amir Ayupov 2020-11-06 10:57:47 -08:00 committed by Maksim Panchenko
parent 5452287710
commit dc48354f71
3 changed files with 55 additions and 5 deletions

View File

@ -1049,12 +1049,10 @@ void BinaryContext::processInterproceduralReferences(BinaryFunction &Function) {
continue;
if (TargetFunction) {
if (TargetFunction->IsFragment) {
if (TargetFunction->IsFragment)
registerFragment(*TargetFunction, Function);
} else if (TargetFunction->getAddress() != Address) {
TargetFunction->
addEntryPointAtOffset(Address - TargetFunction->getAddress());
}
if (auto Offset = Address - TargetFunction->getAddress())
TargetFunction->addEntryPointAtOffset(Offset);
continue;
}

View File

@ -0,0 +1,51 @@
# This reproduces a bug where not registering cold fragment entry points
# leads to removing blocks and an inconsistent CFG after UCE.
# Test assembly was obtained using C-Reduce from this C++ code:
# (compiled with `g++ -O2 -Wl,-q`)
#
# #include <stdexcept>
# int a;
# int main() {
# if (a)
# try {
# throw std::logic_error("");
# } catch (...) {}
# try {
# throw std::logic_error("");
# } catch (...) {}
# }
# REQUIRES: system-linux
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o
# RUN: %host_cxx %t.o -o %t.exe -Wl,-q
# RUN: llvm-bolt %t.exe -o %t.out -dump-dot-all -funcs=main.* 2>&1 | FileCheck %s
#
# CHECK-NOT: Assertion `isValid()' failed.
.globl main
main:
jmp .L3 # jump to the secondary entry point in main.cold.0
.section a,"ax"
main.cold.0:
.cfi_startproc
.cfi_lsda 3,b
ud2
call __cxa_throw
.L3:
nop
.cfi_endproc
.section .gcc_except_table
b:
.byte 0xff,0x3
.uleb128 e-c
c:
.byte 1
.uleb128 e-d
d:
.uleb128 0,0,0,0,0
.uleb128 .L3-main.cold.0
.uleb128 .L3-main.cold.0
e:

View File

@ -42,6 +42,7 @@ config.test_exec_root = os.path.join(config.bolt_obj_root, 'test')
llvm_config.use_default_substitutions()
config.substitutions.append(('%host_cc', config.host_cc))
config.substitutions.append(('%host_cxx', config.host_cxx))
tool_dirs = [config.llvm_tools_dir,
config.test_source_root]