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:
billow 2023-11-06 23:41:42 +08:00 committed by GitHub
parent a336296356
commit 444000416c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 265 additions and 51 deletions

View file

@ -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:

View file

@ -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:

View file

@ -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 */
{

View file

@ -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);
}

View file

@ -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:

View file

@ -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);

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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;
}

View file

@ -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");

View file

@ -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;

View 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