This is an archive of the discontinued LLVM Phabricator instance.

[ELF2] Add mandatory .dynamic section entries on MIPS.
ClosedPublic

Authored by ikudrin on Nov 6 2015, 9:00 AM.

Details

Summary

The MIPS target requires specific dynamic section entries to be defined.

  • DT_MIPS_RLD_VERSION and DT_MIPS_FLAGS store predefined values.
  • DT_MIPS_BASE_ADDRESS holds base VA.
  • DT_MIPS_LOCAL_GOTNO holds the number of local GOT entries.
  • DT_MIPS_SYMTABNO holds the number of .dynsym entries.
  • DT_MIPS_GOTSYM holds the index of the .dynsym entry which corresponds to the first entry of global part of GOT.
  • DT_MIPS_RLD_MAP holds the address to the reserved space in the data segment
  • DT_MIPS_PLTGOT points to the .got.plt section if it exists
  • DT_PLTGOT holds the address of the GOT section.

See "Dynamic Section" in Chapter 5 in the following document for detailed information:
ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf

Diff Detail

Repository
rL LLVM

Event Timeline

ikudrin updated this revision to Diff 39543.Nov 6 2015, 9:00 AM
ikudrin retitled this revision from to [ELF2] Add mandatory .dynamic section entries on MIPS..
ikudrin updated this object.
ikudrin added reviewers: atanasyan, ruiu, rafael.
ikudrin added a project: lld.
ikudrin added a subscriber: llvm-commits.
atanasyan requested changes to this revision.Nov 6 2015, 10:36 AM
atanasyan edited edge metadata.
atanasyan added inline comments.
ELF/OutputSections.cpp
491 ↗(On Diff #39543)

Do you read MIPS ABI? DT_MIPS_PLTGOT is used in the non-PIC MIPS code only. PIC MIPS code uses DT_PLTGOT entry but this entry points to the .got section.

659 ↗(On Diff #39543)

What is the case covered by this if statement?

ELF/OutputSections.h
121 ↗(On Diff #39543)

What is the meaning of the "First" here: Lazy resolver, first local entry of first global entry?

This revision now requires changes to proceed.Nov 6 2015, 10:36 AM
ikudrin added inline comments.Nov 6 2015, 11:28 AM
ELF/OutputSections.cpp
491 ↗(On Diff #39543)

The logic of this line: if we have .plt.got section, then store its address to DT_MIPS_PLTGOT entry. Is something wrong here?
Please note, the DT_PLTGOT entry for MIPS target is mentioned a bit later in this function.

659 ↗(On Diff #39543)

We can have global entries in the GOT or it may consist of reserved and local entries only. In the later case, we'll have to change the expression "Target->getGotHeaderEntriesNum()" to something more reasonable when local GOT entries are added.

ELF/OutputSections.h
121 ↗(On Diff #39543)

For MIPS, it's the first global entry, because we don't have SymbolBody for anything else.
For all other targets it's just the first entry of the GOT, although nobody is interested in it.

ikudrin added inline comments.Nov 6 2015, 11:38 AM
ELF/OutputSections.cpp
491 ↗(On Diff #39543)

Moreover, the logic here is the same as in this patch for the old lld: http://reviews.llvm.org/rL200630.

atanasyan added inline comments.Nov 6 2015, 11:43 AM
ELF/OutputSections.cpp
491 ↗(On Diff #39543)

If MIPS dynamic binary has a .got section, DT_PLTGOT entry should point to it. The DT_MIPS_PLTGOT entry should point to the .got.plt entry if MIPS dynamic binary is non-PIC.

https://sourceware.org/ml/binutils/2008-07/txt00000.txt

659 ↗(On Diff #39543)

Maybe it is better at first to complete GOT implementation and add local entries support and then add dynamic entries support.

ELF/OutputSections.h
121 ↗(On Diff #39543)

In that case "First" might confuse. Because you have to read code to realize that the "First" means first global but sometimes just first entry. If you ask somebody familiar with MIPS what is the first GOT entry he or she answers that it is either "Lazy resolver" entry or "first local entry"

atanasyan added inline comments.Nov 6 2015, 11:48 AM
ELF/OutputSections.cpp
491 ↗(On Diff #39543)

No, old lld works correctly at least in that case. Do you use any MIPS toolchain as a reference implementation?

$ cat test.c
void foo() {}

$ mips-linux-gnu-gcc -fPIC test.c -shared
$ readelf -a a.out
...
[16] .got              PROGBITS        000107c0
...
0x00000003 (PLTGOT)                     0x107c0
ikudrin added inline comments.Nov 6 2015, 12:01 PM
ELF/OutputSections.cpp
491 ↗(On Diff #39543)

I can't catch. This patch even includes the test which checks that DT_PLTGOT holds an address of .got section:

# EXE:          Name: .got
. . .
# EXE-NEXT:     Address: [[GOTADDR:0x[0-9a-f]+]]
. . .
# EXE-DAG:    0x00000003 PLTGOT               [[GOTADDR]]
ELF/OutputSections.h
121 ↗(On Diff #39543)

Let's rename it to something like getFirstGlobal() maybe?

atanasyan added inline comments.Nov 6 2015, 12:10 PM
ELF/OutputSections.cpp
491 ↗(On Diff #39543)

Oh, my bad. Handling of dynamic entries are spread among the code. I did not catch that you handle both DT_PLTGOT and DT_MIPS_PLTGOT entries. You are right.

ELF/OutputSections.h
121 ↗(On Diff #39543)

It is okay to me. Is it acceptable for other targets?

ikudrin added inline comments.Nov 6 2015, 12:22 PM
ELF/OutputSections.cpp
491 ↗(On Diff #39543)

OK, I'll add a comment to explain it.

ELF/OutputSections.h
121 ↗(On Diff #39543)

I think it over till Monday.

ikudrin updated this revision to Diff 39674.Nov 9 2015, 2:56 AM
ikudrin updated this object.
ikudrin edited edge metadata.
  • Add explanatory comments.
  • Add the GotSection::getMipsLocalEntriesNum() method.
  • Rename GotSection::getFirstEntry() -> getMipsFirstGlobalEntry().
ikudrin added inline comments.Nov 9 2015, 3:07 AM
ELF/OutputSections.cpp
491 ↗(On Diff #39543)

See the comment in the writeTo() method.

659 ↗(On Diff #39543)

I'm afraid in that case the patch will be postponed for a while. Right now, I don't have time to implement local GOT entries.

ruiu added inline comments.Nov 9 2015, 12:12 PM
ELF/OutputSections.cpp
96–99 ↗(On Diff #39674)

I don't know why you needed this function. If it's just a forwarder, why don't you call Target->getGotHeaderEntriesNum() instead of this function?

473 ↗(On Diff #39674)

Add a blank line.

ELF/OutputSections.h
121 ↗(On Diff #39674)

Add a blank line before the start of the comment.

126 ↗(On Diff #39674)

Ditto

ELF/Target.cpp
157 ↗(On Diff #39674)

This and removal of getVAStart from Writer are good changes but not related to this patch. Please submit as a separate commit. (You don't need another pre-commit code review for that.)

ikudrin added inline comments.Nov 10 2015, 2:09 AM
ELF/OutputSections.cpp
96–99 ↗(On Diff #39674)

The Target->getGOTHeaderEntriesNum returns the number of the "reserved" GOT entries. This function returns the count of all entries of the local part of GOT, which contains not only the reserved entries but also entries for local symbols. So, the meanings are different.

Even though GotSection does not support entries for local symbols for now, the result is correct and we can use it to write the DT_MIPS_LOCAL_GOTNO dynamic section entry. When the support is added, we will have to update only this function, not DynamicSection::writeTo() method, so the changes will be more local.

ikudrin updated this revision to Diff 39797.Nov 10 2015, 2:28 AM
ikudrin edited edge metadata.
  • Extract getVAStart() change as a separate patch.
  • Rebase on the top.
  • Add comments and blank lines.
atanasyan accepted this revision.Nov 11 2015, 5:03 AM
atanasyan edited edge metadata.

LGTM

This revision is now accepted and ready to land.Nov 11 2015, 5:03 AM
ruiu accepted this revision.Nov 11 2015, 2:27 PM
ruiu edited edge metadata.

LGTM

This revision was automatically updated to reflect the committed changes.