Commit Graph

996 Commits

Author SHA1 Message Date
Omar Sandoval
47ab6142d5 vmtest: fix vmtest.vm -k
The argument to download_kernels() is an iterable of kernels, but we're
passing it a single kernel string.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-05-06 01:35:27 -07:00
Omar Sandoval
abeea40b8a vmtest: fix cleanup of temporary directory on Python < 3.8
In Python before 3.8, tempfile.TemporaryDirectory.cleanup() fails when
the directory doesn't exist. Since we rename the temporary download
directory to its final name, this always fails. Switch to using
tempfile.mkdtemp() directly instead.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-05-05 13:48:35 -07:00
Omar Sandoval
a15de13a7c vmtest: handle exceptions when downloading in thread
Otherwise, an exception causes setup.py test -K to hang.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-05-05 13:19:44 -07:00
Omar Sandoval
a1dc80bc38 CI: reenable vmtest
Now that the vmtest kernels have a new home on GitHub, reenable vmtest
for the CI workflow.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-05-05 01:15:40 -07:00
Omar Sandoval
47c8e0e53e vmtest: fix vmtest kernel build command
Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-05-05 00:34:11 -07:00
Omar Sandoval
ebca2d2f8a CI: add action to build vmtest kernels weekly
The previous commit mentioned this action but forgot to add it.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-05-05 00:30:34 -07:00
Omar Sandoval
841a3dae88 Move vmtest assets to GitHub releases
As noted by commit 738261290f ("CI: temporarily disable vmtest"),
vmtest was generating too much traffic to the Dropbox shared folder that
hosted vmtest kernels. Instead, we can store kernel packages as GitHub
release assets. Update the code for downloading and uploading vmtest
assets, and also add a scheduled GitHub action to build new kernels
every Monday so I don't have to remember to do it manually.

This also drops vmtest support for 5.6-5.9, which now fail to build with
newer binutils due to the issue fixed in Linux kernel commit
1d489151e9f9 ("objtool: Don't fail on missing symbol table").

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-05-05 00:28:56 -07:00
Omar Sandoval
8f7e524b6b docs: update links to main branch
The master branch was renamed to main. GitHub redirects links to the old
branch, but we might as well update them explicitly.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-05-04 17:25:33 -07:00
Omar Sandoval
cf371594f3 tests: run a few test cases with DW_FORM_indirect
Pick a few DWARF parsing test cases that exercise the interesting cases
for DW_FORM_indirect and run them with and without DW_FORM_indirect. We
only test DW_FORM_indirect if libdw is new enough to support it.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-05-04 16:56:54 -07:00
Jay Kamat
95646b47c9 libdrgn: dwarf_index: add support for DW_FORM_indirect
First, add instructions for DW_FORM_indirect. Then, we can call the
function to convert a form to an instruction whenever we see an indirect
instruction.

Note that without elfutils commit d63b26b8d21f ("libdw: handle
DW_FORM_indirect when reading attributes") (queued for elfutils
0.184), DW_FORM_indirect will cause errors later when parsing with
libdw.

Signed-off-by: Jay Kamat <jaygkamat@gmail.com>
2021-05-04 16:56:54 -07:00
Omar Sandoval
609a1cafc6 libdrgn: dwarf_index: check for attribute forms more strictly
Rather than silently ignoring attributes whose form we don't recognize,
return an error. This way, we won't mysteriously skip indexing DIEs.
While we're doing this, split the form -> instruction mapping to its own
functions.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-05-04 16:56:54 -07:00
Omar Sandoval
85c367bf79 Reformat empty docstrings
Black 21.4b2 now replaces empty docstrings with a docstring containing a
single space. Apply that formatting.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-04-30 17:06:47 -07:00
Omar Sandoval
037a510ff2 Fix drgn.FaultError type annotations
FaultError() also takes an error message.

