This is an archive of the discontinued LLVM Phabricator instance.

[llvm-nm] Add --line-numbers flag
ClosedPublic

Authored by mysterymath on May 19 2023, 11:47 AM.

Details

Summary

This flag parallels the binutils flag of the same name. Debugging
information is loaded to print line number information for symbols, with
simlar semantics to llvm-symbolizer.

Diff Detail

Event Timeline

mysterymath created this revision.May 19 2023, 11:47 AM
Herald added a project: Restricted Project. · View Herald Transcript

Add documentation.

mysterymath published this revision for review.May 25 2023, 3:53 PM
mysterymath added reviewers: phosek, mcgrathr.
Herald added a project: Restricted Project. · View Herald TranscriptMay 25 2023, 3:53 PM

Fix test on Windows.

phosek accepted this revision.Jun 27 2023, 12:03 AM

LGTM but I'd wait a day or two before landing this so @jhenderson has a chance to respond.

llvm/tools/llvm-nm/llvm-nm.cpp
770

It'd be better if we could avoid instantiating LLVMSymbolizer unless needed since this is a non-trivial object. A simple way to do would be to move it to printLineNumbers and make it static but there might a cleaner way.

This revision is now accepted and ready to land.Jun 27 2023, 12:03 AM

Sorry for the non-existent response up to now - I'm rather snowed under with review requests.

@MaskRay, any comments?

llvm/test/tools/llvm-nm/X86/line-numbers.test
2

Rather than using a canned object in this test, could you write a simple bit of code in assembly that has a few symbols and then use llvm-mc -g to assemble it with debug information? I would expect this to work for --line-numbers.

Canned object files are opaque and hard to maintain.

5

I'm not sure what this line is intended to be testing? Should that be an extern int e;?

I think it would be useful to have some comments explaining what each line is trying to test.

13

As well as an undefined data symbol, you might want an undefined function too.

llvm/tools/llvm-nm/llvm-nm.cpp
695

Test case?

700–701

Test case? I'm guessing this handles e.g. common or absolute symbols that don't have an associate section?

711–712

Test case?

714–715

Is this tested?

I believe you can have references to symbols from outside text sections after all (e.g. populating a variable with an address of a data symbol).

717–718

For this to be tested, you need at least two undefined symbols referenced via relocations in the same relocation section, but I don't see them, so I'm guessing it's not.

722

Why consumeError here rather than reporting the error? Same in various places below.

756

You need testing for symbols that don't end up with an associated file/line number (both defined and undefined).

770

std::optional<LLVMSymbolizer> which is initialised if LineNumbers is true, perhaps?

Nit: I don't think you need the llvm:: prefix here, right?

MaskRay added inline comments.Jun 27 2023, 2:29 PM
llvm/test/tools/llvm-nm/X86/line-numbers.test
13

e is not declared in this file. I agree that testing a function will be useful. Ideally, also test an undefined symbol that is not referenced (.globl und without a label definition gives an unreferenced undefined symbol)

21

Add -NEXT: whenever applicable.

By default the symbol list is sorted by name/size/addressed, so we don't need to worry about shuffled symbol table by llvm-mc updates.

llvm/tools/llvm-nm/llvm-nm.cpp
2486

This separates OPT_format_EQ and its values. Consider moving this immediately before NoLLVMBitcode

MaskRay added inline comments.Jun 27 2023, 2:32 PM
llvm/tools/llvm-nm/llvm-nm.cpp
734

We want test cases for a local symbol.

mysterymath marked 15 inline comments as done.

Address review feedback

Remove canned binary

MaskRay added inline comments.Sep 6 2023, 7:22 PM
llvm/test/tools/llvm-nm/X86/line-numbers.test
3

What does this check?

jhenderson added inline comments.Sep 7 2023, 12:18 AM
llvm/test/tools/llvm-nm/X86/line-numbers.test
28–42

It's not immediately clear to readers of this why you can't have some or all of these folded into main.s. It would be useful to have comments explaining a) exactly what each test case is trying to test that is different to other cases, and b) why they can't be part of main.s.

64

It would be clearer if there was a blank line between each input file.

llvm/tools/llvm-nm/llvm-nm.cpp
695

Although this is marked as done, it's not clear to me what test case is covering it. Could you please elaborate a bit more?

697

I'm not convinced there's any value in this local variable. In fact, the name SR is non-obvious as to its purpose or anything, and this function is somewhat long. I'd just get rid of the local variable entirely.

