1*9356374aSAndroid Build Coastguard Worker// Copyright 2020 The Abseil Authors. 2*9356374aSAndroid Build Coastguard Worker// 3*9356374aSAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License"); 4*9356374aSAndroid Build Coastguard Worker// you may not use this file except in compliance with the License. 5*9356374aSAndroid Build Coastguard Worker// You may obtain a copy of the License at 6*9356374aSAndroid Build Coastguard Worker// 7*9356374aSAndroid Build Coastguard Worker// https://www.apache.org/licenses/LICENSE-2.0 8*9356374aSAndroid Build Coastguard Worker// 9*9356374aSAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software 10*9356374aSAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS, 11*9356374aSAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*9356374aSAndroid Build Coastguard Worker// See the License for the specific language governing permissions and 13*9356374aSAndroid Build Coastguard Worker// limitations under the License. 14*9356374aSAndroid Build Coastguard Worker 15*9356374aSAndroid Build Coastguard Worker#include <cxxabi.h> 16*9356374aSAndroid Build Coastguard Worker#include <emscripten.h> 17*9356374aSAndroid Build Coastguard Worker 18*9356374aSAndroid Build Coastguard Worker#include <algorithm> 19*9356374aSAndroid Build Coastguard Worker#include <cstring> 20*9356374aSAndroid Build Coastguard Worker 21*9356374aSAndroid Build Coastguard Worker#include "absl/base/internal/raw_logging.h" 22*9356374aSAndroid Build Coastguard Worker#include "absl/debugging/internal/demangle.h" 23*9356374aSAndroid Build Coastguard Worker#include "absl/strings/numbers.h" 24*9356374aSAndroid Build Coastguard Worker#include "absl/strings/str_cat.h" 25*9356374aSAndroid Build Coastguard Worker#include "absl/strings/string_view.h" 26*9356374aSAndroid Build Coastguard Worker 27*9356374aSAndroid Build Coastguard Workerextern "C" { 28*9356374aSAndroid Build Coastguard Workerconst char* emscripten_pc_get_function(const void* pc); 29*9356374aSAndroid Build Coastguard Worker} 30*9356374aSAndroid Build Coastguard Worker 31*9356374aSAndroid Build Coastguard Worker// clang-format off 32*9356374aSAndroid Build Coastguard WorkerEM_JS(bool, HaveOffsetConverter, (), 33*9356374aSAndroid Build Coastguard Worker { return typeof wasmOffsetConverter !== 'undefined'; }); 34*9356374aSAndroid Build Coastguard Worker// clang-format on 35*9356374aSAndroid Build Coastguard Worker 36*9356374aSAndroid Build Coastguard Workernamespace absl { 37*9356374aSAndroid Build Coastguard WorkerABSL_NAMESPACE_BEGIN 38*9356374aSAndroid Build Coastguard Worker 39*9356374aSAndroid Build Coastguard Workervoid InitializeSymbolizer(const char*) { 40*9356374aSAndroid Build Coastguard Worker if (!HaveOffsetConverter()) { 41*9356374aSAndroid Build Coastguard Worker ABSL_RAW_LOG(INFO, 42*9356374aSAndroid Build Coastguard Worker "Symbolization unavailable. Rebuild with -sWASM=1 " 43*9356374aSAndroid Build Coastguard Worker "and -sUSE_OFFSET_CONVERTER=1."); 44*9356374aSAndroid Build Coastguard Worker } 45*9356374aSAndroid Build Coastguard Worker} 46*9356374aSAndroid Build Coastguard Worker 47*9356374aSAndroid Build Coastguard Workerbool Symbolize(const void* pc, char* out, int out_size) { 48*9356374aSAndroid Build Coastguard Worker // Check if we have the offset converter necessary for pc_get_function. 49*9356374aSAndroid Build Coastguard Worker // Without it, the program will abort(). 50*9356374aSAndroid Build Coastguard Worker if (!HaveOffsetConverter()) { 51*9356374aSAndroid Build Coastguard Worker return false; 52*9356374aSAndroid Build Coastguard Worker } 53*9356374aSAndroid Build Coastguard Worker if (pc == nullptr || out_size <= 0) { 54*9356374aSAndroid Build Coastguard Worker return false; 55*9356374aSAndroid Build Coastguard Worker } 56*9356374aSAndroid Build Coastguard Worker const char* func_name = emscripten_pc_get_function(pc); 57*9356374aSAndroid Build Coastguard Worker if (func_name == nullptr) { 58*9356374aSAndroid Build Coastguard Worker return false; 59*9356374aSAndroid Build Coastguard Worker } 60*9356374aSAndroid Build Coastguard Worker 61*9356374aSAndroid Build Coastguard Worker strncpy(out, func_name, out_size); 62*9356374aSAndroid Build Coastguard Worker 63*9356374aSAndroid Build Coastguard Worker if (out[out_size - 1] != '\0') { 64*9356374aSAndroid Build Coastguard Worker // strncpy() does not '\0' terminate when it truncates. 65*9356374aSAndroid Build Coastguard Worker static constexpr char kEllipsis[] = "..."; 66*9356374aSAndroid Build Coastguard Worker int ellipsis_size = std::min<int>(sizeof(kEllipsis) - 1, out_size - 1); 67*9356374aSAndroid Build Coastguard Worker memcpy(out + out_size - ellipsis_size - 1, kEllipsis, ellipsis_size); 68*9356374aSAndroid Build Coastguard Worker out[out_size - 1] = '\0'; 69*9356374aSAndroid Build Coastguard Worker } 70*9356374aSAndroid Build Coastguard Worker 71*9356374aSAndroid Build Coastguard Worker return true; 72*9356374aSAndroid Build Coastguard Worker} 73*9356374aSAndroid Build Coastguard Worker 74*9356374aSAndroid Build Coastguard WorkerABSL_NAMESPACE_END 75*9356374aSAndroid Build Coastguard Worker} // namespace absl 76