about summary refs log tree commit diff
path: root/absl/debugging/symbolize_elf.inc
diff options
context:
space:
mode:
Diffstat (limited to 'absl/debugging/symbolize_elf.inc')
-rw-r--r--absl/debugging/symbolize_elf.inc13
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