Skip to content

Commit

Permalink
Add debuginfod support (#3954)
Browse files Browse the repository at this point in the history
* Add DEBUGINFOD_URLS support
* Add rz_bin_dwarf_from_debuginfod
* Fix rz_bin_dwarf_attr_addr
* Add test for debuginfod
* Filter empty RzBinDWARF
  • Loading branch information
imbillow committed Nov 6, 2023
1 parent a336296 commit 4440004
Show file tree
Hide file tree
Showing 13 changed files with 265 additions and 51 deletions.
34 changes: 17 additions & 17 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ jobs:
if: matrix.run_tests && matrix.enabled && matrix.os != 'macos-12'
run: |
sudo apt-get update
sudo apt-get --assume-yes install libc6 libc6-i386 libc6-dev
sudo apt-get --assume-yes install libc6 libc6-i386 libc6-dev debuginfod
- name: Install gdbserver dependency
if: matrix.run_tests && matrix.enabled && matrix.os == 'ubuntu-22.04'
run: sudo apt-get --assume-yes install gdbserver
Expand Down Expand Up @@ -451,7 +451,7 @@ jobs:
- name: Install test dependencies
run: |
sudo pip3 install 'git+https://github.com/rizinorg/rz-pipe#egg=rzpipe&subdirectory=python'
sudo apt-get install --yes tzdata
sudo apt-get install --yes tzdata debuginfod
- name: Checkout rizin
run: |
git clone https://github.com/${{ github.repository }}
Expand Down Expand Up @@ -520,7 +520,7 @@ jobs:
- name: Run debug tests
run: |
cd test
rz-test -L -o results.json db/archos/linux-x64
rz-test -L -e db/archos/linux-x64/debuginfod -e db/archos/linux-x64/dbg_dmh -o results.json db/archos/linux-x64
working-directory: rizin

build-static:
Expand Down Expand Up @@ -608,7 +608,7 @@ jobs:
name: Test source tarball
if: contains(github.head_ref, 'dist') || contains(github.head_ref, 'extras') || contains(github.ref, 'release-') || github.ref == 'refs/heads/stable'
runs-on: ubuntu-22.04
needs: [create-tarball]
needs: [ create-tarball ]
steps:
- name: Install python and other dependencies
run: sudo apt-get --assume-yes install python3-wheel python3-setuptools python3-pip
Expand Down Expand Up @@ -646,7 +646,7 @@ jobs:
name: Build OSX package
runs-on: macos-12
if: contains(github.head_ref, 'dist') || contains(github.head_ref, 'osx') || contains(github.head_ref, 'mac') || ((contains(github.ref, 'release-') || github.ref == 'refs/heads/stable') && github.event_name == 'push') || github.event_name == 'schedule'
needs: [build-and-test]
needs: [ build-and-test ]
steps:
- uses: actions/checkout@v3
- name: Install pkg-config with Homebrew
Expand All @@ -669,11 +669,11 @@ jobs:
name: Build Windows zip/installer ${{ matrix.name }}
runs-on: windows-latest
if: contains(github.head_ref, 'dist') || contains(github.head_ref, 'windows') || (github.event_name == 'push' && (contains(github.ref, 'release-') || github.ref == 'refs/heads/stable'))
needs: [build-and-test]
needs: [ build-and-test ]
strategy:
fail-fast: false
matrix:
name: [vs2019_static, clang_cl, clang_cl_x86]
name: [ vs2019_static, clang_cl, clang_cl_x86 ]
include:
- name: vs2019_static
compiler: cl
Expand Down Expand Up @@ -714,11 +714,11 @@ jobs:
name: Build Android ${{ matrix.name }} package
runs-on: ubuntu-22.04
if: contains(github.head_ref, 'dist') || contains(github.head_ref, 'android') || ((contains(github.ref, 'release-') || github.ref == 'refs/heads/stable') && github.event_name == 'push') || github.event_name == 'schedule'
needs: [build-and-test]
needs: [ build-and-test ]
strategy:
fail-fast: false
matrix:
name: [x86_64, arm, aarch64]
name: [ x86_64, arm, aarch64 ]
steps:
- uses: actions/checkout@v3
- name: Install dependencies
Expand All @@ -743,7 +743,7 @@ jobs:
name: Include Rizin headers from C++ program (Linux)
runs-on: ubuntu-22.04
if: contains(github.head_ref, 'dist') || contains(github.head_ref, 'cpp') || ((contains(github.ref, 'release-') || github.ref == 'refs/heads/stable') && github.event_name == 'push') || github.event_name == 'schedule'
needs: [build-and-test]
needs: [ build-and-test ]
steps:
- uses: actions/checkout@v3
- name: Install dependencies
Expand All @@ -769,7 +769,7 @@ jobs:
name: Test EXTRA_PREFIX works well
runs-on: ubuntu-22.04
if: contains(github.head_ref, 'dist') || ((contains(github.ref, 'release-') || github.ref == 'refs/heads/stable') && github.event_name == 'push') || github.event_name == 'schedule'
needs: [build-and-test]
needs: [ build-and-test ]
steps:
- uses: actions/checkout@v3
- name: Install dependencies
Expand All @@ -792,7 +792,7 @@ jobs:
build-rzpipe:
name: Build rizin rzpipe
if: contains(github.head_ref, 'dist') || contains(github.ref, 'release-') || github.ref == 'refs/heads/stable' || github.event_name == 'schedule'
needs: [test-tarball]
needs: [ test-tarball ]
runs-on: ubuntu-22.04
env:
RZPIPE_TESTS: "rz-pipe-py rz-pipe-go"
Expand Down Expand Up @@ -821,7 +821,7 @@ jobs:
build-bindgen:
name: Build rz-bindgen
if: contains(github.head_ref, 'dist') || contains(github.ref, 'release-') || github.ref == 'refs/heads/stable' || github.event_name == 'schedule'
needs: [test-tarball]
needs: [ test-tarball ]
runs-on: ubuntu-22.04
steps:
- uses: actions/download-artifact@v3
Expand Down Expand Up @@ -867,7 +867,7 @@ jobs:
system:
- macos-12
runs-on: ${{ matrix.system }}
needs: [build-osx-pkg]
needs: [ build-osx-pkg ]
steps:
- name: Install pkg-config with Homebrew
run: brew install pkg-config
Expand All @@ -888,10 +888,10 @@ jobs:
test-windows-clang_cl:
name: Test Windows installer built with ${{ matrix.name }}
runs-on: windows-latest
needs: [build-windows]
needs: [ build-windows ]
strategy:
matrix:
name: [clang_cl, clang_cl_x86]
name: [ clang_cl, clang_cl_x86 ]
include:
- name: clang_cl
bits: 64
Expand Down Expand Up @@ -1000,7 +1000,7 @@ jobs:
publish-docker-image:
name: Publish Docker image on Docker Hub
needs: [build-and-test]
needs: [ build-and-test ]
runs-on: ubuntu-22.04
if: github.event_name == 'push' || (github.event_name == 'pull_request' && contains(github.head_ref, 'container'))
steps:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/tcc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ jobs:
run: |
python3 -m pip install --user 'git+https://github.com/rizinorg/rz-pipe#egg=rzpipe&subdirectory=python'
sudo apt-get update
sudo apt-get --assume-yes install libc6 libc6-i386
sudo apt-get --assume-yes install libc6 libc6-i386 debuginfod
- name: Run tests
env:
Expand Down
9 changes: 6 additions & 3 deletions librz/analysis/dwarf_process.c
Original file line number Diff line number Diff line change
Expand Up @@ -1527,13 +1527,16 @@ static bool function_from_die(
fcn->link_name = attr_string(attr, ctx);
break;
case DW_AT_low_pc:
fcn->low_pc = rz_bin_dwarf_attr_udata(attr);
fcn->low_pc = rz_bin_dwarf_attr_addr(
attr, ctx->dw, ctx->unit->hdr.encoding.address_size, ctx->unit->addr_base);
break;
case DW_AT_high_pc:
fcn->high_pc = rz_bin_dwarf_attr_udata(attr);
fcn->high_pc = rz_bin_dwarf_attr_addr(
attr, ctx->dw, ctx->unit->hdr.encoding.address_size, ctx->unit->addr_base);
break;
case DW_AT_entry_pc:
fcn->entry_pc = rz_bin_dwarf_attr_udata(attr);
fcn->entry_pc = rz_bin_dwarf_attr_addr(
attr, ctx->dw, ctx->unit->hdr.encoding.address_size, ctx->unit->addr_base);
break;
case DW_AT_specification: /* u64 to declaration DIE with more info */
{
Expand Down
12 changes: 7 additions & 5 deletions librz/bin/dwarf/addr.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
#include <rz_bin_dwarf.h>
#include "dwarf_private.h"

RZ_IPI bool DebugAddr_get_address(const RzBinDwarfAddr *self, ut64 *address,
RZ_API bool rz_bin_dwarf_addr_get(
RZ_BORROW RZ_NONNULL const RzBinDwarfAddr *self,
RZ_BORROW RZ_NONNULL ut64 *address,
ut8 address_size, ut64 base, ut64 index) {
rz_return_val_if_fail(self && self->reader && address, false);
RzBinEndianReader *reader = self->reader;
Expand All @@ -14,25 +16,25 @@ RZ_IPI bool DebugAddr_get_address(const RzBinDwarfAddr *self, ut64 *address,
return true;
}

RZ_IPI void DebugAddr_free(RzBinDwarfAddr *self) {
RZ_API void rz_bin_dwarf_addr_free(RzBinDwarfAddr *self) {
if (!self) {
return;
}
RzBinEndianReader_free(self->reader);
free(self);
}

RZ_IPI RzBinDwarfAddr *DebugAddr_new(RzBinEndianReader *reader) {
RZ_API RZ_OWN RzBinDwarfAddr *rz_bin_dwarf_addr_new(RZ_OWN RZ_NONNULL RzBinEndianReader *reader) {
rz_return_val_if_fail(reader, NULL);
RzBinDwarfAddr *self = RZ_NEW0(RzBinDwarfAddr);
RET_NULL_IF_FAIL(self);
self->reader = reader;
return self;
}

RZ_IPI RzBinDwarfAddr *DebugAddr_from_file(RzBinFile *bf) {
RZ_API RZ_OWN RzBinDwarfAddr *rz_bin_dwarf_addr_from_file(RZ_BORROW RZ_NONNULL RzBinFile *bf) {
rz_return_val_if_fail(bf, NULL);
RzBinEndianReader *r = RzBinEndianReader_from_file(bf, ".debug_addr", false);
RET_NULL_IF_FAIL(r);
return DebugAddr_new(r);
return rz_bin_dwarf_addr_new(r);
}
14 changes: 7 additions & 7 deletions librz/bin/dwarf/attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ RZ_IPI bool RzBinDwarfAttr_parse(
// http://www.dwarfstd.org/doc/DWARF4.pdf#page=161&zoom=100,0,560
switch (attr->form) {
case DW_FORM_addr:
value->kind = RzBinDwarfAttr_Address;
value->kind = RzBinDwarfAttr_Addr;
RET_FALSE_IF_FAIL(read_address(reader, &value->u64, address_size));
break;
case DW_FORM_data1:
Expand Down Expand Up @@ -166,25 +166,25 @@ RZ_IPI bool RzBinDwarfAttr_parse(
DW_AT_addr_base attribute of the associated compilation unit.
index into an array of addresses in the .debug_addr section.*/
case DW_FORM_addrx:
value->kind = RzBinDwarfAttr_Address;
value->kind = RzBinDwarfAttr_AddrIndex;
ULE128_OR_RET_FALSE(value->u64);
break;
case DW_FORM_addrx1:
value->kind = RzBinDwarfAttr_Address;
value->kind = RzBinDwarfAttr_AddrIndex;
U8_OR_RET_FALSE(value->u64);
break;
case DW_FORM_addrx2:
value->kind = RzBinDwarfAttr_Address;
value->kind = RzBinDwarfAttr_AddrIndex;
U_OR_RET_FALSE(16, value->u64);
break;
case DW_FORM_addrx3:
// TODO: .DW_FORM_addrx3
value->kind = RzBinDwarfAttr_Address;
value->kind = RzBinDwarfAttr_AddrIndex;
rz_buf_seek(reader->buffer, 3, RZ_BUF_CUR);
RZ_LOG_ERROR("TODO: DW_FORM_addrx3\n");
break;
case DW_FORM_addrx4:
value->kind = RzBinDwarfAttr_Address;
value->kind = RzBinDwarfAttr_AddrIndex;
U_OR_RET_FALSE(32, value->u64);
break;
case DW_FORM_line_ptr: // offset in a section .debug_line_str
Expand All @@ -211,7 +211,7 @@ RZ_IPI bool RzBinDwarfAttr_parse(
break;
// An index into the .debug_rnglists
case DW_FORM_rnglistx:
value->kind = RzBinDwarfAttr_Address;
value->kind = RzBinDwarfAttr_RangelistPtr;
ULE128_OR_RET_FALSE(value->u64);
break;
default:
Expand Down
35 changes: 33 additions & 2 deletions librz/bin/dwarf/dwarf.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ static inline RZ_OWN RzBinDWARF *dwarf_from_file(
RzBinDWARF *dw = RZ_NEW0(RzBinDWARF);
RET_NULL_IF_FAIL(dw);

dw->addr = DebugAddr_from_file(bf);
dw->addr = rz_bin_dwarf_addr_from_file(bf);
dw->line_str = rz_bin_dwarf_line_str_from_file(bf);
dw->aranges = rz_bin_dwarf_aranges_from_file(bf);

Expand All @@ -38,6 +38,10 @@ static inline RZ_OWN RzBinDWARF *dwarf_from_file(
if (dw->info) {
dw->line = rz_bin_dwarf_line_from_file(bf, dw, is_dwo);
}
if (!(dw->addr || dw->line_str || dw->aranges || dw->str || dw->str_offsets || dw->loclists || dw->rnglists || dw->abbrev)) {
rz_bin_dwarf_free(dw);
return NULL;
}
return dw;
}

Expand Down Expand Up @@ -185,6 +189,33 @@ RZ_API RZ_OWN RzBinDWARF *rz_bin_dwarf_search_debug_file_directory(
return NULL;
}

RZ_API RZ_OWN RzBinDWARF *rz_bin_dwarf_from_debuginfod(
RZ_BORROW RZ_NONNULL RzBinFile *bf,
RZ_BORROW RZ_NONNULL RzList /*<const char *>*/ *debuginfod_urls) {
rz_return_val_if_fail(bf && debuginfod_urls, NULL);

RzBinDWARF *dw = NULL;
char *build_id = read_build_id(bf);
if (!build_id) {
return NULL;
}
RzListIter *it = NULL;
const char *debuginfod_url = NULL;
rz_list_foreach (debuginfod_urls, it, debuginfod_url) {
char *url = rz_str_newf("%s/buildid/%s/debuginfo", debuginfod_url, build_id);
if (!url) {
break;
}
dw = rz_bin_dwarf_from_path(url, false);
free(url);
if (dw) {
break;
}
}
free(build_id);
return dw;
}

/**
* \brief Load DWARF from split DWARF file
* \param filepath The file path
Expand Down Expand Up @@ -225,7 +256,7 @@ RZ_API void rz_bin_dwarf_free(RZ_OWN RZ_NULLABLE RzBinDWARF *dw) {
rz_bin_dwarf_free(dw->parent);

DebugRngLists_free(dw->rnglists);
DebugAddr_free(dw->addr);
rz_bin_dwarf_addr_free(dw->addr);
rz_bin_dwarf_str_free(dw->str);
rz_bin_dwarf_str_offsets_free(dw->str_offsets);

Expand Down
7 changes: 0 additions & 7 deletions librz/bin/dwarf/dwarf_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,6 @@ static inline bool bf_bigendian(RzBinFile *bf) {
}

RZ_IPI bool RzBinDwarfEncoding_from_file(RzBinDwarfEncoding *encoding, RzBinFile *bf);
/// addr

RZ_IPI bool DebugAddr_get_address(const RzBinDwarfAddr *self, ut64 *address,
ut8 address_size, ut64 base, ut64 index);
RZ_IPI void DebugAddr_free(RzBinDwarfAddr *self);
RZ_IPI RzBinDwarfAddr *DebugAddr_new(RzBinEndianReader *reader);
RZ_IPI RzBinDwarfAddr *DebugAddr_from_file(RzBinFile *bf);

/// range

Expand Down
8 changes: 4 additions & 4 deletions librz/bin/dwarf/loclists.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ static bool convert_raw(
*entry = NULL;
return true;
case DW_LLE_base_addressx:
ERR_IF_FAIL(DebugAddr_get_address(
ERR_IF_FAIL(rz_bin_dwarf_addr_get(
addr, &self->base_address,
encoding->address_size, cu->addr_base, raw->base_addressx.addr));
return true;
Expand All @@ -175,17 +175,17 @@ static bool convert_raw(
case DW_LLE_startx_endx:
range = RZ_NEW0(RzBinDwarfRange);
ERR_IF_FAIL(range);
ERR_IF_FAIL(DebugAddr_get_address(
ERR_IF_FAIL(rz_bin_dwarf_addr_get(
addr, &range->begin,
encoding->address_size, cu->addr_base, raw->startx_endx.begin));
ERR_IF_FAIL(DebugAddr_get_address(
ERR_IF_FAIL(rz_bin_dwarf_addr_get(
addr, &range->end,
encoding->address_size, cu->addr_base, raw->startx_endx.end));
break;
case DW_LLE_startx_length:
range = RZ_NEW0(RzBinDwarfRange);
ERR_IF_FAIL(range);
ERR_IF_FAIL(DebugAddr_get_address(
ERR_IF_FAIL(rz_bin_dwarf_addr_get(
addr, &range->begin,
encoding->address_size, cu->addr_base, raw->startx_length.begin));
range->end = (raw->startx_length.length + raw->startx_length.begin) & mask;
Expand Down
8 changes: 4 additions & 4 deletions librz/bin/dwarf/rnglists.c
Original file line number Diff line number Diff line change
Expand Up @@ -154,22 +154,22 @@ static bool convert_raw(
*out = NULL;
return true;
case DW_RLE_base_addressx:
RET_FALSE_IF_FAIL(DebugAddr_get_address(addr, &self->base_address,
RET_FALSE_IF_FAIL(rz_bin_dwarf_addr_get(addr, &self->base_address,
cu->hdr.encoding.address_size, cu->addr_base, raw->base_addressx.addr));
*out = NULL;
return true;
case DW_RLE_startx_endx:
range = RZ_NEW0(RzBinDwarfRange);
RET_FALSE_IF_FAIL(range);
RET_FALSE_IF_FAIL(DebugAddr_get_address(addr, &range->begin,
RET_FALSE_IF_FAIL(rz_bin_dwarf_addr_get(addr, &range->begin,
cu->hdr.encoding.address_size, cu->addr_base, raw->startx_endx.begin));
RET_FALSE_IF_FAIL(DebugAddr_get_address(addr, &range->end,
RET_FALSE_IF_FAIL(rz_bin_dwarf_addr_get(addr, &range->end,
cu->hdr.encoding.address_size, cu->addr_base, raw->startx_endx.end));
break;
case DW_RLE_startx_length:
range = RZ_NEW0(RzBinDwarfRange);
RET_FALSE_IF_FAIL(range);
RET_FALSE_IF_FAIL(DebugAddr_get_address(addr, &range->begin,
RET_FALSE_IF_FAIL(rz_bin_dwarf_addr_get(addr, &range->begin,
cu->hdr.encoding.address_size, cu->addr_base, raw->startx_length.begin));
range->end = (raw->startx_length.length + raw->startx_length.begin) & mask;
break;
Expand Down
Loading

0 comments on commit 4440004

Please sign in to comment.