This is an archive of the discontinued LLVM Phabricator instance.

[llvm-objcopy] Add support for relocations
ClosedPublic

Authored by jakehehrlich on Aug 9 2017, 2:46 PM.

Diff Detail

Repository
rL LLVM

Event Timeline

jakehehrlich created this revision.Aug 9 2017, 2:46 PM
tpimh added a subscriber: tpimh.Aug 23 2017, 3:14 PM

Not specifically related to this change, but I've seen a lot of cases when referencing the Sections vector, where you have to adjust the sh_link/sh_info value by one, to compensate for the lack of a null section in the vector. Would it be perhaps be easier to explicitly add a null section to the front of the vector up front?

As noted in D34167, symbol names are not necessarily unique, so the current algorithm for creating relocations won't work. I'll let you update this diff before trying to review it further!

tools/llvm-objcopy/Object.cpp
162

++Buf

172

Ditto

294–307

Looks to me like this block here and the block below for SHT_REL should be shared in a separate function.

  1. Changed increments as James requested
  2. Deduplicated Rel vs Rela code using setAddend and getAddend along with a new method initRelocations which is templated
  3. Updated the code the work with LGTMed symbol table code
jhenderson edited edge metadata.Aug 29 2017, 2:28 AM

The overall approach looks fine, but I've just noticed that this code won't handle dynamic relocation sections properly, because their sh_link field will point to a dynamic symbol table (SHT_DYNSYM), which is not treated as a symbol table by the current code. If you make the change in the code separately to treat the dynamic symbol table as a SymbolTableSection for initialisation purposes, and adopt the changes I suggest in this review as well, regarding using "RelSec->Symbols" instead of "SymbolTable", then I think this should then work.

test/tools/llvm-objcopy/basic-relocations.test
92

Could you add a case for a relocation that doesn't refer to a symbol at all, please? This would be the case for e.g. R_X86_64_RELATIVE relocations.

tools/llvm-objcopy/Object.cpp
174–175

Debug text left in by accident?

342

Nits: relocaiton -> relocation. Also full stop!

345–346

We need to check that RelSec->Info and RelSec->Link are in range. Also, we should probably emit an error if the link section is not a symbol table.

350

This and the case below should use the relocation section's linked section (i.e. RelSec->Symbols), because it may refer to a symbol table that isn't the static symbol table.

The overall approach looks fine, but I've just noticed that this code won't handle dynamic relocation sections properly, because their sh_link field will point to a dynamic symbol table (SHT_DYNSYM), which is not treated as a symbol table by the current code.

This is actually on purpose (for the most part). Dynamic relocations and dynamic symbol tables are allocated. We shouldn't change the size, layout, or content of allocated sections. I think the actual mistake I made here is treating allocated relocations as relocation sections when they should just be copied and not messed with. I have the same issue in dynamic string tables in fact (though I was aware of that issue but not this one). See how I planned on adding support for dynamic sections here: https://reviews.llvm.org/D36560. For instance say the DT_JMPREL .dynamic entry could be invalidated by messing with an allocated relocation. Also there's really no benefit to removing dynamic relocations since we can't change the size/layout of sections within a segment.

So I propose that we have two classes for relocations, one for allocated and one for non-allocated. This will mirror how I plan on adding support for dynamic symbol tables and dynamic string tables. We should throw an error if the link of an allocated relocation table doesn't have a dynamic (and allocated) symbol table as it's link.

I think support for dynamic/allocated relocations should be added in a later diff (perhaps D36560 or one immediately after it) but I'm fine adding some of it now since it mostly dosn't interact with things from that diff. If I were to add support in this diff I would add a class called DynamicRelocationsSection and it would be constructed when a SHT_REL(A) section is an allocated section instead of constructing a RelocationsSection. It would still have the setSection and setSymTab methods and would have a finalize method that did the same thing. It would inherit from Section rather than SectionBase so that the writeSection method was implemented correctly for us.

  1. Added error handling requested by James
  2. Fixed comment as requested by James

I did not add the requested test because yaml2obj doesn't support adding relocations without symbols. I plan on adding that feature to yaml2obj and then adding that test.

