This is an archive of the discontinued LLVM Phabricator instance.

[InputGraph][Gnu] Add Linkerscript support.
AbandonedPublic

Authored by MaskRay on Nov 19 2013, 8:36 PM.

Details

Summary

This adds new functionality in the InputGraph to parse LinkerScripts.

a) Adds support to expand nodes in the InputGraph.
b) Support for Hidden nodes(Nodes that are internal to the InputGraph, and not part of resolution and parsing).
c) Adds a GnuLdScript/ELFGNULdScript node.

With this dynamic glibc helloworld runs fine(dynamic 'C').

As mentioned earlier by Bigcheese, it also links with libstdc++ with appropriate relocations (dynamic) but fails to run.

<-----------------snip---------------->
$type g++
g++ is hashed (/usr/bin/g++)
$cat a.cpp
#include <iostream>
#include <stdio.h>

class A{
public:

A() {
  std::cout << "A" << std::endl;
}

~A() {
  std::cout << "~A" << std::endl;
}

};

int main()
{

A a;
return 0;

}

$g++ -B`pwd` a.cpp
lld -flavor gnu --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=both -dynamic-linker /lib64/ld-linux-x86-64.so.2 -z relro /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../lib/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../lib/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.8/crtbegin.o -L/usr2/seaswara/tests/lld/extratests/dyncpp -L/usr/lib/gcc/x86_64-linux-gnu/4.8 -L/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.8/../../.. /tmp/ccPK1vpI.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/4.8/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../lib/crtn.o

$readelf -r a.out

Relocation section '.rela.dyn' at offset 0x796 contains 1 entries:

Offset          Info           Type           Sym. Value    Sym. Name + Addend

0000004b0298 000100000005 R_X86_64_COPY 00000000004b0298 _ZSt4cout + 0

Relocation section '.rela.plt' at offset 0x7ae contains 18 entries:

Offset          Info           Type           Sym. Value    Sym. Name + Addend

0000004ac248 000d00000007 R_X86_64_JUMP_SLO 0000000000000000 _Unwind_Resume + 0
0000004ac250 000300000007 R_X86_64_JUMP_SLO 0000000000000000 _ZNSt8ios_base4InitC1E + 0
0000004ac258 000500000007 R_X86_64_JUMP_SLO 0000000000000000 _ZNSt8ios_base4InitD1E + 0
0000004ac260 000200000007 R_X86_64_JUMP_SLO 0000000000000000 _ZStlsISt11char_traits + 0
0000004ac268 000600000007 R_X86_64_JUMP_SLO 0000000000000000 _ZSt4endlIcSt11char_tr + 0
0000004ac270 000700000007 R_X86_64_JUMP_SLO 0000000000000000 _ZNSolsEPFRSoS_E + 0
0000004ac278 000800000007 R_X86_64_JUMP_SLO 0000000000000000 gxx_personality_v0 + 0
0000004ac280 000000000025 R_X86_64_IRELATIV 0000000000419300
0000004ac288 001700000007 R_X86_64_JUMP_SLO 0000000000000000
gcc_personality_v0 + 0
0000004ac290 000000000025 R_X86_64_IRELATIV 0000000000413860
0000004ac298 000000000025 R_X86_64_IRELATIV 000000000042ef10
0000004ac2a0 000000000025 R_X86_64_IRELATIV 0000000000421140
0000004ac2a8 000000000025 R_X86_64_IRELATIV 000000000042b520
0000004ac2b0 000000000025 R_X86_64_IRELATIV 0000000000432ba0
0000004ac2b8 000000000025 R_X86_64_IRELATIV 00000000004668e0
0000004ac2c0 000000000025 R_X86_64_IRELATIV 0000000000464e50
0000004ac2c8 001900000007 R_X86_64_JUMP_SLO 0000000000000000 _Unwind_Backtrace + 0
0000004ac2d0 001800000007 R_X86_64_JUMP_SLO 0000000000000000 _Unwind_GetIP + 0

$./a.out
unexpected reloc type in static binaryAborted

<------------------snip----------------->

Diff Detail

Event Timeline

This seems like a really complicated way to do this. Why can't the linker script node just modify the input graph to add the extra nodes?

Also this has the unrelated undef from shared lib changes.

At the time when the linkerscript node is created or parsed, it has not yet been added to the InputGraph. For this to happen, the linkerscript node needs take InputGraph as one of the arguments, which I think would not be cleaner. Any better ways ?

The shared library changes were needed to have all of the linkerscript changes to work, otherwise it would go in a never ending loop with a helloworld test.

I will split this patch before I commit.

ruiu added a comment.Nov 20 2013, 3:41 PM

Is helloworld example work related to this linker script patch? It looks this patch does not add a new feature, so it looks to me taht it can link helloworld example only because of undef from shared library change. Is this correct?

I completely agree that this patch is combining other functionalities. But all these patches as a whole need to be used inorder to run the tests. This was the only reason of merging them all-together in one patch.

I will split this patch into 4 individual commits before I commit.

a) InputGraph functionality to expand elements
b) InputGraph functionality to set the hidden attribute
c) Add an API to linkingcontext on how undefined atoms from shared libraries need to be processed
d) Add LinkerScript nodes.

I dont know how to add this in the testing environment as GnuLD driver would try to look at the files before it adds to the InputGraph.

Any inputs on this would be really helpful.

ruiu added a comment.Nov 20 2013, 4:34 PM

It is completely fine to send multiple patches, saying that the second and further patches depends on the first one. That would actually help other developers review patch set. Each step needs to compile and pass all tests if applied in sequence, though.

I would make all the tests to work when you pick the individual commits. I am working on adding unit tests to the patches so that any new functionality doesnot break things.

Bigcheese resigned from this revision.Nov 14 2019, 1:10 PM
This revision now requires review to proceed.Nov 14 2019, 1:10 PM
MaskRay requested changes to this revision.Nov 14 2019, 1:23 PM
This revision now requires changes to proceed.Nov 14 2019, 1:23 PM
MaskRay commandeered this revision.Nov 14 2019, 1:23 PM
MaskRay abandoned this revision.
MaskRay edited reviewers, added: shankarke; removed: MaskRay.
lib/ReaderWriter/ELF/ELFLinkingContext.cpp