diff options
Diffstat (limited to 'absl/debugging')
-rw-r--r-- | absl/debugging/symbolize_elf.inc | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/absl/debugging/symbolize_elf.inc b/absl/debugging/symbolize_elf.inc index e73052135c98..14f0c9723a33 100644 --- a/absl/debugging/symbolize_elf.inc +++ b/absl/debugging/symbolize_elf.inc @@ -624,6 +624,13 @@ static bool InSection(const void *address, const ElfW(Shdr) * section) { return start <= address && address < (start + size); } +static const char *ComputeOffset(const char *base, ptrdiff_t offset) { + // Note: cast to uintptr_t to avoid undefined behavior when base evaluates to + // zero and offset is non-zero. + return reinterpret_cast<const char *>( + reinterpret_cast<uintptr_t>(base) + offset); +} + // Read a symbol table and look for the symbol containing the // pc. Iterate over symbols in a symbol table and look for the symbol // containing "pc". If the symbol is found, and its name fits in @@ -676,7 +683,8 @@ static ABSL_ATTRIBUTE_NOINLINE FindSymbolResult FindSymbol( // We keep the original address for opd redirection below. const char *const original_start_address = reinterpret_cast<const char *>(symbol.st_value); - const char *start_address = original_start_address + relocation; + const char *start_address = + ComputeOffset(original_start_address, relocation); if (deref_function_descriptor_pointer && InSection(original_start_address, opd)) { @@ -688,8 +696,7 @@ static ABSL_ATTRIBUTE_NOINLINE FindSymbolResult FindSymbol( // If pc is inside the .opd section, it points to a function descriptor. const size_t size = pc_in_opd ? kFunctionDescriptorSize : symbol.st_size; - const void *const end_address = - reinterpret_cast<const char *>(start_address) + size; + const void *const end_address = ComputeOffset(start_address, size); if (symbol.st_value != 0 && // Skip null value symbols. symbol.st_shndx != 0 && // Skip undefined symbols. #ifdef STT_TLS |