As another note I'm not convinced that this code will handle that case since I didn't consider it when writing this. I might need to change this to support that case.

So I propose that we have two classes for relocations, one for allocated and one for non-allocated. This will mirror how I plan on adding support for dynamic symbol tables and dynamic string tables. We should throw an error if the link of an allocated relocation table doesn't have a dynamic (and allocated) symbol table as it's link.

I think support for dynamic/allocated relocations should be added in a later diff (perhaps D36560 or one immediately after it) but I'm fine adding some of it now since it mostly dosn't interact with things from that diff. If I were to add support in this diff I would add a class called DynamicRelocationsSection and it would be constructed when a SHT_REL(A) section is an allocated section instead of constructing a RelocationsSection. It would still have the setSection and setSymTab methods and would have a finalize method that did the same thing. It would inherit from Section rather than SectionBase so that the writeSection method was implemented correctly for us.

Seems reasonable to me. I'm happy with this change to be made in a different diff (either D36560 or subsequently, whichever you prefer).

I'm guessing that yaml2obj doesn't have support for setting sh_link/sh_info to invalid values? It would be nice to test that the errors get reported when we expect them, but it's not a priority, so can be added later, if somebody gets time.

tools/llvm-objcopy/Object.cpp
346

I think this message could be reworded slightly to read a bit better. Something like: "Link field value " <value> " in relocation section " <section name> " is invalid" would work, I think. Same goes for the info message below.

356

Similar to above, maybe "Link field of relocation section " <section name> " is not a symbol table".

I tested it and it is not possible to add invalid info or link values using yaml2obj. The info value is not allowed to be invalid or not exist. The link value can be any section name you'd like but it will be ignored and replaced with the symbol table index.

In this update:

  1. Fixed comments

Added test for a relocation with no symbol since the change I made to yaml2obj landed

jhenderson accepted this revision.Aug 31 2017, 1:25 AM

I tested it and it is not possible to add invalid info or link values using yaml2obj. The info value is not allowed to be invalid or not exist. The link value can be any section name you'd like but it will be ignored and replaced with the symbol table index.

Ok, fair enough. No need for that to block this, but it should go somewhere on the "Nice to Have at some point" heap!

LGTM, with changes for the two most recent minor comments, and the removal of the debug text in writeRel.

test/tools/llvm-objcopy/symboless-relocation.test
1 ↗(On Diff #113354)

This test should probably be renamed slightly to either no-symbol-relocation.test or symbolless-relocation.test (note the double 'l').

tools/llvm-objcopy/Object.cpp
340

Slight rewording: Now that all sections and symbols have been added we can...

This revision is now accepted and ready to land.Aug 31 2017, 1:25 AM

Fixed comment and test file name. Should be good to land now.

jhenderson requested changes to this revision.Sep 1 2017, 6:04 AM

Sorry, not all changes I asked for have been made - the debug text at line 174 of Object.cpp is still present. Also, the comment still needs fixing slightly.

tools/llvm-objcopy/Object.cpp
340

Please delete the extra "and symbols have been added" bit.

This revision now requires changes to proceed.Sep 1 2017, 6:04 AM
jakehehrlich edited edge metadata.

Sorry about that James. They should be fixed now.

jhenderson accepted this revision.Sep 4 2017, 2:08 AM

LGTM, with the latest comment change I've suggested.

tools/llvm-objcopy/Object.cpp
340

There's still one rogue "and" in that sentence: "Now that all sections and symbols have been added and we can add" - the bold "and" should be removed.

I think you can also remove the "we can" later, along with one other minor bit of rewording. Full suggested comment:

// Now that all sections and symbols have been added we can add
// relocations that reference symbols and set the link and info fields for
// relocation sections.
This revision is now accepted and ready to land.Sep 4 2017, 2:08 AM

Thanks!

Should actually be good to land now

Do you need me to commit it for you?

This revision was automatically updated to reflect the committed changes.

The Relocation struct had a field named Symbol and a type named Symbol. Some compilers fail on this by default and I'm not sure it is standard complaint. This change fixes that issue by renaming the field RelocSymbol.