Files
RedBear-OS/tests/Makefile
T
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

245 lines
4.2 KiB
Makefile

# Binaries that should generate the same output every time
EXPECT_NAMES=\
alloca \
args \
arpainet \
assert \
constructor \
ctype \
dirent/scandir \
errno \
error \
fcntl/create \
fcntl/fcntl \
fnmatch \
futimens \
libgen \
locale \
math \
netdb/getaddrinfo \
ptrace \
regex \
select \
setjmp \
sigaction \
signal \
stdio/all \
stdio/buffer \
stdio/fgets \
stdio/fputs \
stdio/fread \
stdio/freopen \
stdio/fseek \
stdio/fwrite \
stdio/getc_unget \
stdio/mutex \
stdio/popen \
stdio/printf \
stdio/rename \
stdio/scanf \
stdio/setvbuf \
stdio/sprintf \
stdio/printf_space_pad \
stdio/ungetc_ftell \
stdio/ungetc_multiple \
stdio/fscanf_offby1 \
stdio/fscanf \
stdio/printf_neg_pad \
stdlib/a64l \
stdlib/alloc \
stdlib/atof \
stdlib/atoi \
stdlib/div \
stdlib/env \
stdlib/mkostemps \
stdlib/rand \
stdlib/rand48 \
stdlib/random \
stdlib/strtod \
stdlib/strtol \
stdlib/strtoul \
stdlib/system \
string/mem \
string/strcat \
string/strchr \
string/strcpy \
string/strcspn \
string/strlen \
string/strncmp \
string/strpbrk \
string/strrchr \
string/strspn \
string/strstr \
string/strtok \
string/strtok_r \
string/strsignal \
strings \
sys_mman \
time/asctime \
time/gmtime \
time/localtime \
time/macros \
time/mktime \
time/strftime \
time/time \
tls \
unistd/access \
unistd/brk \
unistd/dup \
unistd/exec \
unistd/fchdir \
unistd/fork \
unistd/fsync \
unistd/ftruncate \
unistd/getopt \
unistd/getopt_long \
unistd/pipe \
unistd/rmdir \
unistd/sleep \
unistd/swab \
unistd/write \
waitpid \
wchar/fwide \
wchar/mbrtowc \
wchar/mbsrtowcs \
wchar/printf-on-wchars \
wchar/putwchar \
wchar/wcrtomb \
wchar/wcscspn \
wchar/wcsrchr \
wchar/wcsstr \
wchar/wcstod \
wchar/wcstok \
wchar/wcstol \
wchar/wcscasecmp \
wchar/wcsncasecmp \
wctype/towlower \
wctype/towupper
# TODO: Fix these
# mkfifo
# netdb/netdb \
# need to call fini in ld_so's _start
STATIC_ONLY_NAMES=\
destructor
DYNAMIC_ONLY_NAMES=\
dlfcn
# Binaries that may generate varied output
NAMES=\
$(EXPECT_NAMES) \
dirent/main \
pwd \
stdio/tempnam \
stdio/tmpnam \
stdlib/bsearch \
stdlib/mktemp \
stdlib/realpath \
sys_epoll/epoll \
sys_utsname/uname \
time/gettimeofday \
unistd/chdir \
unistd/getcwd \
unistd/gethostname \
unistd/getid \
unistd/getpagesize \
unistd/isatty \
unistd/link \
unistd/pathconf \
unistd/setid \
unistd/stat \
unistd/sysconf
# resource/getrusage
# time/times
BINS=$(patsubst %,bins_static/%,$(NAMES))
BINS+=$(patsubst %,bins_static/%,$(STATIC_ONLY_NAMES))
BINS+=$(patsubst %,bins_dynamic/%,$(NAMES))
BINS+=$(patsubst %,bins_dynamic/%,$(DYNAMIC_ONLY_NAMES))
EXPECT_BINS=$(patsubst %,bins_static/%,$(EXPECT_NAMES))
EXPECT_BINS+=$(patsubst %,bins_static/%,$(STATIC_ONLY_NAMES))
EXPECT_BINS+=$(patsubst %,bins_dynamic/%,$(EXPECT_NAMES))
EXPECT_BINS+=$(patsubst %,bins_dynamic/%,$(DYNAMIC_ONLY_NAMES))
TEST_RUNNER?=sh --
.PHONY: all clean run expected verify
all: $(BINS)
clean:
rm -rf bins_* gen *.out
run: | $(BINS)
for bin in $(BINS); \
do \
echo "# $${bin} #"; \
"$${bin}" test args || exit $$?; \
done
expected: | $(EXPECT_BINS)
rm -rf expected
mkdir -p expected
for bin in $(EXPECT_BINS); \
do \
echo "# $${bin} #"; \
mkdir -p expected/`dirname $${bin}`; \
"$${bin}" test args > "expected/$${bin}.stdout" 2> "expected/$${bin}.stderr" || exit $$?; \
done
verify: | $(EXPECT_BINS)
$(TEST_RUNNER) ./verify.sh $(EXPECT_BINS)
FLAGS=\
-std=c11 \
-fno-builtin \
-fno-stack-protector \
-Wall \
-pedantic \
-g \
-I .
STATIC_FLAGS=\
-static
DYNAMIC_FLAGS=\
-Wl,--enable-new-dtags \
-Wl,-export-dynamic
../sysroot:
$(MAKE) -C .. sysroot
NATIVE_RELIBC?=0
ifeq ($(NATIVE_RELIBC),0)
FLAGS+=\
-nostdinc \
-nostdlib \
-isystem ../sysroot/include \
../sysroot/lib/crt0.o \
../sysroot/lib/crti.o \
../sysroot/lib/crtn.o
SYSROOT_LIB=$(shell realpath ../sysroot/lib/)
STATIC_FLAGS+=\
$(SYSROOT_LIB)/libc.a
DYNAMIC_FLAGS+=\
-Wl,-dynamic-linker=$(SYSROOT_LIB)/ld64.so.1 \
-Wl,-rpath=$(SYSROOT_LIB):\$$ORIGIN \
-L $(SYSROOT_LIB) \
-lc
DEPS=../sysroot
endif
bins_static/%: %.c $(DEPS)
mkdir -p "$$(dirname "$@")"
$(CC) "$<" -o "$@" $(FLAGS) $(STATIC_FLAGS)
bins_dynamic/%: %.c $(DEPS)
mkdir -p "$$(dirname "$@")"
$(CC) "$<" -o "$@" $(FLAGS) $(DYNAMIC_FLAGS)