diff --git a/lnt/testing/profile/cPerf.cpp b/lnt/testing/profile/cPerf.cpp --- a/lnt/testing/profile/cPerf.cpp +++ b/lnt/testing/profile/cPerf.cpp @@ -130,30 +130,6 @@ throw std::logic_error(Str); } -// Returns true if the ELF file given by filename -// is a shared object (DYN). -bool IsSharedObject(std::string Fname) { - // We replicate the first part of an ELF header here - // so as not to rely on . - struct PartialElfHeader { - unsigned char e_ident[16]; - uint16_t e_type; - }; - const int ET_DYN = 3; - - FILE *stream = fopen(Fname.c_str(), "r"); - if (stream == NULL) - return false; - - PartialElfHeader H; - auto NumRead = fread(&H, 1, sizeof(H), stream); - assert(NumRead == sizeof(H)); - - fclose(stream); - - return H.e_type == ET_DYN; -} - //===----------------------------------------------------------------------===// // Perf structures. Taken from https://lwn.net/Articles/644919/ //===----------------------------------------------------------------------===// @@ -240,7 +216,7 @@ //===----------------------------------------------------------------------===// struct Map { - uint64_t Start, End; + uint64_t Start, End, PgOff; const char *Filename; }; @@ -442,8 +418,7 @@ void emitSymbol( Symbol &Sym, Map &M, std::map>::iterator Event, - std::map &SymEvents, - uint64_t Adjust); + std::map &SymEvents); PyObject *complete(); private: @@ -544,7 +519,7 @@ if (E->header.type == PERF_RECORD_MMAP) { perf_event_mmap *E = (perf_event_mmap *)Buf; auto MapID = Maps.size(); - Maps.push_back({E->start, E->start + E->extent, E->filename}); + Maps.push_back({E->start, E->start + E->extent, E->pgoff, E->filename}); // FIXME: use EventLayouts.begin()->second! perf_sample_id *ID = @@ -555,7 +530,7 @@ if (E->header.type == PERF_RECORD_MMAP2) { perf_event_mmap2 *E = (perf_event_mmap2 *)Buf; auto MapID = Maps.size(); - Maps.push_back({E->start, E->start + E->extent, E->filename}); + Maps.push_back({E->start, E->start + E->extent, E->pgoff, E->filename}); // FIXME: use EventLayouts.begin()->second! perf_sample_id *ID = @@ -570,7 +545,7 @@ auto NewE = parseEvent(((unsigned char*)E) + sizeof(perf_event_header), EventLayouts.begin()->second); auto EventID = NewE.id; - auto PC = NewE.ip; + auto RawPC = NewE.ip; // Search for the map corresponding to this sample. Search backwards through // time, discarding any maps created after our timestamp. @@ -580,12 +555,12 @@ if (I->first > NewE.time) continue; - auto NewI = I->second.upper_bound(PC); + auto NewI = I->second.upper_bound(RawPC); if (NewI == I->second.begin()) continue; --NewI; - if (NewI->first > PC) + if (NewI->first > RawPC) continue; MapID = NewI->second; break; @@ -593,9 +568,10 @@ if (MapID == ~0UL) return &Buf[E->header.size]; assert(MapID != ~0UL); - + + auto DSOPC = RawPC - Maps[MapID].Start + Maps[MapID].PgOff; assert(EventIDs.count(EventID)); - Events[MapID][PC][EventIDs[EventID]] += NewE.period; + Events[MapID][DSOPC][EventIDs[EventID]] += NewE.period; TotalEvents[EventIDs[EventID]] += NewE.period; TotalEventsPerMap[MapID][EventIDs[EventID]] += NewE.period; @@ -705,12 +681,6 @@ if (AllUnderThreshold) continue; - // EXEC ELF objects aren't relocated. DYN ones are, - // so if it's a DYN object adjust by subtracting the - // map base. - bool IsSO = IsSharedObject(Maps[MapID].Filename); - uint64_t Adjust = IsSO ? Maps[MapID].Start : 0; - NmOutput Syms(Nm, BinaryCacheRoot); Syms.reset(&Maps[MapID]); @@ -720,7 +690,7 @@ std::map> SymToEventTotals; while (Event != MapEvents.end() && Sym != Syms.end()) { // Skip events until we find one after the start of Sym - auto PC = Event->first - Adjust; + auto PC = Event->first; if (PC < Sym->Start) { ++Event; continue; @@ -747,7 +717,7 @@ } if (Keep) emitSymbol(Sym, Maps[MapID], MapEvents.lower_bound(Sym.Start), - SymToEventTotals[Sym.Start], Adjust); + SymToEventTotals[Sym.Start]); } } } @@ -755,14 +725,13 @@ void PerfReader::emitSymbol( Symbol &Sym, Map &M, std::map>::iterator Event, - std::map &SymEvents, - uint64_t Adjust) { + std::map &SymEvents) { ObjdumpOutput Dump(Objdump, BinaryCacheRoot); Dump.reset(&M, Sym.Start, Sym.End); emitFunctionStart(Sym.Name); for (uint64_t I = Dump.next(); I < Sym.End; I = Dump.next()) { - auto PC = Event->first - Adjust; + auto PC = Event->first; auto Text = Dump.getText(); if (PC == I) {