summaryrefslogtreecommitdiff
path: root/libunwindstack/ElfInterface.cpp
AgeCommit message (Collapse)Author
2021-06-30Move compression memory object into its own file.Christopher Ferris
The Memory.cpp file is crowded with too much code making it harder and harder to find modify. Since the MemoryXz object is a pretty substantial piece of code, break it out into its own file. Also, remove the extra include files in ElfInterface.cpp that reference the compression includes since that is all encapsulated in the MemoryXz object. Test: Builds and all unit tests pass. Change-Id: I194c9d1309192e7fe08594af15bf4a52537cffe8
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
2020-04-16Optimize Memory::ReadStringDavid Srbecky
This function is responsible for majority of CPU time in prefetto. Reduce the number of memory reads (don't read strings byte-by-byte). Update all calls of ReadString to include the third parameter to have a max read. Add an Elf creation benchmark since this function is on the elf creation path. Test: libunwindstack_unit_test Change-Id: Ia36e1f1a5ba76c9e9f13c43fb9e3691dde7897f2
2020-03-31Fix off-by-one in ReadBuildIDFromMemory.Peter Collingbourne
This was sometimes causing build ids to be truncated, probably because of memory corruption in std::string. A similar off-by-one was fixed in ReadBuildID in aosp/939619. Bug: 129873279 Change-Id: I401fe7f991dbd135f5b4836381b48ea3c6a2243f
2019-12-19Fix handling of possible bad gnu_debugdata_size.Christopher Ferris
Rather than use a std::vector for backing memory, allocate the memory using a new with nothrow, and in MemoryBuffer use realloc. Since the size field is coming from the elf, it could be corrupted or intentionally crafted to cause problems. In addition, add some other protections to make sure that overflows don't occur. Bug: 146215949 Test: Ran unit tests with jemalloc and scudo to verify that they Test: both behave the same way. Change-Id: If14243ce382ba5403a6bacd0ec673452c6b7c3be
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-29Fix potential bad info in eh_frame_hdr.Christopher Ferris
Due to a bug, an elf can have FDEs with a length of zero, while still having another FDE for the same pc with a non-zero length. The eh_frame_hdr can sometimes point to the zero length FDE, but it should have pointed to the non-zero length FDE. In order to fix this, if the eh_frame_hdr points at the zero length FDE then try and find the real FDE directly from eh_frame. The change cleans up and removes unused variables from DwarfEhFrameWithHdr and changes the objects so that all of the DwarfSection objects and DwarfEhFrameWithHdr object inherit from the same class. Add new unit tests to verify this functionality. Bug: 142483624 Test: Unit tests all pass. Change-Id: I128a916e3ba378931de7d44ee15e57e24d4073df
2019-10-21Fix handling of PT_GNU_EH_FRAME.Christopher Ferris
The bias for the PT_GNU_EH_FRAME was using the paddr instead of vaddr. This doesn't match the way the load bias is calculated, which always use vaddr - offset, so change to use vaddr. Found on an old x86 device that has a vdso that sets vaddr differently from paddr. Add a new offline test to catch this case and update the elf interface unit tests. Also, fix a small bug in the unwind_for_offline tool. Bug: 142365899 Test: Unit tests pass. Change-Id: I5f0bf062dd8ee45aa8553189ba493ec962e0b059
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-10-02Fix static GetLoadBias function.Christopher Ferris
The load bias value set in ReadProgramHeaders is out of sync with the algorithm used in the static GetLoadBias function. Sync the two and add tests to verify that they stay in sync. Test: Unit tests pass. Change-Id: I20ac0104970a22a92a5314a41dcadad0c9c22e64
2019-07-09Fix missing load bias.Florian Mayer
There are binaries that have non-executable LOAD with p_offset=0. E.g., Program Headers: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align PHDR 0x000040 0x0000000000400040 0x0000000000400040 0x0002a0 0x0002a0 R 0x8 INTERP 0x0002e0 0x00000000004002e0 0x00000000004002e0 0x00001c 0x00001c R 0x1 [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2] LOAD 0x000000 0x0000000000400000 0x0000000000400000 0x0059e0 0x0059e0 R 0x1000 LOAD 0x006000 0x0000000000406000 0x0000000000406000 0x10f2b05 0x10f2b05 R E 0x1000 LOAD 0x10f9000 0x00000000014f9000 0x00000000014f9000 0x70f634 0x70f634 R 0x1000 LOAD 0x1808f18 0x0000000001c09f18 0x0000000001c09f18 0x089fc8 0x0a7ab8 RW 0x1000 DYNAMIC 0x1864ce0 0x0000000001c65ce0 0x0000000001c65ce0 0x000240 0x000240 RW 0x8 NOTE 0x0002fc 0x00000000004002fc 0x00000000004002fc 0x000020 0x000020 R 0x4 TLS 0x1808f18 0x0000000001c09f18 0x0000000001c09f18 0x000010 0x000010 R 0x8 GNU_EH_FRAME 0x11abde8 0x00000000015abde8 0x00000000015abde8 0x14484c 0x14484c R 0x4 GNU_STACK 0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RWE 0x10 GNU_RELRO 0x1808f18 0x0000000001c09f18 0x0000000001c09f18 0x05c0e8 0x05c0e8 R 0x1 Test: host libunwindstack_test passes. Test: Modified unit tests and new offline test. Change-Id: I3992f712be238c7d4109556580b5dcc71175fe19
2019-06-11Internalize subclasses of MemoryCasey Dahlin
There are many subclasses of the Memory class and the overwhelming majority of them don't need to be exposed externally. We move all of them to internal headers except MemoryOfflineBuffer, which moves to a separate header. This dramatically reduces the exposed API surface and makes the code more modular. Also, remove the Offline code from libbacktrace. It's not used any where. Test: Unit tests pass, clean tree still builds Change-Id: I55dacdf080daba0bfe65c1ad53a4b326bb482e83
2019-04-06Merge "Revert "Check for data races when reading JIT/DEX entries.""Treehugger Robot
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-04-03Fix off by one reading build id.Christopher Ferris
Update unit tests and add new build id displaying in offline unwinds. Bug: 129873279 Test: All unit tests pass. Test: Verify that debuggerd displays build id properly. Change-Id: I97f4a204842447a20c812f535a458155b937d5e1
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
2019-01-15Fix usage of Read instead of ReadFully.Christopher Ferris
Found by inspection. Test: Builds and unit tests passes. Change-Id: I10b63534ae0a3bff9ce56e821c542fa69c15822d
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-05-04Match LZMA SDK 18.05 API.Sen Jiang
Test: libunwindstack_test Change-Id: Ie1c9c91fb4f3585a7543df55a71abf64f8fc6dff
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-24Small behavioral changes to the unwinder.Christopher Ferris
- Be a little more lenient when reading the cies/fdes. If next entry data winds up incorrect, don't fail, simply stop processing the entries. This only applies when reading all of the cies/fdes at once. - Fail to init an eh_frame with no entries and fallback to assuming the eh_frame has no header instead. - Change the step to always try debug_frame first which has the most accurate information. - Add small unit tests and a couple of offline unit tests to verify this behavior. These changes are needed to support offline unwinding since it depends on this new behavior. Bug: 65682279 Test: Ran new unit tests. Change-Id: I3529f1b0c8e14cd7409494e5de2f3c9e78d0855e
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-15unwindstack: rename Memory::Read to ReadFully.Josh Gao
Rename Memory::Read to ReadFully to match its semantics with that of android::base. ReadPartially will be renamed to Read in a follow up commit, kept intentionally separate so that there aren't any callers accidentally switched from ReadFully to Read. Test: treehugger Change-Id: I7d845ac5244c3025d92c8512e960e5d0d1da05af
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
2017-06-28Add .gnu_debugdata support.Christopher Ferris
Update the unwind_info tool to dump all of the sections. Bug: 23762183 Test: Passes new unit tests. Change-Id: I8b223bc208a1a2ef06ed333e6d96943c8f273681
2017-06-23Add section parsing and function name handling.Christopher Ferris
Add the code to parse the Elf section headers. Add the plumbing through of all the symbol handling code. Add tests for all of this new functionality. Bug: 23762183 Test: Pass new unit tests. Change-Id: Ie2d90cbb3d7653c53251dbcf34d9e5d241278377
2017-06-16Add EH frame and debug frame support.Christopher Ferris
Bug: 23762183 Test: Pass new unit tests. Change-Id: I1bfe900e068017ff31998f359bf98d4c5c9af2a5
2017-04-03Add overflow checks in Memory objects.Christopher Ferris
Also change one of the reads to be explicitly ReadField instead of an overloaded Read function. Bug: 23762183 Test: Passes new unit tests. Change-Id: Id848f7b632f67df0c5b7318d9e588942cfd2099a
2017-03-09Elf interface for new unwinder.Christopher Ferris
This cl includes the code to read arm unwind information from a shared library. Bug: 23762183 Test: Passes all unit tests. I can dump the arm unwind information Test: for an arm shared library. Change-Id: I43501ea2eab843b81de8bd5128401dd1971af8d3