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

Support zlib-gnu compressed debug symbols #230

Merged
merged 1 commit into from
May 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,6 @@
[submodule "third_party/demumble"]
path = third_party/demumble
url = https://github.com/nico/demumble.git
[submodule "third_party/zlib"]
path = third_party/zlib
url = https://github.com/madler/zlib
43 changes: 43 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ option(BLOATY_ENABLE_UBSAN "Enable undefined behavior sanitizer." OFF)
option(BLOATY_ENABLE_CMAKETARGETS "Enable installing cmake target files." ON)
option(BLOATY_ENABLE_BUILDID "Enable build id." ON)
option(BLOATY_ENABLE_RE2 "Enable the support for regular expression functions." ON)
option(BLOATY_ENABLE_ZLIB "Enable support for compressed debug info." ON)

if(UNIX)
find_package(PkgConfig)
Expand All @@ -19,6 +20,9 @@ if(BLOATY_ENABLE_RE2)
endif(BLOATY_ENABLE_RE2)
pkg_search_module(CAPSTONE capstone)
pkg_search_module(PROTOBUF protobuf)
if(BLOATY_ENABLE_ZLIB)
pkg_search_module(ZLIB zlib)
endif(BLOATY_ENABLE_ZLIB)
if(BLOATY_ENABLE_RE2)
if(${RE2_FOUND})
MESSAGE(STATUS "System re2 found, using")
Expand All @@ -36,6 +40,13 @@ if(${PROTOBUF_FOUND})
else(${PROTOBUF_FOUND})
MESSAGE(STATUS "System protobuf not found, using bundled version")
endif(${PROTOBUF_FOUND})
if(BLOATY_ENABLE_ZLIB)
if (${ZLIB_FOUND})
MESSAGE(STATUS "System zlib found, using")
else(${ZLIB_FOUND})
MESSAGE(STATUS "System zlib not found, using bundled version")
endif(${ZLIB_FOUND})
endif(BLOATY_ENABLE_ZLIB)
else(${PKG_CONFIG_FOUND})
MESSAGE(STATUS "pkg-config not found, using bundled dependencies")
endif(${PKG_CONFIG_FOUND})
Expand All @@ -62,6 +73,10 @@ if(BLOATY_ENABLE_RE2)
add_definitions(-DUSE_RE2)
endif(BLOATY_ENABLE_RE2)

if(BLOATY_ENABLE_ZLIB)
add_definitions(-DUSE_ZLIB)
endif(BLOATY_ENABLE_ZLIB)

# Set MSVC runtime before including thirdparty libraries
if(MSVC)
# Link also the runtime library statically so that MSVCR*.DLL is not required at runtime.
Expand Down Expand Up @@ -103,6 +118,14 @@ if(UNIX)
add_subdirectory(third_party/protobuf/cmake)
include_directories(SYSTEM third_party/protobuf/src)
endif(${PROTOBUF_FOUND})
if(BLOATY_ENABLE_ZLIB)
if(${ZLIB_FOUND})
include_directories(${ZLIB_INCLUDE_DIRS})
else(${ZLIB_FOUND})
add_subdirectory(third_party/zlib)
include_directories(third_party/zlib)
endif(${ZLIB_FOUND})
endif(BLOATY_ENABLE_ZLIB)
else(UNIX)
if(BLOATY_ENABLE_RE2)
set(RE2_BUILD_TESTING OFF CACHE BOOL "enable testing for RE2" FORCE)
Expand All @@ -119,6 +142,11 @@ else(UNIX)
set(protobuf_BUILD_SHARED_LIBS OFF CACHE BOOL "enable shared libs for proto2" FORCE)
add_subdirectory(third_party/protobuf/cmake)
include_directories(SYSTEM third_party/protobuf/src)

if(BLOATY_ENABLE_ZLIB)
add_subdirectory(third_party/zlib)
include_directories(third_party/zlib)
endif(BLOATY_ENABLE_ZLIB)
endif(UNIX)

