<commit_before>//===- DWARFContext.cpp ---------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugAranges.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/DebugInfo/DWARF/DWARFGdbIndex.h"
#include "llvm/DebugInfo/DWARF/DWARFSection.h"
#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
#include "llvm/DebugInfo/DWARF/DWARFVerifier.h"
#include "llvm/Object/Decompressor.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Object/RelocVisitor.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cstdint>
#include <map>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

using namespace llvm;
using namespace dwarf;
using namespace object;

#define DEBUG_TYPE "dwarf"

using DWARFLineTable = DWARFDebugLine::LineTable;
using FileLineInfoKind = DILineInfoSpecifier::FileLineInfoKind;
using FunctionNameKind = DILineInfoSpecifier::FunctionNameKind;

static void dumpAccelSection(raw_ostream &OS, StringRef Name,
                             const DWARFSection& Section, StringRef StringSection,
                             bool LittleEndian) {
  DWARFDataExtractor AccelSection(Section, LittleEndian, 0);
  DataExtractor StrData(StringSection, LittleEndian, 0);
  OS << "\n." << Name << " contents:\n";
  DWARFAcceleratorTable Accel(AccelSection, StrData);
  if (!Accel.extract())
    return;
  Accel.dump(OS);
}

static void
dumpDWARFv5StringOffsetsSection(raw_ostream &OS, StringRef SectionName,
                                const DWARFSection &StringOffsetsSection,
                                StringRef StringSection, bool LittleEndian) {
  DWARFDataExtractor StrOffsetExt(StringOffsetsSection, LittleEndian, 0);
  uint32_t Offset = 0;
  uint64_t SectionSize = StringOffsetsSection.Data.size();

  while (Offset < SectionSize) {
    unsigned Version = 0;
    DwarfFormat Format = DWARF32;
    unsigned EntrySize = 4;
    // Perform validation and extract the segment size from the header.
    if (!StrOffsetExt.isValidOffsetForDataOfSize(Offset, 4)) {
      OS << "error: invalid contribution to string offsets table in section ."
         << SectionName << ".\n";
      return;
    }
    uint32_t ContributionStart = Offset;
    uint64_t ContributionSize = StrOffsetExt.getU32(&Offset);
    // A contribution size of 0xffffffff indicates DWARF64, with the actual size
    // in the following 8 bytes. Otherwise, the DWARF standard mandates that
    // the contribution size must be at most 0xfffffff0.
    if (ContributionSize == 0xffffffff) {
      if (!StrOffsetExt.isValidOffsetForDataOfSize(Offset, 8)) {
        OS << "error: invalid contribution to string offsets table in section ."
           << SectionName << ".\n";
        return;
      }
      Format = DWARF64;
      EntrySize = 8;
      ContributionSize = StrOffsetExt.getU64(&Offset);
    } else if (ContributionSize > 0xfffffff0) {
      OS << "error: invalid contribution to string offsets table in section ."
         << SectionName << ".\n";
      return;
    }

    // We must ensure that we don't read a partial record at the end, so we
    // validate for a multiple of EntrySize. Also, we're expecting a version
    // number and padding, which adds an additional 4 bytes.
    uint64_t ValidationSize =
        4 + ((ContributionSize + EntrySize - 1) & (-(uint64_t)EntrySize));
    if (!StrOffsetExt.isValidOffsetForDataOfSize(Offset, ValidationSize)) {
      OS << "error: contribution to string offsets table in section ."
         << SectionName << " has invalid length.\n";
      return;
    }

    Version = StrOffsetExt.getU16(&Offset);
    Offset += 2;
    OS << format("0x%8.8x: ", ContributionStart);
    OS << "Contribution size = " << ContributionSize
       << ", Version = " << Version << "\n";

    uint32_t ContributionBase = Offset;
    DataExtractor StrData(StringSection, LittleEndian, 0);
    while (Offset - ContributionBase < ContributionSize) {
      OS << format("0x%8.8x: ", Offset);
      // FIXME: We can only extract strings in DWARF32 format at the moment.
      uint64_t StringOffset =
          StrOffsetExt.getRelocatedValue(EntrySize, &Offset);
      if (Format == DWARF32) {
        OS << format("%8.8x ", StringOffset);
        uint32_t StringOffset32 = (uint32_t)StringOffset;
        const char *S = StrData.getCStr(&StringOffset32);
        if (S)
          OS << format("\"%s\"", S);
      } else
        OS << format("%16.16x ", StringOffset);
      OS << "\n";
    }
  }
}

