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
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
Scanf function requires look ahead to function properly, In case of
scanning from a buffer that will not be an issue, but in our case we are
reading from file, so lookaheads needs to be undone (via lseek) in our
case. The only problem here is that if we opened a file that doesn't
support lseek such as many of the file /dev/*
At least in relibc, each call to ungetc should decrement ftell() by one
also allowing negative ftell() this is not possible on relibc thus gcc
failing to compile (gcc compiles tools that is later used to compile gcc
itself and these tools are the ones that fail)
According to the standards, only one ungetc may be guaranteed however
glibc allows more than one of those, and to be glibc compatiable, one
needs to be able to do the same, allowing only 1 ungetc may trigger bug
while compiling gcc as ungetc is used there alot
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.
There was bug in printf where space paddings cause segfault,
the problem was that it was pulled from the stack twice while it should
be only done once.
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.
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
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.
This patch creates wctype.h and impelementat two functions
that belong to that header file towupper and towlower. These
functions are building blocks for wcscasecmp and wcsncasecmp
which are utilized by binutils.
The implementation for towlower and towupper seams to be complex
so this implementation is mimicking that of musl libc
This patch implements sys/user.h file that works for both x86_64 as well
as aarch64. This include file is used by sys/procfs.h which is needed
dependency for binutils. There is bug in this patch in aarch64 implementation
which is the lack of f128 implementation in rust, thus we can't create cbinding
for long double.
Most shared object in linux have their initialization in a separate
.init_array section. but glibc does not have the same behavour. Instead
the initialization is part of crt0. which (as it seams to me) run after
.init_array section. As such, this patch move IO initialization to
separate function that is marked as .init_array member and then the crt0
call this function only if init_array was never invoked (as in
statically linked binaries).
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
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.