Fixes: 80c9fb35ff ("Add type hint stubs and generate documentation from them")
Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-04-30 17:03:16 -07:00
Omar Sandoval
2ad52cb5f4 libdrgn: add option to time load_debug_info example program
I often use examples/load_debug_info to benchmark loading/DWARF
indexing, so add a -T option that prints the time it takes to load debug
info.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-04-23 09:29:44 -07:00
Omar Sandoval
2d40d6e146 libdrgn: add configure~ to .gitignore
Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-04-23 09:18:16 -07:00
Jay Kamat
c108f9a24c tests: add basic tests for type units
Signed-off-by: Jay Kamat <jaygkamat@gmail.com>
2021-04-23 02:37:31 -07:00
Jay Kamat
6be21f674a libdrgn: follow DW_AT_signature when parsing DWARF types
When using type units, skeleton declarations are made instead of
concrete ones. However, these declarations have signature tags attached
that point to the type unit with the definition, so we can simply follow
the signature to get the concrete type.

Signed-off-by: Jay Kamat <jaygkamat@gmail.com>
2021-04-23 02:37:31 -07:00
Jay Kamat
9dabec1264 libdrgn: add support for parsing type units
Adds support for parsing of type units as enabled by
-fdebug-types-section. If a module has both a debug info section and
type unit section, both are read.

