This is an archive of the discontinued LLVM Phabricator instance.

[ELF] - Better diagnostic for relative relocation to an absolute value error.
ClosedPublic

Authored by grimar on Nov 10 2016, 8:40 AM.

Details

Summary

Patch adds a filename to that error message.

I am facing this now when debugging one of FreeBSD port:
error: relocation R_X86_64_PLT32 cannot refer to absolute symbol __tls_get_addr

Body->File field is empty for next place:

if (AbsVal && RelE) {
  if (Body.isUndefined() && !Body.isLocal() && Body.symbol()->isWeak())
    return true;
  error("relocation " + getRelName(Type) +
        " cannot refer to absolute symbol " + Body.getName());
  return true;
}

It took some time to find the file and since global direction is to make linker more user friendly,
I suggest to add filename for that message.

Diff Detail

Repository
rL LLVM

Event Timeline

grimar updated this revision to Diff 77495.Nov 10 2016, 8:40 AM
grimar retitled this revision from to [ELF] - Better diagnostic for relative relocation to an absolute value error..
grimar updated this object.
grimar added reviewers: ruiu, rafael.
grimar added subscribers: llvm-commits, grimar, evgeny777, davide.
pcc added a subscriber: pcc.Nov 10 2016, 10:26 AM

Test case?

ELF/SymbolTable.h
63 ↗(On Diff #77495)

Why is it necessary to add this parameter, can't you access the file via the section?

ruiu edited edge metadata.Nov 10 2016, 12:45 PM

What is the previous output, and how does it change with this patch? An example would be helpful to understand.

Also out of curiosity, which port produced this?

evgeny777 added inline comments.Nov 10 2016, 1:38 PM
ELF/InputFiles.cpp
471 ↗(On Diff #77495)

Why do you need to pass 'this' pointer if you can use Sec->getFile()

ELF/Relocations.cpp
345 ↗(On Diff #77495)

I suggest printing getLocation(Rel.Section, Rel.Offset) as it seems to be more useful than location of absolute symbol. Also please add ": " after location.

Also out of curiosity, which port produced this?

It is cad/iverilog (iverilog-10.1.1)

grimar updated this revision to Diff 77602.Nov 11 2016, 2:12 AM
grimar edited edge metadata.
  • Addressed review comments.
ELF/InputFiles.cpp
471 ↗(On Diff #77495)

Because Sec can be nullptr, in case of absolute symbol.

ELF/Relocations.cpp
345 ↗(On Diff #77495)

Done, printing both, thanks for hint.

ELF/SymbolTable.h
63 ↗(On Diff #77495)

Section is null for absolute symbols.

In D26508#592123, @ruiu wrote:

What is the previous output, and how does it change with this patch? An example would be helpful to understand.

So previous output would be just something like "relocation R_X86_64_PLT32 cannot refer to absolute symbol answer",
Body->File was empty so it was not possible to print symbol location definition.

I added missing argument to replaceBody (that was an issue of first diff) and also implemented Eugene's
suggestion, now messages seems to be much more helpfull (please see testcase).

Also out of curiosity, which port produced this?

It is cad/iverilog (iverilog-10.1.1)

Just in case - opened an issue: https://llvm.org/bugs/show_bug.cgi?id=30984

grimar updated this revision to Diff 77617.Nov 11 2016, 7:55 AM
  • Rebased.
  • Emit single error instead of 2 for a one place.
ruiu added inline comments.Nov 11 2016, 12:29 PM
ELF/InputFiles.cpp
807–814 ↗(On Diff #77617)

Why don't you pass this instead of nullptr?

ELF/Relocations.cpp
309–310 ↗(On Diff #77617)

I don't think you need to add a new parameter because DefinedRegular has Section member.

349 ↗(On Diff #77617)

Please change the message "cannot refer to absolute symbol '" + Body.getName() + "' defined in "

637 ↗(On Diff #77617)

Revert this change because this is not related.

ELF/SymbolTable.h
63 ↗(On Diff #77495)

Actually, I hope we represent an absolute symbol in a different way than a null pointer so that we can eliminate the parameter. You don't need to do that in this patch though.

grimar updated this revision to Diff 77774.Nov 14 2016, 1:22 AM
  • Addressed review comments.
ELF/InputFiles.cpp
807–814 ↗(On Diff #77617)

addRegular here calls the next code:

template <class ELFT>
std::pair<Symbol *, bool>
SymbolTable<ELFT>::insert(StringRef &Name, uint8_t Type, uint8_t Visibility,
                          bool CanOmitFromDynSym, InputFile *File) {
  bool IsUsedInRegularObj = !File || File->kind() == InputFile::ObjectKind;

If I would pass this, IsUsedInRegularObj then changes from true to false what breaks the logic and test.
I think the condition should be extended to check kind() for BinaryFile, but I also
believe it is out of area of this patch and should be done separatelly.

ELF/Relocations.cpp
309–310 ↗(On Diff #77617)

Additional parameter helps not to assume that Body belongs to DefinedRegular.
Otherwise if I understood idea correctly we can end up with something like:

if (AbsVal && RelE) {
  if (Body.isUndefined() && !Body.isLocal() && Body.symbol()->isWeak())
    return true;

  auto *D = dyn_cast<DefinedRegular<ELFT>>(&Body);
  if (!D)
    fatal(getRelName(Type) + " cannot refer to absolute symbol '" +
          Body.getName() + "' defined in " + getFilename(Body.File));
  else
    error(getLocation(*D->Section, RelOff) + ": relocation " +
          getRelName(Type) + " cannot refer to absolute symbol '" +
          Body.getName() + "' defined in " + getFilename(Body.File));
  return true;
}

I think it is better not to assume that body is DefinedRegular here,
as we are trying to catch and print any possible error un a user-friendly way and also keep code simpler.
What do you think ?

349 ↗(On Diff #77617)

Changed the part of message as suggested.
I think you did not mean you want to remove "getLocation()..... + : relocatiion" part right ?

637 ↗(On Diff #77617)

Done.

ruiu accepted this revision.Nov 14 2016, 1:06 PM
ruiu edited edge metadata.

LGTM.

I still think that there's a way to reduce the number of parameters, but this patch is good enough to land.

This revision is now accepted and ready to land.Nov 14 2016, 1:06 PM
This revision was automatically updated to reflect the committed changes.