This is an archive of the discontinued LLVM Phabricator instance.

Respect pgoff and rely on it for all types of binaries
ClosedPublic

Authored by kpdev42 on Nov 10 2021, 10:53 PM.

Details

Summary

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

Diff Detail

Repository
rLNT LNT

Event Timeline

kpdev42 created this revision.Nov 10 2021, 10:53 PM
kpdev42 requested review of this revision.Nov 10 2021, 10:53 PM
kpdev42 edited the summary of this revision. (Show Details)Nov 10 2021, 11:02 PM
thopre added inline comments.Nov 12 2021, 5:28 AM
lnt/testing/profile/cPerf.cpp
611

Is PgOff 0 for ET_EXEC objects?

kpdev42 updated this revision to Diff 387010.Nov 13 2021, 12:08 AM

Simpleperf generates mmap2 records for all loadable blocks of the same module (not only executable) which may overlap. It may cause an incorrect address calculation because (Start - PgOff) is not a constant for such blocks.

kpdev42 added inline comments.Nov 13 2021, 12:10 AM
lnt/testing/profile/cPerf.cpp
611

Thank you for the question, I've updated a patch, please review

thopre accepted this revision.Nov 13 2021, 2:20 PM

LGTM

This revision is now accepted and ready to land.Nov 13 2021, 2:20 PM
This revision was automatically updated to reflect the committed changes.
DavidSpickett added inline comments.
lnt/testing/profile/cPerf.cpp
565

This has broken our armv7 LNT bot:
https://lab.llvm.org/buildbot/#/builders/174/builds/3548

lnt/testing/profile/cPerf.cpp: In member function ‘unsigned char* PerfReader::readEvent(unsigned char*)’:
lnt/testing/profile/cPerf.cpp:565:7: error: break statement not within loop or switch
  565 |       break;
      |       ^~~~~

Perhaps you wanted to return?

DavidSpickett added inline comments.Nov 15 2021, 5:55 AM
lnt/testing/profile/cPerf.cpp
565

Just saw the fix come in, thanks!

kpdev42 added inline comments.Nov 15 2021, 6:14 AM
lnt/testing/profile/cPerf.cpp
565

Yes, something went wrong during rebase, fixed now. Thank you