Commit Graph

97 Commits

Author SHA1 Message Date
Jeremy Soller a16f535ee8 Merge branch 'aarch64-fixups' into 'master'
aarch64: TLS arch_read implementation

See merge request redox-os/relibc!330
2021-01-18 22:56:49 +00:00
Robin Randhawa 886f467a75 aarch64: TLS arch_read implementation 2021-01-18 22:01:32 +00:00
Mateusz Tabaka 910fb59006 Change ld.so linker script file name for x86_64 Linux to fix compilation issue 2021-01-14 19:50:36 +01:00
Jeremy Soller d94e445ae2 Remove Linux search paths from Redox ld_so 2021-01-11 08:52:57 -07:00
Jeremy Soller 3c1300e8ec Improvements for aarch64 support 2021-01-11 08:52:20 -07:00
Jeremy Soller ccee7eae5f Merge branch 'tlssym' into 'master'
Fix dlsym of TLS variables

See merge request redox-os/relibc!327
2021-01-05 23:03:10 +00:00
Mateusz Tabaka 6497d71d2f Fix dlsym of TLS variables 2021-01-05 22:33:22 +01:00
Mateusz Tabaka 6332828725 Call DSO destructors during exit() 2021-01-05 20:39:36 +01:00
Mateusz Tabaka a7480ea656 Fix global symbols relocations
Instead of a single source of symbols, now linker keeps a list of DSO (former Library) objects
with their own symbols map. That helps to process R_X86_64_COPY relocations correctly.
For example, if 'a.out' executable with dependencies ['libstdc++.so', 'libc.so'] is being loaded
and 'a.out' uses 'stdout' symbol from 'libc.so', its relocation process goes as follows:
- linker processes relocation entry 'stdout' of type R_X86_64_GLOB_DAT from 'libc.so',
- it goes through object list ['a.out', 'libstdc++.so', 'libc.so'] to find first object
  that exports 'stdout' symbol. The symbol is in 'a.out' with the value e.g. '0x404070',
- linker sets 'stdout' symbol GOT entry in 'libc.so' to '0x404070',
....
- linker processes relocation entry 'stdout' of type R_X86_64_COPY from 'a.out',
- it goes through object list excluding 'a.out': ['libstdc++.so', 'libc.so']. The symbol is found in 'libc.so',
- linker copies the 'stdout' symbol content from 'libc.so' to memory at address '0x404070' (in 'a.out' object).

Objects are relocated in reverse order they were loaded. So in the example above, linker starts with relocating
'libc.so' and ends with 'a.out'. It is necessary e.g. when linking with 'libstdc++.so' - there are many
relocations which symbols are found in 'libstdc++.so', so they need to be resolved before their contents are
copied to 'a.out'. That also matches GNU ld.so behavior.
2021-01-03 16:04:40 +01:00
Jeremy Soller 3e49323a3a Merge branch 'dlopen' into 'master'
Add support for dlopen(NULL, ...)

See merge request redox-os/relibc!315
2020-10-02 03:21:42 +00:00
Mateusz Tabaka eee9a80baa Fix tls tests for dynamic linker
* load TLS segment for executable - while we can skip PT_LOAD for executable,
  we still have to load TLS segment.
* set TCB address based on if elf is position independent
2020-10-01 15:45:55 +02:00
Mateusz Tabaka c11aad71b8 Add support for dlopen(NULL, ...) 2020-09-30 11:04:10 +02:00
Mateusz Tabaka 7829a7ade9 Add support for RUNPATH 2020-09-29 23:01:48 +02:00
Mateusz Tabaka 42acd32ac0 Fix TCB master address 2020-09-29 19:15:21 +02:00
Mateusz Tabaka b05d8df5f8 Restore previous load address for ld_so
Current value gives us 0x1234000 - 0x400000 ~ 14 MB for executable,
which is too low for certain programs.
2020-09-29 18:58:35 +02:00
Jeremy Soller 7db83596a2 Merge branch 'gcc_compile' into 'master'
Gcc compile

