Commit Graph

74 Commits

Author SHA1 Message Date
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
oddcoder 67be05d3a3 Use segments instead of sections for calculating which offset to write,
I noticed that the implementation is noth precise although it worked.
and instead of using the sections to identify memory addresses of
DT_DEBUG. I used segements
2020-05-03 14:59:52 +02:00
oddcoder 1182d12006 Fill gaps in binary memory image
Some ELFs can have gaps between the segments, this results in problems
when mprotecting or when converting (addr + size) into rust slice.
Motivated by this This patch will fill these gaps with mmaped addresses.
In theory no real memory should be allocated because mmap is lazy
allocator.
2020-05-03 13:57:24 +02:00
oddcoder 6aeb2d6fa2 Implement code that use .init_array and .fini_array
This patch implements ld.so code that makes use of both .init_array and
.fini_array. .init_array is fully utilized and is used in the correct
manner. However .fini_array is not used yet although the function that
runs .fini_array exists
2020-04-19 14:21:23 +02:00
oddcoder cc7ff54d12 Catch circular dependency when resolving loading shared libraries
This patch implements tree-based data-structure for catching circular
dependency where libA.so will depen on arbitrarily long chain (including
zero length) of libNs.so one of which will depend on libA.so again. The
main intention of this patch was merely capturing the dependency tree to
prioterize which Elf's .init_array and which .fini_array should run
first, but as a side effect it can capture circular dependencies as well.
2020-04-19 13:28:53 +02:00
oddcoder de03566158 Enable RTLD debugging protocol system-wide
This patch makes use of the data structures and functions impelemented
in the last patch to enable RTLD debugging protocol as per SVR4
2020-04-13 12:39:51 +02:00
oddcoder 369d7b42c6 Initial implementation of SVR4 debugging interface for runtime linker 2020-04-13 12:12:48 +02:00
oddcoder cc305fc574 Use Kernel mapped binaries when available.
At least in linux kernel, assuming that a.out is an elf that is linked
against relibc's own ld.so. When a user attempts `./a.out`, Linux kernel
will map `./a.out`, then map `ld.so` and jump into ld.so entry point.
In relibc ld.so will simply ignore the kernel mapped a.out and create
its own mapping. This patch forces relic ld.so to use the already mapped
`a.out` when ever possible. This would normally have slight performance
improvement (especially that currently relibc doesn't map a.out but
instead copy the data into empty mmaped memory).

The real motivation behind this patch is while impelemnting Runtime
linker debugging protocol for relibc. part of the protocol is ld.so
inseting address of some ld.so managed data structure into .dynamic
seciton of a.out then the debugger would check it there. The thing is
that debuggers have information about the kernel loaded ./a.out and they
check that one specifically which is in our case totally ignored by
relibc.
2020-04-07 21:26:58 +02:00
Jeremy Soller 701e64b3a1 ld_so: Default to non-verbose 2020-03-29 20:17:29 -06:00
oddcoder 4860ab12fa Resolve Both strong and weak symbols
This patch keep 2 lists, one for strong symbols and one for weak
symbols. First it will check for the symbol to be resolved in the strong
symbols' list, if it is not there it will then check in the weak symbol
list.
2020-03-08 22:03:21 +02:00
oddcoder c2488b5094 Running ./fmt.sh
These files needs formating by the auto formatter and It keeps popping
up every time I format my own code.
2020-03-07 23:52:27 +02:00
oddcoder 04ea2f9397 Refactor Linker::Link
This patch does basically two things:
- First make `global` variable not public, And make it accessable via a
function `get_sym`.
- Isolate the procedure that collect global symbols into single function
that does that and call it `collect_syms`.

The motivation of this patch is the second one where this procedure is
extended, thus it needs a seamless way to access those symbols
2020-03-07 23:52:27 +02:00
Jeremy Soller 79f265745a Fix redox ld_so 2020-02-28 19:33:20 -07:00
oddcoder bc53164293 Reduce Verbosity level when ld.so is invoked as interpreter 2020-02-24 11:56:12 +02:00
oddcoder 7f8dc2f251 Add support for invoking ld.so via execve() and friends
Introduction:

The original implementation of `relibc_ld_so_start` assumes that
ld.so will always be invoked manually as in "/lib/ld64.so ./a.out"
The problem is regarding this snippet.
    if sp.argc < 2 {
      eprintln!("ld.so [executable] [arguments...]");
      unistd::_exit(1);
      loop {}
    }

As such, In linux when user types "./a.out" he will recieve the message
    ld.so [executable] [arguments...]

This patch makes use of AUXV, specifically AT_ENTRY. When invoking ld.so
manually, AT_ENTRY happens to be the entry point of ld.so. But when
running `./a.out` directly, AT_ENTRY becomes the entry point of `a.out`
this patch compares AT_ENTRY to the entry point of ld.so, if they are
equal only then it will assume that argv[1] is the real program and
adjust the stack, otherwise it will proceed with the stack unadjusted.
2020-02-24 11:56:09 +02:00
Jeremy Soller a3f7a174f6 WIP - implementation of dlfcn 2019-12-18 21:21:25 -07:00
Jeremy Soller 2cbc78f238 Add linker pointer 2019-12-18 21:15:00 -07:00
Jeremy Soller 36eb561128 Format 2019-12-18 20:01:48 -07:00
Jeremy Soller 086c8f6702 Allow running linker more than once 2019-12-17 21:35:47 -07:00
Jeremy Soller 0a06388d2a Store globals and mappings on Linker struct 2019-12-16 21:27:42 -07:00
Jeremy Soller b882ce527d Fix allocation of TLS masters if main image does not require TLS 2019-12-15 11:19:37 -07:00
Jeremy Soller 4818ad61ab Always zero mmap'd memory 2019-12-15 07:46:59 -07:00
Jeremy Soller 886f859bb9 Clear FPU registers before jumping to loaded program 2019-12-15 07:46:49 -07:00
Jeremy Soller fe3607d4e8 ld_so: Zero mapped memory and panic on unsupported relocation 2019-12-06 19:54:54 -07:00