summaryrefslogtreecommitdiff
path: root/libunwindstack/include/unwindstack/ElfInterface.h
AgeCommit message (Collapse)Author
2021-03-30Implement random-access decompression for mini-debug-info.David Srbecky
The XZ file format supports random access if the file was compressed with the right flags (eg xz --block-size=4096). Add support for it so that we only decompress the parts of mini-debug-info that we need. This reduces mini-debug-info memory usage by 20% without any specific optimizations which take advantage of the laziness. (with perfetto system-wide profiling running for a minute) BM_symbol_find_single_from_sorted (best case lookup scenario) is 4x faster and uses 5x less memory. BM_symbol_not_present_from_sorted (worst case lookup scenario) is 2x faster and uses 3x less memory. Bug: 110133331 Test: libunwindstack_test Change-Id: Id067b2d07807463f86ed5fd908b83d079c5a057e
2021-03-23Add shared symbol name cache.David Srbecky
The symbol name related reads and memory operations take about half of the symbol name reading cost now. This CL adds ref-counted read-only shared string cache, which essentially eliminates all of the costs. BM_symbol_find_single_many_times is >10% faster on ARM. (which is 20% if we exclude the fixed ELF loading cost) Real-world profiles seem even more encouraging. The extra memory cost is negligible (by definition, a small fraction of the decompressed mini-debug-info: specifically, the subset of strtab for hit functions). Furthermore, this effectively dedups strings when consecutive unwinds hit similar set of functions. (perfetto might keep several unwind results live) Test: m libunwindstack_unit_test Change-Id: I5cf600bb972fdb9d0f3a57ed0997bead2efa38f4
2021-03-09Add method to get the address and size of the .text section.David Srbecky
This will be used to speed up JIT lookups, by trivially skipping JIT entries that don't need to be decompressed. Test: m libunwindstack_unit_test Change-Id: I6dabc33de245c0b319c19dbfe1f2129987b42f4b
2020-11-26Cleanup templating in ElfInterfaceDavid Srbecky
Reduce verbosity caused by the dual bitness support. (following pattern that I have found useful in ART) The code semantics should be unchanged. Test: m libunwindstack_test Change-Id: Ib65f913d5a8f5217aeb148a2c96f1a85ccfa4096
2020-10-02libunwindstack: Support signal frame CIEs.Ryan Prichard
Mark a CIE with a S in its augmentation string as signal frame. This allows the code to properly handle signal frame data if none of the signal frame pattern matchers work. For a signal frame, DwarfSectionImpl<AddressType>::Eval needs to continue the unwinding even if PC is zero. A zero PC means that the program has crashed, and we should try to recover the real PC using the return address on the stack or LR. This behavior is tested by UnwindOffline.signal_{x86,x86_64}, which modify the libc.so files so that the signal frame pattern matcher fails and the CIE/FDE data is used instead. Test: libunwindstack_test Change-Id: I4655b070028fd984345311a5e743796f8c30ed36
2019-12-03Fix support finding global variables.Christopher Ferris
The code was not properly getting the variable addresses and using the offset and address fields of the .data section. Fix all of that, and update the tests. Bug: 145162678 Test: Unit tests pass. Test: ./art/test/run-test --dex2oat-jobs 4 --host --prebuild --compact-dex-level fast --jit --no-relocate --runtime-option -Xcheck:jni 137-cfi Test: ./art/test/testrunner/testrunner.py -t 137 --host Change-Id: Ic61c4487334fd2273cda9c56eb1a3b525a03edb7
2019-10-08Handle when bias is different in elf headers.Christopher Ferris
The original code assumed that the load bias in the program headers would be exactly the same as in eh_frame/eh_frame_hdr/debug_frame. This isn't guaranteed, so add a section bias for use when creating a DwarfSection. In addtion, make the load bias and section bias a signed value. There is no reason that this value needs to be positive, so don't force it to be. Add a new offline test that has a different load bias in eh_frame than in the executable load. Add additional unit tests to verify the load bias values are set properly. Clean up the tests in ElfInterfaceTest, making all tests names follow the same convention. Bug: 141888859 Bug: 142094469 Test: New units and old unit tests pass on host and taimen. Change-Id: Ib878123ab5545f0f315c749cfe0d27b012d873ee
2019-04-05Revert "Check for data races when reading JIT/DEX entries."David Srbecky
This reverts commit 91dc724d5ba73d60cc0f7c2b01e559e899ff3a87. Reason for revert: Breaks ART tests, reverting to investigate. Change-Id: I1bb905407e87cbd4f832646651133a9caf6fcfc8
2019-03-29Check for data races when reading JIT/DEX entries.David Srbecky
Update the entries only when the list is modified by the runtime. Check that the list wasn't concurrently modified when being read. Bug: 124287208 Test: libunwindstack_test Test: art/test.py -b --host -r -t 137-cfi Change-Id: I87ba70322053a01b3d5be1fdf6310e1dc21bb084
2019-03-13Add support for displaying soname in an apk.Christopher Ferris
Changes: - Change GetSoname to always returns a std::string. - Added new unit tests for the soname printing. - Modify the GetElf() function to save the same elf when we see rosegment linkers that split the read-only and read-write across a map. This avoids creating multiple elf objects for each map. - Fixed a few offline unwind tests. Bug: 29218999 Test: Unit tests pass. Change-Id: Iad7c38b5c2957a8c5fd4ba94ebec335bafcad57d
2019-01-17Add caching of build id in MapInfo object.Christopher Ferris
Change the GetBuildID function to return a std::string. Added benchmark to check how long it takes to get the build id from a file versus an elf object. Added a way to get an elf without passing in a valid process_memory and added tests for this. Test: New unit tests. Change-Id: I3029019767e0181c758d611fe635bc1bf72d6e8e
2018-12-05Read .note.gnu.build-id.Florian Mayer
This will be used by heapprofd to allow us to correlate build ids with memory leaks in libraries and binaries. Test: m Test: host libunwindstack_test Test: run unwind_info against my phone's libc.so (32/64) and compare to readelf Build ID output. Bug: 120186412 Change-Id: I3cefd6cce9a8733509bf35b7175eb0f967783477
2018-08-03Be permissive about badly formed elf files.Christopher Ferris
Here is the allowable issues with an elf file that will not result in an error: - The program headers/section headers offset points to unreadable memory. - Allow missing program header and/or section headers. - Allow a symbol table section header to point to invalid symbol table values. There is no real reason to require the elf file be perfect. Everything in the code has sane defaults, so any missing information won't cause any problems. This gets rid of the warning that occurs any time an elf is loaded from memory. In memory elf files never contain all of the section headers, and do not contain the symbol table data. Update tests to test these new cases. Test: Builds and unit tests all pass. Change-Id: Iaefe2cd6b6c965a01ed425a112d6afae339f3b78
2018-07-12Remove Memory::ReadField.Christopher Ferris
In almost all cases, it is faster to read the entire structure rather than do multiple reads using ReadField. The only case where it would be slower is if doing a remote unwind and ptrace is the only way to read. In all other cases, it's a single system call. In the ptrace call, it will be multiple calls. Given that it is unusual to be forced to use ptrace, it's better to avoid it. It also reduces the code complexity to do a single read, and avoids issues where the code forgets to read the field it needs. Test: Unit tests pass on host and target. Change-Id: I7b3875b2c85d0d88115b1776e1be28521dc0b932
2018-06-22Fix ARM program header values used for exidx.Christopher Ferris
Before, I was using p_vaddr to get the offset into the elf file where the exidx frame starts. I changed that to use p_offset since this already has the load bias offset in it and some elf files do not set p_vaddr properly. Also, use p_filesz instead of p_memsz, since again, some elf files do not set p_memsz to the same as p_filesz. Bug: 110704153 Test: All libbacktrace/libunwindstack unit tests pass. Test: Randomly unwind process on a walleye. Test: Verified that this properly dumps and unwinds the shared Test: library that sets p_vaddr and p_memsz differently. Change-Id: Ic7b1e5d07439f4636fa02cd884a8727a5737372b
2018-06-11Fix handling of load bias values.Christopher Ferris
It turns out that for the dwarf information, if a FDE indicates it's pc relative, then pc has to be incremented by the load bias. If not, then it should not be incremented. Previously, the code always subtracted load bias values from pcs, and assumed that all fdes were incremented by load bias values. The new code actually reads the fdes and adjusted the pcs in the fde and in the eh frame hdr so that load bias values are already handled properly. In addition, add dumping of arm exidx values in unwind_reg_info. This allowed verifying that the debug frame in those elf files was being handled properly. Added a new unit test that only has a debug frame that has a non-zero load bias and has fde entries that do not have pc relative encoding. Fix a couple of other small bugs. Bug: 109824792 Test: All libbacktrace/libunwindstack unit tests pass. Test: Ran ART 137-cfi test and 004-ThreadStress. Test: Verify that displaying the fde start and end pc actually match the Test: real data for fde that have pc relative set, and that don't. Test: Verified that the unwind information for arm exidx matches the Test: debug frame data. Change-Id: I707555286b5cb05df9f25489e8c5ede753cfe0fb
2018-02-15Fix soname reading code.Christopher Ferris
The dynamic section contained an address, not an offset into the elf file to indicate where the soname exists. Changed to use the strtab entries in the section headers to map this address to the actual offset. Refactor the soname test a bit to make it easier to verify the code. Bug: 73499044 Test: Passes new unit tests. Test: Ran unwind_info on the failing shared elf and verified the soinfo Test: is correct. Change-Id: I16ba148389bcb9aadd3566fb442dac27f89fe894
2018-01-24Add error propagation into Unwinder/Elf objects.Christopher Ferris
The backtrace offline code uses these error codes to diagnose errors. In addtion, I've had cases where seeing these errors would help diagnose failures. This also allows us to add a few features to indicate why an unwind terminated (such as max frames exceeded). Bug: 65682279 Test: Updated unit tests pass. Change-Id: If82b5092698e8a194016d670efff1320f9b44d50
2018-01-12Add ability to read jit gdb data.Christopher Ferris
Changes: - New JitDebug class to handle all of the jit gdb interface. - Add unit tests for all, along with new offline test using debug data. - Add new Memory type called MemoryOfflineParts that has multiple MemoryOffline objects to support the offline test. - Update the tools to use the JitDebug object. - Modify libbacktrace to use the JitDebug, but only looking in libart.so and libartd.so. - Change the Format32Bits to Is32Bit since it's more accurate and I use it in a different context where original name didn't make sense. - Add a new function to find global variables in an elf file (GetGlobalVariable). - Add a new function to determine if a pc is valid for this elf (IsValidPc). Bug: 68396769 Test: Ran new unit tests. Added new offline test that uses jit debug data. Test: Ran art test that generates jit data and verified a crash unwinds Test: through the jit data. Change-Id: I6e7ee2f5bab2242028a06feece156dff21c0a974
2017-12-15Fix issues in libunwindstack.Christopher Ferris
- Add a load_bias field in MapInfo so that it can be loaded offline, and also so it can be cached. - Add an Add function to the Maps class so that it's possible to manually create a map. - Remove the OfflineMaps class since I haven't found a reason for this to exist. - Add a pointer to the gnu debugdata compressed section in the interface itself and modify the step path to try eh_frame, then debug_frame, then gnu_debugdata. This way arm can add exidx as the last step behind gnu_debugdata. Add an offline test to verify the order of unwind. - Fix x86_64_ucontext_t since it was a different size on 32 bit and 64 bit systems. Test: Pass new unit tests. Change-Id: I978b70d6c244bd307c62a29886d24c1a8cb2af23
2017-12-05Demand read load bias for a map.Christopher Ferris
Add a static GetLoadBias method to the Elf object that only reads just enough to get the load bias. Add a method to MapInfo that gets the load bias. First attempt to get it if the elf object already exists. If no elf object was created, use the new static method to get the load bias. In BacktraceMap, add a custom iterator so that when code dereferences a map element, that's when the load bias will be retrieved if it hasn't already been set. Bug: 69871050 Test: New unit tests, verify tombstones have non-zero load bias values for Test: libraries with a non-zero load bias. Change-Id: I125f4abc827589957fce2f0df24b0f25d037d732
2017-11-07Add support for only a .eh_frame.Christopher Ferris
Static executables only have a .eh_frame section and no .eh_frame_hdr section. Add support for this by rearranging the class hierarchy and creating a DwarfEhFrameWithHdr class and a DwarfEhFrame class to handle the different cases. Add new unit tests for DwarfEhFrame and for the new functionality. Bug: 68820189 Test: Passes new unit tests, unwinds static executables. Change-Id: I63d7cb8c52a686e96579a2266e18c0d06bbb6e63
2017-10-20Multiple bugfixes, small restructuring.Christopher Ferris
- Move the load bias stored out of ElfInterface into Elf. For the compressed sections, the load bias was not the same as the data from the uncompressed section. - Move the initialization of the compressed section into Init. It was too easy to forget to call the init of the compressed section. - Do not automatically add in load bias to the pc before calling ElfInterface code. Do all of the pc manipulations in the Elf object. - Change the interface GetFunctionName code to pass in the load_bias instead of modifying the pc inside the code. - Modify the Step function to pass in the elf offset, not add it to the pc. It is necessary to have two different relative values when executing the Step: a pc that is relative to the beginning of the elf for the reading data the actual instructions when trying to determine if this is in a signal frame, and a pc that is relative to the map for finding the appropriate unwind information. - Add a feature to Unwinder so that an unwind can be stopped if it ends up in map that has a specified suffix. This is so that the ART unwinding code doesn't require skipping the compressed section. Instead, stop at if trying to unwind through a known suffix code that means the code is in java code. This is important because the compressed section data is not only used by the jave compiled code, so that will continue to work. - Fix tests for restructuring, add new tests for new functionality. Test: Ran art test 137-cfi using new unwinder as default. Test: Ran new unit tests. Change-Id: I42e658c64c5e14f698ba34944a3043afac967884
2017-09-22Add a new unwind method on error.Christopher Ferris
If a function crashes by jumping into unexecutable code, the old method could not unwind through that. Add a fallback method to set the pc from the default return address location. In addition, add a new finished check for steps. This will provide a method to indicate that this step is the last step. This prevents cases where the fallback method might be triggered incorrectly. Update the libbacktrace code to unwind using the new methodology. Update the unwind tool to use the new unwind methodology. Add a new option to crasher that calls through a null function. Create a new object, Unwinder, that encapsulates the a basic unwind. For now, libbacktrace will still use the custom code. Added new unit tests to cover the new cases. Also add a test that crashes calling a nullptr as a function, and then has call frames in the signal stack. Bug: 65842173 Test: Pass all unit tests, verify crasher dumps properly. Change-Id: Ia18430ab107e9f7bdf0e14a9b74710b1280bd7f4
2017-08-30Add proper support for embedded elf files.Christopher Ferris
- Add a method to get the max size of an elf file by reading the section header offset + size. This will properly map an elf file embedded into an apk, instead of just mapping in what is done by the dynamic linker. It does assume that the section headers are at the end of the elf file. - Add new tests for the above functionality. - Update the unwind_symbols tool to take an address for finding a function instead of dumping the entire symbol table. Bug: 23762183 Test: Unit tests pass, unwind through the camera process and verify Test: the GoogleCamera.apk shows some function names. Change-Id: I00c021680fe1d43b60d652bf91bbf6667d9617be
2017-07-14Make the library usable as a library.Christopher Ferris
- Add namespace unwindstack everywhere so that it's easier for other code to use the library. - Move some of the header files into include/unwindstack so that they can be exposed. - Modify the headers so that only a limited number need to be exposed. - Update the tools to use the new headers. - Add a GetLoadBias() call on the Elf object. This prevents the need to get the interface object out of the Elf object. - Move the GetRelPc() call out of the Reg class, to the Elf class. It's not always the case that a Reg object will be around when you want to get a relative pc. The tests for this moved to ElfTest.cpp. Bug: 23762183 Test: Unit tests pass. Change-Id: Iac609dac1dd90ed83d1a1e24ff2579c96c023bc3