Signed-off-by: Jay Kamat <jaygkamat@gmail.com>
2021-04-23 02:37:31 -07:00
Omar Sandoval
33300d426e libdrgn: debug_info: don't overwrite Dwarf_Die passed to drgn_type_from_dwarf_internal()
If the DIE passed to drgn_type_from_dwarf_internal() is a declaration,
then we overwrite it with dwarf_offdie(). As far as I can tell, this
doesn't break anything at the moment, but it's sketchy to overwrite an
input parameter and may cause issues in the future. Use a temporary DIE
on the stack in this case instead.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-04-23 02:37:31 -07:00
Omar Sandoval
155ec92ef2 libdrgn: fix reading 32-bit float object values on big-endian
Closes #99.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-04-22 09:45:41 -07:00
Omar Sandoval
6b79b21ab5 tests: fix test depending on repr(enum.Flag) format
CPython commit b775106d940e ("bpo-40066: Enum: modify `repr()` and
`str()` (GH-22392)") changed repr(enum.Flag) from, e.g.,
<Qualifiers.VOLATILE|CONST: 3> to Qualifiers.CONST|Qualifiers.VOLATILE.
Fix tests.test_type.TestType.test_qualifiers to not assume the format.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-04-22 01:17:22 -07:00
Omar Sandoval
0e2703dd4e libdrgn: python: use _PyDict_GetItemIdWithError()
CPython commit fb5db7ec5862 ("bpo-42006: Stop using PyDict_GetItem,
PyDict_GetItemString and _PyDict_GetItemId. (GH-22648)") (in v3.10)
removed _PyDict_GetItemId() because it suppresses errors. Use
_PyDict_GetItemIdWithError() instead (which we should've been using
anyways).

Closes #101.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-04-22 01:17:22 -07:00
Omar Sandoval
c768e97394 libdrgn: python: use _Thread_local instead of PyThreadState for drgn_in_python
Using a Python dictionary for this is much more heavyweight than just
using a thread-local variable (with no benefit as far as I can tell).
This also gets rid of a call to _PyDict_GetItem().

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-04-22 01:17:12 -07:00
Omar Sandoval
08498967f7 libdrgn: configure with large file support
/proc/pid/mem is indexed by address. On 32-bit systems, addresses may be
out of the range of a 32-bit signed off_t. This results in pread()
returning EINVAL in drgn_read_memory_file(). Use AC_SYS_LARGEFILE in
configure.ac so that we use 64-bit off_t by default.

Closes #98.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-04-21 13:34:31 -07:00
Davide Cavalca
6332f9846a examples: add missing shebangs
Signed-off-by: Davide Cavalca <dcavalca@fb.com>
2021-04-20 11:20:06 -07:00
Davide Cavalca
31cbc187ce add COPYING to sdist
Signed-off-by: Davide Cavalca <dcavalca@fb.com>
2021-04-20 11:17:51 -07:00
Omar Sandoval
738261290f CI: temporarily disable vmtest
With the added Clang tests, apparently vmtest is generating excessive
traffic on Dropbox. Disable it on GitHub Actions until I can work out a
new solution.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-04-04 23:06:19 -07:00
Omar Sandoval
78b4188dd9 drgn 0.0.11
Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-04-03 01:50:09 -07:00
Omar Sandoval
e7367a4a94 libdrgn: Makefile: remove generated source files from CLEANFILES
We don't actually want make clean to remove the generated files that are
included in a distribution tarball, because then the user will need to
regenerate them, and they might not have the dependencies installed.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-04-03 01:31:14 -07:00
Omar Sandoval
a4b9d68a8c Use GPL-3.0-or-later license identifier instead of GPL-3.0+
Apparently the latter is deprecated and the former is preferred.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-04-03 01:10:35 -07:00
Omar Sandoval
c7dc814978 CI: build with -Wall -Werror
This is the documented way that drgn should be built for development, so
let's enforce it.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-04-02 17:28:09 -07:00
Omar Sandoval
113b2700a8 CI: test with GCC and Clang
Everytime I try to build drgn with Clang, there are a few things that
need fixing. Let's test it so that it stays in good shape.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-04-02 17:28:05 -07:00
Omar Sandoval
76d3348a6d libdrgn: hash_table: mark table##_delete_iterator() as unused
GCC doesn't warn about table##_delete_iterator() being unused because it
is inline, but Clang does, so add the unused attribute.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-04-02 16:28:46 -07:00
Omar Sandoval
acf722d315 libdrgn: hash_table: remove unused table##_chunk_set_capacity_scale()
The folly implementation calls this elsewhere, but we only need it in
table##_chunk_mark_eof(), so it was folded in there.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-04-02 16:27:27 -07:00
Omar Sandoval
b772432a86 libdrgn: cfi: don't rely on member containing a flexible array
Clang enables -Wgnu-variable-sized-type-not-at-end by default, which
warns for DRGN_CFI_ROW():

  arch_x86_64.c:735:27: warning: field 'row' with variable sized type 'struct drgn_cfi_row' not at the end of a struct or class is a GNU extension
        [-Wgnu-variable-sized-type-not-at-end]
          .default_dwarf_cfi_row = DRGN_CFI_ROW(

DRGN_CFI_ROW() is gnarly anyways, so instead of having it expand to a
pointer expression relying on this GCC extension, make it expand to an
initializer. Then, we can initialize default_dwarf_cfi_row as a separate
variable rather than directly in the initializer for struct
drgn_architecture_info.

This still relies on a GCC extension for static initialization of
flexible array members, but apparently Clang is okay with that one by
default (-Wgnu-flexible-array-initializer must be enabled explictly or
by -Wgnu or -Wpedantic).

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-04-02 16:19:21 -07:00
Omar Sandoval
5c86e30b6e libdrgn: work around Clang __muloti4 for the third time
See commit 0cb77b303c ("libdrgn: work around Clang __muloti4 again")
and commit 2dd14ad522 ("libdrgn: work around "undefined reference to
'__muloti4'" when using Clang"). These keep sneaking in because I don't
have an old enough version of Clang lying around.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-04-02 15:30:07 -07:00
Omar Sandoval
301cc3f139 libdrgn: fix UBSan "applying zero offset to null pointer" errors
There are a couple of places where we compute `NULL + 0`, which is
undefined behavior. Add a helper to do this safely.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-04-02 13:38:29 -07:00
Omar Sandoval
9c31f11e35 libdrgn: object: fix UBSan error for uninitialized boolean
drgn_object_reinit() and drgn_object_copy() can both load from an
uninitialized little_endian field, causing UBSan errors like:

  libdrgn/object.h:105:27: runtime error: load of value 68, which is not a valid value for type '_Bool'

This only happens when little_endian isn't valid for the type and won't
be used anyways, but it's easy enough to work around.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-04-02 13:38:13 -07:00
Omar Sandoval
c9dc7fd574 libdrgn: type: fix memcpy() undefined behavior
It's undefined behavior to pass NULL to memcpy() even if the length is
zero. See also commit a17215e984 ("libdrgn: dwarf_index: fix memcpy()
undefined behavior").

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-04-02 13:38:13 -07:00
Davide Cavalca
7ca157316f tests: properly escape regexp strings
Signed-off-by: Davide Cavalca <dcavalca@fb.com>
2021-04-02 10:37:33 -07:00
Davide Cavalca
081d7773e1 tests: rename test_type_dies for pytest compatibility
Signed-off-by: Davide Cavalca <dcavalca@fb.com>
2021-04-02 10:37:14 -07:00
Omar Sandoval
39f17a52b8 docs: add missing css, favicon, and logo files to sdist
Closes #96.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-04-02 10:30:28 -07:00
Omar Sandoval
beb0c9d640 drgn 0.0.10 2021-03-31 13:32:05 -07:00
Omar Sandoval
f285764f8a Include full libdrgn distribution in drgn sdist
Building drgn from an sdist currently requires autotools and gawk
because libdrgn in the sdist is more or less a git checkout. It's more
user-friendly to include the autotools output and generated code. Do
this by extending the sdist command to include a full libdrgn
distribution with `make distdir`.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-03-30 23:19:38 -07:00
Omar Sandoval
587ecd4df8 README: add pip to installation dependencies
The README instructs the user to install with pip, but doesn't actually
mention that pip needs to be installed.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-03-30 22:51:46 -07:00
Omar Sandoval
ce7a5e62f8 README: fix installation dependencies for old Debian and Ubuntu
The libelf-dev and libdw-dev packages on Debian Stretch, Ubuntu Xenial,
and older are missing dependencies on liblzma-dev and zlib1g-dev, which
causes pkg-config to fail when running configure. Add them explicitly
for old versions.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-03-30 22:42:11 -07:00
Omar Sandoval
630d39e345 libdrgn: add ORC unwinder
The Linux kernel has its own stack unwinding format for x86-64 called
ORC: https://www.kernel.org/doc/html/latest/x86/orc-unwinder.html. It is
essentially a simplified, less complete version of DWARF CFI. ORC is
generated by analyzing machine code, so it is present for all but a few
ignored functions. In contrast, DWARF CFI is generated by the compiler
and is therefore missing for functions written in assembly and inline
assembly (which is widespread in the kernel).

This implements an ORC stack unwinder: it applies ELF relocations to the
ORC sections, adds a new DRGN_CFI_RULE_REGISTER_ADD_OFFSET CFI rule
kind, parses and efficiently stores ORC data, and translates ORC to drgn
CFI rules. This will allow us to stack trace through assembly code,
interrupts, and system calls.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-03-29 10:01:52 -07:00
Omar Sandoval
090064f20d libdrgn: x86-64: support R_X86_64_PC32 relocation type
This is used for .orc_unwind_ip for kernel modules.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-03-26 15:16:36 -07:00
Omar Sandoval
e0aaaf203d libdrgn: generalize applying ELF relocations
To support unwinding with ORC, we need to apply relocations to
.orc_unwind_ip, which libdwfl doesn't do. That means that we always need
to apply relocations on x86-64, not just as a fast path when the file's
byte order matches the host's. So, generalize handling of 64- vs 32-bit
and little- vs big-endian relocations, and move the handling of
relocation types to an arch-specific callback.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-03-26 15:16:35 -07:00
Omar Sandoval
63672be809 libdrgn: linux_kernel: save module .init section addresses
Linux kernel modules usually contain ELF relocations in DWARF and ORC
sections for symbols in .init sections. Since we ignore .init sections
entirely in cache_kernel_module_sections(), these relocations end up
being based on an address of 0 (so, e.g., a function from .init.text
could be reported as having an address of 0x0). It makes a little more
sense to use the address where the .init section was before it was
freed. So, let's update the sections' sh_addr but continue ignoring them
for determining the module's address range.

Signed-off-by: Omar Sandoval <osandov@osandov.com>
2021-03-26 15:13:47 -07:00