include_directories(.)
Expand Down Expand Up @@ -238,11 +266,21 @@ if(UNIX)
else(${CAPSTONE_FOUND})
set(LIBBLOATY_LIBS ${LIBBLOATY_LIBS} capstone-static)
endif(${CAPSTONE_FOUND})
if(BLOATY_ENABLE_ZLIB)
if(${ZLIB_FOUND})
set(LIBBLOATY_LIBS ${LIBBLOATY_LIBS} ${ZLIB_LIBRARIES})
else(${ZLIB_FOUND})
set(LIBBLOATY_LIBS ${LIBBLOATY_LIBS} zlib)
endif(${ZLIB_FOUND})
endif(BLOATY_ENABLE_ZLIB)
else(UNIX)
set(LIBBLOATY_LIBS libbloaty libprotoc capstone-static)
if(BLOATY_ENABLE_RE2)
set(LIBBLOATY_LIBS ${LIBBLOATY_LIBS} re2)
endif(BLOATY_ENABLE_RE2)
if(BLOATY_ENABLE_ZLIB)
set(LIBBLOATY_LIBS ${LIBBLOATY_LIBS} zlib)
endif(BLOATY_ENABLE_ZLIB)
endif(UNIX)

if(UNIX)
Expand All @@ -257,6 +295,11 @@ if(UNIX)
if(${PROTOBUF_FOUND})
link_directories(${PROTOBUF_LIBRARY_DIRS})
endif(${PROTOBUF_FOUND})
if(BLOATY_ENABLE_ZLIB)
if(${ZLIB_FOUND})
link_directories(${ZLIB_LIBRARY_DIRS})
endif(${ZLIB_FOUND})
endif(BLOATY_ENABLE_ZLIB)
endif(UNIX)

if(DEFINED ENV{LIB_FUZZING_ENGINE})
Expand Down
4 changes: 4 additions & 0 deletions src/bloaty.h
Original file line number Diff line number Diff line change
Expand Up @@ -331,8 +331,12 @@ struct File {
absl::string_view debug_pubnames;
absl::string_view debug_pubtypes;
absl::string_view debug_ranges;

absl::string_view *member_field_by_name(absl::string_view name);
};

absl::string_view zdebug_decompress(absl::string_view contents);

} // namespace dwarf

// Provided by dwarf.cc. To use these, a module should fill in a dwarf::File
Expand Down
57 changes: 57 additions & 0 deletions src/dwarf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
#include <unordered_map>
#include <unordered_set>
#include <vector>
#ifdef USE_ZLIB
#include <zlib.h>
#endif

#include "absl/base/attributes.h"
#include "absl/base/macros.h"
Expand Down Expand Up @@ -1357,6 +1360,60 @@ bool LineInfoReader::ReadLineInfo() {
}
}

string_view *File::member_field_by_name(string_view name) {
if (name == "aranges") {
return &debug_aranges;
} else if (name == "str") {
return &debug_str;
} else if (name == "info") {
return &(debug_info);
} else if (name == "types") {
return &(debug_types);
} else if (name == "abbrev") {
return &(debug_abbrev);
} else if (name == "line") {
return &(debug_line);
} else if (name == "loc") {
return &(debug_loc);
} else if (name == "pubnames") {
return &(debug_pubnames);
} else if (name == "pubtypes") {
return &(debug_pubtypes);
} else if (name == "ranges") {
return &(debug_ranges);
} else {
return NULL;
}
}

string_view zdebug_decompress(string_view contents) {
#ifdef USE_ZLIB
if (contents.size() < 12 || (contents.substr(0, 4) != "ZLIB")) {
return NULL;
}
contents.remove_prefix(4);
uint64_t dlen = uint64_t(uint8_t(contents[7])) +
(uint64_t(uint8_t(contents[6])) << 8) +
(uint64_t(uint8_t(contents[5])) << 16) +
(uint64_t(uint8_t(contents[4])) << 24) +
(uint64_t(uint8_t(contents[3])) << 32) +
(uint64_t(uint8_t(contents[2])) << 40) +
(uint64_t(uint8_t(contents[1])) << 48) +
(uint64_t(uint8_t(contents[0])) << 56);
contents.remove_prefix(8);
unsigned char *dbuf = new unsigned char[dlen];
uLongf zliblen = dlen;
if (uncompress(dbuf, &zliblen, (unsigned char*)(contents.data()), contents.size()) != Z_OK) {
delete[] dbuf;
return NULL;
}
string_view sv((char *)dbuf, zliblen);
return sv;
#else
return NULL;
#endif
}

} // namespace dwarf

