This is an archive of the discontinued LLVM Phabricator instance.

[ELF] - Add additional information about location when emiting linkerscript's parsing errors.
AbandonedPublic

Authored by grimar on Aug 22 2017, 7:23 AM.

Details

Reviewers
ruiu
rafael
Summary

This is PR31128 which complains that we show unclear message when
parsing script like

.= foo

(note: there is no space between `.=')

When LLD see .= foo; it starts reading output section declaration.
It reads section name .=, addess expression foo and expects to see : right after that
all and fails with : expected, but got ; message, which is fully correct in this case,
but not very useful for user who writes simple assignment expression.

FWIW scripts like SECTIONS { .= : { *(.text*) } } are correct, both GNU linkers
would create output section .= in that case, and LLD do the same.

What I suggest is to provide additional error context if available, like this patch do.

Diff Detail

Event Timeline

grimar created this revision.Aug 22 2017, 7:23 AM

I think that this is definitely an improvement, I've made some suggestions but I haven't got a strong opinion.

ELF/ScriptLexer.h
42

It might be better to call this LocationContext if it is specifically going to be used within setLocationContext() and dropLocationContex(). This might help prevent it being used/overwritten in other non LocationContext situations by mistake.

ELF/ScriptParser.cpp
607

Is it worth an RAII wrapper so that you don't have to explicitly remember to call dropLocationContext()?

607

Would it be worth using "section definition for output section" rather than "description for output section" to match the Linker Script manual?

grimar added inline comments.Aug 22 2017, 8:07 AM
ELF/ScriptLexer.h
42

May be, or I was thinking about following names now:
ErrorContext, setErrorContext, dropErrorContext

ELF/ScriptParser.cpp
607

Is it worth an RAII wrapper so that you don't have to explicitly remember to call dropLocationContext()?

I tried 2 more ways here:

  • Simple class that sets/drops context in constructor/destructor.
  • Storing std::weak_ptr<std::string> Context. That way we can do something like:
std::shared_ptr<std::string> setErrorContext(const Twine& Msg) {
  auto Ret = make_shared<std::string>(Msg.cstr());
  Context = Ret;
  return Ret;
}
...
auto C = setErrorContext("blah blah blah");
<and while this shared pointer is alive, following code will print context>
...

if (auto C = Context.lock())
  error(*C);

But I am not sure it worth to do now, when there is only single place where context is used.

Would it be worth using "section definition for output section" rather than "description for output section" to match the > Linker Script manual?

I'll change it, thanks. My wording was based on method name here.

grimar edited the summary of this revision. (Show Details)Aug 22 2017, 8:18 AM
grimar updated this revision to Diff 112183.Aug 22 2017, 9:06 AM
  • Renamed new methods/field, changed error text to suggested.

Thanks very much for the update, I've no further comments.

ruiu added inline comments.Aug 22 2017, 9:13 AM
ELF/ScriptLexer.cpp
81–87

In general, do not call error multiple times for an error message. Call error only once per an error instead. This is important because we have the -error-limit option which manages the number of errors (and that is different from number of lines of error messages.)

I think you can now see why our error message format is something like cannot parse file: /foo/bar. It's because you can concatenate multiple error messages by joining with ":" like this:

error while reading linker script foo.ls: cannot parse file: /foo/bar

So, concatenate error strings into one string and print it out using error just like above.

ELF/ScriptLexer.h
42

I'd name ErrorPrefix as this string is printed as a prefix for an error message.

ELF/ScriptParser.cpp
607

RAII is a good idea, but if you don't want to do that, you don't want to create a set of functions just to set Context local varaible. You could just directly assign values to the variable.

grimar updated this revision to Diff 112321.Aug 23 2017, 2:53 AM
  • Addressed review comments.
ruiu added inline comments.Aug 23 2017, 8:19 AM
ELF/ScriptParser.cpp
608

Don't include ">>>" in a prefix. Just end it with ": ".

grimar added inline comments.Aug 23 2017, 8:27 AM
ELF/ScriptParser.cpp
608

I did that because message printed was huge for me:

error: {{.*}}.script.inc:4: unable to parse description for output section 'boom': malformed number: .temp

where {{.*}}.script was a long path itself.

ruiu edited edge metadata.Aug 23 2017, 8:39 AM

Yes, I understand that, but as I wrote in a previous comment, this kind of style

error: foo bar
>>> A
>>> B
>>> C

is odd unless A, B and C are list items for the same list. In other words, you cannot always simply concatenate all error messages with ">>>\n".

grimar abandoned this revision.Dec 1 2017, 4:13 AM