Add debuginfod support (#3954)
* Add DEBUGINFOD_URLS support * Add rz_bin_dwarf_from_debuginfod * Fix rz_bin_dwarf_attr_addr * Add test for debuginfod * Filter empty RzBinDWARF
This commit is contained in:
parent
a336296356
commit
444000416c
13 changed files with 265 additions and 51 deletions
34
.github/workflows/ci.yml
vendored
34
.github/workflows/ci.yml
vendored
|
|
@ -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
|
||||
|
|
@ -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 }}
|
||||
|
|
@ -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:
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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"
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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:
|
||||
|
|
|
|||
2
.github/workflows/tcc.yml
vendored
2
.github/workflows/tcc.yml
vendored
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -14,7 +16,7 @@ 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;
|
||||
}
|
||||
|
|
@ -22,7 +24,7 @@ RZ_IPI void DebugAddr_free(RzBinDwarfAddr *self) {
|
|||
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);
|
||||
|
|
@ -30,9 +32,9 @@ RZ_IPI RzBinDwarfAddr *DebugAddr_new(RzBinEndianReader *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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
@ -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
|
||||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -652,6 +652,24 @@ static inline RzBinDWARF *load_dwarf(RzCore *core, RzBinFile *binfile) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rz_config_get_b(core->config, "bin.dbginfo.debuginfod")) {
|
||||
char *debuginfod_urls = (char *)rz_config_get(core->config, "bin.dbginfo.debuginfod_urls");
|
||||
if (RZ_STR_ISNOTEMPTY(debuginfod_urls)) {
|
||||
debuginfod_urls = rz_str_new(debuginfod_urls);
|
||||
} else {
|
||||
debuginfod_urls = rz_sys_getenv("DEBUGINFOD_URLS");
|
||||
}
|
||||
RzList *urls = RZ_STR_ISNOTEMPTY(debuginfod_urls) ? rz_str_split_duplist(debuginfod_urls, " ", true) : NULL;
|
||||
if (urls) {
|
||||
RzBinDWARF *sep_dw = rz_bin_dwarf_from_debuginfod(binfile, urls);
|
||||
rz_list_free(urls);
|
||||
if (sep_dw) {
|
||||
sep_dw->parent = dw;
|
||||
return sep_dw;
|
||||
}
|
||||
}
|
||||
}
|
||||
return dw;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3248,6 +3248,10 @@ RZ_API int rz_core_config_init(RzCore *core) {
|
|||
SETCB("bin.dbginfo.dwo_path", "", NULL, "Load separate debug information (DWARF) file if available");
|
||||
SETCB("bin.dbginfo.debug_file_directory", "/usr/lib/debug", NULL,
|
||||
"Set the directories which searches for separate debugging information files to directory");
|
||||
SETCB("bin.dbginfo.debuginfod", "false", NULL,
|
||||
"Load debug file from bin.dbginfo.debuginfod_urls or DEBUGINFOD_URLS environment variable");
|
||||
SETCB("bin.dbginfo.debuginfod_urls", "http://debuginfod.elfutils.org/", NULL,
|
||||
"Looks for debug symbols on the debuginfod servers, the value is a string of a space separated URLs");
|
||||
SETBPREF("bin.relocs", "true", "Load relocs information at startup if available");
|
||||
SETICB("bin.minstr", 0, &cb_binminstr, "Minimum string length for strings in bin plugins");
|
||||
SETICB("bin.maxstr", 0, &cb_binmaxstr, "Maximum string length for strings in bin plugins");
|
||||
|
|
|
|||
|
|
@ -993,7 +993,9 @@ typedef struct {
|
|||
|
||||
// http://www.dwarfstd.org/doc/DWARF4.pdf#page=29&zoom=100,0,0
|
||||
typedef enum {
|
||||
RzBinDwarfAttr_Address,
|
||||
RzBinDwarfAttr_Addr,
|
||||
RzBinDwarfAttr_AddrBase, /// An offset to a set of addresses in the `.debug_addr` section.
|
||||
RzBinDwarfAttr_AddrIndex, /// An index into a set of addresses in the `.debug_addr` section.
|
||||
RzBinDwarfAttr_Block,
|
||||
RzBinDwarfAttr_Constant,
|
||||
RzBinDwarfAttr_UConstant,
|
||||
|
|
@ -1517,6 +1519,9 @@ RZ_API RZ_OWN RzBinDWARF *rz_bin_dwarf_from_path(
|
|||
RZ_API RZ_OWN RzBinDWARF *rz_bin_dwarf_search_debug_file_directory(
|
||||
RZ_BORROW RZ_NONNULL RzBinFile *bf,
|
||||
RZ_BORROW RZ_NONNULL RzList /*<const char *>*/ *debug_file_directorys);
|
||||
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_API void rz_bin_dwarf_free(RZ_OWN RZ_NULLABLE RzBinDWARF *dw);
|
||||
|
||||
|
|
@ -1800,6 +1805,15 @@ RZ_API bool rz_bin_dwarf_block_empty(const RzBinDwarfBlock *self);
|
|||
RZ_API void rz_bin_dwarf_block_dump(const RzBinDwarfBlock *self, RzStrBuf *sb);
|
||||
RZ_API const ut8 *rz_bin_dwarf_block_data(const RzBinDwarfBlock *self);
|
||||
|
||||
/// addr
|
||||
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_API void rz_bin_dwarf_addr_free(RzBinDwarfAddr *self);
|
||||
RZ_API RZ_OWN RzBinDwarfAddr *rz_bin_dwarf_addr_new(RZ_OWN RZ_NONNULL RzBinEndianReader *reader);
|
||||
RZ_API RZ_OWN RzBinDwarfAddr *rz_bin_dwarf_addr_from_file(RZ_BORROW RZ_NONNULL RzBinFile *bf);
|
||||
|
||||
/**
|
||||
* \brief Safely get the string from an RzBinDwarfAttrValue if it has one.
|
||||
*/
|
||||
|
|
@ -1821,6 +1835,30 @@ static inline char *rz_bin_dwarf_attr_string(
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static inline ut64 rz_bin_dwarf_attr_addr(
|
||||
const RzBinDwarfAttr *attr,
|
||||
RzBinDWARF *dw,
|
||||
ut64 addr_size, ut64 base) {
|
||||
rz_return_val_if_fail(attr, UT64_MAX);
|
||||
|
||||
const RzBinDwarfAttrValue *v = &attr->value;
|
||||
if (v->kind == RzBinDwarfAttr_Addr) {
|
||||
return attr->value.u64;
|
||||
} else if (v->kind == RzBinDwarfAttr_AddrIndex) {
|
||||
ut64 addr = 0;
|
||||
if (dw && rz_bin_dwarf_addr_get(dw->addr, &addr, addr_size, base, attr->value.u64)) {
|
||||
return addr;
|
||||
} else {
|
||||
rz_warn_if_reached();
|
||||
}
|
||||
} else if (v->kind == RzBinDwarfAttr_UConstant) {
|
||||
return attr->value.u64;
|
||||
} else {
|
||||
rz_warn_if_reached();
|
||||
}
|
||||
return attr->value.u64;
|
||||
}
|
||||
|
||||
static inline ut64 rz_bin_dwarf_attr_udata(const RzBinDwarfAttr *attr) {
|
||||
rz_return_val_if_fail(attr, UT64_MAX);
|
||||
return attr->value.u64;
|
||||
|
|
|
|||
125
test/db/archos/linux-x64/debuginfod
Normal file
125
test/db/archos/linux-x64/debuginfod
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
NAME="Debugging Information in debuginfod"
|
||||
FILE=
|
||||
CMDS=<<EOF
|
||||
& !debuginfod -vvv -F bins/elf/float_ex1/float_ex1_buildid bins/elf/float_ex1/float_ex1_split-dwarf.debug
|
||||
sleep 10
|
||||
e bin.dbginfo.debuginfod=true
|
||||
e bin.dbginfo.debuginfod_urls=http://127.0.0.1:8002
|
||||
o bins/elf/float_ex1/float_ex1_buildid
|
||||
aaa
|
||||
iS
|
||||
afl
|
||||
pdf @ dbg.fn1
|
||||
qyn
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
paddr size vaddr vsize align perm name type flags
|
||||
-----------------------------------------------------------------------------------------
|
||||
0x00000000 0x0 ---------- 0x0 0x0 ---- NULL
|
||||
0x00000318 0x1c 0x00000318 0x1c 0x0 -r-- .interp PROGBITS alloc
|
||||
0x00000338 0x20 0x00000338 0x20 0x0 -r-- .note.gnu.property NOTE alloc
|
||||
0x00000358 0x24 0x00000358 0x24 0x0 -r-- .note.gnu.build-id NOTE alloc
|
||||
0x0000037c 0x20 0x0000037c 0x20 0x0 -r-- .note.ABI-tag NOTE alloc
|
||||
0x000003a0 0x40 0x000003a0 0x40 0x0 -r-- .hash HASH alloc
|
||||
0x000003e0 0x24 0x000003e0 0x24 0x0 -r-- .gnu.hash GNU_HASH alloc
|
||||
0x00000408 0x108 0x00000408 0x108 0x0 -r-- .dynsym DYNSYM alloc
|
||||
0x00000510 0xac 0x00000510 0xac 0x0 -r-- .dynstr STRTAB alloc
|
||||
0x000005bc 0x16 0x000005bc 0x16 0x0 -r-- .gnu.version VERSYM alloc
|
||||
0x000005d8 0x30 0x000005d8 0x30 0x0 -r-- .gnu.version_r VERNEED alloc
|
||||
0x00000608 0xc0 0x00000608 0xc0 0x0 -r-- .rela.dyn RELA alloc
|
||||
0x000006c8 0x78 0x000006c8 0x78 0x0 -r-- .rela.plt RELA alloc,info
|
||||
0x00001000 0x17 0x00001000 0x17 0x0 -r-x .init PROGBITS alloc,execute
|
||||
0x00001020 0x60 0x00001020 0x60 0x0 -r-x .plt PROGBITS alloc,execute
|
||||
0x00001080 0x8 0x00001080 0x8 0x0 -r-x .plt.got PROGBITS alloc,execute
|
||||
0x00001090 0x31f 0x00001090 0x31f 0x0 -r-x .text PROGBITS alloc,execute
|
||||
0x000013b0 0x9 0x000013b0 0x9 0x0 -r-x .fini PROGBITS alloc,execute
|
||||
0x00002000 0x58 0x00002000 0x58 0x0 -r-- .rodata PROGBITS alloc
|
||||
0x00002058 0x3c 0x00002058 0x3c 0x0 -r-- .eh_frame_hdr PROGBITS alloc
|
||||
0x00002098 0xec 0x00002098 0xec 0x0 -r-- .eh_frame PROGBITS alloc
|
||||
0x00002dc0 0x8 0x00003dc0 0x8 0x0 -rw- .init_array INIT_ARRAY write,alloc
|
||||
0x00002dc8 0x8 0x00003dc8 0x8 0x0 -rw- .fini_array FINI_ARRAY write,alloc
|
||||
0x00002dd0 0x1f0 0x00003dd0 0x1f0 0x0 -rw- .dynamic DYNAMIC write,alloc
|
||||
0x00002fc0 0x28 0x00003fc0 0x28 0x0 -rw- .got PROGBITS write,alloc
|
||||
0x00002fe8 0x40 0x00003fe8 0x40 0x0 -rw- .got.plt PROGBITS write,alloc
|
||||
0x00003028 0x10 0x00004028 0x10 0x0 -rw- .data PROGBITS write,alloc
|
||||
0x00003038 0x0 0x00004038 0x8 0x0 -rw- .bss NOBITS write,alloc
|
||||
0x00003038 0x3b ---------- 0x3b 0x0 ---- .comment PROGBITS merge,strings
|
||||
0x00003078 0x378 ---------- 0x378 0x0 ---- .symtab SYMTAB
|
||||
0x000033f0 0x21c ---------- 0x21c 0x0 ---- .strtab STRTAB
|
||||
0x0000360c 0x11a ---------- 0x11a 0x0 ---- .shstrtab STRTAB
|
||||
0x00001090 1 33 entry0
|
||||
0x000010c0 4 41 -> 34 sym.deregister_tm_clones
|
||||
0x000010f0 4 57 -> 51 sym.register_tm_clones
|
||||
0x00001130 5 57 -> 54 sym.__do_global_dtors_aux
|
||||
0x00001080 1 6 sym.imp.__cxa_finalize
|
||||
0x00001170 1 9 entry.init0
|
||||
0x000013b0 1 9 sym._fini
|
||||
0x00001180 5 170 dbg.fn1
|
||||
0x00001060 1 6 sym.imp.malloc
|
||||
0x00001030 1 6 sym.imp.strncpy
|
||||
0x00001230 1 48 dbg.new_some
|
||||
0x00001050 1 6 sym.imp.memset
|
||||
0x00001260 6 335 dbg.main
|
||||
0x00001000 3 23 sym._init
|
||||
0x00001040 1 6 sym.imp.printf
|
||||
0x00001070 1 6 sym.imp.strdup
|
||||
; CALL XREF from dbg.main @ 0x132a
|
||||
/ _Bool fn1(int a, char *g, double q, struct Some *gg, some_t **out)
|
||||
| ; var char **arg1 @ rdi
|
||||
| ; var const char *arg2 @ rsi
|
||||
| ; var int64_t arg7 @ xmm0
|
||||
| ; var uintmax_t arg3 @ rdx
|
||||
| ; var some_t *arg4 @ rcx
|
||||
| ; arg int a @ stack - 0x10
|
||||
| ; arg char *g @ stack - 0x18
|
||||
| ; arg double q @ stack - 0x20
|
||||
| ; arg struct Some *gg @ stack - 0x28
|
||||
| ; arg some_t **out @ stack - 0x30
|
||||
| 0x00001180 push rbp ; float_ex1.c:15
|
||||
| 0x00001181 mov rbp, rsp
|
||||
| 0x00001184 sub rsp, 0x30
|
||||
| 0x00001188 mov dword [a], edi ; arg1
|
||||
| 0x0000118b mov qword [g], rsi ; arg2
|
||||
| 0x0000118f movsd qword [q], xmm0 ; arg7
|
||||
| 0x00001194 mov qword [gg], rdx ; arg3
|
||||
| 0x00001198 mov qword [out], rcx ; arg4
|
||||
| 0x0000119c cmp qword [gg], 0 ; float_ex1.c:16
|
||||
| ,=< 0x000011a1 je 0x11b2
|
||||
| | 0x000011a7 cmp qword [out], 0
|
||||
| ,==< 0x000011ac jne 0x11bb
|
||||
| |`-> 0x000011b2 mov byte [a + 0x7], 0 ; float_ex1.c:17
|
||||
| |,=< 0x000011b6 jmp 0x121c
|
||||
| `--> 0x000011bb mov edi, 0x18 ; float_ex1.c:19 ; size_t size
|
||||
| | 0x000011c0 call sym.imp.malloc ; void *malloc(size_t size)
|
||||
| | 0x000011c5 mov rcx, rax
|
||||
| | 0x000011c8 mov rax, qword [out]
|
||||
| | 0x000011cc mov qword [rax], rcx
|
||||
| | 0x000011cf mov ecx, dword [a] ; float_ex1.c:20
|
||||
| | 0x000011d2 mov rax, qword [out]
|
||||
| | 0x000011d6 mov rax, qword [rax]
|
||||
| | 0x000011d9 mov dword [rax], ecx
|
||||
| | 0x000011db mov rax, qword [out] ; float_ex1.c:21
|
||||
| | 0x000011df mov rdi, qword [rax]
|
||||
| | 0x000011e2 add rdi, 4 ; char *dest
|
||||
| | 0x000011e6 mov rsi, qword [g] ; const char *src
|
||||
| | 0x000011ea mov edx, 5 ; size_t n
|
||||
| | 0x000011ef call sym.imp.strncpy ; char *strncpy(char *dest, const char *src, size_t n)
|
||||
| | 0x000011f4 movsd xmm0, qword [q] ; float_ex1.c:22
|
||||
| | 0x000011f9 cvtsd2ss xmm0, xmm0
|
||||
| | 0x000011fd mov rax, qword [out]
|
||||
| | 0x00001201 mov rax, qword [rax]
|
||||
| | 0x00001204 movss dword [rax + 0xc], xmm0
|
||||
| | 0x00001209 mov rcx, qword [gg] ; float_ex1.c:23
|
||||
| | 0x0000120d mov rax, qword [out]
|
||||
| | 0x00001211 mov rax, qword [rax]
|
||||
| | 0x00001214 mov qword [rax + 0x10], rcx
|
||||
| | 0x00001218 mov byte [a + 0x7], 1 ; float_ex1.c:24
|
||||
| | ; CODE XREF from dbg.fn1 @ 0x11b6
|
||||
| `-> 0x0000121c mov al, byte [a + 0x7] ; float_ex1.c:25
|
||||
| 0x0000121f and al, 1
|
||||
| 0x00001221 movzx eax, al
|
||||
| 0x00001224 add rsp, 0x30
|
||||
| 0x00001228 pop rbp
|
||||
\ 0x00001229 ret
|
||||
EOF
|
||||
RUN
|
||||
Loading…
Reference in a new issue