// Dump a DWARF string offsets section. This may be a DWARF v5 formatted
// string offsets section, where each compile or type unit contributes a
// number of entries (string offsets), with each contribution preceded by
// a header containing size and version number. Alternatively, it may be a
// monolithic series of string offsets, as generated by the pre-DWARF v5
// implementation of split DWARF.
static void dumpStringOffsetsSection(raw_ostream &OS, StringRef SectionName,
                                     const DWARFSection &StringOffsetsSection,
                                     StringRef StringSection, bool LittleEndian,
                                     unsigned MaxVersion) {
  if (StringOffsetsSection.Data.empty())
    return;
  OS << "\n." << SectionName << " contents:\n";
  // If we have at least one (compile or type) unit with DWARF v5 or greater,
  // we assume that the section is formatted like a DWARF v5 string offsets
  // section.
  if (MaxVersion >= 5)
    dumpDWARFv5StringOffsetsSection(OS, SectionName, StringOffsetsSection,<commit_msg>Merging r310253 and r310267: ------------------------------------------------------------------------ r310253 | sdardis | 2017-08-07 06:30:03 -0700 (Mon, 07 Aug 2017) | 2 lines<commit_after>//===- DWARFContext.cpp ---------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/DebugInfo/DWARF/DWARFAcceleratorTable.h"
#include "llvm/DebugInfo/DWARF/DWARFCompileUnit.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugAranges.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugMacro.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugPubTable.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugRangeList.h"
#include "llvm/DebugInfo/DWARF/DWARFDie.h"
#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
#include "llvm/DebugInfo/DWARF/DWARFGdbIndex.h"
#include "llvm/DebugInfo/DWARF/DWARFSection.h"
#include "llvm/DebugInfo/DWARF/DWARFUnitIndex.h"
#include "llvm/DebugInfo/DWARF/DWARFVerifier.h"
#include "llvm/Object/Decompressor.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Object/RelocVisitor.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/DataExtractor.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cstdint>
#include <map>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

using namespace llvm;
using namespace dwarf;
using namespace object;

#define DEBUG_TYPE "dwarf"

using DWARFLineTable = DWARFDebugLine::LineTable;
using FileLineInfoKind = DILineInfoSpecifier::FileLineInfoKind;
using FunctionNameKind = DILineInfoSpecifier::FunctionNameKind;

static void dumpAccelSection(raw_ostream &OS, StringRef Name,
                             const DWARFSection& Section, StringRef StringSection,
                             bool LittleEndian) {
  DWARFDataExtractor AccelSection(Section, LittleEndian, 0);
  DataExtractor StrData(StringSection, LittleEndian, 0);
  OS << "\n." << Name << " contents:\n";
  DWARFAcceleratorTable Accel(AccelSection, StrData);
  if (!Accel.extract())
    return;
  Accel.dump(OS);
}

static void
dumpDWARFv5StringOffsetsSection(raw_ostream &OS, StringRef SectionName,
                                const DWARFSection &StringOffsetsSection,
                                StringRef StringSection, bool LittleEndian) {
  DWARFDataExtractor StrOffsetExt(StringOffsetsSection, LittleEndian, 0);
  uint32_t Offset = 0;
  uint64_t SectionSize = StringOffsetsSection.Data.size();

  while (Offset < SectionSize) {
    unsigned Version = 0;
    DwarfFormat Format = DWARF32;
    unsigned EntrySize = 4;
    // Perform validation and extract the segment size from the header.
    if (!StrOffsetExt.isValidOffsetForDataOfSize(Offset, 4)) {
      OS << "error: invalid contribution to string offsets table in section ."
         << SectionName << ".\n";
      return;
    }
    uint32_t ContributionStart = Offset;
    uint64_t ContributionSize = StrOffsetExt.getU32(&Offset);
    // A contribution size of 0xffffffff indicates DWARF64, with the actual size
    // in the following 8 bytes. Otherwise, the DWARF standard mandates that
    // the contribution size must be at most 0xfffffff0.
    if (ContributionSize == 0xffffffff) {
      if (!StrOffsetExt.isValidOffsetForDataOfSize(Offset, 8)) {
        OS << "error: invalid contribution to string offsets table in section ."
           << SectionName << ".\n";
        return;
      }
      Format = DWARF64;
      EntrySize = 8;
      ContributionSize = StrOffsetExt.getU64(&Offset);
    } else if (ContributionSize > 0xfffffff0) {
      OS << "error: invalid contribution to string offsets table in section ."
         << SectionName << ".\n";
      return;
    }

    // We must ensure that we don't read a partial record at the end, so we
    // validate for a multiple of EntrySize. Also, we're expecting a version
    // number and padding, which adds an additional 4 bytes.
    uint64_t ValidationSize =
        4 + ((ContributionSize + EntrySize - 1) & (-(uint64_t)EntrySize));
    if (!StrOffsetExt.isValidOffsetForDataOfSize(Offset, ValidationSize)) {
      OS << "error: contribution to string offsets table in section ."
         << SectionName << " has invalid length.\n";
      return;
    }

    Version = StrOffsetExt.getU16(&Offset);
    Offset += 2;
    OS << format("0x%8.8x: ", ContributionStart);
    OS << "Contribution size = " << ContributionSize
       << ", Version = " << Version << "\n";

    uint32_t ContributionBase = Offset;
    DataExtractor StrData(StringSection, LittleEndian, 0);
    while (Offset - ContributionBase < ContributionSize) {
      OS << format("0x%8.8x: ", Offset);
      // FIXME: We can only extract strings in DWARF32 format at the moment.
      uint64_t StringOffset =
          StrOffsetExt.getRelocatedValue(EntrySize, &Offset);
      if (Format == DWARF32) {
        uint32_t StringOffset32 = (uint32_t)StringOffset;
        OS << format("%8.8x ", StringOffset32);
        const char *S = StrData.getCStr(&StringOffset32);
        if (S)
          OS << format("\"%s\"", S);
      } else
        OS << format("%16.16" PRIx64 " ", StringOffset);
      OS << "\n";
    }
  }
}

// Dump a DWARF string offsets section. This may be a DWARF v5 formatted
// string offsets section, where each compile or type unit contributes a
// number of entries (string offsets), with each contribution preceded by
// a header containing size and version number. Alternatively, it may be a
// monolithic series of string offsets, as generated by the pre-DWARF v5
// implementation of split DWARF.
static void dumpStringOffsetsSection(raw_ostream &OS, StringRef SectionName,
                                     const DWARFSection &StringOffsetsSection,
                                     StringRef StringSection, bool LittleEndian,
                                     unsigned MaxVersion) {
  if (StringOffsetsSection.Data.empty())
    return;
  OS << "\n." << SectionName << " contents:\n";
  // If we have at least one (compile or type) unit with DWARF v5 or greater,
  // we assume that the section is formatted like a DWARF v5 string offsets
  // section.
  if (MaxVersion >= 5)
    dumpDWARFv5StringOffsetsSection(OS, SectionName, StringOffsetsSection,
{'fraction_non_alphanumeric': 0.13202652061112713, 'fraction_numerical': 0.01491784375900836, 'mean_word_length': 3.041059988351776, 'pattern_counts': {'":': 0, '<': 137, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 8, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3612518', 'n_tokens_mistral': 4405, 'n_tokens_neox': 4218, 'n_words': 1096}