Page MenuHomePhabricator

[ELF] - Basic versioned symbols support implemented.
ClosedPublic

Authored by grimar on Jun 6 2016, 5:05 AM.

Diff Detail

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes
ruiu added inline comments.Jun 9 2016, 12:23 PM
ELF/OutputSections.h
254

Add a blank line.

grimar added a subscriber: ruiu.Jun 10 2016, 12:23 AM
In D21018#453725, @ruiu wrote:

For some reason, I received no email notifications on this review thread. George, do you have an idea why?

I think the only difference here from my usual style was that I quoted the part of your message and posted responce "Thanks for review ! My response to comments are below." in the same message with responces on review comments. Usually I think I do not do that and comments just auto merged to the last (patch updated) post. I am always using web form for that, so no much ways to do almost the same here exist.

Not sure that it can be the reason, I added you as a subscriber just in case as well, hope that helps.

I haven't fully understand the core part of the patch yet, so this review is mostly on stylistic things. I'll read it again later today or tomorrow. (I'm traveling for a few days until Sunday.)

Ok, just in case I think I`ll also be able to address any comments for this in next 2 days if any.

grimar updated this revision to Diff 60328.Jun 10 2016, 2:54 AM
grimar marked 4 inline comments as done.
  • Addressed review comments.
ELF/OutputSections.h
246

Done.

254

Done.

ELF/SymbolListFile.cpp
147–149

Actually this does not. Though it should be valid С++ construction and works in msvs/gcc,
as far I know clang produces an error if you do not specify all members in aggregate specialization.
So this might be:

Config->SymbolVersions.push_back({next(), {}});

to work. And I do not like this, because if you change the members of struct (amount of them),
you have to be sure to check and update all such places to support clang.

I updated this place, since it is single, but above was the reason why I did not do that initially (even was thinking about adding constructor for Name to Version struct).

152

Done.

ruiu added a comment.Jun 10 2016, 11:01 AM

Ahh, I got the reason why it didn't appear in my inbox. It went to a spam folder. I'm sorry about that. If you have sent me mails and did not get responses, please re-send.

ELF/SymbolListFile.cpp
147–149

Then how about defining a constructor that takes a StringRef?

grimar updated this revision to Diff 60437.Jun 11 2016, 8:50 AM
grimar marked an inline comment as done.
  • Addressed review comment.
ELF/SymbolListFile.cpp
147–149

Done. That is not very consistent with other lld code, but solves the problem.
(actually I just do not understand why it can not be solved(fixed) in clang, as this feature of c++ language looks
pretty cool for me).

pcc added a subscriber: pcc.Jun 13 2016, 1:37 PM
pcc added inline comments.
ELF/OutputSections.cpp
1426

Can we rename our implementation of the ELF hash function to something like hashElf? I previously wasn't aware that we had one.

1431

This is a well-known problem, we probably don't need to call out every instance of it.

1439

Grammar nitpick: "to the number of definitions"

1451

It isn't deterministic to iterate over a DenseMap like that.

1513

Grammar nitpick: "if it exists"

1516

The std::max seems redundant because getVerDefNum() cannot return a value less than 2 here.

ELF/OutputSections.h
245–248

I don't think you need either of the flags or hash fields here. The first one is never anything but zero in your implementation, and you can compute the second one as you produce the contents of the .gnu.version_d section.

251

Instead of having this DenseMap, could you move VerDefEntry's fields to Version?

252

Please update this comment to cover version definitions.

ELF/Symbols.h
143

This field belongs on Symbol, as it is a property of a symbol name (and this won't work correctly if a bitcode file defines a versioned symbol). Can you please move this to Symbol and add a test showing that LTO works correctly with this feature?

On that point, I'm not sure that we want all 3 of SharedSymbol::VersionId, Symbol::VersionScriptGlobal and this new field. Did you think about unifying them somehow?

rafael added inline comments.Jun 16 2016, 6:22 AM
ELF/SymbolListFile.cpp
80

Do we really need to duplicate the parsing? We should be able to have a single parser and take different actions based on the name, no?

grimar marked 9 inline comments as done.Jun 16 2016, 12:37 PM

Hi Peter ! Thanks for usefull review. I hope to update this one soon. As soon as solve unifying problem you're mentioned.

ELF/OutputSections.cpp
1426

I have nothing against that if Rui and Rafael also support the new naming. That can be committed separatelly.

1431

Ok, I did not know about that.

1439

Thanks !

ELF/Symbols.h
143

Probably yes. I am working on unifying.

grimar updated this revision to Diff 61078.Jun 17 2016, 3:34 AM
grimar retitled this revision from [ELF] - Basic versioned symbols support implemented. to [ELF/WIP] - Basic versioned symbols support implemented..
grimar marked 3 inline comments as done.
  • Addressed review comments (all except creating test for LTO, I am working on it as never did such ones yet I think, will update patch later today I think).

Note: script parsing code in this version based on Rafael patch "[PATCH] Make local: optional.", to show how new functionality fits.

grimar updated this revision to Diff 61091.Jun 17 2016, 6:27 AM
  • Added LTO test.
  • Fixed issue: sh_addralign field was not set for .gnu.version_d
ruiu added inline comments.Jun 17 2016, 12:05 PM
ELF/Config.h
38
Version(llvm::StringRef Name) : Name(Name) {}
ELF/OutputSections.cpp
566

Maybe the comment is too detailed and didn't actually say what it is doing? I'd say "Returns the number of version definition entries. Because the first entry is for the version definition itself, it is the number of versioned symbols plus one. Note that we don't support multiple versions yet."

1424

Other sections finalize() functions add strings to .dymstr. Is there any reason you didn't choose to do this in finalize()?

1449

You are writing two different types of records in this loop -- one for the first entry and the other for the remaining entries. It is better to separate the first entry from the others. Then you can remove all the IsBase dispatches from this loop.

ELF/SymbolListFile.cpp
77

Please rebase.

ELF/SymbolTable.cpp
531

Use range-based for loop.

ELF/Writer.cpp
912

Instead of adding isRequired() method, don't instantiate Out<ELFT>::VerSym if not needed. It's what we usually do for other sections.

pcc added inline comments.Jun 17 2016, 12:13 PM
ELF/OutputSections.cpp
1425

I think this should be the soname, not the output file name.

1456

Same here

1501

Fold this variable into its use.

ELF/OutputSections.h
255–257

Either .gnu.version_r or .gnu.version_d.

ELF/Symbols.cpp
270

This is the only place where we are using the VerDef and VersionScriptGlobal fields. Can you replace (VersionScriptGlobal || body()->symbol()->VerDef) here with VersionId != VER_NDX_LOCAL and remove both of those fields?

(Also, body()->symbol()-> is unnecessary here, as it just takes you back to the Symbol you started with.)

Thank you for reviews ! I`ll address your comments during my tomorrow.

grimar updated this revision to Diff 61163.Jun 18 2016, 4:33 AM
grimar marked 12 inline comments as done.
  • Addressed review comments.
grimar added inline comments.Jun 18 2016, 4:34 AM
ELF/Config.h
38

Done.

ELF/OutputSections.cpp
566

Changed.

1424

Moved to finalize(). I think there was some problem, not really remember what exactly in very first iteration of this patch (createDefs did more work that time). Now it is redundant.

1425

Checked that, both ld/gold use soname, and if it is not set then output file name is taken. Corrected the logic to match.

1449

Done.

1456

Fixed.

1501

Done.

ELF/OutputSections.h
255–257

Done.

ELF/SymbolListFile.cpp
77

Done.

ELF/SymbolTable.cpp
531

Done.

ELF/Symbols.cpp
270

Done.

ELF/Writer.cpp
912

Done.

ruiu added inline comments.Jun 18 2016, 5:46 PM
ELF/OutputSections.cpp
567

Make this a function comment.

1449

unsigned -> size_t.

1473

Just pass 1 instead of I.

ELF/SymbolListFile.cpp
127–129

So you are constructing a Version object in two steps -- first by passing only Version parameter to the constructor and then add Cur to its Globals array, right? That's a bit hard to read. Is there any way to do this in one step?

ELF/SymbolTable.cpp
531

size_t should be more accurate type (in practice they don't differ though.)

533

Increment this at end of the loop -- that's easier to read.

ELF/Symbols.h
422

Does unsigned VersionId : 16 save space?

ELF/Writer.cpp
121–123

So, instead of instantiating them unconditionally, can you instantiate them only when needed?

grimar updated this revision to Diff 61194.Jun 19 2016, 3:02 AM
grimar marked 8 inline comments as done.
  • Addressed review comments.
grimar added inline comments.Jun 19 2016, 3:03 AM
ELF/OutputSections.cpp
567

Done.

1449

Done.

1473

Done.

ELF/SymbolListFile.cpp
127–129

Oh. There was a bug here. It created new elf::Version for each global. Though that did not affect whole functionality, it is defenitely not what I wanted.
Fixed.

ELF/SymbolTable.cpp
531

Probably yes, but we also have VersionId of type uint16_t, so I am not sure how much it can be called accurate in total. Changed to size_t.

533

Done.

ELF/Symbols.h
422

72 vs 80, yes.
Moved it under uint8_t Binding; The same result but looks a bit nicer I think ?

ELF/Writer.cpp
121–123

Ah, sorry, I misunderstood at first. Fixed for Verdef (I think because of VerNeed it is not possible to perform that change for other 2, as Out<ELFT>::VerNeed->addSymbol(SS) called after creation of sections).

grimar retitled this revision from [ELF/WIP] - Basic versioned symbols support implemented. to [ELF] - Basic versioned symbols support implemented..Jun 19 2016, 3:15 AM
ruiu accepted this revision.Jun 19 2016, 10:43 PM
ruiu edited edge metadata.

LGTM

ELF/SymbolListFile.h
14

Remove.

ELF/SymbolTable.cpp
535

I'm wondering if this could be I++?

ELF/Writer.cpp
915–916

Add doesn't do anything if an argument is null. So you can remove the if guard.

This revision is now accepted and ready to land.Jun 19 2016, 10:43 PM
In D21018#461946, @ruiu wrote:

LGTM

What a good morning :) Thanks for review, I'll commit in a few hours then.

ELF/SymbolTable.cpp
535

No, because each Version can have a list of globals. And all of them should receive the same VersionId.

This revision was automatically updated to reflect the committed changes.