See merge request redox-os/relibc!303
2020-08-14 15:19:14 +00:00
oddcoder ab92ff9d41 make all ld printlns happen in case of verbose = true and apply cargo fmt
It seams that stdout of ld.so is not that much of an issue but actually
it unfortunately is. The major problem here is that sometimes programs
generate header files in stdout (./getmy_custom_headers > header.h) and
we need to keep that cleen. and this is very very popular in gcc.
2020-08-12 18:57:37 +02:00
oddcoder 7b29f6eb27 Avoid relinking already linked libs
This patch avoids collecting symbols, resolving relocs if they are
already done (usually for example libc.so during a dlopen for another
libfoo.so). This patch is purely for performance boost.
2020-08-12 18:57:37 +02:00
oddcoder 61fcc018fc Refer to libraries with soname if available and avoid loading libs twice
It is usually not optimal to load a library twice and for specifics,
it is **terrible** idea to load libc twice it was enough trouble
dealing with libc statically linked into ld.so. So What this patch does
it check for soname and if a library is already loaded it won't get
loaded again. Why soname ? because unfortunately some bins gets linked
againt libc.so while of their dependencies gets linked against
libc.so.6 while one is usually symbolic link for the other.
2020-08-12 18:57:37 +02:00
Ahmed Abd El Mawgood 40328a0d09 Modify ld_script so that it works on linux.
Honestly, I have no idea why are these modifications needed, but it
seams they are needed
2020-08-12 10:19:32 +00:00
jD91mZM2 0178565f71 Move text section of linker away
Seems to collide with the program being loaded
2020-08-04 12:24:51 +00:00
Jeremy Soller 0c6398abcb Do not require allocation in static_init 2020-08-02 14:32:20 -06:00
Jeremy Soller ebb17654f8 Add llvm_asm features 2020-08-02 13:42:34 -06:00
Jeremy Soller 5d45042d5d Correct more asm! usages 2020-08-02 13:38:29 -06:00
Jeremy Soller f2c2d7c52e Fix compilation on newer nightly, update nightly to 2020-08-01 2020-08-02 12:24:49 -06:00
oddcoder 37a462de5d Apply cargo fmt to the whole repo 2020-07-19 21:27:38 +02:00
no name 890a9ed033 Implement dlopen/close 2020-07-19 21:27:38 +02:00
oddcoder ea3265766c Allow struct Linker to specify which library space to use 2020-07-19 21:21:48 +02:00
oddcoder 02aa400c5c Add callbacks to ld.so version of Linker's function
It is fact that ld.so has libc statially linked into it.

Normally we wouldn't need ld.so functionality once the program is
finalyl loaded, but with the next few patches, we will have dlopen which
will reuse the same ld.so functionality.

The problem is that it seams that huge part of the code is possible not
referntially transparent. That is, it is not impossible that some of the
functions have internals states. So when using the struct Linker that is
initialized by ld.so's copy of libc. we must access it using the same
copy even if both copies are identical.
For example in dlopen if you do linker.load_library(..). That would
segfault because it is using the function from libc not ld.so

So I don't truly undestand why should this be needed, but after long
hours of being stuck I thought maybe.. maybe that is the issue and
indeed it turned out to be so.
2020-07-19 21:21:48 +02:00
oddcoder b4a6a7ece5 Refactor init and fini by merging common code 2020-07-19 21:21:48 +02:00
oddcoder 6d0c9dccd5 Allow Linker struct to specify with library name space to operate on 2020-07-19 21:21:48 +02:00
oddcoder 01b1738b3a Separate library specific data from main Linker struct 2020-07-19 21:21:48 +02:00
oddcoder aaf017d9d1 Fix regression introduced in 5fcf9206
I by mistake commented _dl_debug_state() function which would break
debugging
2020-07-19 21:21:48 +02:00
no name 40acadc7d5 Sanity checking 04f77881d0 2020-07-18 21:15:57 +02:00
oddcoder 3a8817072c Initialize the mspaces of allocator and keep track of it 2020-07-18 21:03:20 +02:00
oddcoder d4b2391221 Fix wrong TLS resolving
I attempted fixing this issue before at 43fbaf99. Although it did work,
it worked wrong, and it was just consistently working (but in wrong way)
until it didn't.

Since this is (hopefully) the real fix, I will try to explain exactly
what is going on.

This is explaination by example:

our TLS is memory of size 0x1000 starting at 0x7ffff6c50000,
but the real size is 0x000068 so we have padding stored at master.offset
= 0xf98

Now our symbol looks as follows

  Offset          Type                Sym. Value    Name
000000432b20  R_X86_64_DTPOFF64   0000000000000058 errno

The old code did 0x7ffff6c50000 + 0xf98 + 000000432b20 which is
obviosly overflowing the memory and wrong.

The right way 0x7ffff6c50000 + 0xf98 + 0000000000000058.

THe Tls base part and offset are added at __tls_get_addr function.
What is left is storing the 0x58 at the relocation address. The problem
is that we don't have 0x58, but we have (binary base + 0x58) in global
symbol table and binary base so what we store is the (binarybase + 0x58
- binary base).

I hope this does turn out to be wrong.
2020-07-18 20:45:37 +02:00
oddcoder 5fcf920675 Fix bugs in handling non pie elfs
The problem here was that we alway added the base address, and we
assumed that all addresses we access are relative but this is not the
case in case of non pie binaries. The issue is that all addresses were
base+offset. so if we added the base again it will ofcourse generate
wrong address.
2020-06-24 10:21:20 +02:00
Jeremy Soller db6a589421 Merge branch 'LD_LIBRARY_PATH' into 'master'
Ld library path

