brintos

brintos / llvm-project-archived public Read only

0
0
Text · 36.7 KiB · 0d03831 Raw
954 lines · cpp
1//===-- LVBinaryReader.cpp ------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This implements the LVBinaryReader class.10//11//===----------------------------------------------------------------------===//12 13#include "llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h"14#include "llvm/Support/Errc.h"15#include "llvm/Support/FormatAdapters.h"16#include "llvm/Support/FormatVariadic.h"17 18using namespace llvm;19using namespace llvm::logicalview;20 21#define DEBUG_TYPE "BinaryReader"22 23// Function names extracted from the object symbol table.24void LVSymbolTable::add(StringRef Name, LVScope *Function,25                        LVSectionIndex SectionIndex) {26  std::string SymbolName(Name);27  auto [It, Inserted] =28      SymbolNames.try_emplace(SymbolName, Function, 0, SectionIndex, false);29  if (!Inserted) {30    // Update a recorded entry with its logical scope and section index.31    It->second.Scope = Function;32    if (SectionIndex)33      It->second.SectionIndex = SectionIndex;34  }35 36  if (Function && It->second.IsComdat)37    Function->setIsComdat();38 39  LLVM_DEBUG({ print(dbgs()); });40}41 42void LVSymbolTable::add(StringRef Name, LVAddress Address,43                        LVSectionIndex SectionIndex, bool IsComdat) {44  std::string SymbolName(Name);45  auto [It, Inserted] = SymbolNames.try_emplace(SymbolName, nullptr, Address,46                                                SectionIndex, IsComdat);47  if (!Inserted)48    // Update a recorded symbol name with its logical scope.49    It->second.Address = Address;50 51  LVScope *Function = It->second.Scope;52  if (Function && IsComdat)53    Function->setIsComdat();54  LLVM_DEBUG({ print(dbgs()); });55}56 57LVSectionIndex LVSymbolTable::update(LVScope *Function) {58  LVSectionIndex SectionIndex = getReader().getDotTextSectionIndex();59  StringRef Name = Function->getLinkageName();60  if (Name.empty())61    Name = Function->getName();62  std::string SymbolName(Name);63 64  if (SymbolName.empty())65    return SectionIndex;66 67  auto It = SymbolNames.find(SymbolName);68  if (It == SymbolNames.end())69    return SectionIndex;70 71  // Update a recorded entry with its logical scope, only if the scope has72  // ranges. That is the case when in DWARF there are 2 DIEs connected via73  // the DW_AT_specification.74  if (Function->getHasRanges()) {75    It->second.Scope = Function;76    SectionIndex = It->second.SectionIndex;77  } else {78    SectionIndex = UndefinedSectionIndex;79  }80 81  if (It->second.IsComdat)82    Function->setIsComdat();83 84  LLVM_DEBUG({ print(dbgs()); });85  return SectionIndex;86}87 88const LVSymbolTableEntry &LVSymbolTable::getEntry(StringRef Name) {89  static LVSymbolTableEntry Empty = LVSymbolTableEntry();90  LVSymbolNames::iterator Iter = SymbolNames.find(Name);91  return Iter != SymbolNames.end() ? Iter->second : Empty;92}93LVAddress LVSymbolTable::getAddress(StringRef Name) {94  LVSymbolNames::iterator Iter = SymbolNames.find(Name);95  return Iter != SymbolNames.end() ? Iter->second.Address : 0;96}97LVSectionIndex LVSymbolTable::getIndex(StringRef Name) {98  LVSymbolNames::iterator Iter = SymbolNames.find(Name);99  return Iter != SymbolNames.end() ? Iter->second.SectionIndex100                                   : getReader().getDotTextSectionIndex();101}102bool LVSymbolTable::getIsComdat(StringRef Name) {103  LVSymbolNames::iterator Iter = SymbolNames.find(Name);104  return Iter != SymbolNames.end() ? Iter->second.IsComdat : false;105}106 107void LVSymbolTable::print(raw_ostream &OS) {108  OS << "Symbol Table\n";109  for (LVSymbolNames::reference Entry : SymbolNames) {110    LVSymbolTableEntry &SymbolName = Entry.second;111    LVScope *Scope = SymbolName.Scope;112    LVOffset Offset = Scope ? Scope->getOffset() : 0;113    OS << "Index: " << hexValue(SymbolName.SectionIndex, 5)114       << " Comdat: " << (SymbolName.IsComdat ? "Y" : "N")115       << " Scope: " << hexValue(Offset)116       << " Address: " << hexValue(SymbolName.Address)117       << " Name: " << Entry.first << "\n";118  }119}120 121void LVBinaryReader::addToSymbolTable(StringRef Name, LVScope *Function,122                                      LVSectionIndex SectionIndex) {123  SymbolTable.add(Name, Function, SectionIndex);124}125void LVBinaryReader::addToSymbolTable(StringRef Name, LVAddress Address,126                                      LVSectionIndex SectionIndex,127                                      bool IsComdat) {128  SymbolTable.add(Name, Address, SectionIndex, IsComdat);129}130LVSectionIndex LVBinaryReader::updateSymbolTable(LVScope *Function) {131  return SymbolTable.update(Function);132}133 134const LVSymbolTableEntry &LVBinaryReader::getSymbolTableEntry(StringRef Name) {135  return SymbolTable.getEntry(Name);136}137LVAddress LVBinaryReader::getSymbolTableAddress(StringRef Name) {138  return SymbolTable.getAddress(Name);139}140LVSectionIndex LVBinaryReader::getSymbolTableIndex(StringRef Name) {141  return SymbolTable.getIndex(Name);142}143bool LVBinaryReader::getSymbolTableIsComdat(StringRef Name) {144  return SymbolTable.getIsComdat(Name);145}146 147void LVBinaryReader::mapVirtualAddress(const object::ObjectFile &Obj) {148  for (const object::SectionRef &Section : Obj.sections()) {149    LLVM_DEBUG({150      Expected<StringRef> SectionNameOrErr = Section.getName();151      StringRef Name;152      if (!SectionNameOrErr)153        consumeError(SectionNameOrErr.takeError());154      else155        Name = *SectionNameOrErr;156      dbgs() << "Index: " << format_decimal(Section.getIndex(), 3) << ", "157             << "Address: " << hexValue(Section.getAddress()) << ", "158             << "Size: " << hexValue(Section.getSize()) << ", "159             << "Name: " << Name << "\n";160      dbgs() << "isCompressed:   " << Section.isCompressed() << ", "161             << "isText:         " << Section.isText() << ", "162             << "isData:         " << Section.isData() << ", "163             << "isBSS:          " << Section.isBSS() << ", "164             << "isVirtual:      " << Section.isVirtual() << "\n";165      dbgs() << "isBitcode:      " << Section.isBitcode() << ", "166             << "isStripped:     " << Section.isStripped() << ", "167             << "isBerkeleyText: " << Section.isBerkeleyText() << ", "168             << "isBerkeleyData: " << Section.isBerkeleyData() << ", "169             << "isDebugSection: " << Section.isDebugSection() << "\n";170      dbgs() << "\n";171    });172 173    if (!Section.isText() || Section.isVirtual() || !Section.getSize())174      continue;175 176    // Record section information required for symbol resolution.177    // Note: The section index returned by 'getIndex()' is one based.178    Sections.emplace(Section.getIndex(), Section);179    addSectionAddress(Section);180 181    // Identify the ".text" section.182    Expected<StringRef> SectionNameOrErr = Section.getName();183    if (!SectionNameOrErr) {184      consumeError(SectionNameOrErr.takeError());185      continue;186    }187    if (*SectionNameOrErr == ".text" || *SectionNameOrErr == "CODE" ||188        *SectionNameOrErr == ".code") {189      DotTextSectionIndex = Section.getIndex();190      // If the object is WebAssembly, update the address offset that191      // will be added to DWARF DW_AT_* attributes.192      if (Obj.isWasm())193        WasmCodeSectionOffset = Section.getAddress();194    }195  }196 197  // Process the symbol table.198  mapRangeAddress(Obj);199 200  LLVM_DEBUG({201    dbgs() << "\nSections Information:\n";202    for (LVSections::reference Entry : Sections) {203      LVSectionIndex SectionIndex = Entry.first;204      const object::SectionRef Section = Entry.second;205      Expected<StringRef> SectionNameOrErr = Section.getName();206      if (!SectionNameOrErr)207        consumeError(SectionNameOrErr.takeError());208      dbgs() << "\nIndex: " << format_decimal(SectionIndex, 3)209             << " Name: " << *SectionNameOrErr << "\n"210             << "Size: " << hexValue(Section.getSize()) << "\n"211             << "VirtualAddress: " << hexValue(VirtualAddress) << "\n"212             << "SectionAddress: " << hexValue(Section.getAddress()) << "\n";213    }214    dbgs() << "\nObject Section Information:\n";215    for (LVSectionAddresses::const_reference Entry : SectionAddresses)216      dbgs() << "[" << hexValue(Entry.first) << ":"217             << hexValue(Entry.first + Entry.second.getSize())218             << "] Size: " << hexValue(Entry.second.getSize()) << "\n";219  });220}221 222void LVBinaryReader::mapVirtualAddress(const object::COFFObjectFile &COFFObj) {223  ErrorOr<uint64_t> ImageBase = COFFObj.getImageBase();224  if (ImageBase)225    ImageBaseAddress = ImageBase.get();226 227  LLVM_DEBUG({228    dbgs() << "ImageBaseAddress: " << hexValue(ImageBaseAddress) << "\n";229  });230 231  uint32_t Flags = COFF::IMAGE_SCN_CNT_CODE | COFF::IMAGE_SCN_LNK_COMDAT;232 233  for (const object::SectionRef &Section : COFFObj.sections()) {234    if (!Section.isText() || Section.isVirtual() || !Section.getSize())235      continue;236 237    const object::coff_section *COFFSection = COFFObj.getCOFFSection(Section);238    VirtualAddress = COFFSection->VirtualAddress;239    bool IsComdat = (COFFSection->Characteristics & Flags) == Flags;240 241    // Record section information required for symbol resolution.242    // Note: The section index returned by 'getIndex()' is zero based.243    Sections.emplace(Section.getIndex() + 1, Section);244    addSectionAddress(Section);245 246    // Additional initialization on the specific object format.247    mapRangeAddress(COFFObj, Section, IsComdat);248  }249 250  LLVM_DEBUG({251    dbgs() << "\nSections Information:\n";252    for (LVSections::reference Entry : Sections) {253      LVSectionIndex SectionIndex = Entry.first;254      const object::SectionRef Section = Entry.second;255      const object::coff_section *COFFSection = COFFObj.getCOFFSection(Section);256      Expected<StringRef> SectionNameOrErr = Section.getName();257      if (!SectionNameOrErr)258        consumeError(SectionNameOrErr.takeError());259      dbgs() << "\nIndex: " << format_decimal(SectionIndex, 3)260             << " Name: " << *SectionNameOrErr << "\n"261             << "Size: " << hexValue(Section.getSize()) << "\n"262             << "VirtualAddress: " << hexValue(VirtualAddress) << "\n"263             << "SectionAddress: " << hexValue(Section.getAddress()) << "\n"264             << "PointerToRawData: " << hexValue(COFFSection->PointerToRawData)265             << "\n"266             << "SizeOfRawData: " << hexValue(COFFSection->SizeOfRawData)267             << "\n";268    }269    dbgs() << "\nObject Section Information:\n";270    for (LVSectionAddresses::const_reference Entry : SectionAddresses)271      dbgs() << "[" << hexValue(Entry.first) << ":"272             << hexValue(Entry.first + Entry.second.getSize())273             << "] Size: " << hexValue(Entry.second.getSize()) << "\n";274  });275}276 277Error LVBinaryReader::loadGenericTargetInfo(StringRef TripleName,278                                            StringRef TheFeatures,279                                            StringRef TheCPU) {280  Triple TheTriple(TripleName);281  std::string TargetLookupError;282  const Target *TheTarget =283      TargetRegistry::lookupTarget(TheTriple, TargetLookupError);284  if (!TheTarget)285    return createStringError(errc::invalid_argument, TargetLookupError.c_str());286 287  // Register information.288  MCRegisterInfo *RegisterInfo = TheTarget->createMCRegInfo(TheTriple);289  if (!RegisterInfo)290    return createStringError(errc::invalid_argument,291                             "no register info for target " + TripleName);292  MRI.reset(RegisterInfo);293 294  // Assembler properties and features.295  MCTargetOptions MCOptions;296  MCAsmInfo *AsmInfo(TheTarget->createMCAsmInfo(*MRI, TheTriple, MCOptions));297  if (!AsmInfo)298    return createStringError(errc::invalid_argument,299                             "no assembly info for target " + TripleName);300  MAI.reset(AsmInfo);301 302  // Target subtargets.303  MCSubtargetInfo *SubtargetInfo(304      TheTarget->createMCSubtargetInfo(TheTriple, TheCPU, TheFeatures));305  if (!SubtargetInfo)306    return createStringError(errc::invalid_argument,307                             "no subtarget info for target " + TripleName);308  STI.reset(SubtargetInfo);309 310  // Instructions Info.311  MCInstrInfo *InstructionInfo(TheTarget->createMCInstrInfo());312  if (!InstructionInfo)313    return createStringError(errc::invalid_argument,314                             "no instruction info for target " + TripleName);315  MII.reset(InstructionInfo);316 317  MC = std::make_unique<MCContext>(Triple(TheTriple), MAI.get(), MRI.get(),318                                   STI.get());319 320  // Assembler.321  MCDisassembler *DisAsm(TheTarget->createMCDisassembler(*STI, *MC));322  if (!DisAsm)323    return createStringError(errc::invalid_argument,324                             "no disassembler for target " + TripleName);325  MD.reset(DisAsm);326 327  MCInstPrinter *InstructionPrinter(TheTarget->createMCInstPrinter(328      Triple(TheTriple), AsmInfo->getAssemblerDialect(), *MAI, *MII, *MRI));329  if (!InstructionPrinter)330    return createStringError(errc::invalid_argument,331                             "no target assembly language printer for target " +332                                 TripleName);333  MIP.reset(InstructionPrinter);334  InstructionPrinter->setPrintImmHex(true);335 336  return Error::success();337}338 339Expected<std::pair<uint64_t, object::SectionRef>>340LVBinaryReader::getSection(LVScope *Scope, LVAddress Address,341                           LVSectionIndex SectionIndex) {342  // Return the 'text' section with the code for this logical scope.343  // COFF: SectionIndex is zero. Use 'SectionAddresses' data.344  // ELF: SectionIndex is the section index in the file.345  if (SectionIndex) {346    LVSections::iterator Iter = Sections.find(SectionIndex);347    if (Iter == Sections.end()) {348      return createStringError(errc::invalid_argument,349                               "invalid section index for: '%s'",350                               Scope->getName().str().c_str());351    }352    const object::SectionRef Section = Iter->second;353    return std::make_pair(Section.getAddress(), Section);354  }355 356  // Ensure a valid starting address for the public names.357  LVSectionAddresses::const_iterator Iter =358      SectionAddresses.upper_bound(Address);359  if (Iter == SectionAddresses.begin())360    return createStringError(errc::invalid_argument,361                             "invalid section address for: '%s'",362                             Scope->getName().str().c_str());363 364  // Get section that contains the code for this function.365  Iter = SectionAddresses.lower_bound(Address);366  if (Iter != SectionAddresses.begin())367    --Iter;368  return std::make_pair(Iter->first, Iter->second);369}370 371Error LVBinaryReader::createInstructions(LVScope *Scope,372                                         LVSectionIndex SectionIndex,373                                         const LVNameInfo &NameInfo) {374  assert(Scope && "Scope is null.");375 376  // Skip stripped functions.377  if (Scope->getIsDiscarded())378    return Error::success();379 380  // Find associated address and size for the given function entry point.381  LVAddress Address = NameInfo.first;382  uint64_t Size = NameInfo.second;383 384  LLVM_DEBUG({385    dbgs() << "\nPublic Name instructions: '" << Scope->getName() << "' / '"386           << Scope->getLinkageName() << "'\n"387           << "DIE Offset: " << hexValue(Scope->getOffset()) << " Range: ["388           << hexValue(Address) << ":" << hexValue(Address + Size) << "]\n";389  });390 391  Expected<std::pair<uint64_t, const object::SectionRef>> SectionOrErr =392      getSection(Scope, Address, SectionIndex);393  if (!SectionOrErr)394    return SectionOrErr.takeError();395  const object::SectionRef Section = (*SectionOrErr).second;396  uint64_t SectionAddress = (*SectionOrErr).first;397 398  Expected<StringRef> SectionContentsOrErr = Section.getContents();399  if (!SectionContentsOrErr)400    return SectionOrErr.takeError();401 402  // There are cases where the section size is smaller than the [LowPC,HighPC]403  // range; it causes us to decode invalid addresses. The recorded size in the404  // logical scope is one less than the real size.405  LLVM_DEBUG({406    dbgs() << " Size: " << hexValue(Size)407           << ", Section Size: " << hexValue(Section.getSize()) << "\n";408  });409  Size = std::min(Size + 1, Section.getSize());410 411  ArrayRef<uint8_t> Bytes = arrayRefFromStringRef(*SectionContentsOrErr);412  uint64_t Offset = Address - SectionAddress;413  if (Offset > Bytes.size()) {414    LLVM_DEBUG({415      dbgs() << "offset (" << hexValue(Offset) << ") is beyond section size ("416             << hexValue(Bytes.size()) << "); malformed input?\n";417    });418    return createStringError(419        errc::bad_address,420        "Failed to parse instructions; offset beyond section size");421  }422  uint8_t const *Begin = Bytes.data() + Offset;423  uint8_t const *End = Bytes.data() + Offset + Size;424 425  LLVM_DEBUG({426    Expected<StringRef> SectionNameOrErr = Section.getName();427    if (!SectionNameOrErr)428      consumeError(SectionNameOrErr.takeError());429    else430      dbgs() << "Section Index: " << hexValue(Section.getIndex()) << " ["431             << hexValue((uint64_t)Section.getAddress()) << ":"432             << hexValue((uint64_t)Section.getAddress() + Section.getSize(), 10)433             << "] Name: '" << *SectionNameOrErr << "'\n"434             << "Begin: " << hexValue((uint64_t)Begin)435             << ", End: " << hexValue((uint64_t)End) << "\n";436  });437 438  // Address for first instruction line.439  LVAddress FirstAddress = Address;440  auto InstructionsSP = std::make_unique<LVLines>();441  LVLines &Instructions = *InstructionsSP;442  DiscoveredLines.emplace_back(std::move(InstructionsSP));443 444  while (Begin < End) {445    MCInst Instruction;446    uint64_t BytesConsumed = 0;447    SmallVector<char, 64> InsnStr;448    raw_svector_ostream Annotations(InsnStr);449    MCDisassembler::DecodeStatus const S =450        MD->getInstruction(Instruction, BytesConsumed,451                           ArrayRef<uint8_t>(Begin, End), Address, outs());452    switch (S) {453    case MCDisassembler::Fail:454      LLVM_DEBUG({ dbgs() << "Invalid instruction\n"; });455      if (BytesConsumed == 0)456        // Skip invalid bytes457        BytesConsumed = 1;458      break;459    case MCDisassembler::SoftFail:460      LLVM_DEBUG({ dbgs() << "Potentially undefined instruction:"; });461      [[fallthrough]];462    case MCDisassembler::Success: {463      std::string Buffer;464      raw_string_ostream Stream(Buffer);465      StringRef AnnotationsStr = Annotations.str();466      MIP->printInst(&Instruction, Address, AnnotationsStr, *STI, Stream);467      LLVM_DEBUG({468        std::string BufferCodes;469        raw_string_ostream StreamCodes(BufferCodes);470        StreamCodes << format_bytes(471            ArrayRef<uint8_t>(Begin, Begin + BytesConsumed), std::nullopt, 16,472            16);473        dbgs() << "[" << hexValue((uint64_t)Begin) << "] "474               << "Size: " << format_decimal(BytesConsumed, 2) << " ("475               << formatv("{0}",476                          fmt_align(StreamCodes.str(), AlignStyle::Left, 32))477               << ") " << hexValue((uint64_t)Address) << ": " << Stream.str()478               << "\n";479      });480      // Here we add logical lines to the Instructions. Later on,481      // the 'processLines()' function will move each created logical line482      // to its enclosing logical scope, using the debug ranges information483      // and they will be released when its scope parent is deleted.484      LVLineAssembler *Line = createLineAssembler();485      Line->setAddress(Address);486      Line->setName(StringRef(Stream.str()).trim());487      Instructions.push_back(Line);488      break;489    }490    }491    Address += BytesConsumed;492    Begin += BytesConsumed;493  }494 495  LLVM_DEBUG({496    size_t Index = 0;497    dbgs() << "\nSectionIndex: " << format_decimal(SectionIndex, 3)498           << " Scope DIE: " << hexValue(Scope->getOffset()) << "\n"499           << "Address: " << hexValue(FirstAddress)500           << format(" - Collected instructions lines: %d\n",501                     Instructions.size());502    for (const LVLine *Line : Instructions)503      dbgs() << format_decimal(++Index, 5) << ": "504             << hexValue(Line->getOffset()) << ", (" << Line->getName()505             << ")\n";506  });507 508  // The scope in the assembler names is linked to its own instructions.509  ScopeInstructions.add(SectionIndex, Scope, &Instructions);510  AssemblerMappings.add(SectionIndex, FirstAddress, Scope);511 512  return Error::success();513}514 515Error LVBinaryReader::createInstructions(LVScope *Function,516                                         LVSectionIndex SectionIndex) {517  if (!options().getPrintInstructions())518    return Error::success();519 520  LVNameInfo Name = CompileUnit->findPublicName(Function);521  if (Name.first != LVAddress(UINT64_MAX))522    return createInstructions(Function, SectionIndex, Name);523 524  return Error::success();525}526 527Error LVBinaryReader::createInstructions() {528  if (!options().getPrintInstructions())529    return Error::success();530 531  LLVM_DEBUG({532    size_t Index = 1;533    dbgs() << "\nPublic Names (Scope):\n";534    for (LVPublicNames::const_reference Name : CompileUnit->getPublicNames()) {535      LVScope *Scope = Name.first;536      const LVNameInfo &NameInfo = Name.second;537      LVAddress Address = NameInfo.first;538      uint64_t Size = NameInfo.second;539      dbgs() << format_decimal(Index++, 5) << ": "540             << "DIE Offset: " << hexValue(Scope->getOffset()) << " Range: ["541             << hexValue(Address) << ":" << hexValue(Address + Size) << "] "542             << "Name: '" << Scope->getName() << "' / '"543             << Scope->getLinkageName() << "'\n";544    }545  });546 547  // For each public name in the current compile unit, create the line548  // records that represent the executable instructions.549  for (LVPublicNames::const_reference Name : CompileUnit->getPublicNames()) {550    LVScope *Scope = Name.first;551    // The symbol table extracted from the object file always contains a552    // non-empty name (linkage name). However, the logical scope does not553    // guarantee to have a name for the linkage name (main is one case).554    // For those cases, set the linkage name the same as the name.555    if (!Scope->getLinkageNameIndex())556      Scope->setLinkageName(Scope->getName());557    LVSectionIndex SectionIndex = getSymbolTableIndex(Scope->getLinkageName());558    if (Error Err = createInstructions(Scope, SectionIndex, Name.second))559      return Err;560  }561 562  return Error::success();563}564 565// During the traversal of the debug information sections, we created the566// logical lines representing the disassembled instructions from the text567// section and the logical lines representing the line records from the568// debug line section. Using the ranges associated with the logical scopes,569// we will allocate those logical lines to their logical scopes.570void LVBinaryReader::processLines(LVLines *DebugLines,571                                  LVSectionIndex SectionIndex,572                                  LVScope *Function) {573  assert(DebugLines && "DebugLines is null.");574 575  // Just return if this compilation unit does not have any line records576  // and no instruction lines were created.577  if (DebugLines->empty() && !options().getPrintInstructions())578    return;579 580  // Merge the debug lines and instruction lines using their text address;581  // the logical line representing the debug line record is followed by the582  // line(s) representing the disassembled instructions, whose addresses are583  // equal or greater that the line address and less than the address of the584  // next debug line record.585  LLVM_DEBUG({586    size_t Index = 1;587    size_t PerLine = 4;588    dbgs() << format("\nProcess debug lines: %d\n", DebugLines->size());589    for (const LVLine *Line : *DebugLines) {590      dbgs() << format_decimal(Index, 5) << ": " << hexValue(Line->getOffset())591             << ", (" << Line->getLineNumber() << ")"592             << ((Index % PerLine) ? "  " : "\n");593      ++Index;594    }595    dbgs() << ((Index % PerLine) ? "\n" : "");596  });597 598  bool TraverseLines = true;599  LVLines::iterator Iter = DebugLines->begin();600  while (TraverseLines && Iter != DebugLines->end()) {601    uint64_t DebugAddress = (*Iter)->getAddress();602 603    // Get the function with an entry point that matches this line and604    // its associated assembler entries. In the case of COMDAT, the input605    // 'Function' is not null. Use it to find its address ranges.606    LVScope *Scope = Function;607    if (!Function) {608      Scope = AssemblerMappings.find(SectionIndex, DebugAddress);609      if (!Scope) {610        ++Iter;611        continue;612      }613    }614 615    // Get the associated instructions for the found 'Scope'.616    LVLines InstructionLines;617    LVLines *Lines = ScopeInstructions.find(SectionIndex, Scope);618    if (Lines)619      InstructionLines = std::move(*Lines);620 621    LLVM_DEBUG({622      size_t Index = 0;623      dbgs() << "\nSectionIndex: " << format_decimal(SectionIndex, 3)624             << " Scope DIE: " << hexValue(Scope->getOffset()) << "\n"625             << format("Process instruction lines: %d\n",626                       InstructionLines.size());627      for (const LVLine *Line : InstructionLines)628        dbgs() << format_decimal(++Index, 5) << ": "629               << hexValue(Line->getOffset()) << ", (" << Line->getName()630               << ")\n";631    });632 633    // Continue with next debug line if there are not instructions lines.634    if (InstructionLines.empty()) {635      ++Iter;636      continue;637    }638 639    for (LVLine *InstructionLine : InstructionLines) {640      uint64_t InstructionAddress = InstructionLine->getAddress();641      LLVM_DEBUG({642        dbgs() << "Instruction address: " << hexValue(InstructionAddress)643               << "\n";644      });645      if (TraverseLines) {646        while (Iter != DebugLines->end()) {647          DebugAddress = (*Iter)->getAddress();648          LLVM_DEBUG({649            bool IsDebug = (*Iter)->getIsLineDebug();650            dbgs() << "Line " << (IsDebug ? "dbg:" : "ins:") << " ["651                   << hexValue(DebugAddress) << "]";652            if (IsDebug)653              dbgs() << format(" %d", (*Iter)->getLineNumber());654            dbgs() << "\n";655          });656          // Instruction address before debug line.657          if (InstructionAddress < DebugAddress) {658            LLVM_DEBUG({659              dbgs() << "Inserted instruction address: "660                     << hexValue(InstructionAddress) << " before line: "661                     << format("%d", (*Iter)->getLineNumber()) << " ["662                     << hexValue(DebugAddress) << "]\n";663            });664            Iter = DebugLines->insert(Iter, InstructionLine);665            // The returned iterator points to the inserted instruction.666            // Skip it and point to the line acting as reference.667            ++Iter;668            break;669          }670          ++Iter;671        }672        if (Iter == DebugLines->end()) {673          // We have reached the end of the source lines and the current674          // instruction line address is greater than the last source line.675          TraverseLines = false;676          DebugLines->push_back(InstructionLine);677        }678      } else {679        DebugLines->push_back(InstructionLine);680      }681    }682  }683 684  LLVM_DEBUG({685    dbgs() << format("Lines after merge: %d\n", DebugLines->size());686    size_t Index = 0;687    for (const LVLine *Line : *DebugLines) {688      dbgs() << format_decimal(++Index, 5) << ": "689             << hexValue(Line->getOffset()) << ", ("690             << ((Line->getIsLineDebug())691                     ? Line->lineNumberAsStringStripped(/*ShowZero=*/true)692                     : Line->getName())693             << ")\n";694    }695  });696 697  // If this compilation unit does not have line records, traverse its scopes698  // and take any collected instruction lines as the working set in order699  // to move them to their associated scope.700  if (DebugLines->empty()) {701    if (const LVScopes *Scopes = CompileUnit->getScopes())702      for (LVScope *Scope : *Scopes) {703        LVLines *Lines = ScopeInstructions.find(Scope);704        if (Lines) {705 706          LLVM_DEBUG({707            size_t Index = 0;708            dbgs() << "\nSectionIndex: " << format_decimal(SectionIndex, 3)709                   << " Scope DIE: " << hexValue(Scope->getOffset()) << "\n"710                   << format("Instruction lines: %d\n", Lines->size());711            for (const LVLine *Line : *Lines)712              dbgs() << format_decimal(++Index, 5) << ": "713                     << hexValue(Line->getOffset()) << ", (" << Line->getName()714                     << ")\n";715          });716 717          if (Scope->getIsArtificial()) {718            // Add the instruction lines to their artificial scope.719            for (LVLine *Line : *Lines)720              Scope->addElement(Line);721          } else {722            DebugLines->append(*Lines);723          }724          Lines->clear();725        }726      }727  }728 729  LVRange *ScopesWithRanges = getSectionRanges(SectionIndex);730  ScopesWithRanges->startSearch();731 732  // Process collected lines.733  LVScope *Scope;734  for (LVLine *Line : *DebugLines) {735    // Using the current line address, get its associated lexical scope and736    // add the line information to it.737    Scope = ScopesWithRanges->getEntry(Line->getAddress());738    if (!Scope) {739      // If missing scope, use the compile unit.740      Scope = CompileUnit;741      LLVM_DEBUG({742        dbgs() << "Adding line to CU: " << hexValue(Line->getOffset()) << ", ("743               << ((Line->getIsLineDebug())744                       ? Line->lineNumberAsStringStripped(/*ShowZero=*/true)745                       : Line->getName())746               << ")\n";747      });748    }749 750    // Add line object to scope.751    Scope->addElement(Line);752 753    // Report any line zero.754    if (options().getWarningLines() && Line->getIsLineDebug() &&755        !Line->getLineNumber())756      CompileUnit->addLineZero(Line);757 758    // Some compilers generate ranges in the compile unit; other compilers759    // only DW_AT_low_pc/DW_AT_high_pc. In order to correctly map global760    // variables, we need to generate the map ranges for the compile unit.761    // If we use the ranges stored at the scope level, there are cases where762    // the address referenced by a symbol location, is not in the enclosing763    // scope, but in an outer one. By using the ranges stored in the compile764    // unit, we can catch all those addresses.765    if (Line->getIsLineDebug())766      CompileUnit->addMapping(Line, SectionIndex);767 768    // Resolve any given pattern.769    patterns().resolvePatternMatch(Line);770  }771 772  ScopesWithRanges->endSearch();773}774 775void LVBinaryReader::processLines(LVLines *DebugLines,776                                  LVSectionIndex SectionIndex) {777  assert(DebugLines && "DebugLines is null.");778  if (DebugLines->empty() && !ScopeInstructions.findMap(SectionIndex))779    return;780 781  // If the Compile Unit does not contain comdat functions, use the whole782  // set of debug lines, as the addresses don't have conflicts.783  if (!CompileUnit->getHasComdatScopes()) {784    processLines(DebugLines, SectionIndex, nullptr);785    return;786  }787 788  // Find the indexes for the lines whose address is zero.789  std::vector<size_t> AddressZero;790  LVLines::iterator It = llvm::find_if(791      *DebugLines, [](LVLine *Line) { return !Line->getAddress(); });792  while (It != std::end(*DebugLines)) {793    AddressZero.emplace_back(std::distance(std::begin(*DebugLines), It));794    It = std::find_if(std::next(It), std::end(*DebugLines),795                      [](LVLine *Line) { return !Line->getAddress(); });796  }797 798  // If the set of debug lines does not contain any line with address zero,799  // use the whole set. It means we are dealing with an initialization800  // section from a fully linked binary.801  if (AddressZero.empty()) {802    processLines(DebugLines, SectionIndex, nullptr);803    return;804  }805 806  // The Compile unit contains comdat functions. Traverse the collected807  // debug lines and identify logical groups based on their start and808  // address. Each group starts with a zero address.809  // Begin, End, Address, IsDone.810  using LVBucket = std::tuple<size_t, size_t, LVAddress, bool>;811  std::vector<LVBucket> Buckets;812 813  LVAddress Address;814  size_t Begin = 0;815  size_t End = 0;816  size_t Index = 0;817  for (Index = 0; Index < AddressZero.size() - 1; ++Index) {818    Begin = AddressZero[Index];819    End = AddressZero[Index + 1] - 1;820    Address = (*DebugLines)[End]->getAddress();821    Buckets.emplace_back(Begin, End, Address, false);822  }823 824  // Add the last bucket.825  if (Index) {826    Begin = AddressZero[Index];827    End = DebugLines->size() - 1;828    Address = (*DebugLines)[End]->getAddress();829    Buckets.emplace_back(Begin, End, Address, false);830  }831 832  LLVM_DEBUG({833    dbgs() << "\nDebug Lines buckets: " << Buckets.size() << "\n";834    for (LVBucket &Bucket : Buckets) {835      dbgs() << "Begin: " << format_decimal(std::get<0>(Bucket), 5) << ", "836             << "End: " << format_decimal(std::get<1>(Bucket), 5) << ", "837             << "Address: " << hexValue(std::get<2>(Bucket)) << "\n";838    }839  });840 841  // Traverse the sections and buckets looking for matches on the section842  // sizes. In the unlikely event of different buckets with the same size843  // process them in order and mark them as done.844  LVLines Group;845  for (LVSections::reference Entry : Sections) {846    LVSectionIndex SectionIndex = Entry.first;847    const object::SectionRef Section = Entry.second;848    uint64_t Size = Section.getSize();849    LLVM_DEBUG({850      dbgs() << "\nSection Index: " << format_decimal(SectionIndex, 3)851             << " , Section Size: " << hexValue(Section.getSize())852             << " , Section Address: " << hexValue(Section.getAddress())853             << "\n";854    });855 856    for (LVBucket &Bucket : Buckets) {857      if (std::get<3>(Bucket))858        // Already done for previous section.859        continue;860      if (Size == std::get<2>(Bucket)) {861        // We have a match on the section size.862        Group.clear();863        LVLines::iterator IterStart = DebugLines->begin() + std::get<0>(Bucket);864        LVLines::iterator IterEnd =865            DebugLines->begin() + std::get<1>(Bucket) + 1;866        for (LVLines::iterator Iter = IterStart; Iter < IterEnd; ++Iter)867          Group.push_back(*Iter);868        processLines(&Group, SectionIndex, /*Function=*/nullptr);869        std::get<3>(Bucket) = true;870        break;871      }872    }873  }874}875 876// Traverse the scopes for the given 'Function' looking for any inlined877// scopes with inlined lines, which are found in 'CUInlineeLines'.878void LVBinaryReader::includeInlineeLines(LVSectionIndex SectionIndex,879                                         LVScope *Function) {880  SmallVector<LVInlineeLine::iterator> InlineeIters;881  std::function<void(LVScope * Parent)> FindInlinedScopes =882      [&](LVScope *Parent) {883        if (const LVScopes *Scopes = Parent->getScopes())884          for (LVScope *Scope : *Scopes) {885            LVInlineeLine::iterator Iter = CUInlineeLines.find(Scope);886            if (Iter != CUInlineeLines.end())887              InlineeIters.push_back(Iter);888            FindInlinedScopes(Scope);889          }890      };891 892  // Find all inlined scopes for the given 'Function'.893  FindInlinedScopes(Function);894  for (LVInlineeLine::iterator InlineeIter : InlineeIters) {895    LVScope *Scope = InlineeIter->first;896    addToSymbolTable(Scope->getLinkageName(), Scope, SectionIndex);897 898    // TODO: Convert this into a reference.899    LVLines *InlineeLines = InlineeIter->second.get();900    LLVM_DEBUG({901      dbgs() << "Inlined lines for: " << Scope->getName() << "\n";902      for (const LVLine *Line : *InlineeLines)903        dbgs() << "[" << hexValue(Line->getAddress()) << "] "904               << Line->getLineNumber() << "\n";905      dbgs() << format("Debug lines: %d\n", CULines.size());906      for (const LVLine *Line : CULines)907        dbgs() << "Line address: " << hexValue(Line->getOffset()) << ", ("908               << Line->getLineNumber() << ")\n";909      ;910    });911 912    // The inlined lines must be merged using its address, in order to keep913    // the real order of the instructions. The inlined lines are mixed with914    // the other non-inlined lines.915    if (InlineeLines->size()) {916      // First address of inlinee code.917      uint64_t InlineeStart = (InlineeLines->front())->getAddress();918      LVLines::iterator Iter =919          llvm::find_if(CULines, [&](LVLine *Item) -> bool {920            return Item->getAddress() == InlineeStart;921          });922      if (Iter != CULines.end()) {923        // 'Iter' points to the line where the inlined function is called.924        // Emulate the DW_AT_call_line attribute.925        Scope->setCallLineNumber((*Iter)->getLineNumber());926        // Mark the referenced line as the start of the inlined function.927        // Skip the first line during the insertion, as the address and928        // line number as the same. Otherwise we have to erase and insert.929        (*Iter)->setLineNumber((*InlineeLines->begin())->getLineNumber());930        ++Iter;931        CULines.insert(Iter, InlineeLines->begin() + 1, InlineeLines->end());932      }933    }934 935    // Remove this set of lines from the container; each inlined function936    // creates an unique set of lines. Remove only the created container.937    CUInlineeLines.erase(InlineeIter);938    InlineeLines->clear();939  }940  LLVM_DEBUG({941    dbgs() << "Merged Inlined lines for: " << Function->getName() << "\n";942    dbgs() << format("Debug lines: %d\n", CULines.size());943    for (const LVLine *Line : CULines)944      dbgs() << "Line address: " << hexValue(Line->getOffset()) << ", ("945             << Line->getLineNumber() << ")\n";946    ;947  });948}949 950void LVBinaryReader::print(raw_ostream &OS) const {951  OS << "LVBinaryReader\n";952  LLVM_DEBUG(dbgs() << "PrintReader\n");953}954