| Index: base/third_party/symbolize/symbolize.cc
|
| diff --git a/base/third_party/symbolize/symbolize.cc b/base/third_party/symbolize/symbolize.cc
|
| index db82b04d4df254a345107f532c636511cc5e6753..d7678956c87f603eb1b0483bb819a9f401ca2dc2 100644
|
| --- a/base/third_party/symbolize/symbolize.cc
|
| +++ b/base/third_party/symbolize/symbolize.cc
|
| @@ -327,7 +327,7 @@ FindSymbol(uint64_t pc, const int fd, char *out, int out_size,
|
| // false.
|
| static bool GetSymbolFromObjectFile(const int fd, uint64_t pc,
|
| char *out, int out_size,
|
| - uint64_t map_start_address) {
|
| + uint64_t map_base_address) {
|
| // Read the ELF header.
|
| ElfW(Ehdr) elf_header;
|
| if (!ReadFromOffsetExact(fd, &elf_header, sizeof(elf_header), 0)) {
|
| @@ -336,7 +336,28 @@ static bool GetSymbolFromObjectFile(const int fd, uint64_t pc,
|
|
|
| uint64_t symbol_offset = 0;
|
| if (elf_header.e_type == ET_DYN) { // DSO needs offset adjustment.
|
| - symbol_offset = map_start_address;
|
| + ElfW(Phdr) phdr;
|
| + // We need to find the PT_LOAD segment corresponding to the read-execute
|
| + // file mapping in order to correctly perform the offset adjustment.
|
| + for (unsigned i = 0; i != elf_header.e_phnum; ++i) {
|
| + if (!ReadFromOffsetExact(fd, &phdr, sizeof(phdr),
|
| + elf_header.e_phoff + i * sizeof(phdr)))
|
| + return false;
|
| + if (phdr.p_type == PT_LOAD &&
|
| + (phdr.p_flags & (PF_R | PF_X)) == (PF_R | PF_X)) {
|
| + // Find the mapped address corresponding to virtual address zero. We do
|
| + // this by first adding p_offset. This gives us the mapped address of
|
| + // the start of the segment, or in other words the mapped address
|
| + // corresponding to the virtual address of the segment. (Note that this
|
| + // is distinct from the start address, as p_offset is not guaranteed to
|
| + // be page aligned.) We then subtract p_vaddr, which takes us to virtual
|
| + // address zero.
|
| + symbol_offset = map_base_address + phdr.p_offset - phdr.p_vaddr;
|
| + break;
|
| + }
|
| + }
|
| + if (symbol_offset == 0)
|
| + return false;
|
| }
|
|
|
| ElfW(Shdr) symtab, strtab;
|
| @@ -783,7 +804,7 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out,
|
| }
|
| }
|
| if (!GetSymbolFromObjectFile(wrapped_object_fd.get(), pc0,
|
| - out, out_size, start_address)) {
|
| + out, out_size, base_address)) {
|
| return false;
|
| }
|
|
|
|
|