See merge request redox-os/relibc!279
2020-06-20 13:17:40 +00:00
oddcoder 0977133cc9 Get rid of assembly code in call_inits_finis 2020-06-20 15:01:13 +02:00
oddcoder 81da1bb1a3 Fix the avoid accessing errno issue from ld_so for real this time
This patch implements access function for both redox and linux and makes
sure that neither access errno variable
2020-06-13 19:55:33 +02:00
no name d5b63a85a4 Revert "Fix compilation on Redox by removing use of access in ld_so"
This reverts commit d9bacaec04.
2020-06-13 19:55:33 +02:00
no name c3ae8022ba Revert "Handle missing paths in load_library search without using access"
This reverts commit b0dde81c75.

The main issue was not with "access" being used, it was with errno being
accessed. This patch accesses errno as well

LD_LIBRARY_PATH="/folder/with/no/libc" ./a.out

gives segfault with the following stack trace

0x00000000004d1cae in relibc::platform::sys::e (sys=18446744073709551614) at src/platform/linux/mod.rs:54
 54                  errno = -(sys as isize) as c_int;
(gdb) bt
 #0  0x00000000004d1cae in relibc::platform::sys::e (sys=18446744073709551614) at src/platform/linux/mod.rs:54
 #1  0x00000000004d361e in <relibc::platform::sys::Sys as relibc::platform::pal::Pal>::open (path=0x5555555634c0, oflag=524288, mode=0) at src/platform/linux/mod.rs:330
 #2  0x000000000049a2ad in relibc::fs::File::open (path=0x5555555634c0, oflag=524288) at src/fs.rs:28
 #3  0x0000000000482b49 in relibc::ld_so::linker::Linker::load_recursive (self=0x7fffffffdd30, name=..., path=...) at src/ld_so/linker.rs:119
 #4  0x0000000000484963 in relibc::ld_so::linker::Linker::load_library (self=0x7fffffffdd30, name=...) at src/ld_so/linker.rs:184
 #5  0x0000000000483b53 in relibc::ld_so::linker::Linker::load_data (self=0x7fffffffdd30, name=..., data=...) at src/ld_so/linker.rs:152
 #6  0x00000000004831fe in relibc::ld_so::linker::Linker::load_recursive (self=0x7fffffffdd30, name=..., path=...) at src/ld_so/linker.rs:140
 #7  0x000000000048228a in relibc::ld_so::linker::Linker::load (self=0x7fffffffdd30, name=..., path=...) at src/ld_so/linker.rs:97
 #8  0x0000000000414a3b in relibc_ld_so_start (sp=0x7fffffffe310, ld_entry=4198896) at src/ld_so/start.rs:182
 #9  0x0000000000401209 in _start () at src/ld_so/src/lib.rs:10
 #10 0x0000000000000001 in ?? ()
 #11 0x00007fffffffe592 in ?? ()
 #12 0x0000000000000000 in ?? ()
2020-06-13 19:55:33 +02:00
Jeremy Soller b0dde81c75 Handle missing paths in load_library search without using access 2020-06-07 14:00:48 -06:00
Jeremy Soller d9bacaec04 Fix compilation on Redox by removing use of access in ld_so 2020-06-06 21:00:57 -06:00
oddcoder 164ef739b3 Apply Cargo fmt for src/ld_so 2020-06-03 23:20:52 +02:00
oddcoder 3aacc160a1 Remove dependency on errno in ld.so
During early parts of ld.so, errno and other thread local variables are
not yet initialized so we cannot use function (such as unistd::access)
that depends on such thread local variables (errno). For this reason
this patch creates small wrapper around the syscall that doesn't not
touch the errno
2020-06-01 11:49:38 +02:00
oddcoder 1b10c3d246 Prioterize search path instead of overwriting it.
Current LD_LIBRARY_PATH implementation overwrites the original search
path, which is not the best idea, instead this patch would check
LD_LIBRARY_PATH first and if it didn't find the libraries it is looking
for, then it will search the original search path
2020-06-01 11:41:19 +02:00
oddcoder 43fbaf9970 Fix a bug in thread local reloations
There was a bug (also uncovered via binutils) where R_X86_64_DTPOFF64 is
set uncorrectly. This program is the minimal reproducer of the seg fault

  #include <errno.h>
  int main() {
        int oerrno = errno;
  }

But it works after the bug fix.
2020-05-13 23:46:39 +02:00
oddcoder d62f9b6819 Fix regression in ld.so elf size calculation
In patch 1182d12006, I mistakingly added
the size of the gap to the total size of the binary, which was not
accurate. As the size of the binary was calculate by subtracting the
upperbound from the lower bound, thus all gaps in the middle are taking
into account.
2020-05-08 22:38:42 +02:00
oddcoder 850dfd971b Make "./a.out" entry the first in rmap list
This fixes a regression in gdb where sometimes it decides to ignore the
first entry in the list.
2020-05-03 14:59:55 +02:00