722

Now that you're reporting the error, there needs to be test cases for the error cases.

756

Although this is marked as done, I expected to see some test cases that had a mixture of "stuff found in the debug information" and "stuff not found in the debug information" to properly exercise this behaviour.

770

Nit: I don't think you need the llvm:: prefix here, right?

Still unaddressed?

mysterymath marked 7 inline comments as done.

Another round of comments

llvm/test/tools/llvm-nm/X86/line-numbers.test
3

Added a comment for this.

5

Yes; 'c' was a typo, it should have been 'e'. Regardless, I've renamed all these symbols to give an indication of why the symbol is part of the test case.

28–42

Added comments before each of these section for this.

llvm/tools/llvm-nm/llvm-nm.cpp
695

This is covered by the initial bitcode file test case; this is a symbolic file that is not an object file, so this dynamic cast fails.

697

This performs a cast; I've rewritten this to explicitly call the constructor to make this clearer. Renamed to Sym.

722

A test case that specifically targets this line encodes a proof that the line is reachable, but I don't have one, as these checks represent instead that there is no known proof that the case isn't reachable. Even if a proof of reachability or non-reachability were available, it would depend on encapsulated implementation details of Symbolizer and earlier portions of llvm-nm, and it shouldn't be baked into the behavior of printing line numbers, since that's logically independent from what kind of module validation has been done up until that point. Even if these cases aren't actually reachable (and thus fully untestable), there should still be checks here, since the reason they're not reachable is so contingent on other factors that should be free to change independently.

756

There is already some of this present in main.s, e.g., the absolute value case has no DWARF. I've added additional cases to main.s to show as many mixtures as are feasible using only the mechanisms available to llvm-mc. Handcrafting DWARF for the test case would make the abstraction level of the test mis-match the abstraction level of the implementation. The implementation is fully abstract over debugging formats, so ideally, it should be possible to update the test cases for such code without the ability to craft DWARF by hand.

770

Ah sorry.

jhenderson added inline comments.Sep 11 2023, 1:33 AM
llvm/test/tools/llvm-nm/X86/line-numbers.test
2–3

Nit: new tests in many of the LLVM tools use ## for comment markers, to help them stand out from the lit and FileCheck directives.

I don't understand how a "symbolic object file" is not already an "object file". This comment looks suspiciously like it's essentially copying code terms into the English prose, without actually stating what is significant. What is a "symbolic object file"? What is an "object file" in this context? Most importantly, how are the two different?

5

If you are trying to show that there is no output, it is better to do count 0 instead of a FileCheck command. However, I'm guessing that the output isn't expected to be empty. Showing that ":" is not in the output feels very fragile though - it could easily appear in a file path (if an absolute path is used on Windows, for example), or indeed other parts of the output. Better would be to match the output that is produced and use stuff like --implicit-check-not={{.}} to show that this is the entire output that is present.

--strict-whitespace also has no purpose in this particular test case.

9

It would make sense for this case to have a comment too, since all the others now do.

23

Can I suggest "... in the absence of any DWARF in the whole object, no line number ..." to clarify the distinction between this and the individual cases data_no_dwarf etc.

43–45

Nit: I'm confused what line wrapping rules you're following in this test file - compare this to the previous comment, and you'll note that one is not wrapped at all, whereas this one is broken up over three lines.

77

Same below.

llvm/tools/llvm-nm/llvm-nm.cpp
697

Could const SymbolRef Sym(S.Sym); be used? That seems clearer to me.

mysterymath marked 6 inline comments as done.

More review comments

llvm/test/tools/llvm-nm/X86/line-numbers.test
2–3

Yep, that's the case, but it's a good point that the tests should be readable while treating the implementation as a black box.

43–45

Yeah, my intent was to break comments along an 80 column boundary, but this was inconsistently applied.

llvm/tools/llvm-nm/llvm-nm.cpp
697

Yeah, that reads better to me too now that you mention it. Done.

jhenderson accepted this revision.Sep 13 2023, 1:19 AM

LGTM. Probably should wait for @MaskRay too.

MaskRay accepted this revision.Sep 18 2023, 5:27 PM

one nit

llvm/tools/llvm-nm/llvm-nm.cpp
763
mysterymath marked an inline comment as done.

Remove semicolon

This revision was landed with ongoing or failed builds.Sep 19 2023, 2:14 PM
This revision was automatically updated to reflect the committed changes.