aboutsummaryrefslogtreecommitdiff
path: root/third_party/abseil-cpp/absl/debugging/symbolize_elf.inc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/abseil-cpp/absl/debugging/symbolize_elf.inc')
-rw-r--r--third_party/abseil-cpp/absl/debugging/symbolize_elf.inc134
1 files changed, 20 insertions, 114 deletions
diff --git a/third_party/abseil-cpp/absl/debugging/symbolize_elf.inc b/third_party/abseil-cpp/absl/debugging/symbolize_elf.inc
index 3ff343d64f..c371635ffa 100644
--- a/third_party/abseil-cpp/absl/debugging/symbolize_elf.inc
+++ b/third_party/abseil-cpp/absl/debugging/symbolize_elf.inc
@@ -57,7 +57,6 @@
#include <unistd.h>
#include <algorithm>
-#include <array>
#include <atomic>
#include <cerrno>
#include <cinttypes>
@@ -75,11 +74,6 @@
#include "absl/base/port.h"
#include "absl/debugging/internal/demangle.h"
#include "absl/debugging/internal/vdso_support.h"
-#include "absl/strings/string_view.h"
-
-#if defined(__FreeBSD__) && !defined(ElfW)
-#define ElfW(x) __ElfN(x)
-#endif
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -88,12 +82,6 @@ ABSL_NAMESPACE_BEGIN
static char *argv0_value = nullptr;
void InitializeSymbolizer(const char *argv0) {
-#ifdef ABSL_HAVE_VDSO_SUPPORT
- // We need to make sure VDSOSupport::Init() is called before any setuid or
- // chroot calls, so InitializeSymbolizer() should be called very early in the
- // life of a program.
- absl::debugging_internal::VDSOSupport::Init();
-#endif
if (argv0_value != nullptr) {
free(argv0_value);
argv0_value = nullptr;
@@ -161,15 +149,13 @@ struct FileMappingHint {
// Moreover, we are using only TryLock(), if the decorator list
// is being modified (is busy), we skip all decorators, and possibly
// loose some info. Sorry, that's the best we could do.
-ABSL_CONST_INIT absl::base_internal::SpinLock g_decorators_mu(
- absl::kConstInit, absl::base_internal::SCHEDULE_KERNEL_ONLY);
+base_internal::SpinLock g_decorators_mu(base_internal::kLinkerInitialized);
const int kMaxFileMappingHints = 8;
int g_num_file_mapping_hints;
FileMappingHint g_file_mapping_hints[kMaxFileMappingHints];
// Protects g_file_mapping_hints.
-ABSL_CONST_INIT absl::base_internal::SpinLock g_file_mapping_mu(
- absl::kConstInit, absl::base_internal::SCHEDULE_KERNEL_ONLY);
+base_internal::SpinLock g_file_mapping_mu(base_internal::kLinkerInitialized);
// Async-signal-safe function to zero a buffer.
// memset() is not guaranteed to be async-signal-safe.
@@ -189,7 +175,6 @@ struct ObjFile {
fd(-1),
elf_type(-1) {
SafeMemZero(&elf_header, sizeof(elf_header));
- SafeMemZero(&phdr[0], sizeof(phdr));
}
char *filename;
@@ -202,10 +187,6 @@ struct ObjFile {
int fd;
int elf_type;
ElfW(Ehdr) elf_header;
-
- // PT_LOAD program header describing executable code.
- // Normally we expect just one, but SWIFT binaries have two.
- std::array<ElfW(Phdr), 2> phdr;
};
// Build 4-way associative cache for symbols. Within each cache line, symbols
@@ -515,7 +496,7 @@ static ABSL_ATTRIBUTE_NOINLINE bool GetSectionHeaderByType(
const int kMaxSectionNameLen = 64;
bool ForEachSection(int fd,
- const std::function<bool(absl::string_view name,
+ const std::function<bool(const std::string &name,
const ElfW(Shdr) &)> &callback) {
ElfW(Ehdr) elf_header;
if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) {
@@ -537,7 +518,7 @@ bool ForEachSection(int fd,
return false;
}
off_t name_offset = shstrtab.sh_offset + out.sh_name;
- char header_name[kMaxSectionNameLen];
+ char header_name[kMaxSectionNameLen + 1];
ssize_t n_read =
ReadFromOffset(fd, &header_name, kMaxSectionNameLen, name_offset);
if (n_read == -1) {
@@ -546,8 +527,9 @@ bool ForEachSection(int fd,
// Long read?
return false;
}
+ header_name[n_read] = '\0';
- absl::string_view name(header_name, strnlen(header_name, n_read));
+ std::string name(header_name);
if (!callback(name, out)) {
break;
}
@@ -705,16 +687,6 @@ static ABSL_ATTRIBUTE_NOINLINE FindSymbolResult FindSymbol(
const char *start_address =
ComputeOffset(original_start_address, relocation);
-#ifdef __arm__
- // ARM functions are always aligned to multiples of two bytes; the
- // lowest-order bit in start_address is ignored by the CPU and indicates
- // whether the function contains ARM (0) or Thumb (1) code. We don't care
- // about what encoding is being used; we just want the real start address
- // of the function.
- start_address = reinterpret_cast<const char *>(
- reinterpret_cast<uintptr_t>(start_address) & ~1);
-#endif
-
if (deref_function_descriptor_pointer &&
InSection(original_start_address, opd)) {
// The opd section is mapped into memory. Just dereference
@@ -1292,36 +1264,6 @@ static bool MaybeInitializeObjFile(ObjFile *obj) {
ABSL_RAW_LOG(WARNING, "%s: failed to read elf header", obj->filename);
return false;
}
- const int phnum = obj->elf_header.e_phnum;
- const int phentsize = obj->elf_header.e_phentsize;
- size_t phoff = obj->elf_header.e_phoff;
- size_t num_executable_load_segments = 0;
- for (int j = 0; j < phnum; j++) {
- ElfW(Phdr) phdr;
- if (!ReadFromOffsetExact(obj->fd, &phdr, sizeof(phdr), phoff)) {
- ABSL_RAW_LOG(WARNING, "%s: failed to read program header %d",
- obj->filename, j);
- return false;
- }
- phoff += phentsize;
- constexpr int rx = PF_X | PF_R;
- if (phdr.p_type != PT_LOAD || (phdr.p_flags & rx) != rx) {
- // Not a LOAD segment, or not executable code.
- continue;
- }
- if (num_executable_load_segments < obj->phdr.size()) {
- memcpy(&obj->phdr[num_executable_load_segments++], &phdr, sizeof(phdr));
- } else {
- ABSL_RAW_LOG(WARNING, "%s: too many executable LOAD segments",
- obj->filename);
- break;
- }
- }
- if (num_executable_load_segments == 0) {
- // This object has no "r-x" LOAD segments. That's unexpected.
- ABSL_RAW_LOG(WARNING, "%s: no executable LOAD segments", obj->filename);
- return false;
- }
}
return true;
}
@@ -1345,52 +1287,23 @@ const char *Symbolizer::GetSymbol(const void *const pc) {
int fd = -1;
if (obj != nullptr) {
if (MaybeInitializeObjFile(obj)) {
- const size_t start_addr = reinterpret_cast<size_t>(obj->start_addr);
- if (obj->elf_type == ET_DYN && start_addr >= obj->offset) {
+ if (obj->elf_type == ET_DYN &&
+ reinterpret_cast<uint64_t>(obj->start_addr) >= obj->offset) {
// This object was relocated.
//
// For obj->offset > 0, adjust the relocation since a mapping at offset
// X in the file will have a start address of [true relocation]+X.
- relocation = start_addr - obj->offset;
-
- // Note: some binaries have multiple "rx" LOAD segments. We must
- // find the right one.
- ElfW(Phdr) *phdr = nullptr;
- for (size_t j = 0; j < obj->phdr.size(); j++) {
- ElfW(Phdr) &p = obj->phdr[j];
- if (p.p_type != PT_LOAD) {
- // We only expect PT_LOADs. This must be PT_NULL that we didn't
- // write over (i.e. we exhausted all interesting PT_LOADs).
- ABSL_RAW_CHECK(p.p_type == PT_NULL, "unexpected p_type");
- break;
- }
- if (pc < reinterpret_cast<void *>(start_addr + p.p_memsz)) {
- phdr = &p;
- break;
- }
- }
- if (phdr == nullptr) {
- // That's unexpected. Hope for the best.
- ABSL_RAW_LOG(
- WARNING,
- "%s: unable to find LOAD segment for pc: %p, start_addr: %zx",
- obj->filename, pc, start_addr);
- } else {
- // Adjust relocation in case phdr.p_vaddr != 0.
- // This happens for binaries linked with `lld --rosegment`, and for
- // binaries linked with BFD `ld -z separate-code`.
- relocation -= phdr->p_vaddr - phdr->p_offset;
- }
+ relocation = reinterpret_cast<ptrdiff_t>(obj->start_addr) - obj->offset;
}
fd = obj->fd;
- if (GetSymbolFromObjectFile(*obj, pc, relocation, symbol_buf_,
- sizeof(symbol_buf_), tmp_buf_,
- sizeof(tmp_buf_)) == SYMBOL_FOUND) {
- // Only try to demangle the symbol name if it fit into symbol_buf_.
- DemangleInplace(symbol_buf_, sizeof(symbol_buf_), tmp_buf_,
- sizeof(tmp_buf_));
- }
+ }
+ if (GetSymbolFromObjectFile(*obj, pc, relocation, symbol_buf_,
+ sizeof(symbol_buf_), tmp_buf_,
+ sizeof(tmp_buf_)) == SYMBOL_FOUND) {
+ // Only try to demangle the symbol name if it fit into symbol_buf_.
+ DemangleInplace(symbol_buf_, sizeof(symbol_buf_), tmp_buf_,
+ sizeof(tmp_buf_));
}
} else {
#if ABSL_HAVE_VDSO_SUPPORT
@@ -1461,7 +1374,7 @@ int InstallSymbolDecorator(SymbolDecorator decorator, void *arg) {
if (!g_decorators_mu.TryLock()) {
// Someone else is using decorators. Get out.
- return -2;
+ return false;
}
int ret = ticket;
if (g_num_decorators >= kMaxDecorators) {
@@ -1489,7 +1402,7 @@ bool RegisterFileMappingHint(const void *start, const void *end, uint64_t offset
if (g_num_file_mapping_hints >= kMaxFileMappingHints) {
ret = false;
} else {
- // TODO(ckennelly): Move this into a string copy routine.
+ // TODO(ckennelly): Move this into a std::string copy routine.
int len = strlen(filename);
char *dst = static_cast<char *>(
base_internal::LowLevelAlloc::AllocWithArena(len + 1, SigSafeArena()));
@@ -1540,7 +1453,7 @@ bool GetFileMappingHint(const void **start, const void **end, uint64_t *offset,
bool Symbolize(const void *pc, char *out, int out_size) {
// Symbolization is very slow under tsan.
- ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN();
+ ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN();
SAFE_ASSERT(out_size >= 0);
debugging_internal::Symbolizer *s = debugging_internal::AllocateSymbolizer();
const char *name = s->GetSymbol(pc);
@@ -1559,16 +1472,9 @@ bool Symbolize(const void *pc, char *out, int out_size) {
}
}
debugging_internal::FreeSymbolizer(s);
- ABSL_ANNOTATE_IGNORE_READS_AND_WRITES_END();
+ ANNOTATE_IGNORE_READS_AND_WRITES_END();
return ok;
}
ABSL_NAMESPACE_END
} // namespace absl
-
-extern "C" bool AbslInternalGetFileMappingHint(const void **start,
- const void **end, uint64_t *offset,
- const char **filename) {
- return absl::debugging_internal::GetFileMappingHint(start, end, offset,
- filename);
-}