eliben / pyelftools

Parsing ELF and DWARF in Python

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ImportError: cannot import name 'bytes2str' from 'elftools.common.utils'

nyholku opened this issue · comments

I tried to install pyelftools like this:

pip3 install pyelftools 

I then downloaded the example code dwarf_pubnames_types.py and when I try to run it I get:

ImportError: cannot import name 'bytes2str' from 'elftools.common.utils' (/usr/local/lib/python3.10/site-packages/elftools/common/utils.py)

When I examine /usr/local/lib/python3.10/site-packages/elftools/common/utils.py I find that there is no bytes2str

But when I look at the utils.py code in github I see that the function is there.

elftools/common/utils.py

So I see if my pip3 install pyelftools are from an different version:

% pip3 show  pyelftools                                                
Name: pyelftools
Version: 0.29
Summary: Library for analyzing ELF files and DWARF debugging information
Home-page: https://github.com/eliben/pyelftools
Author: Eli Bendersky
Author-email: eliben@gmail.com
License: Public domain
Location: /usr/local/lib/python3.10/site-packages
Requires: 
Required-by: 

So this is the latest version and what I see in gitbut, right?

How do I solve this?

The example code in the current state of the repository is already adapted to the Python-3-only changes which were done after the release of v0.29... among other things, this included moving bytes2str around (see 01621ab).

If you want the version compatible with the v0.29 release, check out the repository at the v0.29 tag (or use this link to get the version of the dwarf_pubnames_types.py script: https://github.com/eliben/pyelftools/blob/v0.29/examples/dwarf_pubnames_types.py)

Thanks! That solved the issue.

While I have your attention, is there an example that gets the variable type info for a global variable (in C) ?

I have found examples from the web on how to do that with greadelf however, I'm working with a file which I think has DWARF v4 stuff like this (this output from greadelf)

 <1><2117>: Abbrev Number: 67 (DW_TAG_variable)
    <2118>   DW_AT_location    : 5 byte block: 3 92 ad 0 0 	(DW_OP_addr: ad92)
    <211e>   DW_AT_name        : (indirect string, offset: 0xf07): g_debug_pwm_override
    <2122>   DW_AT_decl_column : 16
    <2123>   DW_AT_decl_file   : 1
    <2124>   DW_AT_decl_line   : 43
    <2125>   DW_AT_external    : 1
    <2125>   DW_AT_type        : signature: 0x90056244416637ed
    <212d>   DW_AT_linkage_name: (indirect string, offset: 0xf07): g_debug_pwm_override

and was I'm stymied by DW_AT_type : signature: 0x90056244416637ed

Is this something that pyelftools support?

Thanks, that looks promising as a starting point. This had the trivial bytes2str issue which was easily fixed with as per @rupran hints above.

This does not appear to have a main so is there an example that uses this code?

Provide your own main. The primary function in that file is describe_cpp_datatype(), but it takes a DW_TAG_variable DIE as a parameter, which has to come from somewhere.

We know for a fact that the logic in that module doesn't cover the whole gamut of the C/C++ datatype system. That was not our ambition at the time. :) If you happen to stumble upon some use case (i. e. some datatype) that the module doesn't describe adequately, feel free to fix and share in a PR.

Yes, of course. Thanks. I think I can take it from there. Thank you and everyone.

One closed form script that calls describe_cpp_datatype() is https://github.com/eliben/pyelftools/blob/master/scripts/dwarfdump.py

One thing with spelling out C(++) datatypes is - do you stop at typedefs, or do you parse through them? The former makes for more readable description, the latter is more useful for practical debugging (should LPCWSTR be treated as a pointer? who knows!) Our current version stops at typedefs, because that's what llvm_dwarfdump does. The private piece of mine that it was originally adapted from did not. Ideally, it should have been a flag-type parameter, but oh well.