Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactored the DWARF parser #280

Merged
merged 11 commits into from
Aug 8, 2021
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,14 @@ add_library(libbloaty STATIC
src/bloaty.h
src/disassemble.cc
${CMAKE_CURRENT_BINARY_DIR}/src/bloaty.pb.cc
src/dwarf/attr.h
src/dwarf/attr.cc
src/dwarf/dwarf_util.cc
src/dwarf/debug_info.cc
src/dwarf/line_info.cc
src/dwarf.cc
src/dwarf_constants.h
src/eh_frame.cc
src/elf.cc
src/macho.cc
src/pe.cc
Expand Down
61 changes: 0 additions & 61 deletions src/bloaty.cc
Original file line number Diff line number Diff line change
Expand Up @@ -165,67 +165,6 @@ static std::string CSVEscape(string_view str) {
}
}


// LineReader / LineIterator ///////////////////////////////////////////////////

// Convenience code for iterating over lines of a pipe.

#if !defined(_MSC_VER)
LineReader::LineReader(LineReader&& other) {
Close();

file_ = other.file_;
pclose_ = other.pclose_;

other.file_ = nullptr;
}

void LineReader::Close() {
if (!file_) return;

if (pclose_) {
pclose(file_);
} else {
fclose(file_);
}
}

void LineReader::Next() {
char buf[256];
line_.clear();
do {
if (!fgets(buf, sizeof(buf), file_)) {
if (feof(file_)) {
eof_ = true;
break;
} else {
std::cerr << "Error reading from file.\n";
exit(1);
}
}
line_.append(buf);
} while(!eof_ && line_[line_.size() - 1] != '\n');

if (!eof_) {
line_.resize(line_.size() - 1);
}
}

LineIterator LineReader::begin() { return LineIterator(this); }
LineIterator LineReader::end() { return LineIterator(nullptr); }

LineReader ReadLinesFromPipe(const std::string& cmd) {
FILE* pipe = popen(cmd.c_str(), "r");

if (!pipe) {
std::cerr << "Failed to run command: " << cmd << "\n";
exit(1);
}

return LineReader(pipe, true);
}
#endif

extern "C" char* __cxa_demangle(const char* mangled_name, char* buf, size_t* n,
int* status);

Expand Down
85 changes: 1 addition & 84 deletions src/bloaty.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "absl/strings/strip.h"
#include "capstone/capstone.h"

#include "dwarf/debug_info.h"
#include "bloaty.pb.h"
#include "range_map.h"
#include "re.h"
Expand Down Expand Up @@ -290,32 +291,6 @@ std::unique_ptr<ObjectFile> TryOpenMachOFile(std::unique_ptr<InputFile>& file);
std::unique_ptr<ObjectFile> TryOpenWebAssemblyFile(std::unique_ptr<InputFile>& file);
std::unique_ptr<ObjectFile> TryOpenPEFile(std::unique_ptr<InputFile>& file);

namespace dwarf {

struct File {
absl::string_view debug_abbrev;
absl::string_view debug_addr;
absl::string_view debug_aranges;
absl::string_view debug_info;
absl::string_view debug_line;
absl::string_view debug_loc;
absl::string_view debug_pubnames;
absl::string_view debug_pubtypes;
absl::string_view debug_ranges;
absl::string_view debug_rnglists;
absl::string_view debug_str;
absl::string_view debug_str_offsets;
absl::string_view debug_types;

absl::string_view* GetFieldByName(absl::string_view name);
void SetFieldByName(absl::string_view name, absl::string_view contents) {
absl::string_view *member = GetFieldByName(name);
if (member) *member = contents;
}
};

} // namespace dwarf

// Provided by dwarf.cc. To use these, a module should fill in a dwarf::File
// and then call these functions.
void ReadDWARFCompileUnits(const dwarf::File& file, const SymbolTable& symtab,
Expand All @@ -325,64 +300,6 @@ void ReadDWARFInlines(const dwarf::File& file, RangeSink* sink,
void ReadEhFrame(absl::string_view contents, RangeSink* sink);
void ReadEhFrameHdr(absl::string_view contents, RangeSink* sink);


// LineReader //////////////////////////////////////////////////////////////////

// Provides range-based for to iterate over lines in a pipe.
//
// for ( auto& line : ReadLinesFromPipe("ls -l") ) {
// }

class LineIterator;

class LineReader {
public:
LineReader(FILE* file, bool pclose) : file_(file), pclose_(pclose) {}
LineReader(LineReader&& other);
LineReader(const LineReader&) = delete;
LineReader& operator=(const LineReader&);


~LineReader() { Close(); }

LineIterator begin();
LineIterator end();

void Next();

const std::string& line() const { return line_; }
bool eof() { return eof_; }

private:
void Close();

FILE* file_;
std::string line_;
bool eof_ = false;
bool pclose_;
};

class LineIterator {
public:
LineIterator(LineReader* reader) : reader_(reader) {}

bool operator!=(const LineIterator& /*other*/) const {
// Hack for range-based for.
return !reader_->eof();
}

void operator++() { reader_->Next(); }

const std::string& operator*() const {
return reader_->line();
}

private:
LineReader* reader_;
};

LineReader ReadLinesFromPipe(const std::string& cmd);

// Demangle C++ symbols according to the Itanium ABI. The |source| argument
// controls what demangling mode we are using.
std::string ItaniumDemangle(absl::string_view symbol, DataSource source);
Expand Down
Loading