This fixes incorrect attribution of events to symbols for ET_DYN objects (shared libraries and PIEs), and also simplifies the code.
Generally, the program linker assigns virtual addresses to segments, and virtual addresses of symbols stored in ELF are also in terms of that.
Upon mmapping a segment, its first byte conicides with the start of the memory mapping.
So to get the value of the program counter in terms of the DSO's virtual addresses, one has to add the virtual address of the segment to the raw PC's offset from the start of the mapping.
Like it is done in perf (see linux/tools/perf/util/map.h):
static inline u64 map__map_ip(struct map *map, u64 ip) { return ip - map->start + map->pgoff; }
(The addresses are translated in thread__find_map() via invoking the map_ip callback that has a comment saying /* ip -> dso rip */.)
OS Laboratory. Huawei Russian Research Institute. Saint-Petersburg
This has broken our armv7 LNT bot:
https://lab.llvm.org/buildbot/#/builders/174/builds/3548
Perhaps you wanted to return?