This is an archive of the discontinued LLVM Phabricator instance.

llvm-symbolizer: teach it about PowerPC64 ELF function descriptors
ClosedPublic

Authored by foad on Nov 4 2014, 3:41 AM.

Details

Summary

Teach llvm-symbolizer about PowerPC64 ELF function descriptors. Symbols in the .opd section point to function descriptors, the first word of which is a pointer to the real function. For the purposes of symbolizing we pretend that the symbol points directly to the function.

This is enough to get decent function names in stack traces for unoptimized binaries, which fixes the sanitizer print-stack-trace test on PowerPC64 Linux.

Diff Detail

Event Timeline

foad updated this revision to Diff 15756.Nov 4 2014, 3:41 AM
foad retitled this revision from to llvm-symbolizer: teach it about PowerPC64 ELF function descriptors.
foad updated this object.
foad edited the test plan for this revision. (Show Details)
foad added reviewers: kcc, samsonov, willschm.
foad added a subscriber: Unknown Object (MLST).
samsonov edited edge metadata.Nov 5 2014, 6:29 PM

Thank you for working on this! Please make sure to add a test case in LLVM testsuite as well (it should go to somewhere like test/tools/llvm-symbolizer). Probably the test case would be a tiny powerpc64 binary with no debug info, so that we can ensure we fetch the function name from symbol table correctly.

tools/llvm-symbolizer/LLVMSymbolize.cpp
49

Consider the following approach: if Module->getArch() is Triple::ppc64 (should we also treat Triple::ppc64le?), and you have an .opd section, create a DataExtractor. Then you can pass this DataExtractor down to addSymbol() as an optional argument, and fetch the actual addresses of functions there. It looks weird to create DataExtractor for each and every of thousands of symbols.

106

You can use DataExtractor::getAddress() instead. Consider using isValidOffsetForDataOfSize to verify that the offset into .opd is valid.

tools/llvm-symbolizer/LLVMSymbolize.h
139

This member doesn't look to be required - Functions and Objects maps are built in the constructor, and you only need this section in "addSymbol" implementation.

foad updated this revision to Diff 15864.Nov 6 2014, 6:33 AM
foad edited edge metadata.

Address Alexey's comments.

foad added a comment.Nov 6 2014, 6:35 AM
In D6110#4, @samsonov wrote:

Consider the following approach: if Module->getArch() is Triple::ppc64 (should we also treat Triple::ppc64le?)

There's no need to do this for ppc64le, because it uses the "ELFv2" ABI which doesn't have function descriptors.

foad added a comment.Nov 6 2014, 6:41 AM

Inline comment.

tools/llvm-symbolizer/LLVMSymbolize.cpp
91–92

I realise this is a bit ugly. As an alternative I could update DataExtractor::isValidOffset{,ForDataOfSize} to take 64-bit offsets.

samsonov added inline comments.Nov 6 2014, 11:35 AM
tools/llvm-symbolizer/LLVMSymbolize.cpp
58

I'd prefer Module->isLittleEndian() here.

91

You can then hide this whole block under

if (OpdExtractor) {}
91–92

Yeah, but let's fix DataExtractor later. Note that you can also compare OpdOffset with "uint32_t Offset" you declare below.

tools/llvm-symbolizer/LLVMSymbolize.h
121

Consider making OpdExtractor argument a raw pointer - it is really optional, and you shouldn't need to create DataExtractor object if it's not needed.

foad updated this revision to Diff 15892.Nov 6 2014, 2:09 PM

Change addSymbol to take a (possibly null) pointer instead of a
reference to the DataExtractor.

samsonov accepted this revision.Nov 6 2014, 4:40 PM
samsonov edited edge metadata.

LGTM, thanks!

tools/llvm-symbolizer/LLVMSymbolize.cpp
60

Put this under the if-statement, where you define OpdExtractor.

This revision is now accepted and ready to land.Nov 6 2014, 4:40 PM
foad updated this revision to Diff 15913.Nov 7 2014, 1:12 AM
foad edited edge metadata.
  • Put assignment to OpdAddress inside the if.
  • Use nullptr instead of 0.
foad closed this revision.Nov 7 2014, 1:19 AM