This is an archive of the discontinued LLVM Phabricator instance.

[ELF] Fix DT_MIPS_LOCAL_GOTNO value when using linker scripts to change section sizes
ClosedPublic

Authored by jhenderson on Nov 1 2017, 8:05 AM.

Details

Summary

The MIPS GOT section has a number of local entries based on the number of pages needed for output sections referenced by GOT page relocations. The number is recorded in the DT_MIPS_LOCAL_GOTNO dynamic section tag. However, the dynamic tag is added before assignAddresses has been called, meaning that any section size used to calculate the value will not include size modifications caused by linker scripts, thunks, etc.

This change moves the calculation of DT_MIPS_LOCAL_GOTNO until writeTo, by which time the output section sizes have been finalized.

I have spun it off from D38361, because the behaviour is already broken.

Diff Detail

Repository
rL LLVM

Event Timeline

jhenderson created this revision.Nov 1 2017, 8:05 AM

Ping.

Regardless of which of D38361 or D38321 is preferred, this should be fixed independently.

atanasyan added inline comments.Nov 9 2017, 2:35 AM
ELF/SyntheticSections.cpp
1189 ↗(On Diff #121129)

Other targets might have dynamic table tags with the same value so we have to check Config->EMachine == EM_MIPS here.

jhenderson updated this revision to Diff 122217.Nov 9 2017, 2:54 AM
jhenderson marked an inline comment as done.

Thanks @atanasyan. I've fixed that.

ruiu added inline comments.Nov 14 2017, 12:03 AM
ELF/SyntheticSections.cpp
1169 ↗(On Diff #122217)

I think this kind of "if (MIPS)" should be avoided. Is there any way to not add that code here? For example, can't you finalize the GOT section before this section?

jhenderson added inline comments.Nov 20 2017, 3:04 AM
ELF/SyntheticSections.cpp
1169 ↗(On Diff #122217)

For example, can't you finalize the GOT section before this section?

Unfortunately this example isn't possible: it's what currently happens and is why we have to use this trick. The problem is that the dynamic section size is determined by the tags in it. This size affects the overall allocatable size of the executable, which means that the tag has to be added either before the new assignAddresses loop, or during, and assigned a value either during or after the loop. Adding the tag during the loop is not great, since that would mean repopulating the dynamic section either completely, or in part during each iteration, so we need to add it before, and assign a value later.

I do have a few alternative ideas though that would move the if (MIPS) out of the writeTo code, if you prefer:

  1. Add a different Entry kind specific for the MipsGot local entries count.
  2. Implement postThunkContents for Dynamic sections, which simply finds this tag and updates it after the Thunk loop (this would still require an "if (MIPS)" but it would not be in the Write code).
  3. Implement updateAllocSize for Dynamic sections, which updates the value of the existing tag. Again, it would be necessary to add an "if (MIPS)" here.
  4. Add a new member to the DynamicSection that points to the DT_MIPS_LOCAL_GOTNO tag, and is set when the tag is initialised. The tag could then be updated during postThunkContents, updateAllocSize, or in writeTo, to remove the need for "if (MIPS)" in these places.

I'm happy to do do any of these changes, if you aren't happy with the current proposal, or if you've got another alternative, I can look at that too.

grimar added inline comments.Nov 20 2017, 3:12 AM
ELF/SyntheticSections.cpp
1169 ↗(On Diff #122217)

I also thought of:

  1. Add a different Entry kind that will be of type std::function<uint64()>.

So you would write:

add({DT_MIPS_LOCAL_GOTNO, [](){ return InX::MipsGot->getLocalEntriesNum(); });

That is not ideal probably, but does not require adding MIPS specific code at least.

jhenderson accepted this revision.Nov 22 2017, 1:44 AM

Rafael posted an LGTM on the mailing list. I will commit this as is, so that it unblocks D38361 but I really like @grimar's suggestion, so I plan on posting another review based on it, which should hopefully resolve any concerns @ruiu still has.

This revision is now accepted and ready to land.Nov 22 2017, 1:44 AM
ruiu added inline comments.Nov 22 2017, 2:06 AM
ELF/SyntheticSections.cpp
1169 ↗(On Diff #122217)

Yes, that's what I was thinking too.

James, please do this after you commit this change so that we can remove if (MIPS).

This revision was automatically updated to reflect the committed changes.
jhenderson added inline comments.Nov 22 2017, 4:17 AM
ELF/SyntheticSections.cpp
1169 ↗(On Diff #122217)

Will do, although I'll wait for D40338 to land, I think.