// Bloaty DWARF Data Sources ///////////////////////////////////////////////////
Expand Down
40 changes: 20 additions & 20 deletions src/elf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1220,27 +1220,27 @@ static void ReadDWARFSections(const InputFile& file, dwarf::File* dwarf) {
ElfFile::Section section;
elf.ReadSection(i, &section);
string_view name = section.GetName();
string_view *target = NULL;
bool decompress = false;

if (name.find(".debug_") == 0) {
string_view suffix = name;
suffix.remove_prefix(string_view(".debug_").size());
target = dwarf->member_field_by_name(suffix);
} else if (name.find(".zdebug_") == 0) {
string_view suffix = name;
suffix.remove_prefix(string_view(".zdebug_").size());
decompress = true;
target = dwarf->member_field_by_name(suffix);
}

if (name == ".debug_aranges") {
dwarf->debug_aranges = section.contents();
} else if (name == ".debug_str") {
dwarf->debug_str = section.contents();
} else if (name == ".debug_info") {
dwarf->debug_info = section.contents();
} else if (name == ".debug_types") {
dwarf->debug_types = section.contents();
} else if (name == ".debug_abbrev") {
dwarf->debug_abbrev = section.contents();
} else if (name == ".debug_line") {
dwarf->debug_line = section.contents();
} else if (name == ".debug_loc") {
dwarf->debug_loc = section.contents();
} else if (name == ".debug_pubnames") {
dwarf->debug_pubnames = section.contents();
} else if (name == ".debug_pubtypes") {
dwarf->debug_pubtypes = section.contents();
} else if (name == ".debug_ranges") {
dwarf->debug_ranges = section.contents();
if (target != NULL) {
if (decompress) {
// XXX zdebug_decompress leaks an allocation XXX
*target = dwarf::zdebug_decompress(section.contents());
} else {
*target = section.contents();
}
}
}
}
Expand Down
40 changes: 20 additions & 20 deletions src/macho.cc
Original file line number Diff line number Diff line change
Expand Up @@ -539,27 +539,27 @@ void ReadDebugSectionsFromSegment(LoadCommand cmd, dwarf::File* dwarf) {

string_view contents =
StrictSubstr(cmd.file_data, section->offset, filesize);
string_view *target = NULL;
bool decompress = false;

if (sectname.find("__debug_") == 0) {
string_view suffix = sectname;
suffix.remove_prefix(string_view("__debug_").size());
target = dwarf->member_field_by_name(suffix);
} else if (sectname.find("__zdebug_") == 0) {
string_view suffix = sectname;
decompress = true;
suffix.remove_prefix(string_view("__zdebug_").size());
target = dwarf->member_field_by_name(suffix);
}

if (sectname == "__debug_aranges") {
dwarf->debug_aranges = contents;
} else if (sectname == "__debug_str") {
dwarf->debug_str = contents;
} else if (sectname == "__debug_info") {
dwarf->debug_info = contents;
} else if (sectname == "__debug_types") {
dwarf->debug_types = contents;
} else if (sectname == "__debug_abbrev") {
dwarf->debug_abbrev = contents;
} else if (sectname == "__debug_line") {
dwarf->debug_line = contents;
} else if (sectname == "__debug_loc") {
dwarf->debug_loc = contents;
} else if (sectname == "__debug_pubnames") {
dwarf->debug_pubnames = contents;
} else if (sectname == "__debug_pubtypes") {
dwarf->debug_pubtypes = contents;
} else if (sectname == "__debug_ranges") {
dwarf->debug_ranges = contents;
if (target != NULL) {
if (decompress) {
// XXX zdebug_decompress leaks an allocation XXX
*target = dwarf::zdebug_decompress(contents);
} else {
*target = contents;
}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions third_party/zlib
Submodule zlib added at cacf7f